Overview

Critical
Severity
8.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in WebGL
DescriptionUse after free in WebGL
ComponentWebGL
Sub-componentANGLE
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker499602793
Fix commitb8352abce038 (angle/angle) +225/-4
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H
CISA KEVNot listed
Creditedanonymous
Reported2026-04-05 (per vendor advisory)
Fix landed2026-07-31 (public git)
Disclosed2026-08-06
Patch gap6 days — fix public in source before the advisory

Background

Layered texture
a multi-layer texture object such as GL_TEXTURE_2D_ARRAY, where an individual layer can be bound to a framebuffer via glFramebufferTextureLayer.
FBO attachment
a FramebufferAttachment recording which texture layer backs a framebuffer’s color/depth/stencil slot; in the GL backend it maps to a driver-side attachment pointing at concrete texture storage.
`TexImage3D` reallocation
calling TexImage3D on an existing GL_TEXTURE_2D_ARRAY to grow its layer count causes the driver to free the old backing store and allocate new, larger storage.
PowerVR Android quirk
on these GPUs the driver keeps FBO attachments pointing at the freed old storage after reallocation instead of rebinding to the new storage, unlike conforming drivers.

Root Cause Analysis

When a layer of a layered texture is attached to a framebuffer and the application then calls TexImage3D to increase the texture’s layer count, TextureGL::setImageHelper reallocates the underlying texture object, freeing the old backing store. On PowerVR Android GPUs the driver does not re-point the existing FBO attachment at the newly allocated storage, so the framebuffer attachment continues to reference the freed old memory. Any subsequent framebuffer operation (draw, read, blit, clear) then reads from or writes to freed GPU memory, which is a classic use-after-free. Before this fix ANGLE had no mechanism to notify a Framebuffer that one of its attached textures had grown its layer count, so the stale binding was never repaired.

The fix introduces a new observer message, SubjectMessage::TextureLayerCountIncreased, that TextureGL::setImageHelper emits before reallocating, letting the framebuffer proactively detach and later reattach to valid storage.

Key insight
The framebuffer must be told about a layer-count increase specifically (not just any texture change) so it can force a detach-then-reattach cycle that rebinds the attachment to the freshly allocated storage instead of the freed old buffer.

Attack Path

  1. Set up layered attachment Create a GL_TEXTURE_2D_ARRAY, attach one of its layers to an FBO via glFramebufferTextureLayer.
  2. Trigger reallocation Call TexImage3D on the texture to increase its layer count, freeing the old backing store and allocating new storage.
  3. Leave attachment stale On PowerVR Android the FBO attachment still points at the freed old storage because the driver did not rebind it.
  4. Access freed memory Issue a draw or read against the framebuffer, causing the GPU to read/write the freed old buffer — a use-after-free.

Impact Assessment

This is a use-after-free in the WebGL/ANGLE GL backend that lets framebuffer operations read from and write to freed GPU memory after a layered texture is reallocated. Because the freed region can be reused for other allocations, an attacker driving WebGL from a web page could disclose or corrupt reclaimed memory, potentially leading to information disclosure or memory corruption. The issue is confined to PowerVR Android GPUs.

Changed Functions

FunctionChangeNotes
FramebufferGL
src/libANGLE/renderer/gl/FramebufferGL.h
modified
Texture2DArrayTestES3_ReattachTextureToFbo
src/tests/gl_tests/TextureTest.cpp
modified

Files Changed

  • src/libANGLE/renderer/gl/FramebufferGL.h
  • util/autogen/angle_features_autogen.h
  • src/libANGLE/renderer/gl/renderergl_utils.cpp
  • include/platform/autogen/FeaturesGL_autogen.h
  • src/libANGLE/Texture.cpp
  • util/autogen/angle_features_autogen.cpp
  • src/libANGLE/renderer/gl/TextureGL.cpp
  • src/libANGLE/Observer.h
  • src/libANGLE/renderer/gl/ContextGL.cpp
  • src/tests/capture_replay_tests/capture_replay_expectations.txt
  • include/platform/gl_features.json
  • src/libANGLE/renderer/gl/FramebufferGL.cpp
  • src/tests/gl_tests/TextureTest.cpp
  • src/libANGLE/Framebuffer.cpp
  • src/libANGLE/renderer/FramebufferImpl.h

