[WebXR Layers] Implement Cube layer
WebXR Layers는 웹 콘텐츠가 compositor layer를 XR 런타임에 직접 제출할 수 있도록 지원하며, 일반적인 framebuffer composition 과정을 우회합니다. WebKit은 XR 작업을 WebProcess(JS, GL 호출 담당)와 UIProcess(XR 세션 소유, OpenXR 통신 담당)로 분리합니다. Cube layer는 그중에서도 특히 까다로운 영역입니다. GL cube map은 6개의 면으로 구성되어 있고, 일반 2D texture처럼 DMABuf를 통해 프로세스 간에 공유할 수 없기 때문입니다.
Source/WebCore/Modules/webxr/WebXRWebGLSwapchain.cpp
이 commit은 XRCubeLayer를 end-to-end로 구현합니다. 구체적으로는 WebCore 측 swapchain 관리, 다중 면/배열 texture 처리를 일반화한 새로운 WebXRWebGLMultiTextureSwapchain abstract base 클래스, cube layer 데이터의 cross-process 직렬화, 그리고 XR_KHR_composition_layer_cube를 활용하는 OpenXR backend가 포함됩니다. 6개의 면은 IPC 전송을 위해 나란히 배치된 2D texture로 직렬화되고, UIProcess에서 reconstructCubeFaces()를 통해 재구성됩니다. Stereo 모드에서는 두 cube map에 걸쳐 12개의 면으로 확장됩니다. 모노/스테레오 모드와 texture-array 기반 cube layer 모두 지원됩니다.
Significance
WebProcess/UIProcess 경계를 넘나드는 상당한 규모의 GPU texture 관리 코드가 새로 추가되었습니다. 다중 면 cube map에 대한 복잡한 index 산술 연산이 포함되어 있어, integer overflow나 bounds confusion 버그가 숨어들기 쉬운 전형적인 영역에 해당합니다.
Audit directions
currentTextureAtIndex에서는 index = m_currentImageIndex * m_imageAttributes.arrayLength + cubeIndex 계산이 size_t/uint32_t 피연산자에 대해 수행됩니다. arrayLength가 크고 m_currentImageIndex도 작지 않은 값이라면, RELEASE_ASSERT에 도달하기 전에 곱셈 단계에서 overflow가 발생할 가능성이 있습니다. 이 경우 in-bounds이지만 잘못된 index가 만들어지게 됩니다. clearTextureRegion에서 slice 인수는 std::optional<GCGLint>(부호 있는 정수)로, negativity check 없이 uint32_t로 직접 캐스트됩니다. 음수 slice가 입력될 경우 매우 큰 unsigned index로 해석됩니다. arrayLength가 어디서 설정되는지, 웹 콘텐츠가 이 값을 조작할 수 있는지 추적해볼 필요가 있습니다. 만약 가능하다면, allocation 크기와 index 산술 연산 모두 공격자의 영향권 안에 들어오게 됩니다. 한편 PlatformXR.serialization.in에 새로 추가된 cubeLayerData의 IPC 직렬화 경로는 새로운 cross-process 공격 면으로, fuzzing을 적용하기에 적합한 대상입니다.