Closed Bug 1483063 Opened 6 years ago Closed 3 years ago

heap-use-after-free in [@ mozilla::AccessibleCaret::SetAppearance]

Categories

(Core :: Layout, defect, P1)

defect

Tracking

()

RESOLVED INCOMPLETE
Tracking Status
firefox63 --- affected

People

(Reporter: tsmith, Unassigned)

References

(Blocks 1 open bug)

Details

(4 keywords)

I am working on getting a reliable reduced testcase. I will attach it once it is available.

==40274==ERROR: AddressSanitizer: heap-use-after-free on address 0x6060001ef8d8 at pc 0x7f07df9beb53 bp 0x7fff1355b0b0 sp 0x7fff1355b0a8
READ of size 8 at 0x6060001ef8d8 thread T0 (file:// Content)
    #0 0x7f07df9beb52 in get src/obj-firefox/dist/include/mozilla/RefPtr.h:296:27
    #1 0x7f07df9beb52 in operator-> src/obj-firefox/dist/include/mozilla/RefPtr.h:328
    #2 0x7f07df9beb52 in CaretElement src/layout/base/AccessibleCaret.h:146
    #3 0x7f07df9beb52 in mozilla::AccessibleCaret::SetAppearance(mozilla::AccessibleCaret::Appearance) src/layout/base/AccessibleCaret.cpp:112
    #4 0x7f07df9cc6d1 in mozilla::AccessibleCaretManager::OnSelectionChanged(nsIDocument*, mozilla::dom::Selection*, short) src/layout/base/AccessibleCaretManager.cpp:217:18
    #5 0x7f07df9ca02f in non-virtual thunk to mozilla::AccessibleCaretEventHub::NotifySelectionChanged(nsIDocument*, mozilla::dom::Selection*, short) src/layout/base/AccessibleCaretEventHub.cpp:741:11
    #6 0x7f07d95a8fd7 in mozilla::dom::Selection::NotifySelectionListeners() src/dom/base/Selection.cpp:3489:15
    #7 0x7f07d95a859c in mozilla::dom::Selection::NotifySelectionListeners(bool) src/dom/base/Selection.cpp:3418:10
    #8 0x7f07d98d7dd9 in nsRange::NotifySelectionListenersAfterRangeSet() src/dom/base/nsRange.cpp:943:16
    #9 0x7f07d990ecfb in applyImpl<nsRange, void (nsRange::*)()> src/obj-firefox/dist/include/nsThreadUtils.h:1168:12
    #10 0x7f07d990ecfb in apply<nsRange, void (nsRange::*)()> src/obj-firefox/dist/include/nsThreadUtils.h:1174
    #11 0x7f07d990ecfb in mozilla::detail::RunnableMethodImpl<nsRange*, void (nsRange::*)(), true, (mozilla::RunnableKind)0>::Run() src/obj-firefox/dist/include/nsThreadUtils.h:1219
    #12 0x7f07d9233337 in nsContentUtils::RemoveScriptBlocker() src/dom/base/nsContentUtils.cpp:5584:15
    #13 0x7f07d9697e88 in ~nsAutoScriptBlocker src/obj-firefox/dist/include/nsContentUtils.h:3550:5
    #14 0x7f07d9697e88 in nsIDocument::AdoptNode(nsINode&, mozilla::ErrorResult&) src/dom/base/nsDocument.cpp:7026
    #15 0x7f07dbd481fc in mozilla::dom::Document_Binding::adoptNode(JSContext*, JS::Handle<JSObject*>, nsIDocument*, JSJitMethodCallArgs const&) src/obj-firefox/dom/bindings/DocumentBinding.cpp:1636:45
    #16 0x7f07dc6d9b39 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:3311:13
    #17 0x7f07e3957b7e in CallJSNative src/js/src/vm/Interpreter.cpp:445:15
    #18 0x7f07e3957b7e in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) src/js/src/vm/Interpreter.cpp:533
    #19 0x7f07e3942467 in CallFromStack src/js/src/vm/Interpreter.cpp:590:12
    #20 0x7f07e3942467 in Interpret(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:3239
    #21 0x7f07e392887e in js::RunScript(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:425:12
    #22 0x7f07e3958454 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) src/js/src/vm/Interpreter.cpp:557:15
    #23 0x7f07e39599e2 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) src/js/src/vm/Interpreter.cpp:603:10
    #24 0x7f07e43e10ca in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) src/js/src/jsapi.cpp:2915:12
    #25 0x7f07db4c047f in mozilla::dom::IdleRequestCallback::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::IdleDeadline&, mozilla::ErrorResult&) src/obj-firefox/dom/bindings/WindowBinding.cpp:868:8
    #26 0x7f07d950197a in Call src/obj-firefox/dist/include/mozilla/dom/WindowBinding.h:720:12
    #27 0x7f07d950197a in mozilla::dom::IdleRequest::IdleRun(nsPIDOMWindowInner*, double, bool) src/dom/base/IdleRequest.cpp:74
    #28 0x7f07d92d841a in nsGlobalWindowInner::RunIdleRequest(mozilla::dom::IdleRequest*, double, bool) src/dom/base/nsGlobalWindowInner.cpp:700:19
    #29 0x7f07d93340ab in nsGlobalWindowInner::RunTimeoutHandler(mozilla::dom::Timeout*, nsIScriptContext*) src/dom/base/nsGlobalWindowInner.cpp:6509:19
    #30 0x7f07d95f3e4b in mozilla::dom::TimeoutManager::RunTimeout(mozilla::TimeStamp const&, mozilla::TimeStamp const&) src/dom/base/TimeoutManager.cpp:877:42
    #31 0x7f07d95f2fbf in mozilla::dom::TimeoutExecutor::MaybeExecute() src/dom/base/TimeoutExecutor.cpp:172:11
    #32 0x7f07d95f593c in Notify src/dom/base/TimeoutExecutor.cpp:240:5
    #33 0x7f07d95f593c in non-virtual thunk to mozilla::dom::TimeoutExecutor::Notify(nsITimer*) src/dom/base/TimeoutExecutor.cpp
    #34 0x7f07d57561a3 in nsTimerImpl::Fire(int) src/xpcom/threads/nsTimerImpl.cpp:704:40
    #35 0x7f07d571229d in nsTimerEvent::Run() src/xpcom/threads/TimerThread.cpp:297:11
    #36 0x7f07d57437f6 in mozilla::ThrottledEventQueue::Inner::ExecuteRunnable() src/xpcom/threads/ThrottledEventQueue.cpp:188:22
    #37 0x7f07d5743337 in mozilla::ThrottledEventQueue::Inner::Executor::Run() src/xpcom/threads/ThrottledEventQueue.cpp:72:15
    #38 0x7f07d56ec402 in mozilla::SchedulerGroup::Runnable::Run() src/xpcom/threads/SchedulerGroup.cpp:337:32
    #39 0x7f07d57297c0 in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:1235:14
    #40 0x7f07d5732525 in NS_ProcessNextEvent(nsIThread*, bool) src/xpcom/threads/nsThreadUtils.cpp:519:10
    #41 0x7f07d6907aae in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:97:21
    #42 0x7f07d6809d9c in RunInternal src/ipc/chromium/src/base/message_loop.cc:325:10
    #43 0x7f07d6809d9c in RunHandler src/ipc/chromium/src/base/message_loop.cc:318
    #44 0x7f07d6809d9c in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:298
    #45 0x7f07df2cece6 in nsBaseAppShell::Run() src/widget/nsBaseAppShell.cpp:158:27
    #46 0x7f07e362ffde in XRE_RunAppShell() src/toolkit/xre/nsEmbedFunctions.cpp:940:22
    #47 0x7f07d6809d9c in RunInternal src/ipc/chromium/src/base/message_loop.cc:325:10
    #48 0x7f07d6809d9c in RunHandler src/ipc/chromium/src/base/message_loop.cc:318
    #49 0x7f07d6809d9c in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:298
    #50 0x7f07e362f092 in XRE_InitChildProcess(int, char**, XREChildData const*) src/toolkit/xre/nsEmbedFunctions.cpp:766:34
    #51 0x4f5b11 in content_process_main src/browser/app/../../ipc/contentproc/plugin-container.cpp:50:30
    #52 0x4f5b11 in main src/browser/app/nsBrowserApp.cpp:287
    #53 0x7f07fab1fb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #54 0x424ee8 in _start (firefox+0x424ee8)

0x6060001ef8d8 is located 24 bytes inside of 64-byte region [0x6060001ef8c0,0x6060001ef900)
freed by thread T0 (file:// Content) here:
    #0 0x4c52f2 in __interceptor_free /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:68:3
    #1 0x7f07df9c5ed4 in operator() src/obj-firefox/dist/include/mozilla/UniquePtr.h:528:5
    #2 0x7f07df9c5ed4 in reset src/obj-firefox/dist/include/mozilla/UniquePtr.h:343
    #3 0x7f07df9c5ed4 in operator= src/obj-firefox/dist/include/mozilla/UniquePtr.h:313
    #4 0x7f07df9c5ed4 in Terminate src/layout/base/AccessibleCaretManager.cpp:133
    #5 0x7f07df9c5ed4 in mozilla::AccessibleCaretEventHub::Terminate() src/layout/base/AccessibleCaretEventHub.cpp:449
    #6 0x7f07df9f3759 in mozilla::PresShell::Destroy() src/layout/base/PresShell.cpp:1283:31
    #7 0x7f07dfb44711 in nsDocumentViewer::DestroyPresShell() src/layout/base/nsDocumentViewer.cpp:4653:15
    #8 0x7f07dfb2f476 in nsDocumentViewer::Destroy() src/layout/base/nsDocumentViewer.cpp:1901:5
    #9 0x7f07e28379aa in nsDocShell::Destroy() src/docshell/base/nsDocShell.cpp:5303:21
    #10 0x7f07e2f66ccd in nsWebBrowser::SetDocShell(nsIDocShell*) src/toolkit/components/browser/nsWebBrowser.cpp:1604:23
    #11 0x7f07e2f6623d in nsWebBrowser::InternalDestroy() src/toolkit/components/browser/nsWebBrowser.cpp:93:3
    #12 0x7f07e2f742c2 in nsWebBrowser::Destroy() src/toolkit/components/browser/nsWebBrowser.cpp:1220:3
    #13 0x7f07e2f744cc in non-virtual thunk to nsWebBrowser::Destroy() src/toolkit/components/browser/nsWebBrowser.cpp
    #14 0x7f07de9c94e2 in mozilla::dom::TabChild::DestroyWindow() src/dom/ipc/TabChild.cpp:1067:21
    #15 0x7f07de9e3727 in mozilla::dom::TabChild::RecvDestroy() src/dom/ipc/TabChild.cpp:2516:3
    #16 0x7f07d755a114 in mozilla::dom::PBrowserChild::OnMessageReceived(IPC::Message const&) src/obj-firefox/ipc/ipdl/PBrowserChild.cpp:4534:20
    #17 0x7f07d6bc2121 in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) src/obj-firefox/ipc/ipdl/PContentChild.cpp:5606:28
    #18 0x7f07d68fd9de in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) src/ipc/glue/MessageChannel.cpp:2236:25
    #19 0x7f07d68f930e in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) src/ipc/glue/MessageChannel.cpp:2166:17
    #20 0x7f07d68fb76d in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) src/ipc/glue/MessageChannel.cpp:2012:5
    #21 0x7f07d68fc4c7 in mozilla::ipc::MessageChannel::MessageTask::Run() src/ipc/glue/MessageChannel.cpp:2045:15
    #22 0x7f07d56ec402 in mozilla::SchedulerGroup::Runnable::Run() src/xpcom/threads/SchedulerGroup.cpp:337:32
    #23 0x7f07d57297c0 in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:1235:14

previously allocated by thread T0 (file:// Content) here:
    #0 0x4c5633 in malloc /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88:3
    #1 0x51a34d in moz_xmalloc src/memory/mozalloc/mozalloc.cpp:70:17
    #2 0x7f07df9caca5 in operator new src/obj-firefox/dist/include/mozilla/mozalloc.h:136:12
    #3 0x7f07df9caca5 in MakeUnique<mozilla::AccessibleCaret, nsIPresShell *&> src/obj-firefox/dist/include/mozilla/UniquePtr.h:680
    #4 0x7f07df9caca5 in mozilla::AccessibleCaretManager::AccessibleCaretManager(nsIPresShell*) src/layout/base/AccessibleCaretManager.cpp:100
    #5 0x7f07df9c565e in MakeUnique<mozilla::AccessibleCaretManager, nsIPresShell *&> src/obj-firefox/dist/include/mozilla/UniquePtr.h:680:27
    #6 0x7f07df9c565e in mozilla::AccessibleCaretEventHub::Init() src/layout/base/AccessibleCaretEventHub.cpp:423
    #7 0x7f07dfd480a3 in nsCanvasFrame::CreateAnonymousContent(nsTArray<nsIAnonymousContentCreator::ContentInfo>&) src/layout/generic/nsCanvasFrame.cpp:98:15
    #8 0x7f07dfad186b in nsCSSFrameConstructor::GetAnonymousContent(nsIContent*, nsIFrame*, nsTArray<nsIAnonymousContentCreator::ContentInfo>&) src/layout/base/nsCSSFrameConstructor.cpp:4084:26
    #9 0x7f07dfaceb02 in nsCSSFrameConstructor::ConstructAnonymousContentForCanvas(nsFrameConstructorState&, nsIFrame*, nsIContent*) src/layout/base/nsCSSFrameConstructor.cpp:2930:3
    #10 0x7f07dfac9ef0 in nsCSSFrameConstructor::ConstructDocElementFrame(mozilla::dom::Element*, nsILayoutHistoryState*) src/layout/base/nsCSSFrameConstructor.cpp:2667:5
    #11 0x7f07dfaf445d in nsCSSFrameConstructor::ContentRangeInserted(nsIContent*, nsIContent*, nsILayoutHistoryState*, nsCSSFrameConstructor::InsertionKind) src/layout/base/nsCSSFrameConstructor.cpp:7353:9
    #12 0x7f07dfa6b7ab in mozilla::RestyleManager::ProcessRestyledFrames(nsStyleChangeList&) src/layout/base/RestyleManager.cpp:1550:25
    #13 0x7f07dfa7c303 in mozilla::RestyleManager::DoProcessPendingRestyles(mozilla::ServoTraversalFlags) src/layout/base/RestyleManager.cpp:3057:9
    #14 0x7f07dfa2055c in ProcessPendingRestyles src/layout/base/RestyleManager.cpp:3134:3
    #15 0x7f07dfa2055c in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) src/layout/base/PresShell.cpp:4297
    #16 0x7f07d9732359 in FlushPendingNotifications src/layout/base/nsIPresShell.h:577:5
    #17 0x7f07d9732359 in nsIDocument::FlushPendingNotifications(mozilla::ChangesToFlush) src/dom/base/nsDocument.cpp:7442
    #18 0x7f07d94a288b in mozilla::dom::Element::GetBoundingClientRect() src/dom/base/Element.cpp:2353:10
    #19 0x7f07dbe4f10a in mozilla::dom::Element_Binding::getBoundingClientRect(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Element*, JSJitMethodCallArgs const&) src/obj-firefox/dom/bindings/ElementBinding.cpp:2721:59
    #20 0x7f07dc6d9b39 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:3311:13
    #21 0x7f07e3957b7e in CallJSNative src/js/src/vm/Interpreter.cpp:445:15
    #22 0x7f07e3957b7e in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) src/js/src/vm/Interpreter.cpp:533
    #23 0x7f07e3942467 in CallFromStack src/js/src/vm/Interpreter.cpp:590:12
    #24 0x7f07e3942467 in Interpret(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:3239
    #25 0x7f07e392887e in js::RunScript(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:425:12
    #26 0x7f07e3958454 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) src/js/src/vm/Interpreter.cpp:557:15
Component: Disability Access APIs → Layout
I can't repro atm. Any thought Emilio?
Flags: needinfo?(emilio)
Keywords: sec-high
Probably fixed by bug 1472020? Can you repro with that patch reverted?
Flags: needinfo?(emilio) → needinfo?(twsmith)
Hmm, actually that's a bit unlikely, let me think a bit about this.
Flags: needinfo?(emilio)
I cannot really make sense of that stack. The allocation and deallocation stacks make sense. But we just null out the caret when deallocating it, since it's a UniquePtr.

I don't know how can we end up with a non-null pointer there. Plus the accessible caret event hub should get deregistered as a selection listener in nsFrameSelection::DisconnectFromPresShell.

Ting-Yu, can you make sense of the stacks here?
Flags: needinfo?(emilio) → needinfo?(aethanyc)
One possible explanation in the deallocation stacks is:

In PresShell::Destroy(), mSelection [1] (nsFrameSelection) doesn't exists, so it fails to de-register AccessibleCaretEventHub as a selection listener from dom::Selection, but AccessibleCaretEventHub terminates itself anyway. 

I have no idea in what circumstances mSelection doesn't exist when calling PresShell::Destroy(). A reliable reduced testcase will definitely help.

[1] https://searchfox.org/mozilla-central/rev/ef8b3886cb173d5534b954b6fb7eb2d94a9473d0/layout/base/PresShell.cpp#1277-1280
Flags: needinfo?(aethanyc)
Can you repro with the original revision from comment 0 and the non-reduced testcase?
I cannot reproduce it at all unfortunately and the fuzzer has only hit it once.
Flags: needinfo?(twsmith)
Priority: -- → P1
Emilio, Tyson – Assuming no additional luck reproducing here (and still no testcase). Can we mark as stalled for now?
Flags: needinfo?(twsmith)
Flags: needinfo?(emilio)
Yes that works for me. I'll reopen if we find a better test case.
Flags: needinfo?(twsmith)
Flags: needinfo?(emilio)
Keywords: stalled

Removing employee no longer with company from CC list of private bugs.

Calling this INCOMPLETE since we don't have a testcase or STR here. Hopefully it was just a cosmic ray, or it's been fixed. :) Feel free to reopen if we can hit this again and can get a testcase or rr recording or a minidump etc.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → INCOMPLETE

Since the bug is closed, the stalled keyword is now meaningless.
For more information, please visit auto_nag documentation.

Keywords: stalled
Group: layout-core-security
You need to log in before you can comment on or make changes to this bug.