Medium watch CVSS 4.3 chrome OOB 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactHeap buffer overflow in SwiftShader
DescriptionHeap buffer overflow in SwiftShader
ComponentSwiftShader
Sub-componentVulkan
Bug ClassOOB
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.
Tracker328109821
Fix commitb1dd8daac2a6 (angle/angle) +122/-2
CWECWE-122 (Heap buffer overflow)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CISA KEVNot listed
CreditedCassidy Kim(@cassidy6564)
Reported2024-03-05 (per vendor advisory)
Fix landed2026-03-09 (public git)
Disclosed2026-05-12
Patch gap64 days — fix public in source before the advisory

Background

ANGLE Vulkan backend
The GL-on-Vulkan translation layer (src/libANGLE/renderer/vulkan/vk_helpers.cpp) that Chrome uses for GPU rendering; the advisory labels the component SwiftShader (the software Vulkan driver ANGLE can run on).
Robust resource init
A security feature that clears newly-allocated texture storage before use; stageRobustResourceClearWithFormat stages a buffer copy to clear the whole image.
`computeCompressedImageSize(glExtents, &totalSize)`
Computes the byte size needed to hold a compressed image for the given extents (width, height, depth).
2D array texture extents
For array textures, stageRobustResourceClearWithFormat rewrites glExtents so the layer count is moved out of depth (depth is set to 1), meaning depth no longer reflects the number of layers.

Root Cause Analysis

ImageHelper::stageResourceClearWithFormat sized the staging buffer for the clear copy by calling computeCompressedImageSize(glExtents, &totalSize), trusting glExtents.depth to represent the extent to be cleared. But its caller stageRobustResourceClearWithFormat modifies glExtents for array textures so that the layer count is carried elsewhere and depth is forced to 1, so for a 2D-array compressed texture the computed size covered only a single layer instead of all layers. The subsequent copy/clear then operated over the full image geometry against a buffer sized for one layer, writing past the allocation — a heap buffer overflow.

The fix adds glExtentForSizeComputation, and when gl::IsArrayTextureType(index.getType()) is true (asserting depth == 1), sets its depth = index.getLayerCount() before calling computeCompressedImageSize, so the buffer is sized for every layer and the copy stays in bounds. The added LargeCompressedImage2DArray/LargeImage2DArray tests exercise a 256×256×512 array texture with a partial sub-image update to force the whole-image robust clear.

Key insight
The size computation used the caller-rewritten depth of 1 for array textures while the actual clear spanned all layers, undersizing the staging buffer; the fix substitutes index.getLayerCount() for the depth when the texture is an array type so the computed size matches the copied extent.

Attack Path

  1. Allocate a large array texture A page calls glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, <compressed/uncompressed format>, 256, 256, 512) so a many-layer image is created with robust init enabled.
  2. Trigger whole-image robust clear A partial glCompressedTexSubImage3D/glTexSubImage3D that does not cover the full image forces stageRobustResourceClearWithFormat to clear the entire image first.
  3. Undersized buffer computed stageResourceClearWithFormat calls computeCompressedImageSize with depth == 1 (array extents rewritten), allocating a staging buffer for a single layer.
  4. Heap buffer overflow The clear copy proceeds over all layers against the one-layer buffer, writing/reading beyond its bounds (the test comments note “copying beyond its bounds”), the heap buffer overflow the advisory reports; escalation beyond the overflow is (inferred).

Impact Assessment

A web page issuing WebGL2/GLES3 calls on a large 2D-array (compressed) texture can cause a heap buffer overflow during robust resource initialization in the GPU process. The vendor advisory rates this medium severity (heap buffer overflow in SwiftShader); the overflow is demonstrated by the sizing bug and regression tests, while any escalation to memory-corruption-based code execution or sandbox effects is (inferred). The precondition is the ability to create a sufficiently large array texture and trigger a whole-image robust clear.

Files Changed

  • src/libANGLE/renderer/vulkan/vk_helpers.cpp
  • src/tests/gl_tests/RobustResourceInitTest.cpp

Audit Directions

  • Extent reuse after caller rewriting
    Audit callees that compute buffer sizes from an extents/glExtents struct that a caller may have repurposed (e.g., depth↔layer-count for array textures); confirm size math uses the true per-layer count.
  • Array vs. 3D texture conflation
    Review paths handling GL_TEXTURE_2D_ARRAY and other array types where layer count is stored outside depth; check IsArrayTextureType/getLayerCount() is applied consistently in every size and copy computation.
  • Robust-init clear sizing
    Examine other stageRobustResourceClear* / stageResourceClear* and compressed-size helpers for mismatches between the extent used to size the staging buffer and the extent used for the actual copy.
