<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>314526</bug_id>
          
          <creation_ts>2026-05-10 21:28:27 -0700</creation_ts>
          <short_desc>REGRESSION (312740@main): [ASan/TSan] `angle::PoolAllocator` has inconsistent layout across translation units, crashing GPU process on WebGL shader compile</short_desc>
          <delta_ts>2026-05-10 22:34:00 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebGL</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar, Regression</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          <dependson>313441</dependson>
          
          <everconfirmed>1</everconfirmed>
          <reporter name="David Kilzer (:ddkilzer)">ddkilzer</reporter>
          <assigned_to name="David Kilzer (:ddkilzer)">ddkilzer</assigned_to>
          <cc>djg</cc>
    
    <cc>kbr</cc>
    
    <cc>kkinnunen</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>2209576</commentid>
    <comment_count>0</comment_count>
    <who name="David Kilzer (:ddkilzer)">ddkilzer</who>
    <bug_when>2026-05-10 21:28:27 -0700</bug_when>
    <thetext>ASan (and TSan) builds of WebKit cause any WebGL shader compile performed in the GPU process to abort with an AddressSanitizer stack-buffer-overflow report in `angle::PoolAllocator::PoolAllocator()`. This is observed across the majority of tests in `LayoutTests/fast/canvas/webgl/` on ASan builds.

Stack trace (representative crash thread, from a local ASan build):

```
==PID==ERROR: AddressSanitizer: stack-buffer-overflow
WRITE of size 88 at 0x... thread TN
0  libclang_rt.asan_osx_dynamic.dylib:  __asan_memset
1  libANGLE-shared.dylib:  angle::PoolAllocator::PoolAllocator()
2  libANGLE-shared.dylib:  sh::TCompiler::compile(angle::Span&lt;char const* const&gt;, ShCompileOptions const&amp;)
3  libANGLE-shared.dylib:  rx::ShaderTranslateTask::translate(void*, ShCompileOptions const&amp;, std::string const&amp;)
4  libANGLE-shared.dylib:  gl::CompileTask::operator()()
5  libANGLE-shared.dylib:  angle::UnlockedTailCall::runImpl(void*)
6  WebCore:  WebCore::GraphicsContextGLANGLE::compileShader(unsigned int)
7  WebKit:  WebKit::RemoteGraphicsContextGL::compileShader(unsigned int)
8  WebKit:  WebKit::RemoteGraphicsContextGL::didReceiveStreamMessage(IPC::StreamServerConnection&amp;, IPC::Decoder&amp;)
[...]
```

The ASan frame report shows the compiler-allocated stack slot for `scopedAlloc` (a `TScopedPoolAllocator` whose only member is an `angle::PoolAllocator`) is 24 bytes wide, but `angle::PoolAllocator::PoolAllocator()` performs an 88-byte `__asan_memset` to zero-initialize its members. The call writes past the end of the 24-byte slot, corrupting the adjacent ASan redzone and other stack locals.

The 88-byte write size comes from the layout `std::vector&lt;Segment&gt; mSingleObjectSegments` + `Span&lt;uint8_t&gt; mCurrentPool` + `std::vector&lt;Segment&gt; mPoolSegments` + `std::vector&lt;Segment&gt; mUnusedSegments`. The 24-byte layout contains only `mSingleObjectSegments`. The three extra vectors are conditionally present under `#if !defined(ANGLE_DISABLE_POOL_ALLOC)` in `Source/ThirdParty/ANGLE/src/common/PoolAlloc.h`.

`ANGLE_DISABLE_POOL_ALLOC` is defined at the top of `PoolAlloc.h` based on whether `ANGLE_WITH_ASAN` or `ANGLE_WITH_TSAN` is visible there. Those macros are defined in `common/platform.h` from `__has_feature()`. The `#if defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN)` check in `PoolAlloc.h` runs BEFORE `common/platform.h` is transitively included (via `common/angleutils.h`, further down in the same header). As a result, whether the sanitizer macros are visible at that check depends on which headers the including translation unit already pulled in:

  * `Source/ThirdParty/ANGLE/src/common/PoolAlloc.cpp` includes `common/PoolAlloc.h` as its first include. At the macro check in `PoolAlloc.h`, `platform.h` has not been processed yet, so `ANGLE_WITH_ASAN` is NOT visible -&gt; `ANGLE_DISABLE_POOL_ALLOC` is NOT defined -&gt; `PoolAllocator` has the 88-byte layout, and the emitted `PoolAllocator::PoolAllocator()` body (defaulted) zero-initializes 88 bytes.
  * `Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp` (the `sh::TCompiler::compile` caller) includes `compiler/translator/Compiler.h` first, which transitively pulls in `common/platform.h` via `Diagnostics.h`/`SymbolTable.h` BEFORE `PoolAlloc.h` is processed. At the macro check, `ANGLE_WITH_ASAN` IS visible -&gt; `ANGLE_DISABLE_POOL_ALLOC` IS defined -&gt; `PoolAllocator` has the 24-byte layout, and the stack slot for `scopedAlloc.mAllocator` is 24 bytes wide.

This is an ODR violation caused by a preprocessor macro check running before the macro-defining header is included. Introduced by Bug 313441 / 312740@main, where the `ANGLE_DISABLE_POOL_ALLOC` selection was added at the top of `PoolAlloc.h`. The previous macro selection at the same position (`#if !defined(NDEBUG)`) did not have this failure mode because `NDEBUG` is a standard compiler-provided macro that is visible regardless of include order.

Steps to reproduce:

1. Build WebKit for macOS with ASan.
2. Run any WebGL layout test that compiles a shader: `Tools/Scripts/run-webkit-tests --no-build --release --no-timeout --no-show-results fast/canvas/webgl/gl-getshadersource.html` (or any similar test).
3. Observe GPU-process crash with ASan `stack-buffer-overflow` report in `WebKitBuild/Release/layout-test-results/com.apple.WebKit.GPU.Development-*-crash-log.txt`.

Binary-level confirmation from `otool -tv` of `libANGLE-shared.dylib` pre-patch shows `angle::PoolAllocator::PoolAllocator()` calling `__asan_memset` with `w2 = #0x58` (88 bytes); consumer translation units allocate only 24 bytes of stack for the corresponding `scopedAlloc`.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2209577</commentid>
    <comment_count>1</comment_count>
    <who name="David Kilzer (:ddkilzer)">ddkilzer</who>
    <bug_when>2026-05-10 21:28:29 -0700</bug_when>
    <thetext>&lt;rdar://problem/176749270&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2209578</commentid>
    <comment_count>2</comment_count>
    <who name="David Kilzer (:ddkilzer)">ddkilzer</who>
    <bug_when>2026-05-10 21:44:11 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/64653</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2209593</commentid>
    <comment_count>3</comment_count>
    <who name="EWS">ews-feeder</who>
    <bug_when>2026-05-10 22:33:58 -0700</bug_when>
    <thetext>Committed 312987@main (346deb2b1c82): &lt;https://commits.webkit.org/312987@main&gt;

Reviewed commits have been landed. Closing PR #64653 and removing active labels.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>