Closed Bug 1414490 Opened 7 years ago Closed 7 years ago

heap-buffer-overflow in nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster

Categories

(Core :: DOM: HTML Parser, defect, P2)

58 Branch
defect

Tracking

()

VERIFIED FIXED
mozilla59
Tracking Status
firefox-esr52 --- unaffected
firefox56 --- unaffected
firefox57 --- unaffected
firefox58 --- verified
firefox59 --- verified

People

(Reporter: nils, Assigned: hsivonen)

References

Details

(4 keywords, Whiteboard: [post-critsmash-triage])

Crash Data

Attachments

(4 files, 5 obsolete files)

Attached file crash.html
The following testcase crashes the latest ASAN build of Firefox.

crash.html:
<script>
function start() {
        o1=window.document;
        o1.write('<html><body><div></div><div></div></body></html>');
        o1.onreadystatechange=fun0;
        o1.close();
}
function fun0() {
        o1.close();
        o1.write('<html><body><div></div><div></div></body></html>');
}
</script>
<body onload="start()"></body>

ASAN output:
=================================================================
==5617==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61500026d978 at pc 0x7fad666e1169 bp 0x7ffe27eae220 sp 0x7ffe27eae218
READ of size 8 at 0x61500026d978 thread T0 (file:// Content)
    #0 0x7fad666e1168 in nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName*, nsHtml5HtmlAttributes*) /builds/worker/workspace/build/src/parser/html/nsHtml5TreeBuilder.cpp:4256:31
    #1 0x7fad666a014a in nsHtml5TreeBuilder::startTag(nsHtml5ElementName*, nsHtml5HtmlAttributes*, bool) /builds/worker/workspace/build/src/parser/html/nsHtml5TreeBuilder.cpp:1109:15
    #2 0x7fad6668f124 in nsHtml5Tokenizer::emitCurrentTagToken(bool, int) /builds/worker/workspace/build/src/parser/html/nsHtml5Tokenizer.cpp:342:21
    #3 0x7fad666c65d2 in int nsHtml5Tokenizer::stateLoop<nsHtml5SilentPolicy>(int, char16_t, int, char16_t*, bool, int, int) /builds/worker/workspace/build/src/parser/html/nsHtml5Tokenizer.cpp:630:50
    #4 0x7fad6668249e in nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer*) /builds/worker/workspace/build/src/parser/html/nsHtml5Tokenizer.cpp:449:11
    #5 0x7fad666665b0 in nsHtml5Parser::Parse(nsTSubstring<char16_t> const&, void*, nsTSubstring<char> const&, bool, nsDTDMode) /builds/worker/workspace/build/src/parser/html/nsHtml5Parser.cpp:388:32
    #6 0x7fad69a4ea34 in nsHTMLDocument::WriteCommon(JSContext*, nsTSubstring<char16_t> const&, bool) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:2016:56
    #7 0x7fad69a4d9e9 in nsHTMLDocument::WriteCommon(JSContext*, mozilla::dom::Sequence<nsTString<char16_t> > const&, bool, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:1910:10
    #8 0x7fad68f689a2 in mozilla::dom::HTMLDocumentBinding::write(JSContext*, JS::Handle<JSObject*>, nsHTMLDocument*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/HTMLDocumentBinding.cpp:689:9
    #9 0x7fad6925aab0 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3040:13
    #10 0x7fad6f5ca3a0 in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #11 0x7fad6f5ca3a0 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:472
    #12 0x7fad6f5cb392 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:540:10
    #13 0x7fad702b6d3e in js::ForwardingProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:176:12
    #14 0x7fad7026c7d5 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:358:23
    #15 0x7fad702969e3 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:511:21
    #16 0x7fad702990c7 in js::proxy_Call(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:770:12
    #17 0x7fad6f5ca71f in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #18 0x7fad6f5ca71f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:454
    #19 0x7fad6f5b5c3b in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:527:12
    #20 0x7fad6f5b5c3b in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3061
    #21 0x7fad6f59d83a in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:422:12
    #22 0x7fad6f5ca49f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:494:15
    #23 0x7fad6f5cb392 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:540:10
    #24 0x7fad702b6d3e in js::ForwardingProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:176:12
    #25 0x7fad7026c7d5 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:358:23
    #26 0x7fad702969e3 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:511:21
    #27 0x7fad702990c7 in js::proxy_Call(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:770:12
    #28 0x7fad6f5ca71f in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #29 0x7fad6f5ca71f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:454
    #30 0x7fad6f5cb392 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:540:10
    #31 0x7fad700114cb 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:3033:12
    #32 0x7fad68c75da5 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:260:37
    #33 0x7fad69677ffd in Call<nsISupports *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:362:12
    #34 0x7fad69677ffd in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:215
    #35 0x7fad69640d26 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1118:51
    #36 0x7fad69642ef2 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1293:20
    #37 0x7fad696225d1 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:462:16
    #38 0x7fad69625aa2 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:826:9
    #39 0x7fad695f4c9a in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, nsIDOMEvent*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:895:12
    #40 0x7fad677cc571 in nsINode::DispatchEvent(nsIDOMEvent*, bool*) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1356:5
    #41 0x7fad695c3385 in mozilla::AsyncEventDispatcher::Run() /builds/worker/workspace/build/src/dom/events/AsyncEventDispatcher.cpp:70:12
    #42 0x7fad672ebb33 in AddScriptRunner /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:5806:13
    #43 0x7fad672ebb33 in nsContentUtils::AddScriptRunner(nsIRunnable*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:5813
    #44 0x7fad695c4393 in mozilla::AsyncEventDispatcher::RunDOMEventWhenSafe() /builds/worker/workspace/build/src/dom/events/AsyncEventDispatcher.cpp:104:3
    #45 0x7fad67708cfe in nsDocument::SetReadyStateInternal(nsIDocument::ReadyState) /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:9864:20
    #46 0x7fad676539a6 in nsContentSink::DidBuildModelImpl(bool) /builds/worker/workspace/build/src/dom/base/nsContentSink.cpp:1543:16
    #47 0x7fad666f51b2 in nsHtml5TreeOpExecutor::DidBuildModel(bool) /builds/worker/workspace/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:169:3
    #48 0x7fad666fdb8c in nsHtml5TreeOpExecutor::FlushDocumentWrite() /builds/worker/workspace/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:616:5
    #49 0x7fad66667f8d in nsHtml5Parser::ParseUntilBlocked() /builds/worker/workspace/build/src/parser/html/nsHtml5Parser.cpp:654:22
    #50 0x7fad66665c46 in nsHtml5Parser::Parse(nsTSubstring<char16_t> const&, void*, nsTSubstring<char> const&, bool, nsDTDMode) /builds/worker/workspace/build/src/parser/html/nsHtml5Parser.cpp:272:14
    #51 0x7fad69a4d565 in nsHTMLDocument::Close(mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:1859:54
    #52 0x7fad68f682dd in mozilla::dom::HTMLDocumentBinding::close(JSContext*, JS::Handle<JSObject*>, nsHTMLDocument*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/HTMLDocumentBinding.cpp:638:9
    #53 0x7fad6925aab0 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3040:13
    #54 0x7fad6f5ca3a0 in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #55 0x7fad6f5ca3a0 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:472
    #56 0x7fad6f5cb392 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:540:10
    #57 0x7fad702b6d3e in js::ForwardingProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:176:12
    #58 0x7fad7026c7d5 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:358:23
    #59 0x7fad702969e3 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:511:21
    #60 0x7fad702990c7 in js::proxy_Call(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:770:12
    #61 0x7fad6f5ca71f in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #62 0x7fad6f5ca71f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:454
    #63 0x7fad6f5b5c3b in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:527:12
    #64 0x7fad6f5b5c3b in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3061
    #65 0x7fad6f59d83a in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:422:12
    #66 0x7fad6f5ca49f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:494:15
    #67 0x7fad6f5cb392 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:540:10
    #68 0x7fad700114cb 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:3033:12
    #69 0x7fad68c75da5 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:260:37
    #70 0x7fad69677ffd in Call<nsISupports *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:362:12
    #71 0x7fad69677ffd in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:215
    #72 0x7fad69640d26 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1118:51
    #73 0x7fad69642ef2 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1293:20
    #74 0x7fad696225d1 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:462:16
    #75 0x7fad69625aa2 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:826:9
    #76 0x7fad6b8f075e in nsDocumentViewer::LoadComplete(nsresult) /builds/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1064:7
    #77 0x7fad6e90e90a in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7764:21
    #78 0x7fad6e90a934 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7562:7
    #79 0x7fad6e91218f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7459:13
    #80 0x7fad66525883 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1321:3
    #81 0x7fad665249ec in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:862:14
    #82 0x7fad66521a78 in nsDocLoader::DocLoaderIsEmpty(bool) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:751:9
    #83 0x7fad66523992 in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:633:5
    #84 0x7fad665245ec in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:489:14
    #85 0x7fad64a93070 in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/netwerk/base/nsLoadGroup.cpp:629:28
    #86 0x7fad677031bd in nsDocument::DoUnblockOnload() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:9374:18
    #87 0x7fad67702d81 in nsDocument::UnblockOnload(bool) /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:9296:9
    #88 0x7fad676dce59 in nsDocument::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5688:3
    #89 0x7fad67756102 in applyImpl<nsDocument, void (nsDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1142:12
    #90 0x7fad67756102 in apply<nsDocument, void (nsDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1148
    #91 0x7fad67756102 in mozilla::detail::RunnableMethodImpl<nsDocument*, void (nsDocument::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1192
    #92 0x7fad648bc4d1 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:396:25
    #93 0x7fad648e1506 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1037:14
    #94 0x7fad648fb9c8 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:513:10
    #95 0x7fad656ceb61 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21
    #96 0x7fad6562f28b in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #97 0x7fad6562f28b in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #98 0x7fad6562f28b in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #99 0x7fad6b098e9f in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:158:27
    #100 0x7fad6f320987 in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:877:22
    #101 0x7fad6562f28b in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10
    #102 0x7fad6562f28b in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319
    #103 0x7fad6562f28b in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299
    #104 0x7fad6f32033a in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:703:34
    #105 0x4ec2de in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:63:30
    #106 0x4ec2de in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:280
    #107 0x7fad81f4282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #108 0x41dbc8 in _start (/fuzzer3/firefox/firefox+0x41dbc8)

0x61500026d978 is located 8 bytes to the left of 512-byte region [0x61500026d980,0x61500026db80)
allocated by thread T0 (file:// Content) here:
    #0 0x4bc44c in malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64:3
    #1 0x4ed85d in moz_xmalloc /builds/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:84:17
    #2 0x7fad666a34a7 in operator new[] /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:218:12
    #3 0x7fad666a34a7 in newJArray /builds/worker/workspace/build/src/parser/html/jArray.h:53
    #4 0x7fad666a34a7 in nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer*) /builds/worker/workspace/build/src/parser/html/nsHtml5TreeBuilder.cpp:78
    #5 0x7fad66665aae in nsHtml5Parser::Parse(nsTSubstring<char16_t> const&, void*, nsTSubstring<char> const&, bool, nsDTDMode) /builds/worker/workspace/build/src/parser/html/nsHtml5Parser.cpp:242:17
    #6 0x7fad69a4ea34 in nsHTMLDocument::WriteCommon(JSContext*, nsTSubstring<char16_t> const&, bool) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:2016:56
    #7 0x7fad69a4d9e9 in nsHTMLDocument::WriteCommon(JSContext*, mozilla::dom::Sequence<nsTString<char16_t> > const&, bool, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/html/nsHTMLDocument.cpp:1910:10
    #8 0x7fad68f689a2 in mozilla::dom::HTMLDocumentBinding::write(JSContext*, JS::Handle<JSObject*>, nsHTMLDocument*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/HTMLDocumentBinding.cpp:689:9
    #9 0x7fad6925aab0 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3040:13
    #10 0x7fad6f5ca3a0 in CallJSNative /builds/worker/workspace/build/src/js/src/jscntxtinlines.h:291:15
    #11 0x7fad6f5ca3a0 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:472
    #12 0x7fad6f5b5c3b in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:527:12
    #13 0x7fad6f5b5c3b in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3061
    #14 0x7fad6f59d83a in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:422:12
    #15 0x7fad6f5ca49f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:494:15
    #16 0x7fad6f5cb392 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:540:10
    #17 0x7fad700114cb 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:3033:12
    #18 0x7fad68c75da5 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:260:37
    #19 0x7fad69677ffd in Call<nsISupports *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:362:12
    #20 0x7fad69677ffd in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:215
    #21 0x7fad69640d26 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1118:51
    #22 0x7fad69642ef2 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1293:20
    #23 0x7fad696225d1 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:462:16
    #24 0x7fad69625aa2 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:826:9
    #25 0x7fad6b8f075e in nsDocumentViewer::LoadComplete(nsresult) /builds/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1064:7
    #26 0x7fad6e90e90a in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7764:21
    #27 0x7fad6e90a934 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7562:7
    #28 0x7fad6e91218f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /builds/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7459:13
    #29 0x7fad66525883 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1321:3
    #30 0x7fad665249ec in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:862:14
    #31 0x7fad66521a78 in nsDocLoader::DocLoaderIsEmpty(bool) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:751:9
    #32 0x7fad66523992 in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:633:5
    #33 0x7fad665245ec in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:489:14
    #34 0x7fad64a93070 in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /builds/worker/workspace/build/src/netwerk/base/nsLoadGroup.cpp:629:28

SUMMARY: AddressSanitizer: heap-buffer-overflow /builds/worker/workspace/build/src/parser/html/nsHtml5TreeBuilder.cpp:4256:31 in nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName*, nsHtml5HtmlAttributes*)
Shadow bytes around the buggy address:
  0x0c2a80045ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2a80045ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
=>0x0c2a80045b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]
  0x0c2a80045b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2a80045b70: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==5617==ABORTING
