egl::Image objects are manually reference counted with a 32-bit reference count (see OpenGL/common/Object{.hpp,.cpp}), using addRef/release, and there is an error path here (when egl::Image::create fails) where the reference taken on renderTarget by source->getRenderTarget() is never dropped.
I haven't verified that this bug can be reached in stable - I'm looking at the code for the latest dev, and various changes have been made to the allocations of egl::Image in dev in the fixes to crbug.com/835299 - the attached PoC is tested against 68.0.3440.7, and for versions prior to the fixes I think a different strategy (or at least texture sizes) will be needed to cause the allocations to fail.
(In 68.0.3440.7, it's possible to create allocations such that the initial texture allocation succeeds, but that the size of the equivalent cube map texture will fail, since cube maps get an additional border pixel - this is the strategy used in the PoC).
Note also that the PoC is triggering the bug directly from javascript - this will take some time! Approximately an hour for me, significantly longer for an ASAN build. This would be much quicker with direct asynchronous access to the GPU command buffer interface, so with an additional renderer bug just using this bug just for sandbox escape.
=================================================================
==145933==ERROR: AddressSanitizer: heap-use-after-free on address 0x61100001d208 at pc 0x7f66d7569d00 bp 0x7ffcb4922af0 sp 0x7ffcb4922ae8
READ of size 8 at 0x61100001d208 thread T0 (chrome)
==145933==WARNING: invalid path to external symbolizer!
==145933==WARNING: Failed to use and restart external symbolizer!
#0 0x7f66d7569cff in es2::Colorbuffer::getRenderTarget() /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Renderbuffer.cpp:538:18
#1 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
0x61100001d208 is located 200 bytes inside of 240-byte region [0x61100001d140,0x61100001d230)
freed by thread T0 (chrome) here:
#0 0x55ec7d63dbd2 in operator delete(void*) _asan_rtl_:3
#1 0x7f66d7578d35 in es2::TextureCubeMap::copyImage(unsigned int, int, unsigned int, int, int, int, int, es2::Renderbuffer*) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Texture.cpp:1285:16
#2 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
previously allocated by thread T0 (chrome) here:
#0 0x55ec7d63cf92 in operator new(unsigned long) _asan_rtl_:3
#1 0x7f66d718613d in egl::Image::create(int, int, int, int, bool) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/common/Image.cpp:1234:10
SUMMARY: AddressSanitizer: heap-use-after-free (/ssd/chrome/src/out/asan/swiftshader/libGLESv2.so+0x6d4cff)
Shadow bytes around the buggy address:
0x0c227fffb9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba10: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x0c227fffba20: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c227fffba30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c227fffba40: fd[fd]fd fd fd fd fa fa fa fa fa fa fa fa fa fa
0x0c227fffba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba60: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
0x0c227fffba70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba90: 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
Shadow gap: cc
==145933==ABORTING
-->
egl::Image objects are manually reference counted with a 32-bit reference count (see OpenGL/common/Object{.hpp,.cpp}), using addRef/release, and there is an error path here (when egl::Image::create fails) where the reference taken on renderTarget by source->getRenderTarget() is never dropped.
I haven't verified that this bug can be reached in stable - I'm looking at the code for the latest dev, and various changes have been made to the allocations of egl::Image in dev in the fixes to crbug.com/835299 - the attached PoC is tested against 68.0.3440.7, and for versions prior to the fixes I think a different strategy (or at least texture sizes) will be needed to cause the allocations to fail.
(In 68.0.3440.7, it's possible to create allocations such that the initial texture allocation succeeds, but that the size of the equivalent cube map texture will fail, since cube maps get an additional border pixel - this is the strategy used in the PoC).
Note also that the PoC is triggering the bug directly from javascript - this will take some time! Approximately an hour for me, significantly longer for an ASAN build. This would be much quicker with direct asynchronous access to the GPU command buffer interface, so with an additional renderer bug just using this bug just for sandbox escape.
=================================================================
==145933==ERROR: AddressSanitizer: heap-use-after-free on address 0x61100001d208 at pc 0x7f66d7569d00 bp 0x7ffcb4922af0 sp 0x7ffcb4922ae8
READ of size 8 at 0x61100001d208 thread T0 (chrome)
==145933==WARNING: invalid path to external symbolizer!
==145933==WARNING: Failed to use and restart external symbolizer!
#0 0x7f66d7569cff in es2::Colorbuffer::getRenderTarget() /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Renderbuffer.cpp:538:18
#1 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
0x61100001d208 is located 200 bytes inside of 240-byte region [0x61100001d140,0x61100001d230)
freed by thread T0 (chrome) here:
#0 0x55ec7d63dbd2 in operator delete(void*) _asan_rtl_:3
#1 0x7f66d7578d35 in es2::TextureCubeMap::copyImage(unsigned int, int, unsigned int, int, int, int, int, es2::Renderbuffer*) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Texture.cpp:1285:16
#2 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
previously allocated by thread T0 (chrome) here:
#0 0x55ec7d63cf92 in operator new(unsigned long) _asan_rtl_:3
#1 0x7f66d718613d in egl::Image::create(int, int, int, int, bool) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/common/Image.cpp:1234:10
SUMMARY: AddressSanitizer: heap-use-after-free (/ssd/chrome/src/out/asan/swiftshader/libGLESv2.so+0x6d4cff)
Shadow bytes around the buggy address:
0x0c227fffb9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba10: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x0c227fffba20: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c227fffba30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c227fffba40: fd[fd]fd fd fd fd fa fa fa fa fa fa fa fa fa fa
0x0c227fffba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba60: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
0x0c227fffba70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba90: 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
Shadow gap: cc
==145933==ABORTING
-->