New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 849217 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Closed: Jun 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows
Pri: 1
Type: Bug-Security


Show other hotlists

Hotlists containing this issue:
webgl-issues


Sign in to add a comment

Security: Reference count leak in SwiftShader OpenGL texture bindings

Project Member Reported by markbrand@google.com, Jun 4 2018

Issue description

This template is ONLY for reporting security bugs. If you are reporting a
Download Protection Bypass bug, please use the "Security - Download
Protection" template. For all other reports, please use a different
template.

Please READ THIS FAQ before filing a bug: https://chromium.googlesource.com
/chromium/src/+/master/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

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

VULNERABILITY DETAILS
There's an object lifetime issue in the Swiftshader OpenGL texture bindings (OpenGL/libGLESv2/Texture.cpp).

The same bug is present in all versions of TextureXX::copyImage, below is the simplest function:

void Texture2D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	egl::Image *renderTarget = source->getRenderTarget();

	if(!renderTarget)
	{
		ERR("Failed to retrieve the render target.");
		return error(GL_OUT_OF_MEMORY);
	}

	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, internalformat);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	if(width != 0 && height != 0)
	{
		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, 0, 0, 0, image[level]);
	}

	renderTarget->release();
}

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 where the reference taken on renderTarget by source->getRenderTarget() is never dropped. This leads to a reference count overflow, and a nice, controlled use-after-free.

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.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.


VERSION
Chrome Version: 68.0.3440.7 
Operating System: linux

REPRODUCTION CASE
Please include a demonstration of the security bug, such as an attached
HTML or binary file that reproduces the bug when loaded in Chrome. PLEASE
make the file as small as possible and remove any content not required to
demonstrate the bug.

FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION
Type of crash: GPU process
Crash State: 

[144553:144553:0604/113443.369302:ERROR:gpu_process_transport_factory.cc(1016)] Lost UI shared context.
[144553:144602:0604/113443.474027:ERROR:object_proxy.cc(616)] Failed to call method: org.freedesktop.Notifications.GetCapabilities: object_path= /org/freedeskt
[144610:144610:0604/113445.417389:ERROR:gles2_cmd_decoder.cc(14816)] [.Offscreen-For-WebGL-0x1b0d726ad000]GL ERROR :GL_OUT_OF_MEMORY : glCopyTexImage2D:
Received signal 11 SEGV_MAPERR ffffc58ecd269cf1
#0 0x55df80ab5d0c base::debug::StackTrace::StackTrace()
#1 0x55df80ab5871 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#2 0x7f73116670c0 <unknown>
#3 0x7f73028d0638 <unknown>
#4 0x7f73028db9ed <unknown>
#5 0x7f73028dcfb4 <unknown>
#6 0x7f73028dfb96 <unknown>
#7 0x55df813cd2ae gl::GLApiBase::glCopyTexImage2DFn()
#8 0x55df818c6d7c gpu::gles2::GLES2DecoderImpl::DoCopyTexImage2D()
#9 0x55df8188f4e5 gpu::gles2::GLES2DecoderImpl::HandleCopyTexImage2D()
#10 0x55df818b31b7 gpu::gles2::GLES2DecoderImpl::DoCommandsImpl<>()
#11 0x55df81875f88 gpu::CommandBufferService::Flush()
#12 0x55df81c57465 gpu::CommandBufferStub::OnAsyncFlush()
#13 0x55df81c5729f _ZN3IPC8MessageTI35GpuCommandBufferMsg_AsyncFlush_MetaNSt3__15tupleIJijbEEEvE8DispatchIN3gpu17CommandBufferStubES8_vMS8_FvijbEEEbPKNS_7MessageEPT_PT0_PT1_T2_
#14 0x55df81c561cb gpu::CommandBufferStub::OnMessageReceived()
#15 0x55df81c54587 gpu::GpuChannel::HandleMessageHelper()
#16 0x55df81c52b25 gpu::GpuChannel::HandleMessage()
#17 0x55df81c5d950 gpu::Scheduler::RunNextTask()
#18 0x55df80a2c34c base::debug::TaskAnnotator::RunTask()
#19 0x55df80a44887 base::MessageLoop::RunTask()
#20 0x55df80a44d67 base::MessageLoop::DoWork()
#21 0x55df80a4775f base::(anonymous namespace)::WorkSourceDispatch()
#22 0x7f730f77df07 g_main_context_dispatch
#23 0x7f730f77e138 <unknown>
#24 0x7f730f77e1cc g_main_context_iteration
#25 0x55df80a47622 base::MessagePumpGlib::Run()
#26 0x55df80a642c5 base::RunLoop::Run()
#27 0x55df83d9b9de content::GpuMain()
#28 0x55df80771bc6 content::ContentMainRunnerImpl::Run()
#29 0x55df8077abb2 service_manager::Main()
#30 0x55df8076fc64 content::ContentMain()
#31 0x55df7ed481b3 ChromeMain
#32 0x7f730b8f92b1 __libc_start_main
#33 0x55df7ed4802a _start
  r8: 0000000000000001  r9: 0000000000000000 r10: 0000000000000000 r11: 0000000000000010
 r12: 0000000000000000 r13: 000000000001ffe0 r14: 0000000000000000 r15: 0000000000001440
  di: 00003a739c2293c0  si: 0000000000000000  bp: 0000000000000000  bx: 00003a739c2293c0
  dx: 0000000000000000  ax: ffffc58ecd269ce1  cx: 0000000000000000  sp: 00007ffe0e7af580
  ip: 00007f73028d0638 efl: 0000000000010246 cgf: 002b000000000033 erf: 0000000000000005
 trp: 000000000000000e msk: 0000000000000000 cr2: ffffc58ecd269cf1