Attached file ASAN output
Group: core-security → dom-core-security
Henri, please take a look.
Assignee: nobody → hsivonen
Priority: -- → P2
Status: NEW → ASSIGNED
I didn't to a full bisect, but this looks recent enough that this is likely a regression from bug 1364399. I don't understand how, yet.
Blocks: 1364399
(In reply to Henri Sivonen (:hsivonen) from comment #3)
> I didn't to a full bisect, but this looks recent enough that this is likely
> a regression from bug 1364399.

Confirmed.
Has Regression Range: --- → yes
Keywords: crash, regression
Sigh. I even had the code to fix this during the process of fixing bug 1364399, but I mistakenly thought the code was unnecessary.

The cause is that we transition to readyState "interactive" after the tokenizer and tree builder have become incapable of accepting more data but the parser doesn't report insertion point as undefined yet.
Attached file More informative test case (obsolete) —
This modification of the test case displays "1" in Chrome, Safari and Edge.

In Firefox, even release and ESR, it shows a large enough number that the number probably comes from memory corruption.
(In reply to Henri Sivonen (:hsivonen) from comment #6)
> Created attachment 8926338 [details]
> More informative test case
> 
> This modification of the test case displays "1" in Chrome, Safari and Edge.
> 
> In Firefox, even release and ESR, it shows a large enough number that the
> number probably comes from memory corruption.

Hmm. The number is stable enough that maybe it comes from something else. It's suspiciously large, though, considering the document.write recursion limit, etc.
Unfortunately, it's totally hopeless to change stuff in this area without a try run:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=fd3d943128d45b0183ea2aca22cb521aeea8006f
Not memory corruption in release and ESR, as this test case iteration shows. Still very bogus.
Attachment #8926338 - Attachment is obsolete: true
The patch that I have make the observable document.writes consistent with Chrome, Safari and Edge, but doesn't make other readystatechange side effects consistent with them. See: https://hsivonen.com/test/p/write-from-readystate.html

I'd like to leave the remaining bits to a follow-up non-security bug.
We were missing https://html.spec.whatwg.org/#ignore-opens-during-unload-counter

However, inserting the increment/decrement exactly where the spec says results in behavior that's inconsistent with Chrome, Safari and Edge.

I suggest we investigate the case that I put it commented out as a follow-up. Probably worth finding out whether the spec is a bit aspirational on that point or whether there's something weird with our pagehide/unload event firing compared to the other browsers.
Attachment #8926515 - Flags: review?(bugs)
(In reply to Henri Sivonen (:hsivonen) from comment #12)
> I suggest we investigate the case that I put [in] commented out as a
> follow-up. Probably worth finding out whether the spec is a bit aspirational
> on that point or whether there's something weird with our pagehide/unload
> event firing compared to the other browsers.

The follow-up should be able to remove the failure annotation from https://searchfox.org/mozilla-central/source/testing/web-platform/meta/html/browsers/browsing-the-web/unloading-documents/001.html.ini
(In reply to Henri Sivonen (:hsivonen) from comment #12)
> However, inserting the increment/decrement exactly where the spec says
> results in behavior that's inconsistent with Chrome, Safari and Edge.

Oh, great. Hixie's commit message says that what the spec says is a "compromise". https://github.com/whatwg/html/commit/f8c7a29c

So it's unclear if the Chrome/Safari/Edge behavior arises from implementing the spec and I'm reading it wrong or if the spec is aspirational compared to real browser behavior.
(In reply to Henri Sivonen (:hsivonen) from comment #14)
> (In reply to Henri Sivonen (:hsivonen) from comment #12)
> > However, inserting the increment/decrement exactly where the spec says
> > results in behavior that's inconsistent with Chrome, Safari and Edge.
> 
> Oh, great. Hixie's commit message says that what the spec says is a
> "compromise". https://github.com/whatwg/html/commit/f8c7a29c
> 
> So it's unclear if the Chrome/Safari/Edge behavior arises from implementing
> the spec and I'm reading it wrong or if the spec is aspirational compared to
> real browser behavior.

Pretty sure it doesn't arise from the spec. Chrome fails all the tests that Hixie wrote when speccing the counter:
http://www.hixie.ch/tests/adhoc/dom/level0/document/open/unload/

Let's land this, considering that this doesn't break our pre-existing tests and makes our behavior less bogus, and then open a spec bug to get an explanation for the behavior that's interoperable between Chrome, Safari and Edge.
Just curious, there isn't any simpler way to fix the security issue?
Comment on attachment 8926515 [details] [diff] [review]
Implement the ignore-opens-during-unload counter

>+++ b/dom/base/AutoIgnoreOpen.h
This file has odd coding style. 2, 3 and 4 spaces used for indentation

> 
>+    bool mInsertionPointPermanentlyUndefined;
I failed to understand why we need this when we have all the AutoIgnoreOpen stuff.
This needs some comments.

Probably minor things, but would like to get the explanation before giving r+.
Attachment #8926515 - Flags: review?(bugs) → review-
> Just curious, there isn't any simpler way to fix the security issue?

Strictly, mInsertionPointPermanentlyUndefined is the bit that fixes memory safety and the rest is constraining the brokenness that arises from doing only that bit.
(In reply to Olli Pettay [:smaug] from comment #17)
> >+    bool mInsertionPointPermanentlyUndefined;
> I failed to understand why we need this when we have all the AutoIgnoreOpen
> stuff.
> This needs some comments.

Are the comments OK in a security fix though?

The comment for mInsertionPointPermanentlyUndefined would be:
    /**
     * This is set when the tokenizer has seen EOF. The purpose is to
     * keep the insertion point undefined between the time the
     * parser has reached the point where it can't accept more input
     * and the time the document's mParser is set to nullptr.
     * Scripts can run during this time period due to an update
     * batch ending and due to various end-of-parse events firing.
     * (Setting mParser on the document to nullptr at the point
     * where this flag gets set to true would break things that for
     * legacy reasons assume that mParser on the document stays
     * non-null though the end-of-parse events.)
     */
Fixed indent.
Attachment #8926515 - Attachment is obsolete: true
And the reason why mInsertionPointPermanentlyUndefined wasn't necessary before was that previously the EOF was processed from within the tree op flush loop, so the insertion point counted as undefined, because it's undefined during the flush loop.
Trying bz for review, since smaug's queue is closed.
Attachment #8927202 - Attachment is obsolete: true
Attachment #8927205 - Flags: review?(bzbarsky)
For clarity, my process here was as follows:
 1) Must undefine insertion point so that document.write() can't reach the parser after EOF.
 2) Oh, bogus behavior ensues.
 3) Need to prevent re-entrancy to document.write during the parser termination when implying document.open from within document.write.
 4) Do something ad hoc to prevent re-entrancy
 5) Oh, there's a spec concept for that and we never implemented it.
 6) Do what the spec says and delete code from step 4.
 7) Oh, the behavior is now further from Chrome, Safari and Edge than it was in step 4.
 8) Comment out one of the things the spec requires to be dealt with in a follow-up and add the re-entrancy prevention to the exact place where needed.
