Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect authorization in GPU
DescriptionIncorrect authorization in GPU
ComponentGPU
Bug ClassLogic Error
Tracker513524705
Fix commitfc0834fae837 (chromium/src) +21/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-09-08

Background

Passthrough command decoder
The GLES2DecoderPassthrough implementation in gles2_cmd_decoder_passthrough.cc that forwards WebGL/GLES2 command-buffer calls to ANGLE with minimal translation.
`GL_TEXTURE_RECTANGLE_ANGLE`
An ANGLE texture-target capability the GPU process uses internally for WebGL contexts but does not expose to untrusted client code.
`IsIgnoredCap()`
A decoder helper that decides whether a capability requested via Enable/Disable command-buffer commands should be silently ignored (treated as GL_INVALID_ENUM) rather than passed through to the driver.
`ScopedEnableTextureRectangleInShaderCompiler`
A scoped helper that transiently re-enables GL_TEXTURE_RECTANGLE_ANGLE around internal shader compiles after it was disabled at context initialization.

Root Cause Analysis

For WebGL contexts, the passthrough decoder deliberately disables GL_TEXTURE_RECTANGLE_ANGLE at context init and only re-enables it internally, transiently, via ScopedEnableTextureRectangleInShaderCompiler around its own shader compiles. The invariant is that this capability must never be controllable by the client renderer, since it is internal-only and blocked in ANGLE for WebGL.

Before the fix, IsIgnoredCap() did not list GL_TEXTURE_RECTANGLE_ANGLE, so an Enable or Disable command carrying that enum fell through to the default branch (returning false) and was forwarded to the driver instead of being rejected. This let a compromised renderer toggle an internal-only capability out from under the decoder’s controlled scoping, an authorization gap in the command-buffer surface.

The fix adds a case GL_TEXTURE_RECTANGLE_ANGLE that returns feature_info_->IsWebGLContext(), causing the command to be ignored and to raise GL_INVALID_ENUM for WebGL/WebGPU-style contexts, restoring the invariant that only internal code manages this state.

Key insight
The single core mistake was omitting an internal-only capability (GL_TEXTURE_RECTANGLE_ANGLE) from the IsIgnoredCap() allow/deny list, leaving it client-reachable through Enable/Disable. The fix closes the gap by treating the capability as ignored for WebGL contexts so the command buffer rejects it with GL_INVALID_ENUM instead of forwarding it.

Attack Path

  1. Compromise the renderer An attacker first gains code execution in a renderer/GPU-client process, giving control over the raw command-buffer stream.
  2. Craft an Enable command The attacker emits an Enable (or Disable) command-buffer command with the internal-only enum GL_TEXTURE_RECTANGLE_ANGLE.
  3. Bypass the decoder check Because IsIgnoredCap() did not cover this enum, the decoder passes it through to ANGLE/the driver rather than rejecting it.
  4. Toggle internal-only state The attacker enables or disables the texture-rectangle capability outside the decoder’s controlled ScopedEnableTextureRectangleInShaderCompiler scoping, violating the intended internal-only usage.

Impact Assessment

An attacker who already controls a renderer gains the ability to manipulate an internal-only GPU capability that should never be client-reachable, i.e., an incorrect-authorization primitive in the GPU process command-buffer surface. This is a logic/authorization defect (medium severity) rather than a direct memory-corruption bug, and it requires the precondition of an already-compromised renderer able to submit arbitrary command-buffer commands. The exposure is scoped to WebGL contexts in the passthrough decoder.

Changed Functions

FunctionChangeNotes
TEST_F
gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
modified

Files Changed

  • gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
  • gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc

Audit Directions

  • Internal-only capability leakage
    Audit every capability the GPU process manages internally (via scoped helpers like ScopedEnableTextureRectangleInShaderCompiler) and confirm each is also listed in IsIgnoredCap() so it cannot be toggled through client Enable/Disable commands.
  • Enum allow-list completeness
    Review switch statements with a permissive default: return false; in command-buffer validation paths for missing internal-only enums that silently fall through to the driver.
  • Context-type gating
    Verify that internal-only state is gated on the correct context type (IsWebGLContext() and equivalent WebGPU checks) so a compromised renderer cannot reach it via a different context type than the one it was scoped for.
From fc0834fae837a6f60c86d2fb04febd191824307c Mon Sep 17 00:00:00 2001
From: Brandon Jones <bajones@chromium.org>
Date: Thu, 06 Aug 2026 15:21:41 -0700
Subject: [PATCH] Reject GL_TEXTURE_RECTANGLE_ANGLE for WebGL contexts

The passthrough decoder uses GL_TEXTURE_RECTANGLE_ANGLE internally
for WebGL contexts via ScopedEnableTextureRectangleInShaderCompiler,
disabling it at context init and re-enabling it only around internal
shader compiles. Adding to IsIgnoredCap() so a compromised renderer
cannot enable it with a WebGPU context.

Bug: 513524705
Change-Id: I9f45058a1a915edbe1b6d7af6fa36669f1c5dd1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8168700
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1675334}
---

diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 8cbf7ae..7fa98ea 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -2207,6 +2207,10 @@
       // it's blocked in ANGLE for WebGL contexts.
       return feature_info_->IsWebGLContext();
 
+    case GL_TEXTURE_RECTANGLE_ANGLE:
+      // Used internally, not exposed to WebGL contexts.
+      return feature_info_->IsWebGLContext();
+
     default:
       return false;
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
index 6073234b..6bb7fac4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
@@ -153,5 +153,22 @@
     GLES2DecoderPassthroughImmediateSizeArgCommandTest,
     ES3ImmediateSizeArgCommandTypes0);
 
+// GL_TEXTURE_RECTANGLE_ANGLE is only for internal use and should not be
+// reachable through the command buffer.
+TEST_F(GLES2WebGLDecoderPassthroughTest, EnableDisableTextureRectangle) {
+  {
+    cmds::Enable cmd;
+    cmd.Init(GL_TEXTURE_RECTANGLE_ANGLE);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  }
+  {
+    cmds::Disable cmd;
+    cmd.Init(GL_TEXTURE_RECTANGLE_ANGLE);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  }
+}
+
 }  // namespace gles2
 }  // namespace gpu
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
index 6073234b..6bb7fac4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_commands.cc
@@ -153,5 +153,22 @@
     GLES2DecoderPassthroughImmediateSizeArgCommandTest,
     ES3ImmediateSizeArgCommandTypes0);
 
+// GL_TEXTURE_RECTANGLE_ANGLE is only for internal use and should not be
+// reachable through the command buffer.
+TEST_F(GLES2WebGLDecoderPassthroughTest, EnableDisableTextureRectangle) {
+  {
+    cmds::Enable cmd;
+    cmd.Init(GL_TEXTURE_RECTANGLE_ANGLE);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  }
+  {
+    cmds::Disable cmd;
+    cmd.Init(GL_TEXTURE_RECTANGLE_ANGLE);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  }
+}
+
 }  // namespace gles2
 }  // namespace gpu
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential hardening bypass: Compromised renderer can re-enable GL_TEXTURE_RECTANGLE_ANGLE on macOS

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 GLES2 passthrough command decoder on macOS fails to block the GL_TEXTURE_RECTANGLE_ANGLE capability in its Enable command handler. A compromised renderer can potentially re-enable this internal-only capability to use restricted rectangle textures in WebGL shaders, bypassing a defense-in-depth measure.

Affected files:

  • gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
  • gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc

Estimated timestamp from git blame: 2020-01-30

Description

On macOS, Chromium uses the GL_TEXTURE_RECTANGLE_ANGLE capability internally to support IOSurface-backed textures. To prevent WebGL user shaders from accessing these textures, Chromium implements a hardening measure by explicitly disabling this capability for WebGL contexts during initialization. This isolation is enforced by the ANGLE shader translator, which blocks the ARB_texture_rectangle extension if the capability is disabled.

However, the passthrough command decoder’s DoEnable handler does not sufficiently filter this capability. The handler relies on IsIgnoredCap to block restricted enums, but IsIgnoredCap lacks an entry for GL_TEXTURE_RECTANGLE_ANGLE. Since ANGLE allows this capability to be toggled for WebGL contexts, a compromised renderer can re-enable it via a standard glEnable command.

Technical Details

In gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc, the capability is disabled at initialization for WebGL contexts:

#if BUILDFLAG(IS_MAC)
  if (feature_info_->IsWebGLContext())
    api()->glDisableFn(GL_TEXTURE_RECTANGLE_ANGLE);
#endif

The DoEnable implementation in gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc validates capabilities using IsIgnoredCap:

error::Error GLES2DecoderPassthroughImpl::DoEnable(GLenum cap) {
  if (IsIgnoredCap(cap)) {
    InsertError(GL_INVALID_ENUM, "Invalid cap.");
    return error::kNoError;
  }
  api()->glEnableFn(cap);
  return error::kNoError;
}

The IsIgnoredCap function in gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc fails to include GL_TEXTURE_RECTANGLE_ANGLE (0x84F5), allowing it to fall through to the default return false case. This allows the glEnable call to reach ANGLE.

Impact

By re-enabling GL_TEXTURE_RECTANGLE_ANGLE, the ANGLE shader translator will no longer set the disableARBTextureRectangle compiler option. This allows a compromised renderer to compile and execute shaders that use #extension GL_ARB_texture_rectangle : enable and sampler2DRect types. This represents a bypass of a hardening layer designed to isolate WebGL from internal macOS texture types.

Potential Steps to Reproduce

These steps are based on code analysis and represent a potential attack vector:

  1. From a compromised renderer process on macOS (using the ANGLE OpenGL backend), send a gles2::cmds::Enable command with cap = 0x84F5 (GL_TEXTURE_RECTANGLE_ANGLE).
  2. Send a ShaderSource command containing GLSL code that attempts to use the GL_ARB_texture_rectangle extension.
  3. Send a CompileShader command and observe that the shader compiles successfully.
  4. In a debug build, subsequent internal usage of ScopedEnableTextureRectangleInShaderCompiler may trigger a DCHECK in ui/gl/gl_utils.cc because the capability is unexpectedly already enabled.

Suggested Fix

Modify GLES2DecoderPassthroughImpl::IsIgnoredCap in gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc to include GL_TEXTURE_RECTANGLE_ANGLE, ensuring it returns true (or at least feature_info_->IsWebGLContext()) to block the renderer from toggling this state.

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.

View on issue tracker