[end of stack trace]
Calling _exit(1). Core file will not be generated.


=================================================================
==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

Client ID (if relevant): [see link above]

 
copytexture.html
1.1 KB View Download
Project Member

Comment 1 by ClusterFuzz, Jun 4 2018

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://clusterfuzz.com/testcase?key=6165891327459328.
Labels: Security_Severity-High Security_Impact-Beta OS-Linux
Owner: capn@chromium.org
Status: Assigned (was: Unconfirmed)
capn: Can you please take a look and also assess whether this impacts stable? Thanks.
Labels: M-68
Project Member

Comment 4 by sheriffbot@chromium.org, Jun 5 2018

Labels: ReleaseBlock-Stable
This is a serious security regression. If you are not able to fix this quickly, please revert the change that introduced it.

If this doesn't affect a release branch, or has not been properly classified for severity, please update the Security_Impact or Security_Severity labels, and remove the ReleaseBlock label. To disable this altogether, apply ReleaseBlock-NA.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 5 by sheriffbot@chromium.org, Jun 5 2018

Labels: Pri-1

Comment 6 by capn@chromium.org, Jun 5 2018

Cc: geoffl...@chromium.org kbr@chromium.org sugoi@chromium.org
Status: Started (was: Assigned)
Thanks for reporting this, Mark! It's interesting to see that fixing the memory allocation overflow can cause a reference counting overflow.

Note that the OpenGL spec states that GL_OUT_OF_MEMORY puts the graphics context in an undefined state. Subsequent calls have undefined behavior, except for error retrieval and destroying the context. So I think strictly speaking it's up to Chromium to reset things and bring it back to defined behavior, since the JavaScript app can't be trusted to do so.

ANGLE already has code to ensure that calls get ignored after a GL_OUT_OF_MEMORY was generated, and the plan has always been to layer ANGLE on top of SwiftShader to make it robust for web usage. But it doesn't seem like that will happen very soon.

Anyway, I'll fix this on SwiftShader's end.

Comment 8 by capn@chromium.org, Jun 5 2018

Labels: -M-68 M-69
Status: Fixed (was: Started)
I don't think this will necessitate a merge to M68? The hour wait time from JavaScript makes this somewhat impractical.
Project Member

Comment 9 by bugdroid1@chromium.org, Jun 6 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/06f66cde750e1f388e19a0390214bb988eed1768

commit 06f66cde750e1f388e19a0390214bb988eed1768
Author: Alexis Hetu <sugoi@google.com>
Date: Wed Jun 06 01:08:17 2018

Roll SwiftShader 57776df..88482c3

https://swiftshader.googlesource.com/SwiftShader.git/+log/57776df..88482c3

BUG= chromium:849217   chromium:846693 

TBR=kbr@chromium.org

TEST=bots

CQ_INCLUDE_TRYBOTS=luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_chromium_cfi_rel_ng;luci.chromium.try:android_optional_gpu_tests_rel

Change-Id: Ifd196a7e538ee5280f3af78db9e95913ad8365ac
Reviewed-on: https://chromium-review.googlesource.com/1087786
Commit-Queue: Alexis Hétu <sugoi@chromium.org>
Reviewed-by: Alexis Hétu <sugoi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#564756}
[modify] https://crrev.com/06f66cde750e1f388e19a0390214bb988eed1768/DEPS

Project Member

Comment 10 by sheriffbot@chromium.org, Jun 6 2018

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
I'm curious if this should be marked Security_Impact-Stable, since if this isn't fixed for M68 then the previous patch which enabled this bug will reach stable in M68.

I have a working exploit for this issue that gets code execution in the GPU process. I will clean up the code and try to get it working on the latest beta M68 release and upload it here next week.

Comment 12 by capn@chromium.org, Jun 22 2018

Cc: nicolasc...@google.com
Labels: -M-69 M-68 Merge-Request-68 OS-Windows
Status: Started (was: Fixed)
Thanks for pointing out this could be readily exploited for malicious code execution. Requesting a merge to not let this reach stable.
Project Member

Comment 13 by sheriffbot@chromium.org, Jun 22 2018

Labels: -Merge-Request-68 Hotlist-Merge-Review Merge-Review-68
This bug requires manual review: DEPS changes referenced in bugdroid comments.
Please contact the milestone owner if you have questions.
Owners: cmasso@(Android), kariahda@(iOS), bhthompson@(ChromeOS), abdulsyed@(Desktop)

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 14 by sheriffbot@chromium.org, Jun 22 2018

Status: Fixed (was: Started)
Please mark security bugs as fixed as soon as the fix lands, and before requesting merges. This update is based on the merge- labels applied to this issue. Please reopen if this update was incorrect.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Merge-Review-68 Merge-Approved-68
M68 approved - branch:3440
Project Member

Comment 16 by bugdroid1@chromium.org, Jun 26 2018

Labels: -merge-approved-68 merge-merged-3440
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/c682da6607db0335dc1ff3abc31443265779ca7e

commit c682da6607db0335dc1ff3abc31443265779ca7e
Author: Nicolas Capens <capn@chromium.org>
Date: Tue Jun 26 17:19:53 2018

Roll SwiftShader cbb80f5..f398044

https://swiftshader.googlesource.com/SwiftShader.git/+log/cbb80f5..f398044

BUG= chromium:849217 

Change-Id: Icdb69767175077f2c5712928217bf1767c10d90f
Reviewed-on: https://chromium-review.googlesource.com/1115210
Reviewed-by: Alexis Hétu <sugoi@chromium.org>
Cr-Commit-Position: refs/branch-heads/3440@{#530}
Cr-Branched-From: 010ddcfda246975d194964ccf20038ebbdec6084-refs/heads/master@{#561733}
[modify] https://crrev.com/c682da6607db0335dc1ff3abc31443265779ca7e/DEPS

Labels: -ReleaseBlock-Stable
Project Member

Comment 18 by sheriffbot@chromium.org, Sep 29

Labels: -Restrict-View-SecurityNotify allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment