Talos Vulnerability Report

TALOS-2020-1085

Google Chrome WebGL code execution vulnerability

August 24, 2020
CVE Number

CVE-2020-6492

Summary

A use-after-free read vulnerability exists in Google Chrome 81.0.4044.138 (Stable), 84.0.4136.5 (Dev) and 84.0.4143.7 (Canary), when a WebGL component fails to properly handle objects in memory. Successful exploitation of this vulnerability can lead to arbitrary code execution in the context of the browser process.

Tested Versions

Google Chrome Google Chrome 81.0.4044.138 (Stable)
Google Chrome Google Chrome 84.0.4136.5 (Dev)
Google Chrome Google Chrome 84.0.4143.7 (Canary)

Product URLs

https://www.google.com/chrome/

CVSSv3 Score

8.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L

CWE

CWE-416 - Use After Free

Details

Google Chrome is one of the most popular web browsers available.

This vulnerability is in ANGLE, a compatibility layer between OpenGL and Direct3D used on Windows by Chrome browser and other project.

Crash presents itself in function “State::syncTextures” which is responsbile for checking if texture has any so called DirtyBits:

Each OpenGL Context state value is stored in gl::State. For instance the blending state, depth/stencil state, and current object bindings. Our problem is deciding how to notify the back-end when app changes front-end state. We decided to bundle changed state into bitsets. Each 1 bit indicates a specific changed state value. We call these bitsets "dirty bits". See gl::State::DirtyBitType.
Each back-end handles state changes in a syncState implementation function that takes a dirty bitset. See examples in the GL back-end, D3D11 back-end and Vulkan back-end.

Container objects such as Vertex Array Objects and Framebuffers also have their own OpenGL front-end state. VAOs store vertex arrays and array buffer bindings. Framebuffers store attachment state and the active read and draw buffers. These containers also have internal dirty bits and syncState methods. See gl::Framebuffer::DirtyBitType and rx::FramebufferVk::syncState for example.

The crash is triggered at line 11 in the following listing, when texture object tries to syncState which leads to function “Texture::syncState”:

1:  angle::Result State::syncTextures(const Context *context)
2:  {
3:      if (mDirtyTextures.none())
4:          return angle::Result::Continue;
5:  
6:      for (size_t textureIndex : mDirtyTextures)
7:      {
8:          Texture *texture = mActiveTexturesCache[textureIndex];
9:          if (texture && texture->hasAnyDirtyBit())
10:          {
11:              ANGLE_TRY(texture->syncState(context));
12:          }
13:      }
14:  
15:      mDirtyTextures.reset();
16:      return angle::Result::Continue;
17:  }

