High watch CVSS 9.6 chrome OOB 🔧 Commit mapped

Overview

High
Severity
9.6
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactOut of bounds write in WebGL
DescriptionOut of bounds write in WebGL
ComponentWebGL
Bug ClassOOB
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker549350408
Fix commit921d48815f19 (angle/angle) +27/-0
CWECWE-787 (Out-of-bounds write)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-08-20 (per vendor advisory)
Fix landed2026-08-26 (public git)
Disclosed2026-09-03
Patch gap8 days — fix public in source before the advisory

Background

ANGLE
the translation layer Chrome’s WebGL runs on top of, mapping GL/WebGL calls to the platform driver (here the OpenGL backend under src/libANGLE/renderer/gl).
`generateMipmap`
the GL operation that derives the smaller mipmap levels of a texture from its base level; ANGLE’s GL backend implements it in TextureGL.
IMG / PowerVR driver
the Imagination Technologies GPU driver family (IsPowerVR(vendor)), which the patch targets with a workaround.
`FeaturesGL` workaround flag
a per-driver toggle (here the new flushBeforeGenerateMipmap) that ANGLE enables conditionally to route around known driver defects.

Root Cause Analysis

On IMG/PowerVR drivers, calling generateMipmap while the texture’s base level is still bound to an active framebuffer object (FBO) drives the driver into “a bad state,” as both the commit message and the added code comment state. ANGLE’s TextureGL mipmap-generation path bound the texture and generated the mipmap without any intervening flush, so the driver processed the mipmap generation against unflushed/aliased FBO state and misbehaved, and the advisory classifies the consequence as an out-of-bounds write in WebGL.

The patch adds a new workaround feature flushBeforeGenerateMipmap, enabled via ANGLE_FEATURE_CONDITION(features, flushBeforeGenerateMipmap, IsPowerVR(vendor)), and in the mipmap-generation function inserts ANGLE_GL_TRY(context, functions->flush()) (guarded by features.flushBeforeGenerateMipmap.enabled) before stateManager->bindTexture(...) and the generate step. Forcing the flush drains the pending FBO work so the base level is no longer treated as an active render target when the mipmap is generated, avoiding the driver’s bad state. The change is a targeted driver workaround, not a bounds check in Chrome’s own code; the out-of-bounds write occurs inside the IMG driver’s handling of the unflushed state.

Key insight
The core mistake was issuing generateMipmap on IMG drivers without flushing while the texture’s base level was still bound to an active FBO, which corrupted driver state; the fix adds the flushBeforeGenerateMipmap workaround to force a flush() first on PowerVR hardware.

Attack Path

  1. Set up the aliasing A WebGL page binds a texture’s base level as an attachment of an active FBO and then requests mipmap generation for that same texture.
  2. Reach the vulnerable path On IMG/PowerVR hardware, ANGLE’s TextureGL mipmap-generation runs bindTexture and generates mipmaps with no flush, so the driver generates the mipmap while the base level is still an active render target.
  3. Driver enters bad state The IMG driver mishandles this unflushed, self-referential FBO/texture state, which the advisory reports as an out-of-bounds write in WebGL, occurring inside the GPU-process driver.
  4. Post-fix behavior With flushBeforeGenerateMipmap enabled on PowerVR, a functions->flush() runs first, draining the FBO work so generation no longer races the active binding; the concrete OOB-write primitive lives in the driver and is (inferred) beyond the advisory’s classification.

Impact Assessment

An attacker with WebGL access on IMG/PowerVR hardware can drive the driver into a state that produces an out-of-bounds write, in the GPU process, by generating a mipmap for a texture whose base level is still bound to an active FBO. The advisory reports an out-of-bounds write in WebGL and does not state exploitation in the wild; any escalation to memory corruption control or a sandbox escape is (inferred), and the vulnerability is gated on running the affected PowerVR driver.

Files Changed

  • util/autogen/angle_features_autogen.h
  • src/libANGLE/renderer/gl/renderergl_utils.cpp
  • include/platform/autogen/FeaturesGL_autogen.h
  • util/autogen/angle_features_autogen.cpp
  • src/libANGLE/renderer/gl/TextureGL.cpp
  • include/platform/gl_features.json

Audit Directions

  • Self-referential texture/FBO state
    Audit other GL operations invoked on a resource that is simultaneously bound as a render target (mipmap generation, copies, clears) for missing flushes or unbinds that leave the driver reading/writing aliased state.
  • Per-vendor driver workarounds
    Where a defect is fixed by a vendor-gated ANGLE_FEATURE_CONDITION, review sibling operations on the same driver family (IMG/PowerVR) for the same unflushed-state hazard that may not yet be worked around.
  • Ordering of flush vs. bind/generate
    Check code paths that assume the driver serializes pending FBO work implicitly; add explicit flushes where correctness depends on prior work completing before a texture-mutating call.