From b1dd8daac2a6b3e8d7ddc38c3e501fbb80baf6d5 Mon Sep 17 00:00:00 2001
From: Amirali Abdolrashidi <[email protected]>
Date: Wed, 04 Mar 2026 17:17:47 -0800
Subject: [PATCH] Vulkan: Fix array compressed tex size for copy

  In ImageHelper::stageResourceClearWithFormat(), the required size for
image copy is determined by computeCompressedImageSize(), which takes a
glExtents arg. However, in stageRobustResourceClearWithFormat(), which
calls this function, the glExtents arg is modified for array textures,
so that the layer count is set to the input depth instead and the depth
is set to 1. This results in a smaller buffer than needed, leading to
memory access errors later.

This change will make sure that the compressed image size uses the
layer count for the array textures.

* Updated ImageHelper::stageResourceClearWithFormat() so the buffer
  size computation for an array compressed texture will use the layer
  count instead of the depth.
  * (computeCompressedImageSize())
  * (Depth is set to 1 in stageRobustResourceClearWithFormat() for
    such textures.)

* Added the following unit tests to RobustResourceInitTestES3:
  * LargeCompressedImage2DArray
    * It makes sure that the proper robust resource clear path is
      applied to the whole image and there is no crash due to an
      incorrect buffer size and copying beyond its bounds.
  * LargeImage2DArray
    * Similar test for a non-compressed texture type.

Bug: chromium:328109821
Change-Id: I4ccbc0287ff6f1b1185e40a4c2cde3d6fffa3b80
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7636098
Reviewed-by: Shahbaz Youssefi <[email protected]>
Reviewed-by: Charlie Lao <[email protected]>
Commit-Queue: Amirali Abdolrashidi <[email protected]>
---

diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 94a7641..fede53c 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -9556,9 +9556,19 @@
 
         const gl::InternalFormat &formatInfo =
             gl::GetSizedInternalFormatInfo(imageFormat.glInternalFormat);
+
+        // For the array compressed textures (e.g., 2D array), the depth is set to 1. This should be
+        // taken into account when calculating the required buffer size for the copy.
+        gl::Extents glExtentForSizeComputation = glExtents;
+        if (gl::IsArrayTextureType(index.getType()))
+        {
+            ASSERT(glExtentForSizeComputation.depth == 1);
+            glExtentForSizeComputation.depth = index.getLayerCount();
+        }
+
         GLuint totalSize;
-        ANGLE_VK_CHECK_MATH(contextVk,
-                            formatInfo.computeCompressedImageSize(glExtents, &totalSize));
+        ANGLE_VK_CHECK_MATH(contextVk, formatInfo.computeCompressedImageSize(
+                                           glExtentForSizeComputation, &totalSize));
 
         std::unique_ptr<RefCounted<BufferHelper>> stagingBuffer =
             std::make_unique<RefCounted<BufferHelper>>();
diff --git a/src/tests/gl_tests/RobustResourceInitTest.cpp b/src/tests/gl_tests/RobustResourceInitTest.cpp
index 5beb889..9ba74e2 100644
--- a/src/tests/gl_tests/RobustResourceInitTest.cpp
+++ b/src/tests/gl_tests/RobustResourceInitTest.cpp
@@ -2039,6 +2039,116 @@
     }
 }
 
