Overview

Critical
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in WebGL
DescriptionUse after free in WebGL
ComponentWebGL
Bug ClassUAF
Tracker520656244
Fix commit092d0d9b5333 (chromium/src) +479/-13
CISA KEVNot listed
Creditedanonymous
Disclosed2026-06-23

Changed Functions

FunctionChangeNotes
TextureAttachment
gpu/command_buffer/service/framebuffer_manager.cc
modified
GetBindingFramebuffersForTexture
gpu/command_buffer/service/framebuffer_manager.cc
modified
if
gpu/command_buffer/service/framebuffer_manager.cc
modified
for
gpu/command_buffer/service/framebuffer_manager.cc
modified
ScopedDepthStencilReattacher
gpu/command_buffer/service/gles2_cmd_decoder.cc
modified
if
gpu/command_buffer/service/gles2_cmd_decoder.cc
modified

Files Changed

  • gpu/command_buffer/service/framebuffer_manager.cc
  • gpu/command_buffer/service/framebuffer_manager.h
  • gpu/command_buffer/service/gles2_cmd_decoder.cc
From 092d0d9b5333e7d68a01f7e0dc44fd3c4f8a5b32 Mon Sep 17 00:00:00 2001
From: Ken Russell <[email protected]>
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 <[email protected]>
Reviewed-by: Geoff Lang <[email protected]>
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;
+  }
Loading diff…

Regression Test / PoC

shipped with the fix
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
Loading diff…

Original Bug Report

reported by [email protected]

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

  1. Serve the attached files with Python:
python3 -m http.server 8899 --bind 127.0.0.1
  1. Set up adb reverse:
adb reverse tcp:8899 tcp:8899
  1. Open in Chrome (no flags):

access http://127.0.0.1:8899/rce1_off.html

  1. 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:

  1. Frees the old 0x80-byte internal storage container associated with the texture
  2. Allocates a new container for the immutable storage
  3. 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

View on issue tracker