From 921d48815f191d63b93aeb9c9921ba6dd95b054e Mon Sep 17 00:00:00 2001
From: Brandon Jones <bajones@chromium.org>
Date: Thu, 20 Aug 2026 13:54:51 -0700
Subject: [PATCH] Insert flush before generateMipmap on IMG

Adds a feature which forces a flush before generating a mipmap,
which avoids a bad state in the IMG driver if the texture's base
level is still bound to an active FBO.

Fixed: chromium:549350408
Change-Id: Id69684690a0fb04a45e0fca7d912bac68f82052c
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/8265721
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
---
diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json
index 18a3244..7d9f4bb 100644
--- a/include/platform/gl_features.json
+++ b/include/platform/gl_features.json
@@ -963,6 +963,14 @@
             "issue": "http://crbug.com/475877320"
         },
         {
+            "name": "flush_before_generate_mipmap",
+            "category": "Workarounds",
+            "description": [
+                "Force a flush before calling generateMipmap to work around driver bugs."
+            ],
+            "issue": "http://crbug.com/549350408"
+        },
+        {
             "name": "split_level_0_pbo_full_sub_image_2D",
             "category": "Workarounds",
             "description": [
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index 63fc458..52c5e88 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -1622,6 +1622,13 @@
     StateManagerGL *stateManager      = GetStateManagerGL(context);
     const angle::FeaturesGL &features = GetFeaturesGL(context);
 
+    if (features.flushBeforeGenerateMipmap.enabled)
+    {
+        // Force a flush before generating the mipmap, which avoids a bad state in the IMG driver if
+        // the texture's base level is still bound to an active FBO.
+        ANGLE_GL_TRY(context, functions->flush());
+    }
+
     stateManager->bindTexture(getType(), mTextureID);
 
     bool recreateMipmapLevelsBeforeGenerate =
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index daded80..2190fd8 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -2748,6 +2748,10 @@
     // Disable EXT_clear_texture entirely on IMG as a speculative fix for driver crashes.
     ANGLE_FEATURE_CONDITION(features, disableClearTexture, IsPowerVR(vendor));
 
+    // Forces a flush before generating a mipmap, which avoids a bad state in the IMG driver if
+    // the texture's base level is still bound to an active FBO.
+    ANGLE_FEATURE_CONDITION(features, flushBeforeGenerateMipmap, IsPowerVR(vendor));
+
     // IMG GL drivers crash while compiling shaders with more than the limit of uniform blocks.
     ANGLE_FEATURE_CONDITION(features, validateMaxPerStageUniformBlocksAtCompileTime,
                             IsPowerVR(vendor));
diff --git a/include/platform/autogen/FeaturesGL_autogen.h b/include/platform/autogen/FeaturesGL_autogen.h
index 58c6372..487cfbe 100644
--- a/include/platform/autogen/FeaturesGL_autogen.h
+++ b/include/platform/autogen/FeaturesGL_autogen.h
@@ -734,6 +734,12 @@
         &members,
     };
 
+    FeatureInfo flushBeforeGenerateMipmap = {
+        "flushBeforeGenerateMipmap",
+        FeatureCategory::OpenGLWorkarounds,
+        &members,
+    };
+
     FeatureInfo splitLevel0PboFullSubImage2D = {
         "splitLevel0PboFullSubImage2D",
         FeatureCategory::OpenGLWorkarounds,
diff --git a/util/autogen/angle_features_autogen.cpp b/util/autogen/angle_features_autogen.cpp
index 2d2096b..5f52c9e 100644
--- a/util/autogen/angle_features_autogen.cpp
+++ b/util/autogen/angle_features_autogen.cpp
@@ -189,6 +189,7 @@
     {Feature::FlushAfterEndingTransformFeedback, "flushAfterEndingTransformFeedback"},
     {Feature::FlushAfterStreamVertexData, "flushAfterStreamVertexData"},
     {Feature::FlushBeforeDeleteTextureIfCopiedTo, "flushBeforeDeleteTextureIfCopiedTo"},
+    {Feature::FlushBeforeGenerateMipmap, "flushBeforeGenerateMipmap"},
     {Feature::FlushOnFramebufferChange, "flushOnFramebufferChange"},
     {Feature::FlushQueriesBeforeDeletingOrUnbindingFbo, "flushQueriesBeforeDeletingOrUnbindingFbo"},
     {Feature::ForceAtomicValueResolution, "forceAtomicValueResolution"},
diff --git a/util/autogen/angle_features_autogen.h b/util/autogen/angle_features_autogen.h
index 0d329ff..99b3126 100644
--- a/util/autogen/angle_features_autogen.h
+++ b/util/autogen/angle_features_autogen.h
@@ -189,6 +189,7 @@
     FlushAfterEndingTransformFeedback,
     FlushAfterStreamVertexData,
     FlushBeforeDeleteTextureIfCopiedTo,
+    FlushBeforeGenerateMipmap,
     FlushOnFramebufferChange,
     FlushQueriesBeforeDeletingOrUnbindingFbo,
     ForceAtomicValueResolution,
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.