I can re-review. Thanks for the explanation.
Attachment #8927205 - Flags: review?(bzbarsky)
Still a question, why mInsertionPointPermanentlyUndefined isn't enough to fix the crash?
(In reply to Olli Pettay [:smaug] from comment #25)
> Still a question, why mInsertionPointPermanentlyUndefined isn't enough to
> fix the crash?

It's enough to fix the crash. I'd have to do another try run without anything else see if the resulting state would otherwise burn the tree or not given the present test cases.
Comment on attachment 8927205 [details] [diff] [review]
Implement the ignore-opens-during-unload counter, with proper indent and bug number in the commit message

mInsertionPointPermanentlyUndefined is still undocumented.
Please add the comment. This is nightly only issue, so I think adding the comment should be fine.
Attachment #8927205 - Flags: review+
We already have an ignore-opens-during-unload counter, as of bug 1412173 landing, fwiw.
fun, that landed two days ago.
Oh great. We were five years behind the times implementing the counter and then we have two patches independently implementing it within 3 days.

I'll rebase.
The orange is tier-2. Let's get this landed before 58 moves to beta.
Attachment #8927205 - Attachment is obsolete: true
Attachment #8927734 - Flags: review?(bugs)
Attachment #8927734 - Flags: review?(bugs) → review+
https://hg.mozilla.org/mozilla-central/rev/baa3bbe7a9d0

Please request Beta approval on this when you get a chance.
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Flags: needinfo?(hsivonen)
Resolution: --- → FIXED
Target Milestone: --- → mozilla59
Waiting for the patch to make it to Nightly before requesting uplift.
Attachment #8927734 - Attachment is obsolete: true
Attachment #8928079 - Flags: review+
Comment on attachment 8928079 [details] [diff] [review]
Patch with the commit message as landed

On second thought, let's get this into beta before a build goes out.

Approval Request Comment
> [Feature/Bug causing the regression]:

Bug 1364399

> [User impact if declined]:

Easily-triggerable memory-unsafety.

> [Is this code covered by automated tests?]:

The memory-unsafety part intentionally isn't, *yet*. The general area is.

> [Has the fix been verified in Nightly?]:

No.

> [Needs manual test from QE? If yes, steps to reproduce]: 

Not really, but the steps are loading the attached test case in an ASAN build.

> [List of other uplifts needed for the feature/fix]:

No.

> [Is the change risky?]:

Not too risky.

> [Why is the change risky/not risky?]:

The change didn't require changes to any of our existing unit tests.

> [String changes made/needed]:

None.
Flags: needinfo?(hsivonen)
Attachment #8928079 - Flags: approval-mozilla-beta?
(In reply to Henri Sivonen (:hsivonen) from comment #36)
> > [Has the fix been verified in Nightly?]:
> 
> No.

Now it has. Behaves OK both in the Linux64 nightly and the ASAN debug build from the same hg revision.
Comment on attachment 8928079 [details] [diff] [review]
Patch with the commit message as landed

Fix a sec-high. Beta58+.
Attachment #8928079 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Group: dom-core-security → core-security-release
Crash Signature: [@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster ]
Flags: qe-verify+
Whiteboard: [post-critsmash-triage]
I managed to reproduce this issue on Firefox 59.0a1(2017-11-13) asan build, under Ubuntu 16.04x64.
The issue is no longer reproducible on Firefox 58.0, or on Firefox 59.0a1(2018-01-17).
Tests were performed under Ubuntu 16.04x64, Windows 10x64 and under macOS 10.12.6.
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: