Closed Bug 1603756 Opened 6 years ago Closed 4 years ago

AddressSanitizer: heap-use-after-free [@ mozilla::dom::HTMLCanvasElement::OnVisibilityChange()::Runnable::Run] with READ of size 8

Categories

(Core :: Graphics: Layers, defect, P5)

defect

Tracking

()

RESOLVED INVALID
Tracking Status
firefox73 --- disabled

People

(Reporter: jkratzer, Unassigned)

References

(Blocks 1 open bug)

Details

(4 keywords, Whiteboard: sec-high when offscreencanvas enabled)

Attachments

(3 files)

Found while fuzzing mozilla-central rev d1ac49b9eb3e. I'm currently working on reducing the testcase and will update once complete.

==41901==ERROR: AddressSanitizer: heap-use-after-free on address 0x61b000044b80 at pc 0x7f3167e5ddf9 bp 0x7ffe982246c0 sp 0x7ffe982246b8
READ of size 8 at 0x61b000044b80 thread T0 (file:// Content)
    #0 0x7f3167e5ddf8 in mozilla::dom::HTMLCanvasElement::OnVisibilityChange()::Runnable::Run() /src/dom/html/HTMLCanvasElement.cpp:1325:32
    #1 0x7f3161cae8b7 in nsThread::ProcessNextEvent(bool, bool*) /src/xpcom/threads/nsThread.cpp:1240:14
    #2 0x7f3161cb8abc in NS_ProcessNextEvent(nsIThread*, bool) /src/xpcom/threads/nsThreadUtils.cpp:486:10
    #3 0x7f3162ed785f in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /src/ipc/glue/MessagePump.cpp:87:21
    #4 0x7f3162dd1b77 in RunInternal /src/ipc/chromium/src/base/message_loop.cc:315:10
    #5 0x7f3162dd1b77 in RunHandler /src/ipc/chromium/src/base/message_loop.cc:308:3
    #6 0x7f3162dd1b77 in MessageLoop::Run() /src/ipc/chromium/src/base/message_loop.cc:290:3
    #7 0x7f3169c2ac48 in nsBaseAppShell::Run() /src/widget/nsBaseAppShell.cpp:137:27
    #8 0x7f316d7517f6 in XRE_RunAppShell() /src/toolkit/xre/nsEmbedFunctions.cpp:946:20
    #9 0x7f3162dd1b77 in RunInternal /src/ipc/chromium/src/base/message_loop.cc:315:10
    #10 0x7f3162dd1b77 in RunHandler /src/ipc/chromium/src/base/message_loop.cc:308:3
    #11 0x7f3162dd1b77 in MessageLoop::Run() /src/ipc/chromium/src/base/message_loop.cc:290:3
    #12 0x7f316d750e9f in XRE_InitChildProcess(int, char**, XREChildData const*) /src/toolkit/xre/nsEmbedFunctions.cpp:781:34
    #13 0x5571d045e0c1 in content_process_main /src/browser/app/../../ipc/contentproc/plugin-container.cpp:56:28
    #14 0x5571d045e0c1 in main /src/browser/app/nsBrowserApp.cpp:303:18
    #15 0x7f31840f6b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #16 0x5571d03b3b8c in _start (/home/worker/builds/m-c-20191213094653-fuzzing-asan-opt/firefox+0x9bb8c)

0x61b000044b80 is located 0 bytes inside of 1552-byte region [0x61b000044b80,0x61b000045190)
freed by thread T0 (file:// Content) here:
    #0 0x5571d042b85d in free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:123:3
    #1 0x7f3161b09a22 in SnowWhiteKiller::~SnowWhiteKiller() /src/xpcom/base/nsCycleCollector.cpp:2416:7
    #2 0x7f3161b08e78 in nsCycleCollector::FreeSnowWhite(bool) /src/xpcom/base/nsCycleCollector.cpp:2609:3
    #3 0x7f3161b10694 in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /src/xpcom/base/nsCycleCollector.cpp:3584:3
    #4 0x7f3161b0ff30 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /src/xpcom/base/nsCycleCollector.cpp:3413:9
    #5 0x7f3161b131ae in nsCycleCollector_collect(nsICycleCollectorListener*) /src/xpcom/base/nsCycleCollector.cpp:3913:21
    #6 0x7f3165d9cf74 in nsJSContext::CycleCollectNow(nsICycleCollectorListener*) /src/dom/base/nsJSEnvironment.cpp:1535:3
    #7 0x7f316735c3b1 in mozilla::dom::FuzzingFunctions_Binding::cycleCollect(JSContext*, unsigned int, JS::Value*) /src/obj-firefox/dom/bindings/FuzzingFunctionsBinding.cpp:67:3
    #8 0x7f316d9b4d2a in CallJSNative /src/js/src/vm/Interpreter.cpp:457:13
    #9 0x7f316d9b4d2a in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /src/js/src/vm/Interpreter.cpp:549:12
    #10 0x7f316d9b6b1f in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /src/js/src/vm/Interpreter.cpp:618:10
    #11 0x7f316d99c492 in CallFromStack /src/js/src/vm/Interpreter.cpp:622:10
    #12 0x7f316d99c492 in Interpret(JSContext*, js::RunState&) /src/js/src/vm/Interpreter.cpp:3116:16
    #13 0x7f316d97e7e4 in js::RunScript(JSContext*, js::RunState&) /src/js/src/vm/Interpreter.cpp:424:10
    #14 0x7f316d9b4e21 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /src/js/src/vm/Interpreter.cpp:590:13
    #15 0x7f316d9b6b1f in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /src/js/src/vm/Interpreter.cpp:618:10
    #16 0x7f316d9b6eb6 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /src/js/src/vm/Interpreter.cpp:635:8
    #17 0x7f316db9abe2 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /src/js/src/jsapi.cpp:2753:10
    #18 0x7f316725fc50 in mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /src/obj-firefox/dom/bindings/EventListenerBinding.cpp:52:8
    #19 0x7f3167c653cb in void mozilla::dom::EventListener::HandleEvent<mozilla::dom::EventTarget*>(mozilla::dom::EventTarget* const&, mozilla::dom::Event&, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) /src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
    #20 0x7f3167c64e04 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /src/dom/events/EventListenerManager.cpp:1076:43
    #21 0x7f3167c66466 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /src/dom/events/EventListenerManager.cpp:1274:17

previously allocated by thread T0 (file:// Content) here:
    #0 0x5571d042badd in malloc /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:145:3
    #1 0x5571d04612cd in moz_xmalloc /src/memory/mozalloc/mozalloc.cpp:52:15
    #2 0x7f3167751772 in operator new /src/obj-firefox/dist/include/mozilla/cxxalloc.h:33:10
    #3 0x7f3167751772 in Create /src/dom/canvas/WebGL1Context.cpp:15:49
    #4 0x7f3167751772 in mozilla::dom::CanvasRenderingContextHelper::CreateContextHelper(mozilla::dom::CanvasContextType, mozilla::layers::LayersBackend) /src/dom/canvas/CanvasRenderingContextHelper.cpp:129:13
    #5 0x7f3167768a0a in CreateContext /src/dom/canvas/CanvasRenderingContextHelper.cpp:108:10
    #6 0x7f3167768a0a in mozilla::dom::OffscreenCanvas::CreateContext(mozilla::dom::CanvasContextType) /src/dom/canvas/OffscreenCanvas.cpp:154:37
    #7 0x7f3167751d4b in mozilla::dom::CanvasRenderingContextHelper::GetContext(JSContext*, nsTSubstring<char16_t> const&, JS::Handle<JS::Value>, mozilla::ErrorResult&) /src/dom/canvas/CanvasRenderingContextHelper.cpp:162:15
    #8 0x7f3167767f7d in mozilla::dom::OffscreenCanvas::GetContext(JSContext*, nsTSubstring<char16_t> const&, JS::Handle<JS::Value>, mozilla::ErrorResult&) /src/dom/canvas/OffscreenCanvas.cpp:111:62
    #9 0x7f3166484b8a in mozilla::dom::OffscreenCanvas_Binding::getContext(JSContext*, JS::Handle<JSObject*>, mozilla::dom::OffscreenCanvas*, JSJitMethodCallArgs const&) /src/obj-firefox/dom/bindings/OffscreenCanvasBinding.cpp:202:64
    #10 0x7f316763d768 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /src/dom/bindings/BindingUtils.cpp:3151:13
    #11 0x7f316d9b4d2a in CallJSNative /src/js/src/vm/Interpreter.cpp:457:13
    #12 0x7f316d9b4d2a in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /src/js/src/vm/Interpreter.cpp:549:12
    #13 0x7f316d9b6b1f in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /src/js/src/vm/Interpreter.cpp:618:10
    #14 0x7f316d99c492 in CallFromStack /src/js/src/vm/Interpreter.cpp:622:10
    #15 0x7f316d99c492 in Interpret(JSContext*, js::RunState&) /src/js/src/vm/Interpreter.cpp:3116:16
    #16 0x7f316d97e7e4 in js::RunScript(JSContext*, js::RunState&) /src/js/src/vm/Interpreter.cpp:424:10
    #17 0x7f316d9b4e21 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /src/js/src/vm/Interpreter.cpp:590:13
    #18 0x7f316d9b6b1f in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /src/js/src/vm/Interpreter.cpp:618:10
    #19 0x7f316d9b6eb6 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /src/js/src/vm/Interpreter.cpp:635:8
    #20 0x7f316db9abe2 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /src/js/src/jsapi.cpp:2753:10
    #21 0x7f316725fc50 in mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /src/obj-firefox/dom/bindings/EventListenerBinding.cpp:52:8
    #22 0x7f3167c653cb in void mozilla::dom::EventListener::HandleEvent<mozilla::dom::EventTarget*>(mozilla::dom::EventTarget* const&, mozilla::dom::Event&, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) /src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
    #23 0x7f3167c64e04 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /src/dom/events/EventListenerManager.cpp:1076:43
    #24 0x7f3167c66466 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /src/dom/events/EventListenerManager.cpp:1274:17

SUMMARY: AddressSanitizer: heap-use-after-free /src/dom/html/HTMLCanvasElement.cpp:1325:32 in mozilla::dom::HTMLCanvasElement::OnVisibilityChange()::Runnable::Run()
Shadow bytes around the buggy address:
  0x0c3680000920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
  0x0c3680000960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c3680000970:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3680000980: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3680000990: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c36800009a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c36800009b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c36800009c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==41901==ABORTING
Group: core-security → dom-core-security

It looks like AsyncCanvasRenderer::mContext is a weak pointer, and maybe that is what is being accessed here. (There are a few other weak references in that class.)

Group: dom-core-security → gfx-core-security
Component: DOM: Core & HTML → Graphics: Layers
Priority: -- → P1
Attached file testcase.html

To reproduce this issue, copy testcase.html and popup.html to the same directory and call testcase.html within firefox.

Attached file popup.html
Attached file prefs.js

Jason, to confirm to trigger this you needed to set gfx.offscreencanvas.enabled to true. Correct?

Flags: needinfo?(jkratzer)
Attachment #9116144 - Attachment mime type: application/x-javascript → text/plain

(In reply to Jeff Muizelaar [:jrmuizel] from comment #5)

Jason, to confirm to trigger this you needed to set gfx.offscreencanvas.enabled to true. Correct?

Jeff, yes that is correct.

Flags: needinfo?(jkratzer)

Ok, great. Deprioritized until we ramp up that code again.

Severity: critical → minor
Priority: P1 → P5

Dan, given this requires to a pref-flip to trigger it probably shouldn't be a sec-high.

Flags: needinfo?(dveditz)

Are we planning to ship offscreencanvas as the default at some point? If so the sec-high is appropriate, but the various status-firefoxXX fields should be marked "disabled". If "some point" is "probably, but no current plans" then I guess we can lower it to sec-moderate.

Flags: needinfo?(dveditz)
Whiteboard: sec-high when offscreencanvas enabled

"some point" is "probably, but no current plans" and this bug is marked as blocking shipping so I've lowered this to sec-moderate.

Keywords: sec-highsec-moderate

I remove the aforementioned visibility subscription in bug 1736177. We don't use it for anything. I would think that would resolve this sec bug.

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → INVALID
Group: gfx-core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: