CVE-2026-9991
Overview
Files Changed
media/base/win/mf_helpers.cc
Patch
From 747eb44e5e8d318a03218102c1fb07a9d8792c86 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Thu, 14 May 2026 20:00:06 -0700
Subject: [PATCH] media: Make GL context current before resolving shared image in MF VEA
This change fixes an issue where `GenerateResourceOnSyncTokenReleased`
executed without making the GL context current.
We now use `SharedContextState::MakeCurrent()` to safely bind the
context before calling `ProduceVideo`.
Bug: 513173565
Change-Id: Id822177da2174e7f03d7da1553e4ab8bb64ab37f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7851364
Reviewed-by: Qiu, Jianlin <jianlin.qiu@intel.com>
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1631024}
---
diff --git a/media/base/win/mf_helpers.cc b/media/base/win/mf_helpers.cc
index e4bb6e2..63d9685 100644
--- a/media/base/win/mf_helpers.cc
+++ b/media/base/win/mf_helpers.cc
@@ -1080,8 +1080,14 @@
RETURN_ON_FAILURE_WITH_CALLBACK(E_FAIL, "Invalid shared context state");
}
+ auto shared_context_state = shared_image_stub->shared_context_state();
+ const bool needs_gl = !shared_context_state->IsGraphiteDawn();
+ if (!shared_context_state->MakeCurrent(nullptr, needs_gl)) {
+ RETURN_ON_FAILURE_WITH_CALLBACK(E_FAIL, "Failed to make context current");
+ }
+
Microsoft::WRL::ComPtr<ID3D11Device> shared_d3d11_device =
- shared_image_stub->shared_context_state()->GetD3D11Device();
+ shared_context_state->GetD3D11Device();
HRESULT hr = shared_d3d11_device ? S_OK : E_FAIL;
RETURN_ON_FAILURE_WITH_CALLBACK(hr, "Invalid shared d3d11 device");
bool use_same_device = (encoder_device.Get() == shared_d3d11_device.Get());
Original Bug Report
Potential cross-origin GPU texture leak via stale GL context in MFVEA
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 without the Chrome Security team. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: A potential vulnerability in the Media Foundation Video Encode Accelerator (MFVEA) could allow a compromised renderer to leak GPU texture data from other origins. The issue stems from failing to ensure a GL context is current before performing operations that rely on thread-local GL state. This leads to cross-origin texture ID confusion when using the passthrough command decoder.
Affected files:
media/base/win/mf_helpers.ccgpu/command_buffer/service/shared_image/d3d_image_representation.ccmedia/gpu/windows/media_foundation_video_encode_accelerator_win.cc
Estimated timestamp from git blame: 2025-01-28
Root Cause analysis
In media/base/win/mf_helpers.cc, the function media::GenerateResourceOnSyncTokenReleased() calls SharedImageManager::ProduceVideo() without first ensuring that a valid GL context is made current on the executing thread.
The callback for GenerateResourceOnSyncTokenReleased is scheduled on a dedicated GPU scheduler sequence (wait_sequence_id_) created by CommandBufferHelperImpl. This sequence executes on the GPU main thread but lacks associated GL context management. In Chrome’s GPU process, gl::g_current_gl_context is a thread_local variable. For performance, CommandBufferStub tasks leave the last used GL context current on the thread rather than clearing it upon completion. Consequently, when the MFVEA callback executes, it inherits whatever GL context was left bound by the previous task—likely a WebGL context belonging to a different renderer origin.
Potential execution Flow
When a mailbox resolves to a GLTextureImageBacking (which a compromised renderer can trigger by requesting GLES2_READ|WRITE usage), the following potential execution flow occurs:
SharedImageManager::ProduceVideocallsGLTextureImageBacking::ProduceVideo, which invokesD3D11VideoImageCopyRepresentation::CreateFromGLingpu/command_buffer/service/shared_image/d3d_image_representation.cc.CreateFromGLretrieves the stalethread_localGL context fromgl::g_current_gl_context.- It then issues GL commands, including
glCopySubTextureCHROMIUM(gl_texture_id, ...). Here,gl_texture_idis the service ID of the attacker’s SharedImage (allocated in theSharedContextState’s namespace). - Under the passthrough command decoder, every WebGL context and the
SharedContextStatehave distinct GL share groups. Service IDNfrom the attacker’s namespace may refer to a completely different texture in the victim’s stale context.
Because ANGLE allocates texture IDs sequentially, achieving an ID collision is trivial. If a collision occurs, the victim’s texture contents are copied into a D3D destination texture, which is then encoded by the Media Foundation Video Encode Accelerator. The resulting bitstream is then returned to the attacker’s renderer.
If no collision occurs or the stale context is in an error state, the code may hit a release-fatal CHECK_EQ(glGetError(), GL_NO_ERROR) in d3d_image_representation.cc, resulting in a GPU process crash.
Impact
This constitutes a potential high-severity cross-origin information leak, allowing an attacker to read pixel data from GPU textures belonging to other origins. Alternatively, it can be used to cause a Denial of Service by crashing the GPU process.
Suggested Fix
The fix is to ensure the SharedContextState’s GL context is made current before calling ProduceVideo. This matches the implementation already present in the sibling D3D12 encoder (media/gpu/windows/d3d12_video_encode_accelerator.cc:149).
// Suggested change in media/base/win/mf_helpers.cc
if (!shared_image_stub->shared_context_state()->MakeCurrent(nullptr)) {
RETURN_ON_FAILURE_WITH_CALLBACK(E_FAIL, "Failed to make context current");
}
Evaluated with Chrome root at commit: b3153093eb3c78c3e88ccf562bcbc20437a04b0e
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.