Audit Directions

  • Reallocation without re-attachment
    audit every path where a texture’s backing store is freed and reallocated (TexImage*, TexStorage*, respecification) for FBO attachments that keep pointing at old storage on non-conforming drivers.
  • Observer message coverage
    verify that all texture state changes that invalidate framebuffer bindings emit a SubjectMessage the Framebuffer actually handles, not just dimension/format changes.
  • Driver-workaround gating
    check that reattachTextureToFboAfterLayerIncrease is enabled on all affected PowerVR Android configurations and that analogous stale-attachment bugs are not present in other backends.
From b8352abce0383b26af32415c1d0f4a6912f665ae Mon Sep 17 00:00:00 2001
From: Zhenyao Mo <zmo@chromium.org>
Date: Thu, 30 Jul 2026 19:25:57 -0700
Subject: [PATCH] ANGLE: Reattach texture layer to FBO after layer count increase

On PowerVR Android GPUs, when a layer of a layered texture (e.g.,
GL_TEXTURE_2D_ARRAY) is attached to a framebuffer and later TexImage3D
is called on the texture to increase its layer count, the framebuffer
remains attached to the old memory instead of the newly allocated
texture storage.

This CL adds the reattachTextureToFboAfterLayerIncrease workaround,
enabled on PowerVR Android. When enabled:
- When TextureGL::setImageHelper detects a layer count increase on a
  GL_TEXTURE_2D_ARRAY texture, it sends a TextureLayerCountIncreased
  subject message before reallocating texture storage via TexImage3D.
- When Framebuffer::onSubjectStateChange receives this message, it
  calls FramebufferGL::onAttachmentLayerCountChange to detach the
  attachment point on the GL driver (calling glFramebufferTextureLayer
  with texture id 0) and sets the attachment dirty bit.
- Re-attachment happens lazily: when the Framebuffer is next bound and
  used, ANGLE's normal state synchronization processes the dirty bit
  and automatically re-attaches the texture layer to the GL framebuffer.
- Adds unit tests verifying correct layer re-attachment behavior across
  single-context and shared multi-context scenarios, instantiated with
  the workaround enabled and disabled.

Bug: chromium:499602793,chromium:537729021
Change-Id: I84899b963d8e8683b5998d281c12263415c709a8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/8162364
Auto-Submit: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
---
diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json
index 32dffc1..f6cd33d 100644
--- a/include/platform/gl_features.json
+++ b/include/platform/gl_features.json
@@ -985,6 +985,14 @@
                 "object on ARM Mali Valhall/Avalon GPUs to avoid driver crash."
             ],
             "issue": "http://crbug.com/534468209"
+        },
+        {
+            "name": "reattach_texture_to_fbo_after_layer_increase",
+            "category": "Workarounds",
+            "description": [
+                "Reattach texture layer to framebuffer after calling TexImage3D to increase layer count on PowerVR Android."
+            ],
+            "issue": "http://crbug.com/499602793"
         }
     ]
 }
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index afa7711..5261ffd 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -2327,6 +2327,18 @@
             return;
         }
 
+        if (message == angle::SubjectMessage::TextureLayerCountIncreased)
+        {
+            FramebufferAttachment *attachment = getAttachmentFromSubjectIndex(index);
+            if (attachment)
+            {
+                (void)mImpl->onAttachmentLayerCountChange(attachment);
+            }
+            mDirtyBits.set(index);
+            onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+            return;
+        }
+
         // This can be triggered by the GL back-end TextureGL class.
         ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged ||
                message == angle::SubjectMessage::TextureIDDeleted);
diff --git a/src/libANGLE/Observer.h b/src/libANGLE/Observer.h
index 526f82b..2e0ddea 100644
--- a/src/libANGLE/Observer.h
+++ b/src/libANGLE/Observer.h
@@ -88,6 +88,9 @@
     // Indicates the underlying object storage has been reallocated.
     ObjectReallocated,
 
+    // Indicates a layered texture's layer count has increased.
+    TextureLayerCountIncreased,
+
     // Indicates a change in foveated rendering state in the subject.
     FoveatedRenderingStateChanged,
 };
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index 3611262..6b05a48 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -2749,6 +2749,9 @@
         case angle::SubjectMessage::ObjectReallocated:
             onStateChange(angle::SubjectMessage::ObjectReallocated);
             break;
+        case angle::SubjectMessage::TextureLayerCountIncreased:
+            onStateChange(angle::SubjectMessage::TextureLayerCountIncreased);
+            break;
         case angle::SubjectMessage::DirtyBitsFlagged:
             signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
 
diff --git a/src/libANGLE/renderer/FramebufferImpl.h b/src/libANGLE/renderer/FramebufferImpl.h
index dbace39..d7ecc89 100644
--- a/src/libANGLE/renderer/FramebufferImpl.h
+++ b/src/libANGLE/renderer/FramebufferImpl.h
@@ -105,6 +105,8 @@
 
     virtual angle::Result onLabelUpdate(const gl::Context *context);
 