Function that is necessary for executing vulnerable code is drawArraysInstanced and it corresponds 1 to 1 to it’s Javascript counterpart:

 1:  void Context::drawArraysInstanced(PrimitiveMode mode,
 2:                                    GLint first,
 3:                                    GLsizei count,
 4:                                    GLsizei instanceCount)
 5:  {
 6:      // No-op if count draws no primitives for given mode
 7:      if (noopDrawInstanced(mode, count, instanceCount))
 8:      {
 9:          return;
10:      }
11:  
12:      ANGLE_CONTEXT_TRY(prepareForDraw(mode));
13:      ANGLE_CONTEXT_TRY(
14:          mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
15:      MarkTransformFeedbackBufferUsage(this, count, instanceCount);
16:      MarkShaderStorageBufferUsage(this);
17:  }

Tracing address of rcx which is at fault led to function libglesv2!gl::Texture::~Texture which by definition does SafeDelete of the texture.

1:  Texture::~Texture()
2:  {
3:      SafeDelete(mTexture);
4:  }

At this point if attacker could properly allocate objects between functions deleteTexture and drawArraysInstanced they could further abuse the use after free condition. The most crucial part of the PoC is in the following listing:

1:  gl.bindTexture(gl.TEXTURE_2D, gl_v3); 
2:  //[...]
3:  gl.deleteTexture(gl_v3); 
4:  gl.drawArraysInstanced(gl.LINES, 952, 85, 751); 

PoC first calls bindTexture and then then deleteTexture , but a stale reference is then used by function drawArraysInstanced at which point the texture does not exists anymore triggering a crash.

With proper memory layout manipulation an attacker can gain full control of this use-after-free vulnerability which could ultimately lead to arbitrary code execution in the context of the browser.

This vulnerability was found by our fuzzer, but during root cause analysis it was discovered that it is very similar to previously reported issue crbug.com/943538 . Indeed, the PoC from that issue was used as a seed in our fuzzer. It is our understanding that the initial vulnerability wasn’t proerly fixed and the regression was not caught because triggering it requires testing on Windows with harware 3D acceleration.

Crash Information

Windbg context:

3:037> r
rax=0000000000000000 rbx=000002ee00740b90 rcx=feeefeeefeeefeee
rdx=000002ee00740b90 rsi=000002ee007cb778 rdi=000002ee00740ba0
rip=00007ffdc295091c rsp=000000f2717fde10 rbp=0000000000000000
 r8=0000000000000004  r9=000002ee0075df50 r10=00007ffdc2e0ece0
r11=000000f2717fde60 r12=0000000000000055 r13=0000000000000001
r14=0000000000000000 r15=00000000000007eb
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
libglesv2!gl::Texture::syncState+0x16:
00007ffd`c295091c 488b01          mov     rax,qword ptr [rcx] ds:feeefeee`feeefeee=????????????????

Address Sanitizer output:

==7132==ERROR: AddressSanitizer: heap-use-after-free on address 0x120760d34508 at pc 0x7ffd5792a3f1 bp 0x00a5ac1fe670 sp 0x00a5ac1fe6b8
READ of size 8 at 0x120760d34508 thread T0
SCARINESS: 51 (8-byte-read-heap-use-after-free)
==7132==WARNING: Failed to use and restart external symbolizer!
==7132==*** WARNING: Failed to initialize DbgHelp!              ***
==7132==*** Most likely this means that the app is already      ***
==7132==*** using DbgHelp, possibly with incompatible flags.    ***
==7132==*** Due to technical reasons, symbolization might crash ***
==7132==*** or produce wrong results.                           ***
[7304:5472:0512/140013.152:ERROR:device_event_log_impl.cc(208)] [14:00:13.160] Bluetooth: bluetooth_adapter_winrt.cc:1074 Getting Default Adapter failed.
    #0 0x7ffd5792a3f0 in gl::State::syncTextures C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\State.cpp:3108
    #1 0x7ffd577fa2a1 in gl::Context::drawArraysInstanced C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\Context.cpp:2202
    #2 0x7ffd5775848c in gl::DrawArraysInstanced C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libGLESv2\entry_points_gles_3_0_autogen.cpp:588
    #3 0x7ffd6fb7f401 in gpu::gles2::GLES2DecoderPassthroughImpl::DoDrawArraysInstancedANGLE C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough_doers.cc:4454
    #4 0x7ffd6d4a1ca5 in gpu::gles2::GLES2DecoderPassthroughImpl::HandleDrawArraysInstancedANGLE C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough_handlers.cc:1786
    #5 0x7ffd69b364c4 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommandsImpl<0> C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:834
    #6 0x7ffd69b35900 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommands C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:772
    #7 0x7ffd66cd6e6d in gpu::CommandBufferService::Flush C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\command_buffer_service.cc:69
    #8 0x7ffd645c1835 in gpu::CommandBufferStub::OnAsyncFlush C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:517
    #9 0x7ffd645c11bb in IPC::MessageT<GpuCommandBufferMsg_AsyncFlush_Meta,std::__1::tuple<int,unsigned int,std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>>>,void>::Dispatch<gpu::CommandBufferStub,gpu::CommandBufferStub,void,void (gpu::CommandBufferStub::*)(int, unsigned int, const std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>> &)> C:\b\s\w\ir\cache\builder\src\ipc\ipc_message_templates.h:139
    #10 0x7ffd645be531 in gpu::CommandBufferStub::OnMessageReceived C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:166
    #11 0x7ffd645d201f in gpu::GpuChannel::HandleMessageHelper C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:622
    #12 0x7ffd645cc172 in gpu::GpuChannel::HandleMessage C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:580
    #13 0x7ffd6427a11d in gpu::Scheduler::RunNextTask C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\scheduler.cc:554
    #14 0x7ffd630c4e99 in base::TaskAnnotator::RunTask C:\b\s\w\ir\cache\builder\src\base\task\common\task_annotator.cc:142
    #15 0x7ffd630f6ed3 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:329
    #16 0x7ffd630f6644 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:254
    #17 0x7ffd65882f23 in base::MessagePumpDefault::Run C:\b\s\w\ir\cache\builder\src\base\message_loop\message_pump_default.cc:39
    #18 0x7ffd630f869a in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:443
    #19 0x7ffd6307bc71 in base::RunLoop::Run C:\b\s\w\ir\cache\builder\src\base\run_loop.cc:124
    #20 0x7ffd652c8af9 in content::GpuMain C:\b\s\w\ir\cache\builder\src\content\gpu\gpu_main.cc:419
    #21 0x7ffd62d7903a in content::ContentMainRunnerImpl::Run C:\b\s\w\ir\cache\builder\src\content\app\content_main_runner_impl.cc:847
    #22 0x7ffd62e36f3e in service_manager::Main C:\b\s\w\ir\cache\builder\src\services\service_manager\embedder\main.cc:454
    #23 0x7ffd62d771e2 in content::ContentMain C:\b\s\w\ir\cache\builder\src\content\app\content_main.cc:19
    #24 0x7ffd59f613f4 in ChromeMain C:\b\s\w\ir\cache\builder\src\chrome\app\chrome_main.cc:110
    #25 0x7ff6bf185a3e in MainDllLoader::Launch C:\b\s\w\ir\cache\builder\src\chrome\app\main_dll_loader_win.cc:161
    #26 0x7ff6bf18299a in main C:\b\s\w\ir\cache\builder\src\chrome\app\chrome_exe_main_win.cc:271
    #27 0x7ff6bf548adf in __scrt_common_main_seh d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #28 0x7ffe0b577973 in BaseThreadInitThunk+0x13 (C:\Windows\System32\KERNEL32.DLL+0x180017973)
    #29 0x7ffe0bc7a270 in RtlUserThreadStart+0x20 (C:\Windows\SYSTEM32\ntdll.dll+0x18006a270)

0x120760d34508 is located 392 bytes inside of 560-byte region [0x120760d34380,0x120760d345b0)
freed by thread T0 here:
    #0 0x7ff6bf21c024 in free C:\b\s\w\ir\cache\builder\src\third_party\llvm\compiler-rt\lib\asan\asan_malloc_win.cpp:82
    #1 0x7ffd57941889 in gl::Texture::~Texture C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\Texture.cpp:682
    #2 0x7ffd578ffe9b in gl::TypedResourceManager<gl::Texture,gl::HandleAllocator,gl::TextureManager,gl::TextureID>::deleteObject C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\ResourceManager.cpp:100
    #3 0x7ffd577ef3e8 in gl::Context::deleteTexture C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\Context.cpp:810
    #4 0x7ffd57818465 in gl::Context::deleteTextures C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\Context.cpp:6057
    #5 0x7ffd5774a81c in gl::DeleteTextures C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libGLESv2\entry_points_gles_2_0_autogen.cpp:796
    #6 0x7ffd6454d46b in gpu::gles2::TexturePassthrough::~TexturePassthrough C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\texture_manager.cc:545
    #7 0x7ffd66bdea3e in base::RefCounted<gpu::gles2::TexturePassthrough,base::DefaultRefCountedTraits<gpu::gles2::TexturePassthrough>>::Release C:\b\s\w\ir\cache\builder\src\base\memory\ref_counted.h:345
    #8 0x7ffd6fb5b3b1 in gpu::gles2::GLES2DecoderPassthroughImpl::DoDeleteTextures C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough_doers.cc:1108
    #9 0x7ffd69b364c4 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommandsImpl<0> C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:834
    #10 0x7ffd69b35900 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommands C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:772
    #11 0x7ffd66cd6e6d in gpu::CommandBufferService::Flush C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\command_buffer_service.cc:69
    #12 0x7ffd645c1835 in gpu::CommandBufferStub::OnAsyncFlush C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:517
    #13 0x7ffd645c11bb in IPC::MessageT<GpuCommandBufferMsg_AsyncFlush_Meta,std::__1::tuple<int,unsigned int,std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>>>,void>::Dispatch<gpu::CommandBufferStub,gpu::CommandBufferStub,void,void (gpu::CommandBufferStub::*)(int, unsigned int, const std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>> &)> C:\b\s\w\ir\cache\builder\src\ipc\ipc_message_templates.h:139
    #14 0x7ffd645be531 in gpu::CommandBufferStub::OnMessageReceived C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:166
    #15 0x7ffd645d201f in gpu::GpuChannel::HandleMessageHelper C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:622
    #16 0x7ffd645cc172 in gpu::GpuChannel::HandleMessage C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:580
    #17 0x7ffd6427a11d in gpu::Scheduler::RunNextTask C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\scheduler.cc:554
    #18 0x7ffd630c4e99 in base::TaskAnnotator::RunTask C:\b\s\w\ir\cache\builder\src\base\task\common\task_annotator.cc:142
    #19 0x7ffd630f6ed3 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:329
    #20 0x7ffd630f6644 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:254
    #21 0x7ffd65882f23 in base::MessagePumpDefault::Run C:\b\s\w\ir\cache\builder\src\base\message_loop\message_pump_default.cc:39
    #22 0x7ffd630f869a in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:443
    #23 0x7ffd6307bc71 in base::RunLoop::Run C:\b\s\w\ir\cache\builder\src\base\run_loop.cc:124
    #24 0x7ffd652c8af9 in content::GpuMain C:\b\s\w\ir\cache\builder\src\content\gpu\gpu_main.cc:419
    #25 0x7ffd62d7903a in content::ContentMainRunnerImpl::Run C:\b\s\w\ir\cache\builder\src\content\app\content_main_runner_impl.cc:847
    #26 0x7ffd62e36f3e in service_manager::Main C:\b\s\w\ir\cache\builder\src\services\service_manager\embedder\main.cc:454
    #27 0x7ffd62d771e2 in content::ContentMain C:\b\s\w\ir\cache\builder\src\content\app\content_main.cc:19
    #28 0x7ffd59f613f4 in ChromeMain C:\b\s\w\ir\cache\builder\src\chrome\app\chrome_main.cc:110

previously allocated by thread T0 here:
    #0 0x7ff6bf21c124 in malloc C:\b\s\w\ir\cache\builder\src\third_party\llvm\compiler-rt\lib\asan\asan_malloc_win.cpp:98
    #1 0x7ffd5893da12 in operator new d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp:35
    #2 0x7ffd579054b8 in gl::TextureManager::AllocateNewObject C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\ResourceManager.cpp:234
    #3 0x7ffd5782da9c in gl::TypedResourceManager<gl::Texture,gl::HandleAllocator,gl::TextureManager,gl::TextureID>::checkObjectAllocationImpl<gl::TextureType> C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\ResourceManager.h:113
    #4 0x7ffd577f1d42 in gl::Context::bindTexture C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\Context.cpp:1027
    #5 0x7ffd57747e0f in gl::BindTexture C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libGLESv2\entry_points_gles_2_0_autogen.cpp:161
    #6 0x7ffd6fb566b1 in gpu::gles2::GLES2DecoderPassthroughImpl::DoBindTexture C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough_doers.cc:549
    #7 0x7ffd69b364c4 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommandsImpl<0> C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:834
    #8 0x7ffd69b35900 in gpu::gles2::GLES2DecoderPassthroughImpl::DoCommands C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\gles2_cmd_decoder_passthrough.cc:772
    #9 0x7ffd66cd6e6d in gpu::CommandBufferService::Flush C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\command_buffer_service.cc:69
    #10 0x7ffd645c1835 in gpu::CommandBufferStub::OnAsyncFlush C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:517
    #11 0x7ffd645c11bb in IPC::MessageT<GpuCommandBufferMsg_AsyncFlush_Meta,std::__1::tuple<int,unsigned int,std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>>>,void>::Dispatch<gpu::CommandBufferStub,gpu::CommandBufferStub,void,void (gpu::CommandBufferStub::*)(int, unsigned int, const std::__1::vector<gpu::SyncToken,std::__1::allocator<gpu::SyncToken>> &)> C:\b\s\w\ir\cache\builder\src\ipc\ipc_message_templates.h:139
    #12 0x7ffd645be531 in gpu::CommandBufferStub::OnMessageReceived C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\command_buffer_stub.cc:166
    #13 0x7ffd645d201f in gpu::GpuChannel::HandleMessageHelper C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:622
    #14 0x7ffd645cc172 in gpu::GpuChannel::HandleMessage C:\b\s\w\ir\cache\builder\src\gpu\ipc\service\gpu_channel.cc:580
    #15 0x7ffd6427a11d in gpu::Scheduler::RunNextTask C:\b\s\w\ir\cache\builder\src\gpu\command_buffer\service\scheduler.cc:554
    #16 0x7ffd630c4e99 in base::TaskAnnotator::RunTask C:\b\s\w\ir\cache\builder\src\base\task\common\task_annotator.cc:142
    #17 0x7ffd630f6ed3 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:329
    #18 0x7ffd630f6644 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:254
    #19 0x7ffd65882f23 in base::MessagePumpDefault::Run C:\b\s\w\ir\cache\builder\src\base\message_loop\message_pump_default.cc:39
    #20 0x7ffd630f869a in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run C:\b\s\w\ir\cache\builder\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:443
    #21 0x7ffd6307bc71 in base::RunLoop::Run C:\b\s\w\ir\cache\builder\src\base\run_loop.cc:124
    #22 0x7ffd652c8af9 in content::GpuMain C:\b\s\w\ir\cache\builder\src\content\gpu\gpu_main.cc:419
    #23 0x7ffd62d7903a in content::ContentMainRunnerImpl::Run C:\b\s\w\ir\cache\builder\src\content\app\content_main_runner_impl.cc:847
    #24 0x7ffd62e36f3e in service_manager::Main C:\b\s\w\ir\cache\builder\src\services\service_manager\embedder\main.cc:454
    #25 0x7ffd62d771e2 in content::ContentMain C:\b\s\w\ir\cache\builder\src\content\app\content_main.cc:19
    #26 0x7ffd59f613f4 in ChromeMain C:\b\s\w\ir\cache\builder\src\chrome\app\chrome_main.cc:110
    #27 0x7ff6bf185a3e in MainDllLoader::Launch C:\b\s\w\ir\cache\builder\src\chrome\app\main_dll_loader_win.cc:161
    #28 0x7ff6bf18299a in main C:\b\s\w\ir\cache\builder\src\chrome\app\chrome_exe_main_win.cc:271

SUMMARY: AddressSanitizer: heap-use-after-free C:\b\s\w\ir\cache\builder\src\third_party\angle\src\libANGLE\State.cpp:3108 in gl::State::syncTextures
Shadow bytes around the buggy address:
  0x041c4ce26850: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x041c4ce26860: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x041c4ce26870: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x041c4ce26880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x041c4ce26890: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x041c4ce268a0: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x041c4ce268b0: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa
  0x041c4ce268c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x041c4ce268d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x041c4ce268e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x041c4ce268f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
  Shadow gap:              cc
==7132==ABORTING

Timeline

2020-05-19 - Vendor Disclosure
2020-06-08 - Vendor assigned CVE-2020-6492; fix landed in Chrome in 85.0.4149.0
2020-08-24 - Public Release

Credit

Discovered by Marcin Towalski of Cisco Talos.