CVE-2026-13028
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
TextureAttachmentgpu/command_buffer/service/framebuffer_manager.cc |
modified | |
GetBindingFramebuffersForTexturegpu/command_buffer/service/framebuffer_manager.cc |
modified | |
ifgpu/command_buffer/service/framebuffer_manager.cc |
modified | |
forgpu/command_buffer/service/framebuffer_manager.cc |
modified | |
ScopedDepthStencilReattachergpu/command_buffer/service/gles2_cmd_decoder.cc |
modified | |
ifgpu/command_buffer/service/gles2_cmd_decoder.cc |
modified |
Files Changed
gpu/command_buffer/service/framebuffer_manager.ccgpu/command_buffer/service/framebuffer_manager.hgpu/command_buffer/service/gles2_cmd_decoder.cc
Patch
From 092d0d9b5333e7d68a01f7e0dc44fd3c4f8a5b32 Mon Sep 17 00:00:00 2001
From: Ken Russell <kbr@chromium.org>
Date: Fri, 12 Jun 2026 16:27:04 -0700
Subject: [PATCH] Add workaround reattaching depth/stencil attachments.
When a depth/stencil attachment to an FBO (bound or unbound) is
redefined, this workaround first unbinds it from all FBOs and then
reattaches it afterward. Apply this to certain vendors' GPUs.
Disable the previous recreate_fbo_upon_flush workaround, as it has
been demonstrated to be ineffective. Do not remove the code yet as the
new approach must be tested first.
Added tests ensuring the workaround has no unexpected side-effects.
Co-authored with jetski-cli.
Bug: 520656244
Change-Id: Ieaad9410b36092aff9d0f0f46c2373911b24d0ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7910927
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1646310}
---
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 430d8a2d6..2dce5944 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -138,6 +138,10 @@
scoped_refptr<Renderbuffer> renderbuffer_;
};
+GLint Framebuffer::Attachment::layer() const {
+ return 0;
+}
+
class TextureAttachment
: public Framebuffer::Attachment {
public:
@@ -188,7 +192,7 @@
GLsizei samples() const override { return samples_; }
- GLint layer() const { return layer_; }
+ GLint layer() const override { return layer_; }
GLenum target() const override { return target_; }
@@ -1237,5 +1241,46 @@
framebuffer_state_change_count_;
}
+std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>>
+FramebufferManager::GetBindingFramebuffersForTexture(TextureRef* texture_ref) {
+ std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>> result;
+ if (!texture_ref) {
+ return result;
+ }
+ for (const auto& pair : framebuffers_) {
+ Framebuffer* framebuffer = pair.second.get();
+ for (GLenum attachment_point :
+ {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}) {
+ const Framebuffer::Attachment* attachment =
+ framebuffer->GetAttachment(attachment_point);
+ if (attachment && attachment->IsTexture(texture_ref)) {
+ result.push_back({pair.second, attachment_point});
+ }
+ }
+ }
+ return result;
+}
+
+std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>>
+FramebufferManager::GetBindingFramebuffersForRenderbuffer(
+ Renderbuffer* renderbuffer) {
+ std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>> result;
+ if (!renderbuffer) {
+ return result;
+ }
+ for (const auto& pair : framebuffers_) {
+ Framebuffer* framebuffer = pair.second.get();
+ for (GLenum attachment_point :
+ {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}) {
+ const Framebuffer::Attachment* attachment =
+ framebuffer->GetAttachment(attachment_point);
+ if (attachment && attachment->IsRenderbuffer(renderbuffer)) {
+ result.push_back({pair.second, attachment_point});
+ }
+ }
+ }
+ return result;
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index c77b6bf2..376149ba 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -58,6 +58,7 @@
virtual bool IsRenderbuffer(Renderbuffer* renderbuffer) const = 0;
virtual bool IsSameAttachment(const Attachment* attachment) const = 0;
virtual bool Is3D() const = 0;
+ virtual GLint layer() const;
// If it's a 3D texture attachment, return true if
// FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is smaller than the number of
@@ -383,6 +384,12 @@
bool IsComplete(const Framebuffer* framebuffer);
+ std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>>
+ GetBindingFramebuffersForTexture(TextureRef* texture_ref);
+
+ std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>>
+ GetBindingFramebuffersForRenderbuffer(Renderbuffer* renderbuffer);
+
void IncFramebufferStateChangeCount() {
// make sure this is never 0.
framebuffer_state_change_count_ =
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e91a6778..38ebebae 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -726,6 +726,7 @@
friend class ScopedFramebufferCopyBinder;
friend class BackFramebuffer;
friend class BackTexture;
+ friend class ScopedDepthStencilReattacher;
enum FramebufferOperation {
kFramebufferDiscard,
@@ -2550,6 +2551,157 @@
ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
}
+class ScopedDepthStencilReattacher {
+ public:
+ ScopedDepthStencilReattacher(GLES2DecoderImpl* decoder,
+ TextureRef* texture_ref);
+ ScopedDepthStencilReattacher(GLES2DecoderImpl* decoder,
+ Renderbuffer* renderbuffer);
+ ~ScopedDepthStencilReattacher();
+
+ private:
+ struct SavedAttachmentInfo {
+ scoped_refptr<Framebuffer> framebuffer;
+ GLenum attachment_point;
+ GLenum texture_target = 0;
+ GLint texture_level = 0;
+ GLsizei texture_samples = 0;
+ GLint texture_layer = 0;
+ bool is_texture = false;
+ bool is_renderbuffer = false;
+ };
+
+ void Initialize();
+
+ raw_ptr<GLES2DecoderImpl> decoder_;
+ raw_ptr<TextureRef> texture_ref_ = nullptr;
+ raw_ptr<Renderbuffer> renderbuffer_ = nullptr;
+ std::vector<SavedAttachmentInfo> saved_attachments_;
+ scoped_refptr<Framebuffer> old_read_fbo_;
+ scoped_refptr<Framebuffer> old_draw_fbo_;
+};
+
+ScopedDepthStencilReattacher::ScopedDepthStencilReattacher(
+ GLES2DecoderImpl* decoder,
+ TextureRef* texture_ref)
+ : decoder_(decoder), texture_ref_(texture_ref) {
+ Initialize();
+}
+
+ScopedDepthStencilReattacher::ScopedDepthStencilReattacher(
+ GLES2DecoderImpl* decoder,
+ Renderbuffer* renderbuffer)
+ : decoder_(decoder), renderbuffer_(renderbuffer) {
+ Initialize();
+}
+
+void ScopedDepthStencilReattacher::Initialize() {
+ if (!decoder_->workarounds().reattach_fbo_depth_stencil_on_reallocation) {
+ return;
+ }
+
+ std::vector<std::pair<scoped_refptr<Framebuffer>, GLenum>> detached_fbos;
+ if (texture_ref_) {
+ detached_fbos =
+ decoder_->framebuffer_manager()->GetBindingFramebuffersForTexture(
+ texture_ref_);
+ } else if (renderbuffer_) {
+ detached_fbos =
+ decoder_->framebuffer_manager()->GetBindingFramebuffersForRenderbuffer(
+ renderbuffer_);
+ }
+
+ if (detached_fbos.empty()) {
+ return;
+ }
Regression Test / PoC
diff --git a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
index 123aa81..704c02a 100644
--- a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
@@ -706,4 +706,254 @@
glDeleteRenderbuffers(1, &rb);
}
+class GLReattachFboDepthStencilTest : public GLClearFramebufferTest {
+ protected:
+ void SetUp() override {
+ GpuDriverBugWorkarounds workarounds;
+ if (GetParam()) {
+ workarounds.reattach_fbo_depth_stencil_on_reallocation = true;
+ }
+ gl_.InitializeWithWorkarounds(GetGlManagerOptions(), workarounds);
+ }
+
+ void RunReattachFboDepthStencilTest(bool use_texture,
+ bool bind_fbo_during_reallocation);
+};
+
+INSTANTIATE_TEST_SUITE_P(GLReattachFboDepthStencilTestWithParam,
+ GLReattachFboDepthStencilTest,
+ ::testing::Bool());
+
+void GLReattachFboDepthStencilTest::RunReattachFboDepthStencilTest(
+ bool use_texture,
+ bool bind_fbo_during_reallocation) {
+ GLuint fbo = 0;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLuint color_tex = 0;
+ glGenTextures(1, &color_tex);
+ glBindTexture(GL_TEXTURE_2D, color_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ color_tex, 0);
+
+ GLuint depth_obj = 0;
+ if (use_texture) {
+ glGenTextures(1, &depth_obj);
+ glBindTexture(GL_TEXTURE_2D, depth_obj);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 16, 16, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ depth_obj, 0);
+ } else {
+ glGenRenderbuffers(1, &depth_obj);
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_obj);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 16, 16);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_obj);
+ }
+
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // Clear color to Green, depth to 1.0 (far).
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClearDepthf(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ const uint8_t kGreen[] = {0, 255, 0, 255};
+ const uint8_t kRed[] = {255, 0, 0, 255};
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ // Enable depth test. Draw Red quad at depth 0.5. Should pass (0.5 < 1.0).
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ InitDraw();
+ SetDrawDepth(0.5f);
+ SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
+ DrawQuad();
+
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kRed, nullptr));
+
+ // Clear color to Green, depth to 0.0 (near).
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClearDepthf(0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ // Draw Red quad at depth 0.5. Should fail (0.5 is not < 0.0).
+ DrawQuad();
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ if (!bind_fbo_during_reallocation) {
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ // Redefine depth attachment (reallocate to 16x16).
+ if (use_texture) {
+ glBindTexture(GL_TEXTURE_2D, depth_obj);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 16, 16, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
+ } else {
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_obj);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 16, 16);
+ }
+
+ if (!bind_fbo_during_reallocation) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ }
+
+ // Clear depth to 1.0.
+ glClearDepthf(1.0f);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ // Draw Red quad at depth 0.5. Should pass (0.5 < 1.0).
+ SetDrawDepth(0.5f);
+ SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
+ DrawQuad();
+
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kRed, nullptr));
+
+ glDeleteFramebuffers(1, &fbo);
+ glDeleteTextures(1, &color_tex);
+ if (use_texture) {
+ glDeleteTextures(1, &depth_obj);
+ } else {
+ glDeleteRenderbuffers(1, &depth_obj);
+ }
+}
+
+TEST_P(GLReattachFboDepthStencilTest, TextureReallocationBound) {
+ RunReattachFboDepthStencilTest(true, true);
+}
+
+TEST_P(GLReattachFboDepthStencilTest, TextureReallocationUnbound) {
+ RunReattachFboDepthStencilTest(true, false);
+}
+
+TEST_P(GLReattachFboDepthStencilTest, RenderbufferReallocationBound) {
+ RunReattachFboDepthStencilTest(false, true);
+}
+
+TEST_P(GLReattachFboDepthStencilTest, RenderbufferReallocationUnbound) {
+ RunReattachFboDepthStencilTest(false, false);
+}
+
+class ES3ReattachFboDepthStencilTest : public GLReattachFboDepthStencilTest {
+ protected:
+ GLManager::Options GetGlManagerOptions() override {
+ GLManager::Options options;
+ options.context_type = CONTEXT_TYPE_OPENGLES3;
+ return options;
+ }
+
+ bool ShouldSkipTest() const {
+ return (!gl_.decoder() || !gl_.decoder()->GetContextGroup());
+ }
+
+ void RunTexImage2DToTexStorage2DTest(bool bind_fbo_during_reallocation);
+};
+
+INSTANTIATE_TEST_SUITE_P(ES3ReattachFboDepthStencilTestWithParam,
+ ES3ReattachFboDepthStencilTest,
+ ::testing::Bool());
+
+void ES3ReattachFboDepthStencilTest::RunTexImage2DToTexStorage2DTest(
+ bool bind_fbo_during_reallocation) {
+ if (ShouldSkipTest()) {
+ return;
+ }
+
+ GLuint fbo = 0;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLuint color_tex = 0;
+ glGenTextures(1, &color_tex);
+ glBindTexture(GL_TEXTURE_2D, color_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ color_tex, 0);
+
+ GLuint depth_tex = 0;
+ glGenTextures(1, &depth_tex);
+ glBindTexture(GL_TEXTURE_2D, depth_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 16, 16, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ depth_tex, 0);
+
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // Clear color to Green, depth to 1.0 (far).
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClearDepthf(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ const uint8_t kGreen[] = {0, 255, 0, 255};
+ const uint8_t kRed[] = {255, 0, 0, 255};
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ // Enable depth test. Draw Red quad at depth 0.5. Should pass.
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ InitDraw();
+ SetDrawDepth(0.5f);
+ SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
+ DrawQuad();
+
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kRed, nullptr));
+
+ // Clear color to Green, depth to 0.0 (near).
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClearDepthf(0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ // Draw Red quad at depth 0.5. Should fail.
+ DrawQuad();
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kGreen, nullptr));
+
+ if (!bind_fbo_during_reallocation) {
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ // Redefine depth attachment via glTexStorage2D.
+ glBindTexture(GL_TEXTURE_2D, depth_tex);
+ glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 16, 16);
+
+ if (!bind_fbo_during_reallocation) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ }
+
+ // Clear depth to 1.0.
+ glClearDepthf(1.0f);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ // Draw Red quad at depth 0.5. Should pass.
+ SetDrawDepth(0.5f);
+ SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
+ DrawQuad();
+
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kRed, nullptr));
+
+ glDeleteFramebuffers(1, &fbo);
+ glDeleteTextures(1, &color_tex);
+ glDeleteTextures(1, &depth_tex);
+}
+
+TEST_P(ES3ReattachFboDepthStencilTest, TexImage2DToTexStorage2DBound) {
+ RunTexImage2DToTexStorage2DTest(true);
+}
+
+TEST_P(ES3ReattachFboDepthStencilTest, TexImage2DToTexStorage2DUnbound) {
+ RunTexImage2DToTexStorage2DTest(false);
+}
+
} // namespace gpu
Original Bug Report
New UAF trigger for https://issues.chromium.org/issues/493747593 (Fullchain RCE)
VULNERABILITY DETAILS
https://issues.chromium.org/issues/493747593 There is something wrong with the original Qualcomm suggested fix, they don’t quite understand it yet, I retriggered it with the help of LLM.
Use-after-free in Qualcomm Adreno GPU driver (libGLESv2_adreno.so) reachable from web contents via WebGL2 texStorage2D on FBO-attached depth texture. The driver frees the internal 0x80-byte storage container but leaves the FBO’s cached pointer (fbo+0x2a8) dangling. A subsequent glClear triggers the driver’s completeness check which dereferences the dangling pointer, allowing heap spray reoccupation and arbitrary code execution in Chrome’s GPU process.
The bug is in the Adreno GPU driver, reachable through Chrome Browser from remote web content without any user interaction beyond page navigation. No special flags, no renderer patches, no extensions required.
VERSION Chrome Version: 148.0.7778.217 stable
Note that this is the newest version I got on Samsung s25
Operating System: Android 16 (Samsung Galaxy S25 / SM-S9310, Adreno 830 GPU, firmware S9310ZCSBCZE1, driver build f61dec9117) samsung/pa1qzcx/pa1q:16/BP4A.251205.006/S9310ZCSBCZE1_CHCBCZE1:user/release-keys
REPRODUCTION CASE
- Serve the attached files with Python:
python3 -m http.server 8899 --bind 127.0.0.1
- Set up adb reverse:
adb reverse tcp:8899 tcp:8899
- Open in Chrome (no flags):
access http://127.0.0.1:8899/rce1_off.html
- GPU process crashes within seconds with fault addr 0x0043434343434343.
Trigger sequence in the PoC:
- Create depth texture T (texImage2D DEPTH_COMPONENT24 64x64)
- Create FBO A, attach T as depth attachment
- bindFramebuffer(null) — cross-FBO trick
- texStorage2D(T, 1, DEPTH_COMPONENT24, 128, 128) — frees old container, fbo A+0x2a8 dangles
- Heap spray: re-texImage2D 1024 RGBA16F W=15 textures via PBO — reoccupies freed container with 0x4343
- bindFramebuffer(A), checkFramebufferStatus, clear(DEPTH_BUFFER_BIT) — driver reads dangling container → crash
FOR CRASHES
Type of crash: GPU process (privileged_process0) Crash State: Original
06-07 17:41:51.703 18049 18049 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-07 17:41:51.703 18049 18049 F DEBUG : Build fingerprint: 'samsung/pa1qzcx/pa1q:16/BP4A.251205.006/S9310ZCSBCZE1_CHCBCZE1:user/release-keys'
06-07 17:41:51.703 18049 18049 F DEBUG : Kernel Release: '6.6.98-android15-8-p93745ce-abogkiS9310ZCSBCZE1-4k'
06-07 17:41:51.703 18049 18049 F DEBUG : Revision: '11'
06-07 17:41:51.703 18049 18049 F DEBUG : ABI: 'arm64'
06-07 17:41:51.703 18049 18049 F DEBUG : Processor: '5'
06-07 17:41:51.703 18049 18049 F DEBUG : Timestamp: 2026-06-07 17:41:51.580909379+0800
06-07 17:41:51.703 18049 18049 F DEBUG : Process uptime: 7s
06-07 17:41:51.703 18049 18049 F DEBUG : Executable: /system/bin/app_process64
06-07 17:41:51.703 18049 18049 F DEBUG : Cmdline: com.android.chrome:privileged_process0
06-07 17:41:51.703 18049 18049 F DEBUG : pid: 17705, tid: 17730, name: CrGpuMain >>> com.android.chrome:privileged_process0 <<<
06-07 17:41:51.703 18049 18049 F DEBUG : uid: 10422
06-07 17:41:51.703 18049 18049 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
06-07 17:41:51.703 18049 18049 F DEBUG : pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
06-07 17:41:51.703 18049 18049 F DEBUG : esr: 0000000092000004 (Data Abort Exception 0x24)
06-07 17:41:51.703 18049 18049 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0043434343434343 (read)
06-07 17:41:51.703 18049 18049 F DEBUG : x0 b40000741bc7b360 x1 0000000000008d40 x2 0000000000000000 x3 47cb497e67487fe4
06-07 17:41:51.703 18049 18049 F DEBUG : x4 0000000000000003 x5 0000000000008d40 x6 a635992e0c8cd953 x7 b40000752bdf09f0
06-07 17:41:51.703 18049 18049 F DEBUG : x8 0000000000008cd5 x9 0000000000008d40 x10 0000000000000001 x11 0000006e0008e218
06-07 17:41:51.703 18049 18049 F DEBUG : x12 0000000000000000 x13 0000006e00183400 x14 000000000000006a x15 0000000000000001
06-07 17:41:51.703 18049 18049 F DEBUG : x16 0000007394a1ef40 x17 000000769dd5591c x18 00000073427dc000 x19 0000006e030aa300
06-07 17:41:51.703 18049 18049 F DEBUG : x20 0000000000000001 x21 0000000043434343 x22 0000006e030aa330 x23 0000000000000000
06-07 17:41:51.703 18049 18049 F DEBUG : x24 0000006e030aa340 x25 0000006e030aa330 x26 0000006e030aa340 x27 4343434343434343
06-07 17:41:51.703 18049 18049 F DEBUG : x28 0000000000000004 x29 0000007343905550
06-07 17:41:51.703 18049 18049 F DEBUG : lr 005ff5f2b955df24 sp 0000007343905530 pc 0000007394a1f208 pst 0000000020001000
06-07 17:41:51.703 18049 18049 F DEBUG : esr 0000000092000004
06-07 17:41:51.703 18049 18049 F DEBUG : 29 total frames
06-07 17:41:51.703 18049 18049 F DEBUG : backtrace:
06-07 17:41:51.703 18049 18049 F DEBUG : #00 pc 000000000021c208 /vendor/lib64/egl/libGLESv2_adreno.so (!!!0000!804c660e2d6053be57921a5fd6d4bb!f61dec9117!+376) (BuildId: 7930b2c86c3cf072ea40709321b1af75)
06-07 17:41:51.703 18049 18049 F DEBUG : #01 pc 000000000918df20 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #02 pc 0000000009197ad0 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #03 pc 00000000091bb004 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #04 pc 00000000077f9ff0 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #05 pc 00000000077f9528 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #06 pc 00000000077f9254 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #07 pc 00000000077f90fc /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #08 pc 00000000077f906c /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #09 pc 00000000077a5da8 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #10 pc 00000000078e7848 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #11 pc 0000000005c7b6ec /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #12 pc 0000000005c3afb0 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #13 pc 0000000005c3ab18 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #14 pc 00000000074e6ad8 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #15 pc 0000000005c9f038 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #16 pc 0000000005c026b0 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #17 pc 0000000005c012f0 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #18 pc 0000000005c01000 /data/app/~~DVixuWwBoqC_JU6cqq4w-A==/com.google.android.trichromelibrary_777821733-W-KsS5MHnN-okuo11GfeGQ==/base.apk!libmonochrome_64.so (offset 0x948000) (BuildId: 21d860e69ceda9d90a1c4aac6abe65adee735df4)
06-07 17:41:51.703 18049 18049 F DEBUG : #19 pc 00000000002e4570 /system/framework/arm64/boot.oat (art_jni_trampoline+112) (BuildId: a2d6a559f5778b9b6315baec706b53a709156608)
06-07 17:41:51.703 18049 18049 F DEBUG : #20 pc 00000000006680e8 /apex/com.android.art/lib64/libart.so (nterp_helper+152) (BuildId: 11dac5edfc6a4111efd44d494b5f3993)
06-07 17:41:51.703 18049 18049 F DEBUG : #21 pc 00000000000e4552 /data/app/~~cL9Qcf_m-_LsOdBMyG4-UA==/com.android.chrome-15HfHhAmKbAZwTLL3jzWpA==/base.apk (offset 0x218000) (sr3.run+574)
06-07 17:41:51.704 18049 18049 F DEBUG : #22 pc 00000000000a95e0 /system/framework/arm64/boot.oat (java.lang.Thread.run+64) (BuildId: a2d6a559f5778b9b6315baec706b53a709156608)
06-07 17:41:51.704 18049 18049 F DEBUG : #23 pc 00000000002aaf94 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: 11dac5edfc6a4111efd44d494b5f3993)
06-07 17:41:51.704 18049 18049 F DEBUG : #24 pc 0000000000270940 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+220) (BuildId: 11dac5edfc6a4111efd44d494b5f3993)
06-07 17:41:51.704 18049 18049 F DEBUG : #25 pc 00000000004bee24 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1184) (BuildId: 11dac5edfc6a4111efd44d494b5f3993)
06-07 17:41:51.704 18049 18049 F DEBUG : #26 pc 00000000004be974 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8) (BuildId: 11dac5edfc6a4111efd44d494b5f3993)
06-07 17:41:51.704 18049 18049 F DEBUG : #27 pc 00000000000866ec /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*) (.__uniq.67847048707805468364044055584648682506)+184) (BuildId: 0669c520dd58ab0634801cae537d6b06)
06-07 17:41:51.704 18049 18049 F DEBUG : #28 pc 000000000007900c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: 0669c520dd58ab0634801cae537d6b06)
INFO:root:Stack found. Symbolizing...
Symbolizing stack using ABI=arm64
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x43434343434343 in tid 31376 (CrGpuMain), pid 31303 (ileged_process0)
Build fingerprint: 'samsung/pa1qzcx/pa1q:16/BP4A.251205.006/S9310ZCSBCZE1_CHCBCZE1:user/release-keys'
Revision: '11'
pid: 31303, tid: 31376, name: CrGpuMain >>> org.chromium.chrome:privileged_process0 <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0043434343434343 (read)
Stack Trace:
RELADDR FUNCTION FILE:LINE
000000000021c208 !!!0000!804c660e2d6053be57921a5fd6d4bb!f61dec9117!+376) (BuildId: 7930b2c86c3cf072ea40709321b1af75 /vendor/lib64/egl/libGLESv2_adreno.so
00000000093c6de8 gpu::gles2::Framebuffer::GetStatus(gpu::gles2::TextureManager*, unsigned int) const ../../gpu/command_buffer/service/framebuffer_manager.cc:886:19
v------> gpu::gles2::GLES2DecoderImpl::DoCheckFramebufferStatus(unsigned int) ../../gpu/command_buffer/service/gles2_cmd_decoder.cc:7182:23
00000000093d2194 gpu::gles2::GLES2DecoderImpl::HandleCheckFramebufferStatus(unsigned int, void const volatile*) ../../gpu/command_buffer/service/gles2_cmd_decoder_autogen.h:347:17
00000000093f28a8 gpu::error::Error gpu::gles2::GLES2DecoderImpl::DoCommandsImpl<false>(unsigned int, void const volatile*, int, int*) ../../gpu/command_buffer/service/gles2_cmd_decoder.cc:4756:18
0000000003f202c4 gpu::CommandBufferService::Flush(int, gpu::AsyncAPIInterface*) ../../gpu/command_buffer/service/command_buffer_service.cc:267:35
00000000094d3a10 gpu::CommandBufferStub::OnAsyncFlush(int, unsigned int, std::__Cr::vector<gpu::SyncToken, std::__Cr::allocator<gpu::SyncToken>> const&) ../../gpu/ipc/service/command_buffer_stub.cc:504:22
00000000094d3714 gpu::CommandBufferStub::ExecuteDeferredRequest(gpu::mojom::DeferredCommandBufferRequestParams&, gpu::FenceSyncReleaseDelegate*) ../../gpu/ipc/service/command_buffer_stub.cc:173:7
00000000094d90d8 gpu::GpuChannel::ExecuteDeferredRequest(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*) ../../gpu/ipc/service/gpu_channel.cc:854:13
v------> void base::internal::DecayedFunctorTraits<void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>&&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>&&>::Invoke<void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel> const&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*>(void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel> const&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>&&, gpu::FenceSyncReleaseDelegate*&&) ../../base/functional/bind_internal.h:740:12
v------> void base::internal::InvokeHelper<true, base::internal::FunctorTraits<void (gpu::GpuChannel::*&&)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>&&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>&&>, void, 0ul, 1ul>::MakeItSo<void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), std::__Cr::tuple<base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>, gpu::FenceSyncReleaseDelegate*>(void (gpu::GpuChannel::*&&)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), std::__Cr::tuple<base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>&&, gpu::FenceSyncReleaseDelegate*&&) ../../base/functional/bind_internal.h:956:5
v------> void base::internal::Invoker<base::internal::FunctorTraits<void (gpu::GpuChannel::*&&)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>&&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>&&>, base::internal::BindState<true, true, false, void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>, void (gpu::FenceSyncReleaseDelegate*)>::RunImpl<void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), std::__Cr::tuple<base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>, 0ul, 1ul>(void (gpu::GpuChannel::*&&)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), std::__Cr::tuple<base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>&&, std::__Cr::integer_sequence<unsigned long, 0ul, 1ul>, gpu::FenceSyncReleaseDelegate*&&) ../../base/functional/bind_internal.h:1069:14
00000000094dbd7c base::internal::Invoker<base::internal::FunctorTraits<void (gpu::GpuChannel::*&&)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>&&, mojo::StructPtr<gpu::mojom::DeferredRequestParams>&&>, base::internal::BindState<true, true, false, void (gpu::GpuChannel::*)(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*), base::WeakPtr<gpu::GpuChannel>, mojo::StructPtr<gpu::mojom::DeferredRequestParams>>, void (gpu::FenceSyncReleaseDelegate*)>::RunOnce(base::internal::BindStateBase*, gpu::FenceSyncReleaseDelegate*) ../../base/functional/bind_internal.h:982:12
v------> base::OnceCallback<void (media::DemuxerStream*)>::Run(media::DemuxerStream*) && ../../base/functional/callback.h:155:12
v------> void base::internal::DecayedFunctorTraits<base::OnceCallback<void (media::DemuxerStream*)>, media::DemuxerStream*&&>::Invoke<base::OnceCallback<void (media::DemuxerStream*)>, media::DemuxerStream*>(base::OnceCallback<void (media::DemuxerStream*)>&&, media::DemuxerStream*&&) ../../base/functional/bind_internal.h:815:49
v------> void base::internal::InvokeHelper<false, base::internal::FunctorTraits<base::OnceCallback<void (media::DemuxerStream*)>&&, media::DemuxerStream*&&>, void, 0ul>::MakeItSo<base::OnceCallback<void (media::DemuxerStream*)>, std::__Cr::tuple<base::internal::UnretainedWrapper<media::DemuxerStream, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>>(base::OnceCallback<void (media::DemuxerStream*)>&&, std::__Cr::tuple<base::internal::UnretainedWrapper<media::DemuxerStream, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>&&) ../../base/functional/bind_internal.h:932:12
v------> void base::internal::Invoker<base::internal::FunctorTraits<base::OnceCallback<void (media::DemuxerStream*)>&&, media::DemuxerStream*&&>, base::internal::BindState<false, true, true, base::OnceCallback<void (media::DemuxerStream*)>, base::internal::UnretainedWrapper<media::DemuxerStream, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>, void ()>::RunImpl<base::OnceCallback<void (media::DemuxerStream*)>, std::__Cr::tuple<base::internal::UnretainedWrapper<media::DemuxerStream, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>, 0ul>(base::OnceCallback<void (media::DemuxerStream*)>&&, std::__Cr::tuple<base::internal::UnretainedWrapper<media::DemuxerStream, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>&&, std::__Cr::integer_sequence<unsigned long, 0ul>) ../../base/functional/bind_internal.h:1069:14
0000000003841ba4 base::internal::Invoker<base::internal::FunctorTraits<base::OnceCallback<void (void const*)>&&, collaboration::CollaborationController*&&>, base::internal::BindState<false, true, true, base::OnceCallback<void (void const*)>, base::internal::UnretainedWrapper<collaboration::CollaborationController, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>, void ()>::RunOnce(base::internal::BindStateBase*) ../../base/functional/bind_internal.h:982:12
v------> base::OnceCallback<void ()>::Run() && ../../base/functional/callback.h:155:12
0000000003f265b8 gpu::Scheduler::ExecuteSequence(base::IdType<gpu::SyncPointOrderData, unsigned int, 0u, 1u>) ../../gpu/command_buffer/service/scheduler.cc:739:29
0000000003f25b0c gpu::Scheduler::RunNextTask() ../../gpu/command_buffer/service/scheduler.cc:628:3
v------> base::OnceCallback<void ()>::Run() && ../../base/functional/callback.h:155:12
0000000006de7a34 base::TaskAnnotator::RunTaskImpl(base::PendingTask&) ../../base/task/common/task_annotator.cc:229:34
v------> void base::TaskAnnotator::RunTask<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*)::$_3>(perfetto::StaticString, base::PendingTask&, base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*)::$_3&&) ../../base/task/common/task_annotator.h:112:5
0000000006dfff70 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:482:23
0000000006dffae0 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:345:40
0000000006d9dd08 base::MessagePumpDefault::Run(base::MessagePump::Delegate*) ../../base/message_loop/message_pump_default.cc:65:55
0000000006e005e0 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:657:12
0000000006dc8ebc base::RunLoop::Run(base::Location const&) ../../base/run_loop.cc:135:14
000000000c5ef9ec content::GpuMain(content::MainFunctionParams) ../../content/gpu/gpu_main.cc:642:14
0000000006d765e0 content::RunOtherNamedProcessTypeMain(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, content::MainFunctionParams, content::ContentMainDelegate*) ../../content/app/content_main_runner_impl.cc:764:14
0000000006d77464 content::ContentMainRunnerImpl::Run() ../../content/app/content_main_runner_impl.cc:1165:10
0000000006d7500c content::RunContentProcess(content::ContentMainParams, content::ContentMainRunner*) ../../content/app/content_main.cc:356:36
0000000006d75f68 content::StartContentMain(bool) ../../content/app/android/content_main_android.cc:54:10
00000000002c2300 art_quick_generic_jni_trampoline+144) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
00000000006680e8 nterp_helper+152) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
00000000002aae76 offset 0x20a1000) (ft1.run+574 /data/app/~~C57UxPkaLjaVkvyrQAYIlw==/org.chromium.chrome-9S4pPjCnfD-K8TFfUMRrtg==/base.apk/libmonochrome.so
00000000000a95e0 java.lang.Thread.run+64) (BuildId: a2d6a559f5778b9b6315baec706b53a709156608 /system/framework/arm64/boot.oat
00000000002aaf94 art_quick_invoke_stub+612) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
0000000000270940 art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+220) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
00000000004bee24 art::Thread::CreateCallback(void*)+1184) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
00000000004be974 art::Thread::CreateCallbackWithUffdGc(void*)+8) (BuildId: 11dac5edfc6a4111efd44d494b5f3993 /apex/com.android.art/lib64/libart.so
00000000000866ec __pthread_start(void*) (.__uniq.67847048707805468364044055584648682506)+184) (BuildId: 0669c520dd58ab0634801cae537d6b06 /apex/com.android.runtime/lib64/bionic/libc.so
000000000007900c __start_thread+68) (BuildId: 0669c520dd58ab0634801cae537d6b06 /apex/com.android.runtime/lib64/bionic/libc.so
ROOT CAUSE
The bug is in the Qualcomm Adreno GPU driver (libGLESv2_adreno.so, build f61dec9117). When glTexStorage2D is called on a texture that is attached to an FBO as a depth attachment, the driver:
- Frees the old 0x80-byte internal storage container associated with the texture
- Allocates a new container for the immutable storage
- But does NOT update the FBO’s cached pointer at fbo+0x2a8, which still points to the freed container
The cross-FBO trick (bindFramebuffer(null) before texStorage2D) is required because the driver only updates fbo+652 (a dirty flag) for the currently bound FBO. By binding FBO 0 (default) before calling texStorage2D, the driver sets fbo0+652 instead of fboA+652, so FBO A’s cached container pointer remains stale.
When glClear(GL_DEPTH_BUFFER_BIT) is later called on FBO A, the driver’s completeness check function (804c660e) walks the dangling container at fbo+0x2a8. If the freed container has been reoccupied by attacker-controlled data (via RGBA16F texImage2D heap spray), the attacker controls the data read by the completeness check, leading to arbitrary code execution through the driver’s vtable dispatch (20bf65c8 → a970ffdb → BLR vtable[184]).
The ANGLE workaround “recreateFboUponFlush” (CL 7815775, Bug chromium:493747593) recreates the FBO on flush/finish/fenceSync. This is bypassed by using a detached canvas (no compositor flush) and avoiding all synchronous GL calls in the trigger loop.
SUGGESTED FIX
For Chrome/ANGLE:
- Extend the recreateFboUponFlush workaround to also trigger on glClear/glDraw* when the draw FBO has an immutable depth/stencil texture attachment with stale state, not only on flush/finish/fenceSync.
- Alternatively, add a workaround that calls glFramebufferTexture2D to re-attach the depth texture after texStorage2D is called on an FBO-attached texture, forcing the driver to refresh its cached container pointer.
For Qualcomm (upstream driver fix):
- In the glTexStorage2D implementation, iterate all FBOs that reference the respecified texture and update their cached container pointers (fbo+0x2a8) to point to the newly allocated container, or mark them dirty so the next FBO operation refreshes the pointer.
CREDIT INFORMATION Reporter credit: Anymous