+    virtual angle::Result onAttachmentLayerCountChange(gl::FramebufferAttachment *attachment);
+
     const gl::FramebufferState &getState() const { return mState; }
 
   protected:
@@ -116,6 +118,12 @@
     return false;
 }
 
+inline angle::Result FramebufferImpl::onAttachmentLayerCountChange(
+    gl::FramebufferAttachment *attachment)
+{
+    return angle::Result::Continue;
+}
+
 // Default implementation returns the format specified in the attachment.
 inline const gl::InternalFormat &FramebufferImpl::getImplementationColorReadFormat(
     const gl::Context *context) const
diff --git a/src/libANGLE/renderer/gl/ContextGL.cpp b/src/libANGLE/renderer/gl/ContextGL.cpp
index c78f216..fd2c023 100644
--- a/src/libANGLE/renderer/gl/ContextGL.cpp
+++ b/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -143,7 +143,7 @@
         funcs->genFramebuffers(1, &fbo);
     }
 
-    return new FramebufferGL(data, fbo, false);
+    return new FramebufferGL(data, fbo, false, funcs, getStateManager());
 }
 
 TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index e24641c..625eefc 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -464,11 +464,17 @@
     return textureGL->hasEmulatedAlphaChannel(attachment->getTextureImageIndex());
 }
 
-FramebufferGL::FramebufferGL(const gl::FramebufferState &data, GLuint id, bool emulatedAlpha)
+FramebufferGL::FramebufferGL(const gl::FramebufferState &data,
+                             GLuint id,
+                             bool emulatedAlpha,
+                             const FunctionsGL *functions,
+                             StateManagerGL *stateManager)
     : FramebufferImpl(data),
       mFramebufferID(id),
       mHasEmulatedAlphaAttachment(emulatedAlpha),
-      mAppliedEnabledDrawBuffers(1)
+      mAppliedEnabledDrawBuffers(1),
+      mFunctions(functions),
+      mStateManager(stateManager)
 {
     ASSERT((isDefault() && id == 0) || !isDefault());
 }
@@ -1377,6 +1383,15 @@
     return blitter->clearFramebuffer(context, colorAttachments, depth, stencil, this);
 }
 
+angle::Result FramebufferGL::onAttachmentLayerCountChange(gl::FramebufferAttachment *attachment)
+{
+    ASSERT(!isDefault() && attachment && attachment->isAttached() &&
+           attachment->type() == GL_TEXTURE && mFunctions->framebufferTextureLayer);
+    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+    mFunctions->framebufferTextureLayer(GL_FRAMEBUFFER, attachment->getBinding(), 0, 0, 0);
+    return angle::Result::Continue;
+}
+
 angle::Result FramebufferGL::syncState(const gl::Context *context,
                                        GLenum binding,
                                        const gl::Framebuffer::DirtyBits &dirtyBits,
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.h b/src/libANGLE/renderer/gl/FramebufferGL.h
index 18cc840..31c5706 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.h
+++ b/src/libANGLE/renderer/gl/FramebufferGL.h
@@ -28,7 +28,11 @@
 class FramebufferGL : public FramebufferImpl
 {
   public:
-    FramebufferGL(const gl::FramebufferState &data, GLuint id, bool emulatedAlpha);
+    FramebufferGL(const gl::FramebufferState &data,
+                  GLuint id,
+                  bool emulatedAlpha,
+                  const FunctionsGL *functions,
+                  StateManagerGL *stateManager);
     ~FramebufferGL() override;
 
     void destroy(const gl::Context *context) override;
@@ -84,6 +88,8 @@
     // The GL back-end requires a full sync state before we call checkStatus.
     bool shouldSyncStateBeforeCheckStatus() const override;
 
+    angle::Result onAttachmentLayerCountChange(gl::FramebufferAttachment *attachment) override;
+
     gl::FramebufferStatus checkStatus(const gl::Context *context) const override;
 
     angle::Result ensureAttachmentsInitialized(const gl::Context *context,
@@ -152,6 +158,8 @@
     GLuint mFramebufferID;
     bool mHasEmulatedAlphaAttachment;
     gl::DrawBufferMask mAppliedEnabledDrawBuffers;
+    const FunctionsGL *mFunctions;
+    StateManagerGL *mStateManager;
 };
 
 bool IsEmulatedAlphaChannelTextureAttachment(const gl::FramebufferAttachment *attachment);
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index 697ff2b..7ece705 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -278,6 +278,16 @@
         onStateChange(angle::SubjectMessage::ObjectReallocated);
     }
 
+    if (features.reattachTextureToFboAfterLayerIncrease.enabled &&
+        getType() == gl::TextureType::_2DArray)
+    {
+        const gl::ImageDesc &desc = mState.getImageDesc(target, level);
+        if (size.depth > desc.size.depth)
+        {
+            onStateChange(angle::SubjectMessage::TextureLayerCountIncreased);
+        }
+    }
+
     const gl::InternalFormat &originalInternalFormatInfo =
         gl::GetInternalFormatInfo(internalFormat, type);
     nativegl::TexImageFormat texImageFormat =
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 732f843..46afe19 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -2788,6 +2788,10 @@
     ANGLE_FEATURE_CONDITION(features, avoidComplexExpressionsInStructConstructor,
                             IsPowerVR(vendor));
 
+    // http://crbug.com/499602793
+    ANGLE_FEATURE_CONDITION(features, reattachTextureToFboAfterLayerIncrease,
+                            IsPowerVR(vendor) && IsAndroid());
+
     // Mac Intel drivers are unable to allocate buffers larger than ~1gb
     ANGLE_FEATURE_CONDITION(features, limitMaxBufferSizeTo1gb, isApple && isIntel);
 }
diff --git a/src/tests/capture_replay_tests/capture_replay_expectations.txt b/src/tests/capture_replay_tests/capture_replay_expectations.txt
index 3a6a919..e140de3 100644
--- a/src/tests/capture_replay_tests/capture_replay_expectations.txt
+++ b/src/tests/capture_replay_tests/capture_replay_expectations.txt
@@ -286,3 +286,6 @@
 
 # Crashes on win and linux trace bots
 372059358 : MultisampleTestES3.CopyTexImage2DFromMsaaDefaultFbo/* = SKIP_FOR_CAPTURE
+
+# Fails on win and linux trace bots
+499602793 : Texture2DArrayTestES3_ReattachTextureToFbo.IncreaseLayersWithFramebufferAttachedMultiContext/* = SKIP_FOR_CAPTURE
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index acc3375..8ebcd4d 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -9298,6 +9298,135 @@
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+class Texture2DArrayTestES3_ReattachTextureToFbo : public Texture2DArrayTestES3
+{};
+
+// Test increasing layer count of a 2D array texture when one of its layers is attached to a
+// framebuffer. http://crbug.com/499602793
+TEST_P(Texture2DArrayTestES3_ReattachTextureToFbo, IncreaseLayersWithFramebufferAttached)
+{
+    // http://crbug.com/499602793 - Metal backend does not support redefining 2D array texture
+    // layer count without releasing storage.
+    ANGLE_SKIP_TEST_IF(IsMetal());
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    std::vector<GLColor> pixelsRed(4 * 4 * 1, GLColor::red);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsRed.data());
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
+
+    // Increase layer count to 2.
+    std::vector<GLColor> pixelsGreen(4 * 4 * 2, GLColor::green);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsGreen.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Verify layer 0 points to the new memory (green).
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Verify layer 1 is also green.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 1);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Clear layer 1 to blue and verify.
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::blue);
+
+    // Now sample from layer 0 and layer 1 using a shader to ensure texture memory matches FBO
+    // memory.
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
+    glUseProgram(mProgram);
+    glUniform1i(mTextureArrayLocation, 0);
+
+    // Verify layer 0 is green.
+    glUniform1i(mTextureArraySliceUniformLocation, 0);
+    drawQuad(mProgram, "position", 0.5f);
+    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
+
+    // Verify layer 1 is blue.
+    glUniform1i(mTextureArraySliceUniformLocation, 1);
+    drawQuad(mProgram, "position", 0.5f);
+    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::blue);
+}
+
+// Test increasing layer count of a 2D array texture when one of its layers is attached to a
+// framebuffer in one context, and the texture is redefined in another shared context.
+// http://crbug.com/499602793
+TEST_P(Texture2DArrayTestES3_ReattachTextureToFbo,
+       IncreaseLayersWithFramebufferAttachedMultiContext)
+{
+    // http://crbug.com/499602793 - Metal backend does not support redefining 2D array texture
+    // layer count without releasing storage.
+    ANGLE_SKIP_TEST_IF(IsMetal());
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    std::vector<GLColor> pixelsRed(4 * 4 * 1, GLColor::red);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsRed.data());
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
+
+    // Set up and switch to a secondary context sharing resources with the current context.
+    EGLWindow *window          = getEGLWindow();
+    EGLDisplay display         = window->getDisplay();
+    EGLConfig config           = window->getConfig();
+    EGLSurface surface         = window->getSurface();
+    EGLint contextAttributes[] = {
+        EGL_CONTEXT_MAJOR_VERSION_KHR,
+        GetParam().majorVersion,
+        EGL_CONTEXT_MINOR_VERSION_KHR,
+        GetParam().minorVersion,
+        EGL_NONE,
+    };
+    EGLContext context1 = eglGetCurrentContext();
+    EGLContext context2 = eglCreateContext(display, config, context1, contextAttributes);
+    ASSERT_NE(context2, EGL_NO_CONTEXT);
+    eglMakeCurrent(display, surface, surface, context2);
+
+    // In the secondary context, bind the texture and increase layer count to 2.
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    std::vector<GLColor> pixelsGreen(4 * 4 * 2, GLColor::green);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsGreen.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Switch back to the primary context.
+    eglMakeCurrent(display, surface, surface, context1);
+
+    // Verify layer 0 points to the new memory (green).
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Attach layer 1 to the FBO in context1 and verify. Explicitly calling
+    // glFramebufferTextureLayer attaches to the newly allocated texture storage.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 1);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Clear layer 1 to blue and verify.
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::blue);
+
... (file diff truncated)
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/src/tests/capture_replay_tests/capture_replay_expectations.txt b/src/tests/capture_replay_tests/capture_replay_expectations.txt
index 3a6a919..e140de3 100644
--- a/src/tests/capture_replay_tests/capture_replay_expectations.txt
+++ b/src/tests/capture_replay_tests/capture_replay_expectations.txt
@@ -286,3 +286,6 @@
 
 # Crashes on win and linux trace bots
 372059358 : MultisampleTestES3.CopyTexImage2DFromMsaaDefaultFbo/* = SKIP_FOR_CAPTURE
+
+# Fails on win and linux trace bots
+499602793 : Texture2DArrayTestES3_ReattachTextureToFbo.IncreaseLayersWithFramebufferAttachedMultiContext/* = SKIP_FOR_CAPTURE
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index acc3375..8ebcd4d 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -9298,6 +9298,135 @@
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+class Texture2DArrayTestES3_ReattachTextureToFbo : public Texture2DArrayTestES3
+{};
+
+// Test increasing layer count of a 2D array texture when one of its layers is attached to a
+// framebuffer. http://crbug.com/499602793
+TEST_P(Texture2DArrayTestES3_ReattachTextureToFbo, IncreaseLayersWithFramebufferAttached)
+{
+    // http://crbug.com/499602793 - Metal backend does not support redefining 2D array texture
+    // layer count without releasing storage.
+    ANGLE_SKIP_TEST_IF(IsMetal());
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    std::vector<GLColor> pixelsRed(4 * 4 * 1, GLColor::red);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsRed.data());
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
+
+    // Increase layer count to 2.
+    std::vector<GLColor> pixelsGreen(4 * 4 * 2, GLColor::green);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsGreen.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Verify layer 0 points to the new memory (green).
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Verify layer 1 is also green.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 1);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Clear layer 1 to blue and verify.
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::blue);
+
+    // Now sample from layer 0 and layer 1 using a shader to ensure texture memory matches FBO
+    // memory.
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
+    glUseProgram(mProgram);
+    glUniform1i(mTextureArrayLocation, 0);
+
+    // Verify layer 0 is green.
+    glUniform1i(mTextureArraySliceUniformLocation, 0);
+    drawQuad(mProgram, "position", 0.5f);
+    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
+
+    // Verify layer 1 is blue.
+    glUniform1i(mTextureArraySliceUniformLocation, 1);
+    drawQuad(mProgram, "position", 0.5f);
+    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::blue);
+}
+
+// Test increasing layer count of a 2D array texture when one of its layers is attached to a
+// framebuffer in one context, and the texture is redefined in another shared context.
+// http://crbug.com/499602793
+TEST_P(Texture2DArrayTestES3_ReattachTextureToFbo,
+       IncreaseLayersWithFramebufferAttachedMultiContext)
+{
+    // http://crbug.com/499602793 - Metal backend does not support redefining 2D array texture
+    // layer count without releasing storage.
+    ANGLE_SKIP_TEST_IF(IsMetal());
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    std::vector<GLColor> pixelsRed(4 * 4 * 1, GLColor::red);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsRed.data());
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
+
+    // Set up and switch to a secondary context sharing resources with the current context.
+    EGLWindow *window          = getEGLWindow();
+    EGLDisplay display         = window->getDisplay();
+    EGLConfig config           = window->getConfig();
+    EGLSurface surface         = window->getSurface();
+    EGLint contextAttributes[] = {
+        EGL_CONTEXT_MAJOR_VERSION_KHR,
+        GetParam().majorVersion,
+        EGL_CONTEXT_MINOR_VERSION_KHR,
+        GetParam().minorVersion,
+        EGL_NONE,
+    };
+    EGLContext context1 = eglGetCurrentContext();
+    EGLContext context2 = eglCreateContext(display, config, context1, contextAttributes);
+    ASSERT_NE(context2, EGL_NO_CONTEXT);
+    eglMakeCurrent(display, surface, surface, context2);
+
+    // In the secondary context, bind the texture and increase layer count to 2.
+    glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+    std::vector<GLColor> pixelsGreen(4 * 4 * 2, GLColor::green);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 pixelsGreen.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Switch back to the primary context.
+    eglMakeCurrent(display, surface, surface, context1);
+
+    // Verify layer 0 points to the new memory (green).
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Attach layer 1 to the FBO in context1 and verify. Explicitly calling
+    // glFramebufferTextureLayer attaches to the newly allocated texture storage.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 1);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
+
+    // Clear layer 1 to blue and verify.
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::blue);
+
+    // Clean up secondary context.
+    eglDestroyContext(display, context2);
+}
+
 // Create a 3D texture, use it, then redefine one level without changing dimensions.
 TEST_P(Texture3DTestES3, RedefineLevelData)
 {
@@ -23208,6 +23337,16 @@
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3);
 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3_ReattachTextureToFbo);
+ANGLE_INSTANTIATE_TEST_ES3_AND(
+    Texture2DArrayTestES3_ReattachTextureToFbo,
+    ES3_OPENGL().enable(Feature::ReattachTextureToFboAfterLayerIncrease),
+    ES3_OPENGL().disable(Feature::ReattachTextureToFboAfterLayerIncrease),
+    ES3_OPENGLES().enable(Feature::ReattachTextureToFboAfterLayerIncrease),
+    ES3_OPENGLES().disable(Feature::ReattachTextureToFboAfterLayerIncrease),
+    ES3_VULKAN().enable(Feature::ReattachTextureToFboAfterLayerIncrease),
+    ES3_VULKAN().disable(Feature::ReattachTextureToFboAfterLayerIncrease));
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSizeTextureArrayTest);
 ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
Loading diff…

Original Bug Report

reported by ha...@gmail.com

Use After Free in GrowMipLevelArray lead android sandbox escape

ecurity Bug

Important: Please do not change the component of this bug manually.

Please READ THIS FAQ before filing a bug: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md

Please see the following link for instructions on filing security bugs: https://www.chromium.org/Home/chromium-security/reporting-security-bugs

Reports may be eligible for reward payments under the Chrome VRP: https://g.co/chrome/vrp

NOTE: Security bugs are normally made public once a fix has been widely deployed.

VULNERABILITY DETAILS

The function GrowMipLevelArray is responsible for expanding the per-texture MipLevel array when a texture is redefined with additional layers.

The vulnerable reallocation:

psMipLevel = GLES3Realloc(psTex->psMipLevel,
    sizeof(GLES3MipMapLevel) * ui32NewMaxLevels);

After realloc(), the FBO’s apsAttachment[] array still holds pointers into the old (now freed) MipLevel array. Subsequent operations that access the FBO attachment through these stale pointers trigger Use-After-Free.

Chrome Version: [146.0.7680.177] + [stable]

Operating System: [Android pixel 10 latest patch]

REPRODUCTION CASE

1.just open chrome on pixel 10 with MTE enabled,no need other flags enable MTE step 1.1 push chrome-command-line to /data/local/tmp 1.2 #enable-command-line-on-non-rooted-devices 1.3 reload chrome

2.load poc.html

3.logcat | grep DEBUG

FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION

Type of crash: [gpu.]

Crash State:

Symbolizing stack using ABI=arm64
signal 11 (SIGSEGV), code 9 (SEGV_MTESERR), fault addr 0x74a96f4730 in tid 9369 (CrGpuMain), pid 9353 (ileged_process2)
Build fingerprint: 'google/frankel/frankel:16/CP1A.260305.018/14887507:user/release-keys'
Revision: 'MP1.0'
pid: 9353, tid: 9369, name: CrGpuMain  >>> org.chromium.chrome:privileged_process2 <<<
signal 11 (SIGSEGV), code 9 (SEGV_MTESERR), fault addr 0x00000074a96f4730 (read)

Stack Trace:
  RELADDR   FUNCTION                                                                          FILE:LINE
  000000000008fe48  ScheduleTA+1336) (BuildId: cefd59f52838946b0e646aaf2bb04c76                       /vendor/lib64/egl/libGLESv2_powervr.so
  0000000000082fd4  KickUnFlushed_ScheduleTA+68) (BuildId: cefd59f52838946b0e646aaf2bb04c76           /vendor/lib64/egl/libGLESv2_powervr.so
  00000000000cd704  RM_FlushUnKickedResource+340) (BuildId: cefd59f52838946b0e646aaf2bb04c76          /vendor/lib64/egl/libGLESv2_powervr.so
  0000000000146bc0  TexImage3D+640) (BuildId: cefd59f52838946b0e646aaf2bb04c76                        /vendor/lib64/egl/libGLESv2_powervr.so
  00000000001468e0  Impl_glTexImage3D(unsigned int, int, int, int, int, int, int, unsigned int, unsigned int, void const*, GLES3Context_TAG*) (.__uniq.124271684878746512121637812560551803626)+96) (BuildId: cefd59f52838946b0e646aaf2bb04c76  /vendor/lib64/egl/libGLESv2_powervr.so
  0000000000146174  glTexImage3D+68) (BuildId: cefd59f52838946b0e646aaf2bb04c76                       /vendor/lib64/egl/libGLESv2_powervr.so
  0000000003675648  rx::TextureGL::setImageHelper(gl::Context const*, gl::TextureTarget, unsigned long, unsigned int, angle::Extents<int> const&, unsigned int, unsigned int, unsigned char const*)  ../../third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp:286:22
  0000000003674c58  rx::TextureGL::setImage(gl::Context const*, gl::ImageIndex const&, unsigned int, angle::Extents<int> const&, unsigned int, unsigned int, gl::PixelUnpackState const&, gl::Buffer*, unsigned char const*)  ../../third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp:240:15
  00000000035a9b3c  gl::Texture::setImage(gl::Context*, gl::PixelUnpackState const&, gl::Buffer*, gl::TextureTarget, int, unsigned int, angle::Extents<int> const&, unsigned int, unsigned int, unsigned char const*)  ../../third_party/angle/src/libANGLE/Texture.cpp:1413:25
  000000000352c230  gl::Context::texImage3D(gl::TextureTarget, int, int, int, int, int, int, unsigned int, unsigned int, void const*)  ../../third_party/angle/src/libANGLE/Context.cpp:5609:32
  00000000083b3958  GL_TexImage3DRobustANGLE                                                          ../../third_party/angle/src/libGLESv2/entry_points_gles_ext_autogen.cpp:3495:22
  0000000009a0e364  gpu::gles2::GLES2DecoderPassthroughImpl::DoTexImage3D(unsigned int, int, int, int, int, int, int, unsigned int, unsigned int, int, void const*)  ../../gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc:2930:10
  0000000009a1a2dc  gpu::gles2::GLES2DecoderPassthroughImpl::HandleTexImage3D(unsigned int, void const volatile*)  ../../gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc:1101:10
  00000000099fb52c  gpu::error::Error gpu::gles2::GLES2DecoderPassthroughImpl::DoCommandsImpl<false>(unsigned int, void const volatile*, int, int*)  ../../gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc:742:20
  00000000042bd920  gpu::CommandBufferService::Flush(int, gpu::AsyncAPIInterface*)                    ../../gpu/command_buffer/service/command_buffer_service.cc:267:35
  0000000009aca028  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
  0000000009ac9cc0  gpu::CommandBufferStub::ExecuteDeferredRequest(gpu::mojom::DeferredCommandBufferRequestParams&, gpu::FenceSyncReleaseDelegate*)  ../../gpu/ipc/service/command_buffer_stub.cc:173:7
  0000000009acfb50  gpu::GpuChannel::ExecuteDeferredRequest(mojo::StructPtr<gpu::mojom::DeferredRequestParams>, gpu::FenceSyncReleaseDelegate*)  ../../gpu/ipc/service/gpu_channel.cc:833:13
  0000000009ad29e0  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
  0000000009ad2964  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
  0000000003bb79a4  base::internal::Invoker<base::internal::FunctorTraits<base::OnceCallback<void (BrowserWindowInterface*)>&&, base::raw_ptr<BrowserWindowInterface, (partition_alloc::internal::RawPtrTraits)1>&&>, base::internal::BindState<false, true, true, base::OnceCallback<void (BrowserWindowInterface*)>, base::internal::UnretainedWrapper<BrowserWindowInterface, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)1>>, void ()>::RunOnce(base::internal::BindStateBase*)  ../../base/functional/bind_internal.h:982:12
  v------>  base::OnceCallback<void ()>::Run() &&                                             ../../base/functional/callback.h:155:12
  00000000042c3384  gpu::Scheduler::ExecuteSequence(base::IdType<gpu::SyncPointOrderData, unsigned int, 0u, 1u>)  ../../gpu/command_buffer/service/scheduler.cc:707:29
  00000000042c2a7c  gpu::Scheduler::RunNextTask()                                                     ../../gpu/command_buffer/service/scheduler.cc:625:3
  v------>  base::OnceCallback<void ()>::Run() &&                                             ../../base/functional/callback.h:155:12
  000000000703a1fc  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
  0000000007056a3c  base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*)  ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:475:23
  0000000007056640  base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork()   ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:346:40
  0000000006fead28  base::MessagePumpDefault::Run(base::MessagePump::Delegate*)                       ../../base/message_loop/message_pump_default.cc:42:55
  0000000007057100  base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta)  ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:650:12
  00000000070182cc  base::RunLoop::Run(base::Location const&)                                         ../../base/run_loop.cc:135:14
  000000000ce4b014  content::GpuMain(content::MainFunctionParams)                                     ../../content/gpu/gpu_main.cc:485:14
  0000000006fc2288  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:762:14
  0000000006fc30d8  content::ContentMainRunnerImpl::Run()                                             ../../content/app/content_main_runner_impl.cc:1152:10
  0000000006fc0acc  content::RunContentProcess(content::ContentMainParams, content::ContentMainRunner*)  ../../content/app/content_main.cc:358:36
  0000000006fc1ac8  content::StartContentMain(bool)                                                   ../../content/app/android/content_main_android.cc:54:10
  00000000002c2300  art_quick_generic_jni_trampoline+144) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  00000000002ab260  art_quick_invoke_static_stub+640) (BuildId: 61c7a211c01ef3c0068b4fbe31051050      /apex/com.android.art/lib64/libart.so
  0000000000585c88  bool art::interpreter::DoCall<false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, bool, art::JValue*)+1984) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  000000000048ff6c  void art::interpreter::ExecuteSwitchImplCpp<false>(art::interpreter::SwitchImplContext*)+468) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  00000000003d1718  ExecuteSwitchImplAsm+8) (BuildId: 61c7a211c01ef3c0068b4fbe31051050                /apex/com.android.art/lib64/libart.so
  000000000029005c  offset 0x4085000) (xi1.run+0                                                      /data/app/~~ayCs0G1cEE9vDupqqYSiOA==/org.chromium.chrome-OG-qSl8JAd4v0pHWHiahqA==/base.apk/libmonochrome.so
  00000000003d136c  art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.__uniq.112435418011751916792819755956732575238.llvm.15381326084910962254)+364) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  00000000003d0aa0  artQuickToInterpreterBridge+1020) (BuildId: 61c7a211c01ef3c0068b4fbe31051050      /apex/com.android.art/lib64/libart.so
  00000000002c2438  art_quick_to_interpreter_bridge+88) (BuildId: 61c7a211c01ef3c0068b4fbe31051050    /apex/com.android.art/lib64/libart.so
  00000000000049a8  offset 0x2000000) (java.lang.Thread.run+136                                       [anon_shmem:dalvik-jit-code-cache]
  00000000002aaf94  art_quick_invoke_stub+612) (BuildId: 61c7a211c01ef3c0068b4fbe31051050             /apex/com.android.art/lib64/libart.so
  00000000002709b0  art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+220) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  00000000004bdfc8  art::Thread::CreateCallback(void*)+1184) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  00000000004bdb18  art::Thread::CreateCallbackWithUffdGc(void*)+8) (BuildId: 61c7a211c01ef3c0068b4fbe31051050  /apex/com.android.art/lib64/libart.so
  000000000008a914  __pthread_start(void*) (.__uniq.67847048707805468364044055584648682506)+180) (BuildId: 8d65ea529c21c79c019713e50adb6675  /apex/com.android.runtime/lib64/bionic/libc.so
  000000000007b5a4  __start_thread+68) (BuildId: 8d65ea529c21c79c019713e50adb6675                     /apex/com.android.runtime/lib64/bionic/libc.so

Please do not close this page again. Please find a professional to categorize it.

View on issue tracker