CVE-2026-17810
Overview
Files Changed
src/dawn/native/opengl/PhysicalDeviceGL.cpp
Patch
From b84c4b43197dedf9e22d242270b497a138c6358c Mon Sep 17 00:00:00 2001 From: Shrek Shao <[email protected]> Date: Tue, 23 Jun 2026 09:30:58 -0700 Subject: [PATCH] Compat: Require GL_EXT_color_buffer_float for GL device creation Require the GL_EXT_color_buffer_float extension in PhysicalDevice::InitializeImpl(). As it is required in WebGPU compatibility mode spec. Since GL_EXT_color_buffer_float is now guaranteed in compat device, the CopyTextureToTexture vulnerability is gone. GL_EXT_color_buffer_half_float is subset so no need checking it anymore now. Bug: 516882109 Change-Id: I82ca687def2cd57d8a08ed84363f2bf85b93e784 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/318275 Commit-Queue: Shrek Shao <[email protected]> Auto-Submit: Shrek Shao <[email protected]> Reviewed-by: Stephen White <[email protected]> --- diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp index b597959..49d07ac 100644 --- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp +++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp @@ -158,6 +158,9 @@ switch (GetBackendType()) { case wgpu::BackendType::OpenGLES: DAWN_INVALID_IF(!mFunctions.IsAtLeastGLES(3, 1), "OpenGL ES 3.1 is required."); + DAWN_INVALID_IF(!mFunctions.IsAtLeastGLES(3, 2) && + !mFunctions.IsGLExtensionSupported("GL_EXT_color_buffer_float"), + "GL_EXT_color_buffer_float is required for OpenGL ES 3.1."); break; case wgpu::BackendType::OpenGL: DAWN_INVALID_IF(!mFunctions.IsAtLeastGL(4, 4), "Desktop OpenGL 4.4 is required."); @@ -443,11 +446,11 @@ bool supportsStencilWriteTexture = gl.GetVersion().IsDesktop() || gl.IsGLExtensionSupported("GL_OES_texture_stencil8"); - bool isFloat32Renderable = gl.GetVersion().IsDesktop() || gl.IsAtLeastGLES(3, 2) || - gl.IsGLExtensionSupported("GL_EXT_color_buffer_float"); - bool isFloat16Renderable = - isFloat32Renderable || gl.IsGLExtensionSupported("GL_EXT_color_buffer_half_float"); - bool isRG11B10UfloatRenderable = isFloat32Renderable; + DAWN_ASSERT(gl.GetVersion().IsDesktop() || gl.IsAtLeastGLES(3, 2) || + gl.IsGLExtensionSupported("GL_EXT_color_buffer_float")); + bool isFloat32Renderable = true; + bool isFloat16Renderable = true; + bool isRG11B10UfloatRenderable = true; // TODO(crbug.com/dawn/343): Investigate emulation. deviceToggles->Default(Toggle::DisableIndexedDrawBuffers, !supportsIndexedDrawBuffers);
Original Bug Report
Potential GPU memory leak on GLES 3.1 devices due to missing float format checks in T2T copies
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The texture-to-texture (T2T) copy workaround routing logic in Dawn lacks checks for float-renderability toggles. On OpenGL ES 3.1 devices where float renderability is unsupported, direct copies silently fail while the destination texture is incorrectly marked as initialized. Subsequent reads of the texture bypass lazy-clearing and expose uninitialized GPU heap memory.
Affected files:
third_party/dawn/src/dawn/native/CommandEncoder.cppthird_party/dawn/src/dawn/native/opengl/CommandBufferGL.cppthird_party/dawn/src/dawn/native/opengl/UtilsGL.cpp
Estimated timestamp from git blame: 2025-01-17
Description
There is a potential security vulnerability in Dawn’s Texture-to-Texture (T2T) copy path on OpenGL ES 3.1 devices that do not support float-renderability extensions (such as GL_EXT_color_buffer_float or GL_EXT_color_buffer_half_float).
In third_party/dawn/src/dawn/native/CommandEncoder.cpp, the function ShouldUseT2B2TForT2T determines if a copy operation must use an intermediate workaround buffer or if it can use a direct native copy. However, this function lacks checks for the following float-renderability toggles:
UseBlitForRG11B10UfloatTextureCopyUseBlitForFloat16TextureCopyUseBlitForFloat32TextureCopy
Because these toggles are not checked, ShouldUseT2B2TForT2T returns false on devices requiring float-copy workarounds, causing Dawn to attempt a direct native copy.
Mechanism of Failure
- When executing
CopyTextureToTextureinthird_party/dawn/src/dawn/native/opengl/CommandBufferGL.cpp, the destination texture subresource is marked as initialized before performing the actual copy if the copy completely covers the subresource:if (IsCompleteSubresourceCopiedTo(dstTexture, copySize.ToExtent3D(), dst.mipLevel, dst.aspect)) { dstTexture->SetIsSubresourceContentInitialized(true, dstRange); } - The OpenGL backend executes
CopyImageSubDatainthird_party/dawn/src/dawn/native/opengl/UtilsGL.cpp. On OpenGL ES 3.1 devices, it falls back to manualglBlitFramebufferemulation using temporary framebuffers (FBOs). - Attaching non-color-renderable textures to the FBO yields a
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTstatus, causingglBlitFramebufferto generate aGL_INVALID_FRAMEBUFFER_OPERATIONerror and fail silently without writing any data. - In release builds,
DAWN_GL_TRYcompiles to direct calls without active error-checking ((gl.call)), letting the failure pass silently. - The destination texture’s memory remains uninitialized, but internal tracking registers it as initialized. A subsequent readback via compute shader (T2B) samples raw, uninitialized GPU memory and transfers it to the renderer.
Potential Reproduction Steps
Note: These are suggested steps based on static analysis of the source code. Our tooling currently lacks the capability to execute live code on GLES 3.1 emulation targets.
- On a platform with a GLES 3.1 driver lacking float color-renderability (such as
GL_EXT_color_buffer_float), obtain a WebGPU compatibility adapter. - Create a destination float texture (
rgba16floatorrgba32float) and a source texture containing known data. - Execute a
copyTextureToTexturecall to copy the source to the destination completely. The destination is marked as initialized, but the copy silently fails. - Execute
copyTextureToBufferto read back the destination texture to a host-mappable buffer. The T2B path utilizes the compute shader blit workaround. - Because the destination is marked as initialized, the lazy-clearing check is bypassed. The compute shader reads uncleared GPU memory into the buffer, leaking cross-origin GPU heap data.
Suggested Fix
Update ShouldUseT2B2TForT2T in third_party/dawn/src/dawn/native/CommandEncoder.cpp to check float-renderability toggles and return true if they are enabled for the corresponding textures:
bool ShouldUseT2B2TForT2T(const DeviceBase* device,
const Format& srcFormat,
const Format& dstFormat) {
// ... existing checks ...
// Float formats checks
if ((srcFormat.format == wgpu::TextureFormat::RG11B10Ufloat &&
device->IsToggleEnabled(Toggle::UseBlitForRG11B10UfloatTextureCopy)) ||
((srcFormat.format == wgpu::TextureFormat::R16Float ||
srcFormat.format == wgpu::TextureFormat::RG16Float ||
srcFormat.format == wgpu::TextureFormat::RGBA16Float) &&
device->IsToggleEnabled(Toggle::UseBlitForFloat16TextureCopy)) ||
((srcFormat.format == wgpu::TextureFormat::R32Float ||
srcFormat.format == wgpu::TextureFormat::RG32Float ||
srcFormat.format == wgpu::TextureFormat::RGBA32Float) &&
device->IsToggleEnabled(Toggle::UseBlitForFloat32TextureCopy))) {
return true;
}
return false;
}
Evaluated with Chrome root at commit: b1520ef4a76878853a31f0943b565e42060edec8
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.