← All issues

[WebXR Layers] Implement Cube layer

bccc465

WebXR Layers let web content submit compositor layers directly to the XR runtime, bypassing normal framebuffer composition. WebKit splits XR work between the WebProcess (JS, GL calls) and the UIProcess (owns the XR session, talks to OpenXR). Cube layers are uniquely difficult: GL cube maps have 6 faces and cannot be shared across processes via DMABuf like ordinary 2D textures.

Source/WebCore/Modules/webxr/WebXRWebGLSwapchain.cpp

PlatformGLObject WebXRWebGLStaticImageSwapchain::currentTextureAtIndex(uint32_t cubeIndex)
{
if (m_imageAttributes.textureType != GL::TEXTURE_CUBE_MAP)
return currentTexture();
size_t index = m_currentImageIndex * m_imageAttributes.arrayLength + cubeIndex;
RELEASE_ASSERT(m_textures.size() > index);
return m_textures[index];
}

This commit implements XRCubeLayer end-to-end: WebCore-side swapchain management, a new WebXRWebGLMultiTextureSwapchain abstract base generalizing multi-face/array texture handling, cross-process serialization of cube layer data, and an OpenXR backend using XR_KHR_composition_layer_cube. The 6 faces are serialized into side-by-side 2D textures for IPC transfer, then reconstructed in the UIProcess via reconstructCubeFaces(). Stereo mode doubles this to 12 faces across two cube maps. Both mono/stereo and texture-array-backed cube layers are supported.

This is substantial new GPU texture-management code crossing the WebProcess/UIProcess boundary, with non-trivial index arithmetic over multi-face cube maps — exactly where integer overflow or bounds-confusion bugs tend to hide.

currentTextureAtIndex computes index = m_currentImageIndex * m_imageAttributes.arrayLength + cubeIndex over size_t/uint32_t operands — if arrayLength is large and m_currentImageIndex non-trivial, the multiplication can overflow before the RELEASE_ASSERT, producing an in-bounds-but-wrong index. In clearTextureRegion, the slice argument is a std::optional<GCGLint> (signed) cast directly to uint32_t without a negativity check; a negative slice becomes a large unsigned index. Trace where arrayLength is set and whether web content can influence it — if so, both allocation size and index arithmetic are attacker-influenced. The new IPC serialization path in PlatformXR.serialization.in for cubeLayerData is a fresh cross-process surface worth fuzzing.