CVE-2026-7955
Overview
Files Changed
gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
Patch
From a8b79551f4bc5001d859115cede7eadcdd481257 Mon Sep 17 00:00:00 2001 From: Yuki Shiino <[email protected]> Date: Mon, 30 Mar 2026 08:04:44 -0700 Subject: [PATCH] [gpu] Mark SetCleared iff succeeded in PassthroughResources::SharedImageData::EnsureClear Bug: 496441232 Change-Id: I605e9f15400bd174979107f0729a359127e8328c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7706449 Reviewed-by: Saifuddin Hitawala <[email protected]> Commit-Queue: Saifuddin Hitawala <[email protected]> Auto-Submit: Yuki Shiino <[email protected]> Cr-Commit-Position: refs/heads/main@{#1607104} --- diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index 9514ae65..0947f6c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc @@ -473,13 +473,16 @@ api->glDisableFn(GL_SCISSOR_TEST); api->glClearFn(GL_COLOR_BUFFER_BIT); + if (api->glCheckFramebufferStatusEXTFn(GL_FRAMEBUFFER) == + GL_FRAMEBUFFER_COMPLETE) { + // Mark the shared image as cleared. + representation_->SetCleared(); + } + // Delete the generated framebuffer. api->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture->target(), 0, 0); api->glDeleteFramebuffersEXTFn(1, &fbo); - - // Mark the shared image as cleared. - representation_->SetCleared(); } }
Original Bug Report
GPU memory leak via unchecked GL errors in SharedImageData::EnsureClear
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: A compromised renderer can potentially read uninitialized GPU memory by creating a SharedImage with prefers_external_sampler=true. The GPU process’s EnsureClear function fails to clear GL_TEXTURE_EXTERNAL_OES textures on certain platforms due to silent GL attachment failures, but still marks them as cleared. The renderer can then sample the uncleared memory, leading to cross-origin or cross-process information disclosure.
Affected files:
gpu/command_buffer/service/gles2_cmd_decoder_passthrough.ccgpu/ipc/service/shared_image_stub.ccgpu/command_buffer/service/shared_image/ozone_image_backing_factory.ccgpu/command_buffer/service/shared_image/ozone_image_gl_textures_holder.cc
Estimated timestamp from git blame: 2022-07-21
Vulnerability Details
There is a potential high-severity information disclosure vulnerability in the GPU process. Specifically, the function PassthroughResources::SharedImageData::EnsureClear() in gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc fails to handle OpenGL errors when attempting to clear uninitialized SharedImage backing memory.
When a SharedImage is created with the prefers_external_sampler flag set to true, its underlying OpenGL texture is initialized with the GL_TEXTURE_EXTERNAL_OES target (see OzoneImageGLTexturesHolder). Later, to prevent uninitialized memory from being exposed to the renderer, the command buffer invokes EnsureClear().
Inside EnsureClear():
- A temporary Framebuffer Object (FBO) is generated.
- The code attempts to attach the texture to the FBO:
api->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture->target(), texture->service_id(), 0); - It issues a
glClearcommand. - It unconditionally executes
representation_->SetCleared(), marking the memory as safe for renderer consumption.
However, on certain platforms (such as Linux and ChromeOS using ANGLE-on-Vulkan), attaching a GL_TEXTURE_EXTERNAL_OES texture to an FBO is unsupported unless the GL_EXT_YUV_target extension is fully supported and enabled. In environments where it is not, the glFramebufferTexture2DEXTFn call silently fails and raises a GL_INVALID_OPERATION error. The FBO remains incomplete, causing the subsequent glClear to act as a silent no-op. Because EnsureClear() performs no error checking (e.g., glCheckFramebufferStatusEXT or glGetError), the uninitialized buffer is incorrectly marked as cleared.
Suggested Steps to Trigger
Note: These are potential steps suggested by our setup, which does not currently have the ability to run code to verify a working proof of concept.
- Compromise Renderer: An attacker gains arbitrary code execution within the sandboxed renderer process.
- Send IPC Request: The attacker crafts a
CreateSharedImageIPC request. They specify a multi-planar format (e.g.,NV12) and manually set theprefers_external_samplerflag totrue. - Bypass OS Constraints: On non-Windows/Apple platforms (e.g., Linux/Ozone),
SharedImageStub::CreateSharedImagedoes not block theprefers_external_samplerflag, allowing the request to proceed. - Allocate Uninitialized Memory: The
OzoneImageBackingFactoryallocates a fresh native pixmap (e.g., a dma-buf) containing uninitialized memory that may hold stale data from other processes or origins. - Trigger EnsureClear: The renderer sends a
CreateAndTexStorage2DSharedImageINTERNALcommand. The GPU process maps the mailbox and triggersPassthroughResources::SharedImageData::EnsureClear(). - Silent Failure: The FBO attachment fails silently due to the
GL_TEXTURE_EXTERNAL_OEStarget, the clear acts as a no-op, and the uninitialized image is marked ascleared. - Exfiltrate Data: The compromised renderer binds the texture, uses a GLSL shader with
samplerExternalOESto sample the uninitialized memory into a readable renderbuffer, and extracts the sensitive pixels usingglReadPixels.
Suggested Fix
The EnsureClear() function must verify that the clear operation actually succeeded before marking the representation as cleared.
- Introduce a check for framebuffer completeness (
api->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) after attaching the texture, or explicitly checkglGetError(). - If the FBO is incomplete,
EnsureClearmust not callrepresentation_->SetCleared(). - Instead, the implementation should either fallback to an alternative clear mechanism (e.g., clearing the native pixmap via CPU mapping or Skia before it is bound to GL), or explicitly fail the command and terminate the context to prevent uninitialized memory access.
Evaluated with Chrome root at commit: 0eb4855bda702feaaa8b899336664f97e3df88b8
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. Please feel free to reach out to me if you have concerns or feedback.