High watch CVSS 4.7 chrome Uninitialized Memory 🔧 Commit mapped

Overview

High
Severity
4.7
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUninitialized resource in ANGLE
DescriptionUninitialized resource in ANGLE
ComponentANGLE
Sub-componentD3D11
Bug ClassUninitialized Memory
Action tierwatch — information disclosure — security-relevant, below the RCE-class bar
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.
Tracker556789073
Fix commitc2b3395143b5 (angle/angle) +4/-1
CWECWE-908
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-09-03 (per vendor advisory)
Fix landed2026-09-11 (public git)
Disclosed2026-09-29
Patch gap18 days — fix public in source before the advisory

Background

`glCopyTexImage2D` self-copy
a GL command copying framebuffer pixels into a texture where the source framebuffer and destination texture are the same image at the same mip level, handled in ANGLE’s D3D11 backend by handleCopyImageSelfCopyRedefine.
Robust resource initialization / WebGL
modes (isRobustResourceInitEnabled(), isWebGL()) that require newly created or resized texture storage to be deterministically zero-initialized so no stale GPU memory is observable.
`initializeContents`
the ANGLE call that performs that zero-initialization for a texture image and clears the “needs init” state; the GL front-end otherwise marks the image initialized after a redefine.
`ClipRectangle` / out-of-bounds source
when the copy’s source rectangle lies fully outside the framebuffer, no pixels are copied, so the code redefines the destination and returns early.

Root Cause Analysis

handleCopyImageSelfCopyRedefine detected the case where the source rectangle is fully out of bounds of the framebuffer (nothing to copy), called redefineDest(destExtents) to resize the destination texture, and then returned angle::Result::Continue early. That early return skipped initializeContents(), so the newly (re)sized destination texture storage was left with stale or undefined contents, while the GL front-end nonetheless marked the image as initialized. This violates the robust-init invariant that any texture image the front-end treats as initialized has actually been zero-filled under robust resource init or WebGL.

The fix inserts, before the early return, a guarded call ANGLE_TRY(initializeContents(context, GL_NONE, destIndex)) when context->isWebGL() || context->isRobustResourceInitEnabled(), ensuring the fully-out-of-bounds self-copy zero-initializes the resized destination so its later-observable contents are defined; the corresponding Texture2DTestES3RobustInit.CopyTexImageOutOfBoundsSelf skip is removed from the D3D11 expectations.

Key insight
The single mistake was an early return after redefineDest() that skipped initializeContents() for a fully out-of-bounds self-copy, leaving resized texture storage uninitialized while marked initialized; the fix calls initializeContents() before that return whenever robust init or WebGL is enabled.

Attack Path

  1. Set up a self-copy target In a WebGL/robust-init context on the D3D11 backend, create a texture bound as both the framebuffer source and the destination for glCopyTexImage2D at the same mip level.
  2. Issue an out-of-bounds self-copy that resizes Call glCopyTexImage2D with a source rectangle fully outside the framebuffer and destination extents larger than the current image, reaching the handleCopyImageSelfCopyRedefine branch that redefines the destination and returns early.
  3. Leave storage uninitialized but marked initialized Pre-patch, redefineDest resizes the destination while initializeContents() is skipped, so the new storage holds stale/undefined data yet the front-end considers it initialized.
  4. Read back the stale contents Subsequently sample or read the destination texture (inferred) to observe uninitialized GPU memory, an information-disclosure primitive.

Impact Assessment

An attacker driving WebGL on the ANGLE D3D11 backend can produce a texture whose resized storage is never zero-initialized yet is treated as initialized, then read stale or undefined GPU memory contents from it. The advisory classifies this as an uninitialized resource in ANGLE and reports no exploited-in-the-wild status; the readback step that turns this into observable disclosure is (inferred) and not shown in the diff, and no escalation beyond information disclosure is demonstrated.

Files Changed

  • src/tests/angle_end2end_tests_expectations.txt
  • src/libANGLE/renderer/d3d/TextureD3D.cpp

Audit Directions

  • Early returns after resize/redefine
    Look for texture/buffer paths that resize or redefine storage and then return before the corresponding initializeContents()/zero-fill, especially guarded by “nothing to copy/clip” conditions.
  • Front-end marks initialized vs. backend actually initializes
    Audit cases where the GL front-end sets an image initialized while a backend fast/early path can skip the actual initialization under robust-resource-init or WebGL.
  • Copy/blit corner cases with out-of-bounds or empty regions
    Review CopyTexImage, CopySubImage, blit, and self-copy handlers for out-of-bounds, empty, or clipped-to-nothing rectangles that bypass initialization while altering storage dimensions.
From c2b3395143b5b0ae3f74bd120ad5e7f1fbd9318a Mon Sep 17 00:00:00 2001
From: Le Hoang Quyen <[email protected]>
Date: Thu, 10 Sep 2026 23:37:38 +0800
Subject: [PATCH] D3D11: fixing robust init for self copy same mip lvl

When performing a glCopyTexImage2D self-copy on the same mip level
with a source rectangle fully out of bounds of the framebuffer,
handleCopyImageSelfCopyRedefine checked ClipRectangle and returned
early after redefining the destination texture.

This early return bypassed the call to initializeContents(), leaving
the newly resized destination texture uninitialized with stale or
undefined contents while the front-end marked the image initialized.

This patch calls initializeContents() prior to the early return when
robust resource initialization or WebGL is enabled, ensuring that
fully out-of-bounds self-copies are properly zero-initialized. Also
removes the test skip expectation for the
Texture2DTestES3RobustInit.CopyTexImageOutOfBoundsSelf test on
Win D3D11.

Bug: chromium:556789073
Change-Id: I03b5f6c6f7fc15dfc4696808b35f9d5f8ed44195
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/8387697
Auto-Submit: Quyen Le <[email protected]>
Commit-Queue: Quyen Le <[email protected]>
Reviewed-by: Kenneth Russell <[email protected]>
---
diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 2141213..fa1a434 100644
--- a/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -134,6 +134,10 @@
     {
         // We won't be copying, but redefine the destination texture in case sourceArea is larger
         ANGLE_TRY(redefineDest(destExtents));
+        if (context->isWebGL() || context->isRobustResourceInitEnabled())
+        {
+            ANGLE_TRY(initializeContents(context, GL_NONE, destIndex));
+        }
         return angle::Result::Continue;
     }
 
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index e0fd24e..ab192b7 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -644,7 +644,6 @@
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelCopyTexImageSrcDst/* = SKIP
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelTexSubImageDstWithUnpackSlow/* = SKIP
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelBlitDst/* = SKIP
-556789073 WIN D3D11 : Texture2DTestES3RobustInit.CopyTexImageOutOfBoundsSelf/* = SKIP
 
 // Android
 42264624 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index e0fd24e..ab192b7 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -644,7 +644,6 @@
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelCopyTexImageSrcDst/* = SKIP
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelTexSubImageDstWithUnpackSlow/* = SKIP
 526451592 WIN D3D11 : ImageTestES3.NonZeroLevelBlitDst/* = SKIP
-556789073 WIN D3D11 : Texture2DTestES3RobustInit.CopyTexImageOutOfBoundsSelf/* = SKIP
 
 // Android
 42264624 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP
Loading diff…