Closed Bug 1464784 (CVE-2018-12363) Opened 6 years ago Closed 6 years ago

heap-use-after-free in nsINode::Append

Categories

(Core :: DOM: Core & HTML, defect)

62 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: bzbarsky)

References

Details

(4 keywords, 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 62.0a1 (SourceStamp=043e4ab6e72469ed8121f4da98dcdfef983a49d9). It requires a fuzzing build (--enable-fuzzing) and the pref fuzzing.enabled=true

<script>
function start() {
	o13=(new DOMParser()).parseFromString("<html xmlns='http://www.w3.org/1999/xhtml'><s></s></html>",'text/html');
	o17=o13.all[3];
	o54=(new DOMParser()).parseFromString("<html xmlns='http://www.w3.org/1999/xhtml'><input></input></html>",'text/html');
	o58=o54.all[3];
	o60=(new DOMParser()).parseFromString("<html xmlns='http://www.w3.org/1999/xhtml'><li></li></html>",'text/html');
	o61=o60.all[0];
	o66=(new DOMParser()).parseFromString("<html xmlns='http://www.w3.org/1999/xhtml'><tbody></tbody></html>",'text/html');
	o17.addEventListener('DOMNodeRemoved',fun0);
	try{o72=o66.prepend(o61,undefined);}catch(e){}
	o77=document.createElementNS('http://www.w3.org/1999/xhtml','iframe');
	o61.appendChild(o77);
	o79=o77.cloneNode(true);
	document.documentElement.append(o17);
}
var count = 0;
function fun0() {
	count++;
	if(count==1) {
		o79.append(o58,o17,undefined);
	} else if(count==2) {
		document.documentElement.prepend(o79);
		o149=o58.parentNode;
		document.documentElement.append(o149);
	        document.documentElement.prepend(o17,undefined);
		o149=null;o58=null;o17=null;o79=null;o66=null;o13=null;o54=null;o60=null;o77=null;
		FuzzingFunctions.garbageCollect();FuzzingFunctions.cycleCollect();FuzzingFunctions.garbageCollect();FuzzingFunctions.cycleCollect();
	} else if(count==4) {
		 document.documentElement.prepend(undefined,o61);
	}
}
</script>
<body onload="start()"></body>

ASAN output:
=================================================================
==12349==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d0002671c8 at pc 0x7fcb7cf962d0 bp 0x7ffc143ad2b0 sp 0x7ffc143ad2a8
READ of size 8 at 0x61d0002671c8 thread T0 (file:// Content)
    #0 0x7fcb7cf962cf in CreateTextNode /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5763:44
    #1 0x7fcb7cf962cf in GetNodeFromNodeOrString(mozilla::dom::OwningNodeOrString const&, nsIDocument*) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1429
    #2 0x7fcb7cf59ac2 in ConvertNodesOrStringsIntoNode(mozilla::dom::Sequence<mozilla::dom::OwningNodeOrString> const&, nsIDocument*, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1453:35
    #3 0x7fcb7cf5ac33 in nsINode::Append(mozilla::dom::Sequence<mozilla::dom::OwningNodeOrString> const&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1638:5
    #4 0x7fcb7ec79dd6 in mozilla::dom::ElementBinding::append(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Element*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/ElementBinding.cpp:5175:9
    #5 0x7fcb7f381b81 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:3280:13
    #6 0x7fcb85c4c157 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #7 0x7fcb85c4c157 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:468
    #8 0x7fcb85c36fa5 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:523:12
    #9 0x7fcb85c36fa5 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #10 0x7fcb85c1d4c6 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:418:12
    #11 0x7fcb85c4bed5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:490:15
    #12 0x7fcb85c4d152 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:536:10
    #13 0x7fcb86794a5a 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:2981:12
    #14 0x7fcb7eb2ed05 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
    #15 0x7fcb7faaa64e in HandleEvent<mozilla::dom::EventTarget *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
    #16 0x7fcb7faaa64e in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1121
    #17 0x7fcb7faabddb in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1291:20
    #18 0x7fcb7fa960e7 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16
    #19 0x7fcb7fa99ee3 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:961:9
    #20 0x7fcb7cab1cc2 in nsContentUtils::MaybeFireNodeRemoved(nsINode*, nsINode*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4776:5
    #21 0x7fcb7cf5bc71 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1926:7
    #22 0x7fcb7cf5ac5f in InsertBefore /builds/worker/workspace/build/src/dom/base/nsINode.h:1847:12
    #23 0x7fcb7cf5ac5f in AppendChild /builds/worker/workspace/build/src/dom/base/nsINode.h:1851
    #24 0x7fcb7cf5ac5f in nsINode::Append(mozilla::dom::Sequence<mozilla::dom::OwningNodeOrString> const&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1643
    #25 0x7fcb7ec79dd6 in mozilla::dom::ElementBinding::append(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Element*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/ElementBinding.cpp:5175:9
    #26 0x7fcb7f381b81 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:3280:13
    #27 0x7fcb85c4c157 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #28 0x7fcb85c4c157 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:468
    #29 0x7fcb85c36fa5 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:523:12
    #30 0x7fcb85c36fa5 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #31 0x7fcb85c1d4c6 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:418:12
    #32 0x7fcb85c4bed5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:490:15
    #33 0x7fcb85c4d152 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:536:10
    #34 0x7fcb86794a5a 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:2981:12
    #35 0x7fcb7eb298be 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
    #36 0x7fcb7fae611a in void mozilla::dom::EventHandlerNonNull::Call<nsISupports*>(nsISupports* const&, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JSCompartment*) /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:363:12
    #37 0x7fcb7fae3a84 in mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:214:12
    #38 0x7fcb7faaa69d in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1124:52
    #39 0x7fcb7faabddb in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1291:20
    #40 0x7fcb7fa960e7 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16
    #41 0x7fcb7fa99ee3 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:961:9
    #42 0x7fcb81da5378 in nsDocumentViewer::LoadComplete(nsresult) /builds/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1166:7
    #43 0x7fcb84f06cc2 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7169:21
    #44 0x7fcb84f030e9 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:6962:7
    #45 0x7fcb84f0a8ef in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp
    #46 0x7fcb7bacbb97 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1309:3
    #47 0x7fcb7bacac1a in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:852:14
    #48 0x7fcb7bac77f8 in nsDocLoader::DocLoaderIsEmpty(bool) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:741:9
    #49 0x7fcb7bac97bc in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:627:5
    #50 0x7fcb7baca7dc in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp
    #51 0x7fcb79e825fa in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/netwerk/base/nsLoadGroup.cpp:629:28
    #52 0x7fcb7ceaa74a in DoUnblockOnload /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:8340:18
    #53 0x7fcb7ceaa74a in nsDocument::UnblockOnload(bool) /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:8262
    #54 0x7fcb7ce8afd4 in nsIDocument::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5224:3
    #55 0x7fcb7cf9d314 in applyImpl<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1165:12
    #56 0x7fcb7cf9d314 in apply<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1171
    #57 0x7fcb7cf9d314 in mozilla::detail::RunnableMethodImpl<nsIDocument*, void (nsIDocument::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1216
    #58 0x7fcb79c77821 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:337:32
    #59 0x7fcb79c96146 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1090:14
    #60 0x7fcb79cb2080 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:519:10
    #61 0x7fcb7ab9364a in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21
    #62 0x7fcb7aae6cf9 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #63 0x7fcb7aae6cf9 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #64 0x7fcb7aae6cf9 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #65 0x7fcb8170643a in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:157:27
    #66 0x7fcb859637bb in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:893:22
    #67 0x7fcb7aae6cf9 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #68 0x7fcb7aae6cf9 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #69 0x7fcb7aae6cf9 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #70 0x7fcb85963180 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:719:34
    #71 0x4f50dc in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:50:30
    #72 0x4f50dc in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:282
    #73 0x7fcb999cc82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #74 0x42476c in _start (/fuzzer3/firefox/firefox+0x42476c)

0x61d0002671c8 is located 328 bytes inside of 1968-byte region [0x61d000267080,0x61d000267830)
freed by thread T0 (file:// Content) here:
    #0 0x4c5172 in __interceptor_free /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:68:3
    #1 0x7fcb79b1d730 in SnowWhiteKiller::~SnowWhiteKiller() /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2729:25
    #2 0x7fcb79b25b1f in FreeSnowWhite /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2917:3
    #3 0x7fcb79b25b1f in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3925
    #4 0x7fcb79b24fad in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3746:9
    #5 0x7fcb79b28ec2 in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:4315:21
    #6 0x7fcb7cf725de in nsJSContext::CycleCollectNow(nsICycleCollectorListener*) /builds/worker/workspace/build/src/dom/base/nsJSEnvironment.cpp:1488:3
    #7 0x7fcb7eda41da in mozilla::dom::FuzzingFunctionsBinding::cycleCollect(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/FuzzingFunctionsBinding.cpp:54:3
    #8 0x7fcb85c4c157 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #9 0x7fcb85c4c157 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:468
    #10 0x7fcb85c36fa5 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:523:12
    #11 0x7fcb85c36fa5 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #12 0x7fcb85c1d4c6 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:418:12
    #13 0x7fcb85c4bed5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:490:15
    #14 0x7fcb85c4d152 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:536:10
    #15 0x7fcb86794a5a 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:2981:12
    #16 0x7fcb7eb2ed05 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
    #17 0x7fcb7faaa64e in HandleEvent<mozilla::dom::EventTarget *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
    #18 0x7fcb7faaa64e in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1121
    #19 0x7fcb7faabddb in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1291:20
    #20 0x7fcb7fa960e7 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16
    #21 0x7fcb7fa99ee3 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:961:9
    #22 0x7fcb7cab1cc2 in nsContentUtils::MaybeFireNodeRemoved(nsINode*, nsINode*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4776:5
    #23 0x7fcb7cf5bc71 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1926:7
    #24 0x7fcb7cf59adc in InsertBefore /builds/worker/workspace/build/src/dom/base/nsINode.h:1847:12
    #25 0x7fcb7cf59adc in AppendChild /builds/worker/workspace/build/src/dom/base/nsINode.h:1851
    #26 0x7fcb7cf59adc in ConvertNodesOrStringsIntoNode(mozilla::dom::Sequence<mozilla::dom::OwningNodeOrString> const&, nsIDocument*, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1454
    #27 0x7fcb7cf5ac33 in nsINode::Append(mozilla::dom::Sequence<mozilla::dom::OwningNodeOrString> const&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1638:5
    #28 0x7fcb7ec79dd6 in mozilla::dom::ElementBinding::append(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Element*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/ElementBinding.cpp:5175:9
    #29 0x7fcb7f381b81 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:3280:13
    #30 0x7fcb85c4c157 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #31 0x7fcb85c4c157 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:468
    #32 0x7fcb85c36fa5 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:523:12
    #33 0x7fcb85c36fa5 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #34 0x7fcb85c1d4c6 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:418:12
    #35 0x7fcb85c4bed5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:490:15
    #36 0x7fcb85c4d152 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:536:10
    #37 0x7fcb86794a5a 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:2981:12

previously allocated by thread T0 (file:// Content) here:
    #0 0x4c54b3 in malloc /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88:3
    #1 0x4f5f7d in moz_xmalloc /builds/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:70:17
    #2 0x7fcb7fe7e170 in operator new /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:156:12
    #3 0x7fcb7fe7e170 in NS_NewHTMLDocument(nsIDocument**, bool) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:156
    #4 0x7fcb811ea681 in NS_NewDOMDocument(nsIDocument**, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, mozilla::dom::DocumentType*, nsIURI*, nsIURI*, nsIPrincipal*, bool, nsIGlobalObject*, DocumentFlavor) /builds/worker/workspace/build/src/dom/xml/XMLDocument.cpp:86:10
    #5 0x7fcb7cc74d09 in mozilla::dom::DOMParser::SetUpDocument(DocumentFlavor, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/DOMParser.cpp:312:17
    #6 0x7fcb7cc747f6 in mozilla::dom::DOMParser::ParseFromString(nsTSubstring<char16_t> const&, mozilla::dom::SupportedType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/DOMParser.cpp:68:38
    #7 0x7fcb7eab0708 in mozilla::dom::DOMParserBinding::parseFromString(JSContext*, JS::Handle<JSObject*>, mozilla::dom::DOMParser*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/DOMParserBinding.cpp:79:49
    #8 0x7fcb7f381b81 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:3280:13
    #9 0x7fcb85c4c157 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15
    #10 0x7fcb85c4c157 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:468
    #11 0x7fcb85c36fa5 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:523:12
    #12 0x7fcb85c36fa5 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086
    #13 0x7fcb85c1d4c6 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:418:12
    #14 0x7fcb85c4bed5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:490:15
    #15 0x7fcb85c4d152 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:536:10
    #16 0x7fcb86794a5a 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:2981:12
    #17 0x7fcb7eb298be 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
    #18 0x7fcb7fae611a in void mozilla::dom::EventHandlerNonNull::Call<nsISupports*>(nsISupports* const&, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JSCompartment*) /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:363:12
    #19 0x7fcb7fae3a84 in mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:214:12
    #20 0x7fcb7faaa69d in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1124:52
    #21 0x7fcb7faabddb in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1291:20
    #22 0x7fcb7fa960e7 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16
    #23 0x7fcb7fa99ee3 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:961:9
    #24 0x7fcb81da5378 in nsDocumentViewer::LoadComplete(nsresult) /builds/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1166:7
    #25 0x7fcb84f06cc2 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7169:21
    #26 0x7fcb84f030e9 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:6962:7
    #27 0x7fcb84f0a8ef in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp
    #28 0x7fcb7bacbb97 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1309:3
    #29 0x7fcb7bacac1a in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:852:14
    #30 0x7fcb7bac77f8 in nsDocLoader::DocLoaderIsEmpty(bool) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:741:9
    #31 0x7fcb7bac97bc in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:627:5
    #32 0x7fcb7baca7dc in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp

SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5763:44 in CreateTextNode
Shadow bytes around the buggy address:
  0x0c3a80044de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3a80044df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3a80044e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3a80044e10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3a80044e20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c3a80044e30: fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd
  0x0c3a80044e40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3a80044e50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3a80044e60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3a80044e70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c3a80044e80: 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
==12349==ABORTING
Attached file ASAN output
Boris, do you have cycles to look at this?
Group: core-security → dom-core-security
Flags: needinfo?(bzbarsky)
I haven't reproduced this in an ASAN build yet, but generally speaking the issue is that nsINode::Append does:

  ConvertNodesOrStringsIntoNode(aNodes, OwnerDoc(), aRv);

ConvertNodesOrStringsIntoNode can remove things in aNodes from the DOM, which can run script via mutation events (DOMNodeRemoved).  That script can adopt the node append() was called on into a different document, so it not longer keeps its old owner document alive, then cause that owner document to be destroyed, and then the pointer passed in OwnerDoc becomes bogus.

We should be taking a stack ref to the document here, and probably annotating some of this stuff MOZ_CAN_RUN_SCRIPT.
I have yet to manage to build an ASAN build.  When I try to, I get:

 0:03.58 ../build/libjs_static.a(BinSource.o): In function `sancov.module_ctor':
 0:03.58 /home/bzbarsky/mozilla/inbound/mozilla/js/src/frontend/BinSource.cpp:(.text.sancov.module_ctor[sancov.module_ctor]+0x4): undefined reference to `__start___sancov_guards'

with a mozconfig that certainly used to work for ASAN builds before.  :(

I guess I can try just doing this via try tomorrow....
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
I tested that with try ASAN builds.
Flags: needinfo?(bzbarsky)
Attachment #8982216 - Flags: review?(bugs) → review+
I guess branches may need another patch because of the OZ_CAN_RUN_SCRIPT annotation.
Comment on attachment 8982216 [details] [diff] [review]
Hold a strong ref to the document in callers of ConvertNodesOrStringsIntoNode

[Security approval request comment]
How easily could an exploit be constructed based on the patch?  Not very easily.  You still have to think a bit about how to get to a potential deallocated object access, then do the right steps and force GC to happen at the right time.  That said, I suspect someone competent could figure it out.

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?  Everything back to Firefox 26.

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

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?  I have a backport to esr52.  This patch applies as-is to esr60 (and beta, of course).

How likely is this patch to cause regressions; how much testing does it need?  This is very safe.
Attachment #8982216 - Flags: sec-approval?
Comment on attachment 8982216 [details] [diff] [review]
Hold a strong ref to the document in callers of ConvertNodesOrStringsIntoNode

[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-high
User impact if declined: Potential security exploits.
Fix Landed on Version: 62, presumably.
Risk to taking this patch (and alternatives if risky): Low risk.
String or UUID changes made by this patch: None.

See https://wiki.mozilla.org/Release_Management/ESR_Landing_Process for more info.

Approval Request Comment
[Feature/Bug causing the regression]: Bug 911477.
[User impact if declined]: Potential security exploits.
[Is this code covered by automated tests?]: No, because it's a security bug
[Has the fix been verified in Nightly?]: No
[Needs manual test from QE? If yes, steps to reproduce]: The steps I used were to modify the ASAN mozconfig in our tree to look like the fuzzing-asan one, then load the testcase from comment 0 in the resulting try build...
[List of other uplifts needed for the feature/fix]: None
[Is the change risky?]: No
[Why is the change risky/not risky?]: It just holds some stack strong refs.  Apart from a bit more time spent refcounting, there are no risks.
[String changes made/needed]: None.
Attachment #8982216 - Flags: approval-mozilla-esr60?
Attachment #8982216 - Flags: approval-mozilla-beta?
Comment on attachment 8982280 [details] [diff] [review]
Backport for esr52

[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-high
User impact if declined: Potential security exploits.
Fix Landed on Version: 62, presumably.
Risk to taking this patch (and alternatives if risky): Low risk.
String or UUID changes made by this patch: None.

See https://wiki.mozilla.org/Release_Management/ESR_Landing_Process for more info.
Attachment #8982280 - Flags: approval-mozilla-esr52?
Comment on attachment 8982216 [details] [diff] [review]
Hold a strong ref to the document in callers of ConvertNodesOrStringsIntoNode

Approvals given.
Attachment #8982216 - Flags: sec-approval?
Attachment #8982216 - Flags: sec-approval+
Attachment #8982216 - Flags: approval-mozilla-esr60?
Attachment #8982216 - Flags: approval-mozilla-esr60+
Attachment #8982216 - Flags: approval-mozilla-beta?
Attachment #8982216 - Flags: approval-mozilla-beta+
Attachment #8982280 - Flags: approval-mozilla-esr52? → approval-mozilla-esr52+
https://hg.mozilla.org/mozilla-central/rev/4aed3a8d30d8
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla62
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-12363
I managed to reproduce the crash with the testcase from bug description on Linux 16.04 using older ASAN fuzzy build downloaded from https://tools.taskcluster.net/index/gecko.v2.mozilla-central.pushdate.2018.05.07.20180507085353.firefox/linux64-fuzzing-asan-opt

I verified as fixed on Linux with the latest asan fuzzy build downloaded from:
https://tools.taskcluster.net/index/gecko.v2.mozilla-central.latest.firefox/linux64-fuzzing-asan-opt

I also can confirm that the crash is not reproducing on latest Nightly build 62.0a1, Build ID 20180621013659 on Window 10 x64, Mac OS X 10.13 and Linux 16.04.
Blocks: 911477
I verified as fixed on Ubuntu 16.04 x64 using the following builds:
-latest Beta 61 ASAN fuzzy
-latest ESR 60 ASAN fuzzy
-latest ESR 52 ASAN fuzzy

Also, I verified that the crash is not reproducible on:
Beta 61.0b14, Firefox ESR 60.0.2 and Firefox ESR 52.9.0 on Windows 10 x64, Ubuntu 16.04 x64 and Mac OS X 10.12
Status: RESOLVED → VERIFIED
Flags: qe-verify+
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: