Chrome · ANGLE
CVE-2026-106247
OOB in ANGLE
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
src/tests/gl_tests/DebugMarkerTest.cppsrc/libANGLE/Context.cpp
Patch
From 3e88857d92eb32f2c862652bbf8603d97f3789b0 Mon Sep 17 00:00:00 2001
From: Tzarial <zork@google.com>
Date: Thu, 16 Jul 2026 15:04:47 +0000
Subject: [PATCH] Cap GLES debug marker length
Cap the marker length in Context::pushGroupMarker and
Context::insertEventMarker via GetMarkerLength to
maxDebugMessageLength (1024) to prevent driver and validation layer
issues when handling large labels, and avoid unbounded buffer growth
in backends.
Bug: b/524435922
Test: angle_end2end_tests --gtest_filter=DebugMarkerTest.*
Test: angle_deqp_gles2_tests --gtest_filter=*debug_marker*
Change-Id: I910971a589f49ab9dc7611c1a0e27aab7789ea64
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/8108817
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Tzarial <zork@chromium.org>
---
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index acd6b60..ac1243e 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -424,14 +424,16 @@
}
}
-GLsizei GetMarkerLength(GLsizei length, const char *marker)
+GLsizei GetMarkerLength(GLsizei length, const char *marker, GLsizei maxLength)
{
if (length == 0)
{
- return static_cast<GLsizei>(
+ length = static_cast<GLsizei>(
std::min<size_t>(strlen(marker), std::numeric_limits<GLsizei>::max()));
}
- return length;
+ // https://crbug.com/524435922: Cap debug marker length to prevent driver or validation layer
+ // issues with large labels.
+ return std::min(length, maxLength);
}
enum SubjectIndexes : angle::SubjectIndex
@@ -3222,7 +3224,9 @@
}
// If <length> is 0 then <marker> is assumed to be null-terminated.
- ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(GetMarkerLength(length, marker), marker));
+ ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(
+ GetMarkerLength(length, marker, static_cast<GLsizei>(getCaps().maxDebugMessageLength)),
+ marker));
}
void Context::pushGroupMarker(GLsizei length, const char *marker)
@@ -3241,8 +3245,9 @@
else
{
// If <length> is 0 then <marker> is assumed to be null-terminated.
- ANGLE_CONTEXT_TRY(
- mImplementation->pushGroupMarker(GetMarkerLength(length, marker), marker));
+ ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(
+ GetMarkerLength(length, marker, static_cast<GLsizei>(getCaps().maxDebugMessageLength)),
+ marker));
}
mState.incrementGroupMarkers();
}
diff --git a/src/tests/gl_tests/DebugMarkerTest.cpp b/src/tests/gl_tests/DebugMarkerTest.cpp
index e23a370..d8054c5 100644
--- a/src/tests/gl_tests/DebugMarkerTest.cpp
+++ b/src/tests/gl_tests/DebugMarkerTest.cpp
@@ -147,6 +147,30 @@
ASSERT_GL_NO_ERROR();
}
+// Test that passing an oversized marker to EXT_debug_marker entry points does not crash.
+TEST_P(DebugMarkerTest, OversizedMarkerNoCrash)
+{
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_debug_marker"));
+
+ // Create a string larger than 16KB (default page size for PoolAllocator in CBH)
+ std::string largeMarker(32 * 1024, 'a');
+
+ glPushGroupMarkerEXT(static_cast<GLsizei>(largeMarker.length()), largeMarker.c_str());
+
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR)
+ {
+ glPopGroupMarkerEXT();
+ }
+ else
+ {
+ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), error);
+ }
+
+ glInsertEventMarkerEXT(static_cast<GLsizei>(largeMarker.length()), largeMarker.c_str());
+ ASSERT_GL_NO_ERROR();
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(DebugMarkerTest);
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/src/tests/gl_tests/DebugMarkerTest.cpp b/src/tests/gl_tests/DebugMarkerTest.cpp
index e23a370..d8054c5 100644
--- a/src/tests/gl_tests/DebugMarkerTest.cpp
+++ b/src/tests/gl_tests/DebugMarkerTest.cpp
@@ -147,6 +147,30 @@
ASSERT_GL_NO_ERROR();
}
+// Test that passing an oversized marker to EXT_debug_marker entry points does not crash.
+TEST_P(DebugMarkerTest, OversizedMarkerNoCrash)
+{
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_debug_marker"));
+
+ // Create a string larger than 16KB (default page size for PoolAllocator in CBH)
+ std::string largeMarker(32 * 1024, 'a');
+
+ glPushGroupMarkerEXT(static_cast<GLsizei>(largeMarker.length()), largeMarker.c_str());
+
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR)
+ {
+ glPopGroupMarkerEXT();
+ }
+ else
+ {
+ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), error);
+ }
+
+ glInsertEventMarkerEXT(static_cast<GLsizei>(largeMarker.length()), largeMarker.c_str());
+ ASSERT_GL_NO_ERROR();
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(DebugMarkerTest);
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.
References
On This Page