CVE-2026-85050
Overview
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.
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
- 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.
- Reach the vulnerable path
On IMG/PowerVR hardware, ANGLE’s
TextureGLmipmap-generation runsbindTextureand generates mipmaps with no flush, so the driver generates the mipmap while the base level is still an active render target. - 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.
- Post-fix behavior
With
flushBeforeGenerateMipmapenabled on PowerVR, afunctions->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
(inferred), and the vulnerability is gated on running the affected PowerVR driver.Files Changed
util/autogen/angle_features_autogen.hsrc/libANGLE/renderer/gl/renderergl_utils.cppinclude/platform/autogen/FeaturesGL_autogen.hutil/autogen/angle_features_autogen.cppsrc/libANGLE/renderer/gl/TextureGL.cppinclude/platform/gl_features.json
Audit Directions
- Self-referential texture/FBO stateAudit 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 workaroundsWhere 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/generateCheck 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.
Patch
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,