Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in ANGLE
DescriptionInappropriate implementation in ANGLE
ComponentANGLE
Bug ClassLogic Error
Tracker516887576
Fix commited784009865c (angle/angle) +6/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-07-29

Files Changed

  • src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
  • src/tests/angle_end2end_tests_expectations.txt
From ed784009865c3f8129f26083eb4e89df94fc1c4d Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Tue, 09 Jun 2026 14:43:46 -0400
Subject: [PATCH] Request robust access on native EGL contexts.

We would request reset notifications but not robust buffer access.

Covered by existing tests, I haven't seen a driver yet that appears to
test differently by enabling this flag.

Fixed: chromium:516887576
Change-Id: Ie0e931da44199026822b2b27c97f5d34b5d9853d
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7914803
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
---

diff --git a/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp b/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
index 8ebc52f..67978fe 100644
--- a/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
+++ b/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
@@ -199,6 +199,7 @@
 
             attribsWithRobustness.insert(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY,
                                          EGL_LOSE_CONTEXT_ON_RESET);
+            attribsWithRobustness.insert(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE);
             if (mHasNVRobustnessVideoMemoryPurge)
             {
                 attribsWithRobustness.insert(EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE);
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index a95769c..3cebdb0 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -2731,6 +2731,11 @@
 // Pixel4's GLES driver fails new test: TransformFeedbackTest.CaptureThenUseAsUBO.
 419403192 PIXEL4ORXL GLES : TransformFeedbackTest.CaptureThenUseAsUBO/* = SKIP
 
+// Pixel4 GLES driver fails to compile the GLES1 uber shader when robustness is enabled
+516887576 PIXEL4ORXL GLES : LightsTest.DiffuseGradient/* = SKIP
+516887576 PIXEL4ORXL GLES : LightsTest.FlatLitMesh/* = SKIP
+516887576 PIXEL4ORXL GLES : LightsTest.SmoothLitMesh/* = SKIP
+
 454067880 D3D9 : GLSLTest.ComplicatedMultielementSwizzle1/* = SKIP
 454067880 D3D11 : GLSLTest.ComplicatedMultielementSwizzle1/* = 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 a95769c..3cebdb0 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -2731,6 +2731,11 @@
 // Pixel4's GLES driver fails new test: TransformFeedbackTest.CaptureThenUseAsUBO.
 419403192 PIXEL4ORXL GLES : TransformFeedbackTest.CaptureThenUseAsUBO/* = SKIP
 
+// Pixel4 GLES driver fails to compile the GLES1 uber shader when robustness is enabled
+516887576 PIXEL4ORXL GLES : LightsTest.DiffuseGradient/* = SKIP
+516887576 PIXEL4ORXL GLES : LightsTest.FlatLitMesh/* = SKIP
+516887576 PIXEL4ORXL GLES : LightsTest.SmoothLitMesh/* = SKIP
+
 454067880 D3D9 : GLSLTest.ComplicatedMultielementSwizzle1/* = SKIP
 454067880 D3D11 : GLSLTest.ComplicatedMultielementSwizzle1/* = SKIP
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential driver-level GPU out-of-bounds vertex fetch via ANGLE EGL backend robustness omission

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: ANGLE’s GL-on-native-EGL backend fails to request the robust access attribute during native context creation but still claims robust buffer access behavior support based on the driver’s extension string. This disables ANGLE’s CPU-side out-of-bounds vertex validation, causing unvalidated draw calls to be passed directly to the native driver. On native contexts created without the robust access flag, this can lead to driver-level out-of-bounds vertex fetching and potential GPU memory disclosure.

Affected files:

  • third_party/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
  • third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp

Estimated timestamp from git blame: 2017-08-25

Root Cause Analysis

In ANGLE’s GL-on-native-EGL backend, when native driver contexts are created inside DisplayEGL::initializeContext (third_party/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp), the backend fails to request robust buffer access. While sibling backends correctly set their respective robust access bits during context creation (e.g., DisplayGLX.cpp sets GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB and DisplayWGL.cpp sets WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB), the EGL backend only sets reset notification strategy and video memory purge attributes:

// From DisplayEGL::initializeContext in DisplayEGL.cpp:
if (mHasEXTCreateContextRobustness)
{
    egl::AttributeMap attribsWithRobustness(attribs);

    attribsWithRobustness.insert(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY,
                                 EGL_LOSE_CONTEXT_ON_RESET);
    if (mHasNVRobustnessVideoMemoryPurge)
    { 
        attribsWithRobustness.insert(EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, GL_TRUE);
    }
    // EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT (or EGL_CONTEXT_OPENGL_ROBUST_ACCESS) is omitted here!

Despite omitting this context creation attribute, ANGLE’s GL capability detection in renderergl_utils.cpp sets extensions->robustBufferAccessBehaviorKHR = true simply if the driver exposes the extension string GL_KHR_robust_buffer_access_behavior or GL_ARB_robust_buffer_access_behavior:

// From renderergl_utils.cpp:
extensions->robustBufferAccessBehaviorKHR =
    extensions->robustnessEXT &&
    (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
     functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));

Because the underlying native EGL context does not actually have robust access enabled, the driver’s robustness guarantees are inactive on many drivers. However, because ANGLE sees robustBufferAccessBehaviorKHR as true, it disables its own CPU-side out-of-bounds vertex validation in Context::initCaps (third_party/angle/src/libANGLE/Context.cpp):

mBufferAccessValidationEnabled =
    !mSupportedExtensions.robustBufferAccessBehaviorKHR && mRequiresRobustBehavior;

Since mBufferAccessValidationEnabled is set to false, validation steps are skipped during drawing commands in validationES.h (e.g., ValidateDrawArraysAttribs and ValidateDrawElementsCommon check isBufferAccessValidationEnabled() and return early). Unvalidated draw arguments, including out-of-bounds indices or base vertices, are forwarded directly to the native GPU driver, triggering driver-level out-of-bounds vertex fetching.

Potential Attack Scenario

Note: The following are suggested potential steps; we do not currently possess a working proof of concept.

  1. A compromised renderer process or an untrusted web page requests a WebGL/WebGL2 context on a platform using ANGLE’s GL-on-EGL backend (such as Android or Linux with the GL backend active).
  2. The context is initialized, and hasRobustAccess() is set to true on the frontend, while the backend native context is created without the robust access flag.
  3. The attacker binds a vertex buffer containing a known size and populates an element index buffer containing indices that point outside the vertex buffer bounds.
  4. The attacker issues a draw call (e.g., gl.drawElements). Because ANGLE’s CPU-side validation is bypassed, the out-of-bounds indices are forwarded to the native driver.
  5. The GPU driver executes the draw call by fetching vertex data from out-of-bounds GPU memory addresses, which may be rendered into a readable framebuffer or captured via transform feedback, potentially allowing the attacker to leak cross-origin GPU memory.

Suggested Fix

Update DisplayEGL::initializeContext to append EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT (set to EGL_TRUE) when creating a robust context if mHasEXTCreateContextRobustness is supported:

if (mHasEXTCreateContextRobustness)
{
    egl::AttributeMap attribsWithRobustness(attribs);
    attribsWithRobustness.insert(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE);
    // ... rest of robustness attributes

Alternatively, ANGLE’s OpenGL backend capability detection should query the active context flags (such as checking GL_CONTEXT_FLAGS for GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT) to verify that the robust-access bit is actually active on the context before advertising robustBufferAccessBehaviorKHR as supported.

Evaluated with Chrome root at commit: b1520ef4a76878853a31f0943b565e42060edec8


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