+// Test that using TexStorage3D with a large 2D array texture followed by TexSubImage works with
+// robust init.
+TEST_P(RobustResourceInitTestES3, LargeImage2DArray)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kWidth  = 256;
+    constexpr int kHeight = 256;
+    constexpr int kDepth  = 512;
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, kDepth);
+
+    // The bounds of the subimage copy should not cover the entire image. This will make sure that
+    // the robust resource clear is applied to the whole image before the subimage copy.
+    constexpr int kSubWidth  = 8;
+    constexpr int kSubHeight = 8;
+    constexpr int kSubDepth  = 8;
+    std::vector<GLColor> subData(kSubWidth * kSubHeight * kSubDepth, GLColor::red);
+    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSubWidth, kSubHeight, kSubDepth, GL_RGBA,
+                    GL_UNSIGNED_BYTE, subData.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Draw on FBO sampling from layer 0 of the texture.
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+    glViewport(0, 0, kWidth, kHeight);
+
+    draw2DArrayTexturedQuad(0.5, 1.0, false, 0);
+    ASSERT_GL_NO_ERROR();
+
+    // Verify the colors on the inside and the outside of the updated area.
+    EXPECT_PIXEL_RECT_EQ(0, 0, kSubWidth, kSubHeight, GLColor::red);
+    EXPECT_PIXEL_RECT_EQ(kSubWidth, 0, kWidth - kSubWidth, kHeight, GLColor::transparentBlack);
+    EXPECT_PIXEL_RECT_EQ(0, kSubHeight, kSubWidth, kHeight - kSubHeight, GLColor::transparentBlack);
+}
+
+// Test that using TexStorage3D with a large 2D array texture followed by CompressedTexSubImage
+// works with robust init, and does not crash by trying to copy beyond its memory bounds during
+// the initial robust clear.
+TEST_P(RobustResourceInitTestES3, LargeCompressedImage2DArray)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    constexpr int kWidth  = 256;
+    constexpr int kHeight = 256;
+    constexpr int kDepth  = 512;
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, kWidth, kHeight,
+                   kDepth);
+
+    // The bounds of the subimage copy should not cover the entire image. This will make sure that
+    // the robust resource clear is applied to the whole image before the subimage copy.
+    constexpr int kSubWidth         = 8;
+    constexpr int kSubHeight        = 8;
+    constexpr int kSubDepth         = 8;
+    constexpr int kSubImageByteSize = kSubWidth * kSubHeight * kSubDepth / 2;
+    std::vector<uint8_t> subData(kSubImageByteSize);
+    static constexpr uint8_t kRed_4x4_rgb_dxt1[] = {
+        0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00,
+    };
+    static_assert(kSubImageByteSize % 8 == 0);
+    for (size_t i = 0; i < kSubImageByteSize; i += 8)
+    {
+        memcpy(&subData[i], kRed_4x4_rgb_dxt1, sizeof(kRed_4x4_rgb_dxt1));
+    }
+    glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSubWidth, kSubHeight, kSubDepth,
+                              GL_COMPRESSED_RGB_S3TC_DXT1_EXT, kSubImageByteSize, subData.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Draw on FBO sampling from layer 0 of the texture.
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+    glViewport(0, 0, kWidth, kHeight);
+
+    draw2DArrayTexturedQuad(0.5, 1.0, false, 0);
+    ASSERT_GL_NO_ERROR();
+
+    // Verify the colors on the inside and the outside of the updated area.
+    EXPECT_PIXEL_RECT_EQ(0, 0, kSubWidth, kSubHeight, GLColor::red);
+    EXPECT_PIXEL_RECT_EQ(kSubWidth, 0, kWidth - kSubWidth, kHeight, GLColor::black);
+    EXPECT_PIXEL_RECT_EQ(0, kSubHeight, kSubWidth, kHeight - kSubHeight, GLColor::black);
+}
+
 // Test drawing to a framebuffer with not all draw buffers enabled
 TEST_P(RobustResourceInitTestES3, SparseDrawBuffers)
 {
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/src/tests/gl_tests/RobustResourceInitTest.cpp b/src/tests/gl_tests/RobustResourceInitTest.cpp
index 5beb889..9ba74e2 100644
--- a/src/tests/gl_tests/RobustResourceInitTest.cpp
+++ b/src/tests/gl_tests/RobustResourceInitTest.cpp
@@ -2039,6 +2039,116 @@
     }
 }
 
+// Test that using TexStorage3D with a large 2D array texture followed by TexSubImage works with
+// robust init.
+TEST_P(RobustResourceInitTestES3, LargeImage2DArray)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kWidth  = 256;
+    constexpr int kHeight = 256;
+    constexpr int kDepth  = 512;
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, kDepth);
+
+    // The bounds of the subimage copy should not cover the entire image. This will make sure that
+    // the robust resource clear is applied to the whole image before the subimage copy.
+    constexpr int kSubWidth  = 8;
+    constexpr int kSubHeight = 8;
+    constexpr int kSubDepth  = 8;
+    std::vector<GLColor> subData(kSubWidth * kSubHeight * kSubDepth, GLColor::red);
+    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSubWidth, kSubHeight, kSubDepth, GL_RGBA,
+                    GL_UNSIGNED_BYTE, subData.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Draw on FBO sampling from layer 0 of the texture.
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+    glViewport(0, 0, kWidth, kHeight);
+
+    draw2DArrayTexturedQuad(0.5, 1.0, false, 0);
+    ASSERT_GL_NO_ERROR();
+
+    // Verify the colors on the inside and the outside of the updated area.
+    EXPECT_PIXEL_RECT_EQ(0, 0, kSubWidth, kSubHeight, GLColor::red);
+    EXPECT_PIXEL_RECT_EQ(kSubWidth, 0, kWidth - kSubWidth, kHeight, GLColor::transparentBlack);
+    EXPECT_PIXEL_RECT_EQ(0, kSubHeight, kSubWidth, kHeight - kSubHeight, GLColor::transparentBlack);
+}
+
+// Test that using TexStorage3D with a large 2D array texture followed by CompressedTexSubImage
+// works with robust init, and does not crash by trying to copy beyond its memory bounds during
+// the initial robust clear.
+TEST_P(RobustResourceInitTestES3, LargeCompressedImage2DArray)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    constexpr int kWidth  = 256;
+    constexpr int kHeight = 256;
+    constexpr int kDepth  = 512;
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, kWidth, kHeight,
+                   kDepth);
+
+    // The bounds of the subimage copy should not cover the entire image. This will make sure that
+    // the robust resource clear is applied to the whole image before the subimage copy.
+    constexpr int kSubWidth         = 8;
+    constexpr int kSubHeight        = 8;
+    constexpr int kSubDepth         = 8;
+    constexpr int kSubImageByteSize = kSubWidth * kSubHeight * kSubDepth / 2;
+    std::vector<uint8_t> subData(kSubImageByteSize);
+    static constexpr uint8_t kRed_4x4_rgb_dxt1[] = {
+        0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00,
+    };
+    static_assert(kSubImageByteSize % 8 == 0);
+    for (size_t i = 0; i < kSubImageByteSize; i += 8)
+    {
+        memcpy(&subData[i], kRed_4x4_rgb_dxt1, sizeof(kRed_4x4_rgb_dxt1));
+    }
+    glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSubWidth, kSubHeight, kSubDepth,
+                              GL_COMPRESSED_RGB_S3TC_DXT1_EXT, kSubImageByteSize, subData.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Draw on FBO sampling from layer 0 of the texture.
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+    glViewport(0, 0, kWidth, kHeight);
+
+    draw2DArrayTexturedQuad(0.5, 1.0, false, 0);
+    ASSERT_GL_NO_ERROR();
+
+    // Verify the colors on the inside and the outside of the updated area.
+    EXPECT_PIXEL_RECT_EQ(0, 0, kSubWidth, kSubHeight, GLColor::red);
+    EXPECT_PIXEL_RECT_EQ(kSubWidth, 0, kWidth - kSubWidth, kHeight, GLColor::black);
+    EXPECT_PIXEL_RECT_EQ(0, kSubHeight, kSubWidth, kHeight - kSubHeight, GLColor::black);
+}
+
 // Test drawing to a framebuffer with not all draw buffers enabled
 TEST_P(RobustResourceInitTestES3, SparseDrawBuffers)
 {
Loading diff…

Original Bug Report

reported by [email protected]

heap-buffer-overflow in vk::Image::copy

tested os: ubuntu 22.04 tested chrome version: stable & dev

repro steps: ./chrome –user-data-dir=/tmp/xx7 –disable-gpu http://localhost:8000/crash.html

==1598117==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7efd9d6f3917 at pc 0x5589cea51a62 bp 0x7efd7c161f70 sp 0x7efd7c161730 READ of size 2336 at 0x7efd9d6f3917 thread T17 #0 0x5589cea51a61 in __asan_memcpy asan_rtl:3 #1 0x7efda5896041 in vk::Image::copy(void const*, void*, unsigned int, unsigned int, VkImageSubresourceLayers const&, VkOffset3D const&, VkExtent3D const&) ./../../third_party/swiftshader/src/Vulkan/VkImage.cpp:659:5 #2 0x7efda58966cc in vk::Image::copyFrom(vk::Buffer*, VkBufferImageCopy2 const&) ./../../third_party/swiftshader/src/Vulkan/VkImage.cpp:684:2 #3 0x7efda585bd72 in vk::CommandBuffer::submit(vk::CommandBuffer::ExecutionState&) ./../../third_party/swiftshader/src/Vulkan/VkCommandBuffer.cpp:2383:12 #4 0x7efda58b5e4f in vk::Queue::submitQueue(vk::Queue::Task const&) ./../../third_party/swiftshader/src/Vulkan/VkQueue.cpp:104:42 #5 0x7efda58b4fe0 in vk::Queue::taskLoop(marl::Scheduler*) ./../../third_party/swiftshader/src/Vulkan/VkQueue.cpp:156:4 #6 0x7efda58b8985 in __invoke<void (vk::Queue::)(marl::Scheduler ), vk::Queue , marl::Scheduler , void> ./../../third_party/libc++/src/include/__type_traits/invoke.h:118:25 #7 0x7efda58b8985 in __thread_execute<std::__Cr::unique_ptr<std::__Cr::__thread_struct, std::__Cr::default_deletestd::__Cr::__thread_struct >, void (vk::Queue::)(marl::Scheduler ), vk::Queue , marl::Scheduler , 2UL, 3UL> ./../../third_party/libc++/src/include/__thread/thread.h:193:3 #8 0x7efda58b8985 in void std::__Cr::__thread_proxy<std::__Cr::tuple<std::__Cr::unique_ptr<std::__Cr::__thread_struct, std::__Cr::default_deletestd::__Cr::__thread_struct>, void (vk::Queue::)(marl::Scheduler), vk::Queue, marl::Scheduler>>(void) ./../../third_party/libc++/src/include/__thread/thread.h:202:3 #9 0x5589cea516a8 in asan_thread_start(void*) asan_rtl:28

0x7efd9d6f3917 is located 0 bytes after 4194583-byte region [0x7efd9d2f3800,0x7efd9d6f3917) allocated by thread T0 (chrome) here: #0 0x5589cea53b0f in __interceptor_malloc asan_rtl:3 #1 0x7efda5d543fd in allocate ./../../third_party/swiftshader/src/System/Memory.cpp:81:42 #2 0x7efda5d543fd in sw::allocateZeroOrPoison(unsigned long, unsigned long) ./../../third_party/swiftshader/src/System/Memory.cpp:110:9 #3 0x7efda587c9a2 in vk::DeviceMemory::allocateBuffer() ./../../third_party/swiftshader/src/Vulkan/VkDeviceMemory.cpp:342:11 #4 0x7efda587b5d6 in allocate ./../../third_party/swiftshader/src/Vulkan/VkDeviceMemory.cpp:275:12 #5 0x7efda587b5d6 in vk::DeviceMemory::Allocate(VkAllocationCallbacks const*, VkMemoryAllocateInfo const*, VkNonDispatchableHandle<VkDeviceMemory_T*>, vk::Device) ./../../third_party/swiftshader/src/Vulkan/VkDeviceMemory.cpp:103:29 #6 0x7efda58d21b2 in vkAllocateMemory ./../../third_party/swiftshader/src/Vulkan/libVulkan.cpp:1382:20 #7 0x7efdb1ee8637 in allocate ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_wrapper.h:1497:12 #8 0x7efdb1ee8637 in rx::(anonymous namespace)::FindAndAllocateCompatibleMemory(rx::vk::Context*, rx::vk::MemoryAllocationType, rx::vk::MemoryProperties const&, unsigned int, unsigned int*, VkMemoryRequirements const&, void const*, unsigned int*, rx::vk::DeviceMemory*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_utils.cpp:112:40 #9 0x7efdb1ee4d9d in AllocateAndBindBufferOrImageMemoryrx::vk::Buffer ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_utils.cpp:188:5 #10 0x7efdb1ee4d9d in AllocateBufferOrImageMemoryrx::vk::Buffer ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_utils.cpp:212:5 #11 0x7efdb1ee4d9d in rx::vk::AllocateBufferMemory(rx::vk::Context*, rx::vk::MemoryAllocationType, unsigned int, unsigned int*, void const*, rx::vk::Buffer*, unsigned int*, rx::vk::DeviceMemory*, unsigned long*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_utils.cpp:562:12 #12 0x7efdb1e782d7 in rx::vk::BufferPool::allocateNewBuffer(rx::vk::Context*, unsigned long) ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:3426:5 #13 0x7efdb1e78f36 in rx::vk::BufferPool::allocateBuffer(rx::vk::Context*, unsigned long, unsigned long, rx::vk::BufferSuballocation*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:3547:5 #14 0x7efdb1e8b6ad in rx::vk::BufferHelper::initSuballocation(rx::vk::Context*, unsigned int, unsigned long, unsigned long, rx::BufferUsageType, rx::vk::BufferPool*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:4934:5 #15 0x7efdb1c40663 in rx::ContextVk::initBufferAllocation(rx::vk::BufferHelper*, unsigned int, unsigned long, unsigned long, rx::BufferUsageType) ./../../third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp:7124:42 #16 0x7efdb1bd89ef in acquireBufferHelper ./../../third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp:1209:5 #17 0x7efdb1bd89ef in rx::BufferVk::setDataWithMemoryType(gl::Context const*, gl::BufferBinding, void const*, unsigned long, unsigned int, gl::BufferUsage) ./../../third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp:469:9 #18 0x7efdb1bd7ff1 in rx::BufferVk::setDataWithUsageFlags(gl::Context const*, gl::BufferBinding, void*, void const*, unsigned long, gl::BufferUsage, unsigned int) ./../../third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp:423:12 #19 0x7efdb1fc792b in gl::Buffer::bufferDataImpl(gl::Context*, gl::BufferBinding, void const*, long, gl::BufferUsage, unsigned int) ./../../third_party/angle/src/libANGLE/Buffer.cpp:159:16 #20 0x7efdb1fc7d39 in gl::Buffer::bufferData(gl::Context*, gl::BufferBinding, void const*, long, gl::BufferUsage) ./../../third_party/angle/src/libANGLE/Buffer.cpp:123:12 #21 0x5589e8198737 in gpu::gles2::GLES2DecoderPassthroughImpl::DoBufferData(unsigned int, long, void const*, unsigned int) ./../../gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc:666:10 #22 0x5589e814908d in gpu::error::Error gpu::gles2::GLES2DecoderPassthroughImpl::DoCommandsImpl<false>(unsigned int, void const volatile*, int, int*) ./../../gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc:737:20 #23 0x5589e86675bb in gpu::CommandBufferService::Flush(int, gpu::AsyncAPIInterface*) ./../../gpu/command_buffer/service/command_buffer_service.cc:232:35 #24 0x5589e8656b33 in gpu::CommandBufferStub::OnAsyncFlush(int, unsigned int, std::__Cr::vector<gpu::SyncToken, std::__Cr::allocatorgpu::SyncToken> const&) ./../../gpu/ipc/service/command_buffer_stub.cc:507:22 #25 0x5589e8656009 in gpu::CommandBufferStub::ExecuteDeferredRequest(gpu::mojom::DeferredCommandBufferRequestParams&) ./../../gpu/ipc/service/command_buffer_stub.cc:155:7 #26 0x5589e86728d1 in gpu::GpuChannel::ExecuteDeferredRequest(mojo::StructPtrgpu::mojom::DeferredRequestParams) ./../../gpu/ipc/service/gpu_channel.cc:874:13 #27 0x5589e8682066 in void base::internal::DecayedFunctorTraits<void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), base::WeakPtrgpu::GpuChannel&&, mojo::StructPtrgpu::mojom::DeferredRequestParams&&>::Invoke<void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), base::WeakPtrgpu::GpuChannel const&, mojo::StructPtrgpu::mojom::DeferredRequestParams>(void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), base::WeakPtrgpu::GpuChannel const&, mojo::StructPtrgpu::mojom::DeferredRequestParams&&) ./../../base/functional/bind_internal.h:738:12 #28 0x5589e8681e4c in MakeItSo<void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), std::__Cr::tuple<base::WeakPtrgpu::GpuChannel, mojo::StructPtrgpu::mojom::DeferredRequestParams > > ./../../base/functional/bind_internal.h:954:5 #29 0x5589e8681e4c in RunImpl<void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), std::__Cr::tuple<base::WeakPtrgpu::GpuChannel, mojo::StructPtrgpu::mojom::DeferredRequestParams >, 0UL, 1UL> ./../../base/functional/bind_internal.h:1067:14 #30 0x5589e8681e4c in base::internal::Invoker<base::internal::FunctorTraits<void (gpu::GpuChannel::&&)(mojo::StructPtrgpu::mojom::DeferredRequestParams), base::WeakPtrgpu::GpuChannel&&, mojo::StructPtrgpu::mojom::DeferredRequestParams&&>, base::internal::BindState<true, true, false, void (gpu::GpuChannel::)(mojo::StructPtrgpu::mojom::DeferredRequestParams), base::WeakPtrgpu::GpuChannel, mojo::StructPtrgpu::mojom::DeferredRequestParams>, void ()>::RunOnce(base::internal::BindStateBase) ./../../base/functional/bind_internal.h:980:12 #31 0x5589e5472d2d in Run ./../../base/functional/callback.h:156:12 #32 0x5589e5472d2d in gpu::SchedulerDfs::ExecuteSequence(base::IdType<gpu::SyncPointOrderData, unsigned int, 0u, 1u>) ./../../gpu/command_buffer/service/scheduler_dfs.cc:740:24 #33 0x5589e5470c42 in gpu::SchedulerDfs::RunNextTask() ./../../gpu/command_buffer/service/scheduler_dfs.cc:665:3 #34 0x5589e5474833 in Invoke<void (gpu::SchedulerDfs::)(), gpu::SchedulerDfs > ./../../base/functional/bind_internal.h:738:12 #35 0x5589e5474833 in MakeItSo<void (gpu::SchedulerDfs::)(), std::__Cr::tuple<base::internal::UnretainedWrapper<gpu::SchedulerDfs, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> > > ./../../base/functional/bind_internal.h:930:12 #36 0x5589e5474833 in RunImpl<void (gpu::SchedulerDfs::)(), std::__Cr::tuple<base::internal::UnretainedWrapper<gpu::SchedulerDfs, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >, 0UL> ./../../base/functional/bind_internal.h:1067:14 #37 0x5589e5474833 in base::internal::Invoker<base::internal::FunctorTraits<void (gpu::SchedulerDfs::&&)(), gpu::SchedulerDfs>, base::internal::BindState<true, true, false, void (gpu::SchedulerDfs::)(), base::internal::UnretainedWrapper<gpu::SchedulerDfs, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>>, void ()>::RunOnce(base::internal::BindStateBase) ./../../base/functional/bind_internal.h:980:12 #38 0x5589e04d8834 in Run ./../../base/functional/callback.h:156:12 #39 0x5589e04d8834 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) ./../../base/task/common/task_annotator.cc:202:34 #40 0x5589e053a11f in RunTask<(lambda at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:475:11)> ./../../base/task/common/task_annotator.h:89:5 #41 0x5589e053a11f in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) ./../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:473:23 #42 0x5589e0539109 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() ./../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:338:40 #43 0x5589e053aeda in non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() ./../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:0:0

Thread T17 created by T0 (chrome) here: #0 0x5589cea39981 in ___interceptor_pthread_create asan_rtl:3 #1 0x7efda58b522e in __libcpp_thread_create ./../../third_party/libc++/src/include/__thread/support/pthread.h:181:10 #2 0x7efda58b522e in std::__Cr::thread::thread<void (vk::Queue::)(marl::Scheduler), vk::Queue*, marl::Scheduler*&, 0>(void (vk::Queue::&&)(marl::Scheduler), vk::Queue*&&, marl::Scheduler*&) ./../../third_party/libc++/src/include/__thread/thread.h:212:14 #3 0x7efda58b4e7b in vk::Queue::Queue(vk::Device*, marl::Scheduler*) ./../../third_party/swiftshader/src/Vulkan/VkQueue.cpp:38:16 #4 0x7efda586e7ac in vk::Device::Device(VkDeviceCreateInfo const*, void*, vk::PhysicalDevice*, VkPhysicalDeviceFeatures const*, std::__Cr::shared_ptrmarl::Scheduler const&) ./../../third_party/swiftshader/src/Vulkan/VkDevice.cpp:139:26 #5 0x7efda58cf925 in DispatchableObject<const VkDeviceCreateInfo , void , vk::PhysicalDevice , const VkPhysicalDeviceFeatures , std::__Cr::shared_ptrmarl::Scheduler > ./../../third_party/swiftshader/src/Vulkan/VkObject.hpp:127:8 #6 0x7efda58cf925 in Create<vk::DispatchableObject<vk::Device, VkDevice_T >, VkDevice_T , VkDeviceCreateInfo, vk::PhysicalDevice , const VkPhysicalDeviceFeatures , std::__Cr::shared_ptrmarl::Scheduler > ./../../third_party/swiftshader/src/Vulkan/VkObject.hpp:65:34 #7 0x7efda58cf925 in VkResult vk::DispatchableObject<vk::Device, VkDevice_T>::Create<VkDeviceCreateInfo, vk::PhysicalDevice, VkPhysicalDeviceFeatures const, std::__Cr::shared_ptrmarl::Scheduler>(VkAllocationCallbacks const, VkDeviceCreateInfo const, VkDevice_T, vk::PhysicalDevice, VkPhysicalDeviceFeatures const*, std::__Cr::shared_ptrmarl::Scheduler) ./../../third_party/swiftshader/src/Vulkan/VkObject.hpp:147:10 #8 0x7efda58cf275 in vkCreateDevice ./../../third_party/swiftshader/src/Vulkan/libVulkan.cpp:1264:9 #9 0x7efd9e92d81a in terminator_CreateDevice ./../../third_party/vulkan-deps/vulkan-loader/src/loader/loader.c:5833:11 #10 0x7efd9e930dc5 in loader_create_device_chain ./../../third_party/vulkan-deps/vulkan-loader/src/loader/loader.c:4937:15 #11 0x7efd9e92f3d6 in loader_layer_create_device ./../../third_party/vulkan-deps/vulkan-loader/src/loader/loader.c:4317:11 #12 0x7efd9e944818 in vkCreateDevice ./../../third_party/vulkan-deps/vulkan-loader/src/loader/trampoline.c:1005:20 #13 0x7efdb1cd475f in rx::RendererVk::createDeviceAndQueue(rx::DisplayVk*, unsigned int) ./../../third_party/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp:3490:5 #14 0x7efdb1ccfc97 in rx::RendererVk::initialize(rx::DisplayVk*, egl::Display*, char const*, char const*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp:1978:5 #15 0x7efdb1c598a2 in rx::DisplayVk::initialize(egl::Display*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp:110:39 #16 0x7efdb1ef49d6 in rx::DisplayVkXcb::initialize(egl::Display*) ./../../third_party/angle/src/libANGLE/renderer/vulkan/linux/xcb/DisplayVkXcb.cpp:64:23 #17 0x7efdb2082e1b in egl::Display::initialize() ./../../third_party/angle/src/libANGLE/Display.cpp:1066:36 #18 0x7efdb1b7a7ef in egl::Initialize(egl::Thread*, egl::Display*, int*, int*) ./../../third_party/angle/src/libGLESv2/egl_stubs.cpp:514:5 #19 0x7efdb1b817eb in EGL_Initialize ./../../third_party/angle/src/libGLESv2/entry_points_egl_autogen.cpp:478:27 #20 0x5589e46a02dc in gl::GLDisplayEGL::InitializeDisplay(bool, std::__Cr::vector<gl::DisplayType, std::__Cr::allocatorgl::DisplayType>, gl::EGLDisplayPlatform, gl::GLDisplayEGL*) ./../../ui/gl/gl_display.cc:783:10 #21 0x5589e469e96f in gl::GLDisplayEGL::Initialize(bool, std::__Cr::vector<gl::DisplayType, std::__Cr::allocatorgl::DisplayType>, gl::EGLDisplayPlatform) ./../../ui/gl/gl_display.cc:673:8 #22 0x5589d0db7189 in ui::GLOzoneEGL::InitializeGLOneOffPlatform(bool, std::__Cr::vector<gl::DisplayType, std::__Cr::allocatorgl::DisplayType>, gl::GpuPreference) ./../../ui/ozone/common/gl_ozone_egl.cc:25:17 #23 0x5589e86976c7 in gl::init::InitializeGLOneOffPlatform(gl::GpuPreference) ./../../ui/gl/init/gl_initializer_ozone.cc:27:26 #24 0x5589e8695ddb in gl::init::InitializeGLOneOffPlatformImplementation(bool, bool, bool, gl::GpuPreference) ./../../ui/gl/init/gl_factory.cc:211:24 #25 0x5589e8695771 in gl::init::(anonymous namespace)::InitializeGLOneOffPlatformHelper(bool, gl::GpuPreference) ./../../ui/gl/init/gl_factory.cc:135:10 #26 0x5589e8695b0f in gl::init::InitializeGLNoExtensionsOneOff(bool, gl::GpuPreference) ./../../ui/gl/init/gl_factory.cc:166:10 #27 0x5589e86f74d2 in gpu::GpuInit::InitializeAndStartSandbox(base::CommandLine*, gpu::GpuPreferences const&) ./../../gpu/ipc/service/gpu_init.cc:443:18 #28 0x5589f6e36f28 in content::GpuMain(content::MainFunctionParams) ./../../content/gpu/gpu_main.cc:357:39 #29 0x5589ddbf8f98 in content::RunZygote(content::ContentMainDelegate*) ./../../content/app/content_main_runner_impl.cc:676:14 #30 0x5589ddbfa4c1 in 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:780:12 #31 0x5589ddbfceff in content::ContentMainRunnerImpl::Run() ./../../content/app/content_main_runner_impl.cc:1146:10 #32 0x5589ddbf72f0 in content::RunContentProcess(content::ContentMainParams, content::ContentMainRunner*) ./../../content/app/content_main.cc:333:36 #33 0x5589ddbf796b in content::ContentMain(content::ContentMainParams) ./../../content/app/content_main.cc:346:10 #34 0x5589df0d3c4f in HeadlessChildMain ./../../headless/app/headless_shell.cc:195:12 #35 0x5589df0d3c4f in headless::HeadlessShellMain(content::ContentMainParams) ./../../headless/app/headless_shell.cc:256:5 #36 0x5589cea89da5 in ChromeMain ./../../chrome/app/chrome_main.cc:178:14 #37 0x7efdb9029d8f in __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/pwn11/asan-linux-release/chrome+0xe55aa61) (BuildId: e96457291d9dde52) Shadow bytes around the buggy address: 0x7efd9d6f3680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7efd9d6f3700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7efd9d6f3780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7efd9d6f3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7efd9d6f3880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7efd9d6f3900: 00 00[07]fa fa fa fa fa fa fa fa fa fa fa fa fa 0x7efd9d6f3980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x7efd9d6f3a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x7efd9d6f3a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x7efd9d6f3b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x7efd9d6f3b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb

==1598117==ADDITIONAL INFO

==1598117==Note: Please include this section with the ASan report. Task trace:

==1598117==END OF ADDITIONAL INFO ==1598117==ABORTING

View on issue tracker