Bug 1249377 (CVE-2016-1961)

ZDI-CAN-3574: nsHTMLDocument SetBody Use-After-Free RCE

VERIFIED FIXED in Firefox 45



3 years ago
a month ago


(Reporter: dveditz, Assigned: mccr8)


(5 keywords)

20 Branch
Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(firefox44 wontfix, firefox45+ verified, firefox46+ verified, firefox47+ verified, firefox-esr3845+ verified, firefox-esr45 verified)


(Whiteboard: [adv-main45+][adv-esr38.7+] dom-triaged btpp-fixnow, crash signature)


(4 attachments, 1 obsolete attachment)



3 years ago
HP's Zero Day Initiative has identified a vulnerability affecting the following products:

  Mozilla Firefox

-- VULNERABILITY DETAILS ------------------------

Tested against Firefox on Windows 8.1 32-bit

[JavaScript Warning: "Successfully compiled asm.js code (total compilation time 1ms; not stored in cache (too small to benefit))" {file: "" line: 0}]
[JavaScript Error: "The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol." {file: "" line: 0}]
[JavaScript Error: "TelemetryStopwatch: key "FX_PAGE_LOAD_MS" was already initialized" {file: "resource://gre/modules/TelemetryStopwatch.jsm" line: 52}]
[JavaScript Error: "NS_ERROR_NOT_AVAILABLE: prompt aborted by user" {file: "resource://gre/components/nsPrompter.js" line: 431}]
[JavaScript Error: "uncaught exception: out of memory" {file: "" line: 98}]
(2d8.43c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00070006 ebx=00028410 ecx=0017c560 edx=00028544 esi=70d68518 edi=70d40000
eip=222201d1 esp=0017c558 ebp=00005245 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210287
222201d1 813c0757696e45  cmp     dword ptr [edi+eax],456E6957h ds:0023:70db0006=????????
0:000> kv
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0017c564 61109f1a 00000002 171e6940 14469240 0x222201d1
0017c580 60fdbad1 00000000 00000000 0017c790 xul!IsAllowedAsChild+0x4a (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsinode.cpp @ 1759]
0017c590 60fda05b 00000000 14469240 00000000 xul!nsINode::EnsurePreInsertionValidity2+0x19 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsinode.cpp @ 1910]
0017c790 61eeefdd 00000000 14469240 00000000 xul!nsINode::ReplaceOrInsertBefore+0x9f (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsinode.cpp @ 1977]
0017c7b8 61dc7a93 14469240 0017c7d8 0017c938 xul!nsHTMLDocument::SetBody+0x82 (FPO: [2,2,4]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\html\nshtmldocument.cpp @ 1055]
0017c7e8 6107fc75 103195f0 0017c828 42710000 xul!mozilla::dom::HTMLDocumentBinding::set_body+0xd0 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\obj-firefox\dom\bindings\htmldocumentbinding.cpp @ 201]
0017c834 60efe92c 103195f0 00000001 42710000 xul!mozilla::dom::GenericBindingSetter+0xe8 (FPO: [3,10,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\bindings\bindingutils.cpp @ 2642]
0017c8cc 60e82040 00000000 0017cc40 0017ca78 xul!js::Invoke+0xbc (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 489]
0017c970 60e7acda 0017c9b0 00000001 0017ca78 xul!js::Invoke+0x1c0 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 542]
0017c9e8 60e7a73d 0017cb08 0017cf00 0017ca78 xul!SetExistingProperty+0x1b9 (FPO: [6,21,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\nativeobject.cpp @ 2278]
0017ca9c 60e7a3d8 0017cb08 0017cf00 0017cc90 xul!js::NativeSetProperty+0x2ad (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\nativeobject.cpp @ 2312]
0017cad8 611d5dca 0017cb08 0017cf00 0017cc90 xul!js::SetProperty+0x35 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\nativeobject.h @ 1453]
0017cb94 611d466c 103195f0 0017ccc4 0017cf00 xul!js::SetPropertyIgnoringNamedGetter+0x7e (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\baseproxyhandler.cpp @ 136]
0017cbe8 611d459f 103195f0 0017ccc4 0017cf00 xul!mozilla::dom::DOMProxyHandler::set+0x81 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\bindings\domjsproxyhandler.cpp @ 218]
0017cc48 611d44b8 0017ccc4 0017cf00 0017cc90 xul!js::Proxy::set+0xe2 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\proxy.cpp @ 345]
0017cc60 611d440d 103195f0 0017ccc4 0017cf00 xul!js::proxy_SetProperty+0x1a (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\proxy.cpp @ 606]
0017cca0 60e861b0 0017ccc4 0017cf00 0017cd18 xul!JSObject::nonNativeSetProperty+0x53 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\jsobj.cpp @ 1046]
0017ccc8 60e87aa6 103195f0 0017ce1c 0017cf00 xul!js::DirectProxyHandler::set+0x81 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\directproxyhandler.cpp @ 241]
0017cd20 611d459f 103195f0 0017ce1c 0017cf00 xul!js::CrossCompartmentWrapper::set+0xa5 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\crosscompartmentwrapper.cpp @ 181]
0017cd80 611d44b8 0017ce1c 0017cf00 0017cdd0 xul!js::Proxy::set+0xe2 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\proxy.cpp @ 345]
0017cd98 60e7a432 103195f0 0017ce1c 0017cf00 xul!js::proxy_SetProperty+0x1a (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\proxy\proxy.cpp @ 606]
0017cdd8 60e7a33a 0017ce1c 0017cf00 0c0560b0 xul!js::SetProperty+0x8f (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\nativeobject.h @ 1452]
0017ce2c 60eb3dfd 0c0560a8 0017cf00 0c0560b0 xul!SetPropertyOperation+0x92 (FPO: [3,12,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 313]
0017dad0 61465216 09d508cc 62a31130 0017db90 xul!Interpret+0x11dd (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 2601]
0017db10 60efe976 103195f0 0017db80 ffffff88 xul!js::RunScript+0x1b6 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 430]
0017dba4 60fe344d 00000000 103195f0 0017df30 xul!js::Invoke+0x106 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\vm\interpreter.cpp @ 510]
0017dc6c 60fb775c 0017dd70 0017dcc8 0017dca8 xul!JS::Call+0x17f (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\js\src\jsapi.cpp @ 2965]
0017dd34 60fb762e 103195f0 0017dd70 162d6970 xul!mozilla::dom::EventHandlerNonNull::Call+0xf0 (FPO: [5,42,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\obj-firefox\dom\bindings\eventhandlerbinding.cpp @ 260]
0017dea4 60fb7bf5 171c2d48 162d6970 0017df18 xul!mozilla::dom::EventHandlerNonNull::Call<nsISupports *>+0x95 (FPO: [7,82,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\obj-firefox\dist\include\mozilla\dom\eventhandlerbinding.h @ 351]
0017e0b0 60e25099 171c2d40 162d6970 0017e43c xul!mozilla::JSEventHandler::HandleEvent+0x141 (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\events\jseventhandler.cpp @ 216]
0017e324 60e23b8b 144df800 0017e4b0 0017e444 xul!mozilla::EventListenerManager::HandleEventInternal+0x339 (FPO: [5,150,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\events\eventlistenermanager.cpp @ 1156]
0017e388 60fd5c40 00000000 0017e430 13aa44f8 xul!mozilla::EventTargetChainItem::HandleEventTargetChain+0x19b (FPO: [2,15,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\events\eventdispatcher.cpp @ 317]
0017e45c 60fb4582 0017e4b0 00000000 0017e4a4 xul!mozilla::EventDispatcher::Dispatch+0x5c0 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\events\eventdispatcher.cpp @ 655]
0017e510 60fabdaa 1717e5e0 00000000 fffdffef xul!nsDocumentViewer::LoadComplete+0x26e (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\layout\base\nsdocumentviewer.cpp @ 1001]
0017e878 60fabb56 13aa4414 1783982c 00000000 xul!nsDocShell::EndPageLoad+0xfb (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\docshell\base\nsdocshell.cpp @ 7418]
0017e89c 6114dfb0 15ce21c8 60f95904 17839800 xul!nsDocShell::OnStateChange+0xed (FPO: [5,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\docshell\base\nsdocshell.cpp @ 7224]
0017e8c0 6121177e 13aa4800 13aa4400 0017e98c xul!nsStandardURL::SchemeIs+0x2c (FPO: [3,0,4]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\netwerk\base\nsstandardurl.cpp @ 1878]
0017e960 61212e35 13aa4414 1783982c 13aa4518 xul!nsSecureBrowserUIImpl::OnStateChange+0x4b9 (FPO: [5,17,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\security\manager\ssl\nssecurebrowseruiimpl.cpp @ 1176]
0017e9fc 612132e2 00000001 15010160 13aa4404 xul!nsDocLoader::doStopDocumentLoad+0x73 (FPO: [2,16,4]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\uriloader\base\nsdocloader.cpp @ 831]
0017ead4 6120f4dd 15010180 612107e1 15010160 xul!nsDocLoader::OnStopRequest+0x128 (FPO: [4,27,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\uriloader\base\nsdocloader.cpp @ 609]
0017eaf0 61210534 15010180 629864f8 0017eb44 xul!nsLoadGroup::AddRef+0xd (FPO: [1,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\netwerk\base\nsloadgroup.cpp @ 159]
0017eb00 6113c461 15010160 629864f8 0017eb44 xul!nsLoadGroup::QueryInterface+0x14 (FPO: [3,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\netwerk\base\nsloadgroup.cpp @ 159]
0017eb10 6113c428 13b5fd10 629864f8 0017eb44 xul!nsWeakReference::QueryReferent+0x18 (FPO: [3,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\glue\nsweakreference.cpp @ 123]
0017eb2c 60fd7f64 fb4dc964 62988b48 0017eb64 xul!nsQueryReferent::operator()+0x18 (FPO: [1,0,4]) (CONV: fastcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\glue\nsweakreference.cpp @ 56]
0017eb64 60e159e5 00000000 0f1ec800 1783a800 xul!nsIDocument::GetDocumentLoadGroup+0x2c (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsidocument.h @ 332]
0017eb80 60e18627 60e1863b 00000001 01c41240 xul!nsDocument::UnblockOnload+0x74 (FPO: [1,0,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsdocument.cpp @ 9046]
0017ebd8 60e1c19c 60fd07a9 42725640 0017eec8 xul!nsDocument::DispatchContentLoadedEvents+0x101 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\dom\base\nsdocument.cpp @ 5179]
0017ebdc 60fd07a9 42725640 0017eec8 01c41240 xul!nsRunnableMethodImpl<void (__thiscall mozilla::dom::XULDocument::*)(void),1>::Run+0x15 (FPO: [1,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\obj-firefox\dist\include\nsthreadutils.h @ 872]
0017ecec 6111324a 01c41240 00000000 0017ed0f xul!nsThread::ProcessNextEvent+0x633 (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\threads\nsthread.cpp @ 964]
0017ed10 61131586 629c93b0 00000000 00000000 xul!NS_ProcessPendingEvents+0x24 (FPO: [0,2,4]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\glue\nsthreadutils.cpp @ 239]
0017ed40 6112eea8 00000200 000c022e 0f438c00 xul!nsWindow::DispatchPendingEvents+0x35 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nswindow.cpp @ 3944]
0017ee88 61112bd4 00000200 0017eec4 0017eec8 xul!nsWindow::ProcessMessage+0x6e5 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nswindow.cpp @ 5302]
0017eeb4 61112b1c 0f438c00 01000200 00000000 xul!nsWindow::WindowProcInternal+0xab (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nswindow.cpp @ 4583]
0017eef4 61112af6 61112b29 000c022e 00000200 xul!CallWindowProcCrashProtected+0x1f (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\base\nscrashonexception.cpp @ 35]
0017ef10 76e28aa0 000c022e 00000200 00000000 xul!nsWindow::WindowProc+0x2d (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nswindow.cpp @ 4535]
0017ef3c 76e28c71 61112ac9 000c022e 00000200 USER32!_InternalCallWinProc+0x2b
0017efc0 76e28d47 000c022e 00000200 00000000 USER32!UserCallWinProcCheckWow+0x13e (FPO: [Non-Fpo])
0017f028 76e28a70 1922213b 0017f090 60fcf82d USER32!DispatchMessageWorker+0x41c (FPO: [Non-Fpo])
0017f034 60fcf82d 0017f074 01c1c404 00000000 USER32!DispatchMessageW+0x10 (FPO: [Non-Fpo])
0017f090 60fcfc4c 00000000 01c1c404 0017f1c4 xul!nsAppShell::ProcessNextNativeEvent+0x1a3 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nsappshell.cpp @ 373]
0017f0ac 60fd0440 00000000 0000000a 00000000 xul!nsBaseAppShell::OnProcessNextEvent+0x8f (FPO: [3,1,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\nsbaseappshell.cpp @ 271]
0017f1c4 60fcf4b7 01c41240 00000000 0017f1fc xul!nsThread::ProcessNextEvent+0x2ca (FPO: [Non-Fpo]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\xpcom\threads\nsthread.cpp @ 936]
0017f1f4 60fceb81 01c53301 fb4dd1ec 01c1c400 xul!mozilla::ipc::MessagePump::Run+0x5f (FPO: [1,4,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\ipc\glue\messagepump.cpp @ 95]
0017f22c 60fcebbc 01c41240 00000001 60f7d800 xul!MessageLoop::RunHandler+0x20 (FPO: [SEH]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\ipc\chromium\src\base\message_loop.cc @ 228]
0017f24c 60fcfb59 09d95840 00000000 60fcfa37 xul!MessageLoop::Run+0x19 (FPO: [Non-Fpo]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\ipc\chromium\src\base\message_loop.cc @ 202]
0017f258 60fcfa37 01c1c400 09d95840 612388d7 xul!nsBaseAppShell::Run+0x32 (FPO: [1,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\nsbaseappshell.cpp @ 158]
0017f264 612388d7 01c1c400 63caa5a0 0edc6300 xul!nsAppShell::Run+0x1b (FPO: [1,0,4]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\widget\windows\nsappshell.cpp @ 257]
0017f274 611683b3 09d95840 0017f4f0 0017f4d8 xul!nsAppStartup::Run+0x20 (FPO: [1,0,0]) (CONV: stdcall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\toolkit\components\startup\nsappstartup.cpp @ 282]
0017f460 61168550 00000001 0017f620 0017f5d8 xul!XREMain::XRE_mainRun+0x4c7 (FPO: [0,117,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\toolkit\xre\nsapprunner.cpp @ 4298]
0017f47c 6116a5fc 00000000 01812ff8 0017f600 xul!XREMain::XRE_main+0x122 (FPO: [3,2,0]) (CONV: thiscall) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\toolkit\xre\nsapprunner.cpp @ 4391]
0017f5d8 01281675 00000001 01812ff8 0017f620 xul!XRE_main+0x3e (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\toolkit\xre\nsapprunner.cpp @ 4494]
0017f76c 01281312 01c1c0a0 01816ff8 ffffc000 firefox!do_main+0x125 (FPO: [1,92,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\browser\app\nsbrowserapp.cpp @ 212]
0017f810 012810dc 012824eb 012824eb 0017f86c firefox!NS_internal_main+0x122 (FPO: [Non-Fpo]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\browser\app\nsbrowserapp.cpp @ 354]
0017f824 0128246e 01812ff8 013cbf98 013cdf70 firefox!wmain+0xbc (FPO: [2,0,0]) (CONV: cdecl) [c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\toolkit\xre\nswindowswmain.cpp @ 138]
0017f86c 76864198 7f547000 76864170 c43a910b firefox!__tmainCRTStartup+0xfe (FPO: [Non-Fpo]) (CONV: cdecl) [f:\dd\vctools\crt\crtw32\startup\crt0.c @ 255]
0017f880 77222cb1 7f547000 5941fe22 00000000 KERNEL32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo])
0017f8c8 77222c7f ffffffff 7724e744 00000000 ntdll!LdrRemoveLoadAsDataTable+0x191
0017f8d8 00000000 012824eb 7f547000 00000000 ntdll!LdrRemoveLoadAsDataTable+0x15f
0:000> !lmi xul
Loaded Module Info: [xul]
         Module: xul
   Base Address: 60da0000
     Image Name: C:\Program Files\Mozilla Firefox\xul.dll
   Machine Type: 332 (I386)
     Time Stamp: 56b55a4f Fri Feb 05 18:28:31 2016
           Size: 25b1000
       CheckSum: 250ec9d
Characteristics: 2122  
Debug Data Dirs: Type  Size     VA  Pointer
             CODEVIEW    76, 1f11818, 1f10618 RSDS - GUID: {38E42F42-A4D0-489D-8C1F-967BEADFCA64}
               Age: 2, Pdb: c:\builds\moz2_slave\rel-m-rel-w32_bld-000000000000\build\obj-firefox\toolkit\library\xul.pdb
                   ??    14, 1f11890, 1f10690 [Data not mapped]
                CLSID     4, 1f118a4, 1f106a4 [Data not mapped]
     Image Type: FILE     - Image read successfully from debugger.
                 C:\Program Files\Mozilla Firefox\xul.dll
    Symbol Type: PDB      - Symbols loaded successfully from image path.
       Compiler: Linker - front end [0.0 bld 0] - back end [12.0 bld 30723]
    Load Report: private symbols & lines, source indexed
0:000> lmvm xul
start    end        module name
60da0000 63351000   xul        (private pdb symbols)  z:\export\symbols\xul.pdb\38E42F42A4D0489D8C1F967BEADFCA642\xul.pdb
    Loaded symbol image file: C:\Program Files\Mozilla Firefox\xul.dll
    Image path: C:\Program Files\Mozilla Firefox\xul.dll
    Image name: xul.dll
    Timestamp:        Fri Feb 05 18:28:31 2016 (56B55A4F)
    CheckSum:         0250EC9D
    ImageSize:        025B1000
    File version:
    Product version:
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0000.04b0
    CompanyName:      Mozilla Foundation
    ProductName:      Firefox
    InternalName:     Firefox
    OriginalFilename: xul.dll
    ProductVersion:   44.0.1
    FileVersion:      44.0.1
    FileDescription:  44.0.1
    LegalCopyright:   License: MPL 2
    LegalTrademarks:  Mozilla
    Comments:         Mozilla
0:000> vertarget
Windows 8 Version 9600 UP Free x86 compatible
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 6.3.9600.17415 (winblue_r4.141028-1500)
Machine Name:
Debug session time: Wed Feb 10 15:28:01.372 2016 (UTC - 8:00)
System Uptime: 0 days 0:19:13.452
Process Uptime: 0 days 0:01:40.437
  Kernel time: 0 days 0:00:00.578
  User time: 0 days 0:00:02.218


Root of the bug:


nsHTMLDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv)
  Element* root = GetRootElement();

  // The body element must be either a body tag or a frameset tag. And we must
  // have a html root tag, otherwise GetBody will not return the newly set
  // body.
  if (!newBody ||
      !newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) ||
      !root || !root->IsHTMLElement() ||
      !root->IsHTMLElement(nsGkAtoms::html)) {

  // Use DOM methods so that we pass through the appropriate security checks.
  nsCOMPtr<Element> currentBody = GetBodyElement();
  if (currentBody) {
    root->ReplaceChild(*newBody, *currentBody, rv);
  } else {
    root->AppendChild(*newBody, rv);


  nsINode* AppendChild(nsINode& aNode, mozilla::ErrorResult& aError)
    return InsertBefore(aNode, nullptr, aError);

  nsINode* InsertBefore(nsINode& aNode, nsINode* aChild,
                        mozilla::ErrorResult& aError)
    return ReplaceOrInsertBefore(false, &aNode, aChild, aError);


nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
                               nsINode* aRefChild, ErrorResult& aError)
  // XXXbz I wish I could assert that nsContentUtils::IsSafeToRunScript() so we
  // could rely on scriptblockers going out of scope to actually run XBL
  // teardown, but various crud adds nodes under scriptblockers (e.g. native
  // anonymous content).  The only good news is those insertions can't trigger
  // the bad XBL cases.
  MOZ_ASSERT_IF(aReplace, aRefChild);

  EnsurePreInsertionValidity1(*aNewChild, aRefChild, aError);
  if (aError.Failed()) {
    return nullptr;

  uint16_t nodeType = aNewChild->NodeType();

  // Before we do anything else, fire all DOMNodeRemoved mutation events
  // We do this up front as to avoid having to deal with script running
  // at random places further down.
  // Scope firing mutation events so that we don't carry any state that
  // might be stale
    // This check happens again further down (though then using IndexOf).
    // We're only checking this here to avoid firing mutation events when
    // none should be fired.
    // It's ok that we do the check twice in the case when firing mutation
    // events as we need to recheck after running script anyway.
    if (aRefChild && aRefChild->GetParentNode() != this) {
      return nullptr;

    // If we're replacing, fire for node-to-be-replaced.
    // If aRefChild == aNewChild then we'll fire for it in check below
    if (aReplace && aRefChild != aNewChild) {
      nsContentUtils::MaybeFireNodeRemoved(aRefChild, this, OwnerDoc());

    // If the new node already has a parent, fire for removing from old
    // parent
    nsINode* oldParent = aNewChild->GetParentNode();
    if (oldParent) {
      nsContentUtils::MaybeFireNodeRemoved(aNewChild, oldParent,

    // If we're inserting a fragment, fire for all the children of the
    // fragment
    if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
    // Verify that our aRefChild is still sensible
    if (aRefChild && aRefChild->GetParentNode() != this) {
      return nullptr;

  EnsurePreInsertionValidity2(aReplace, *aNewChild, aRefChild, aError);

-- CREDIT ---------------------------------------

This vulnerability was discovered by:

   lokihardt working with HP's Zero Day Initiative

Comment 1

3 years ago
Mac nightly crash looks like a null deref (null aParent in nsINode::IsAllowedAsChild)


On a 32-bit Windows build it crashes on 0xffffffffe5e5e655 -- our marker for UAF.


The windows version of the stack has two extra functions. Compiler inlining? Or an actual difference?
Crash Signature: [@ IsAllowedAsChild ]

Comment 2

3 years ago
(In reply to Daniel Veditz [:dveditz] from comment #1)
> Mac nightly crash looks like a null deref (null aParent in
> nsINode::IsAllowedAsChild)
Poison values on OSX show up as null derefs on crash-stats, so it is probably also a poison crash.
Posted file asan_log.txt
Reproduced on Linux x86_64 (ASan)

Comment 4

3 years ago
The "freed by" stack in Tyson's ASan log is suspicious. We're spinning a nested event loop, and then calling FreeSnowWhite() in there. Presumably that is from the alert().

Comment 5

3 years ago
I would assume that the actual problem is happening earlier at the final release of the shared element, and the alert() is just a gadget to break the informal protection that snow white gives us. I'll try to figure out where that is happening.
Assignee: nobody → continuation

Comment 6

3 years ago
Oh, right, there's a writeup in comment 0. We just need to hold a strong reference to root in nsHTMLDocument::SetBody()...
The basic problem is that nsHTMLDocument::SetBody does:

  Element* root = GetRootElement();
  root->AppendChild(*newBody, rv);

What the testcase does is:

  doc.body = d.childNodes[0];

where "d" has a mutation listener that tries really hard to make sure that "root" is no longer referenced by anything.  In particular, it removes all the kids of "root", removes "root" from its parent, and a few other things.  It also goes ahead and adds a new <html> element to the document and tries to set its doc.body; I have no idea why.  It's also operating inside a document that used to live a in docshell that's been torn down; that probably just helps things get cced.
Midaired with comment 6, clearly.  ;)

Comment 9

3 years ago
I'll audit the code a bit but this at least keeps the test case from crashing.


3 years ago
Attachment #8720975 - Flags: review?(bzbarsky)
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.

Attachment #8720975 - Flags: review?(bzbarsky) → review+
Though a comment explaining why the strong ref is there would be nice; maybe a followup for when this bug is opened up?

Comment 13

3 years ago
[Tracking Requested - why for this release]: sec-critical with a trivial fix.
This will need sec-approval to be checked in.

Comment 15

3 years ago
Posted patch Test case. (obsolete) — Splinter Review
For landing much later after we open the bug. I also added a comment.

To make this into a Mochitest, I was able to replace this:
  document.location.href = "javascript:ShellStage.spray(); document.location.href='http://google.com';";

...with just this:

I guess the GC and CC is enough to free the element and immediately destroy it.

The good news is that this means we shouldn't have to add any extra fuzzing support to detect these kinds of SnowWhite problems.
Attachment #8721080 - Flags: review?(bzbarsky)

Comment 16

3 years ago
Test case should land later.
Flags: in-testsuite?

Comment 17

3 years ago
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.

[Security approval request comment]
How easily could an exploit be constructed based on the patch? Probably pretty easily. The problem is obvious, and this is similar to many other security issues we've seen before.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem? No more than the patch does. Code comments and test comments will be landed in a later separate patch once this bug is open or released everywhere.

Which older supported branches are affected by this flaw? All, this dates to Firefox 20.

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

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? The same patch should apply. This code is stable enough there shouldn't be much additional risk for backports.

How likely is this patch to cause regressions; how much testing does it need? Very low risk.
Attachment #8720975 - Flags: sec-approval?


3 years ago
OS: Unspecified → All
Hardware: Unspecified → All
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.


Please nominate patches for Aurora, Beta, and ESR38, especially since this is probably pretty obvious of an issue.
Attachment #8720975 - Flags: sec-approval? → sec-approval+

Comment 19

3 years ago
Comment on attachment 8721080 [details] [diff] [review]
Test case.

Well, I'll see if I can reduce the test case a little more.
Attachment #8721080 - Flags: review?(bzbarsky)

Comment 20

3 years ago
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.

[Approval Request Comment]
[Feature/regressing bug #]: bug 819239 , Firefox 20
If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-crit
User impact if declined: possible exploits
Fix Landed on Version: 37
Risk to taking this patch (and alternatives if risky): very low
String or UUID changes made by this patch: none
[Describe test coverage new/current, TreeHerder]: this code is called frequently. I added a test for this particular problem, but it can't be checked in yet.
Attachment #8720975 - Flags: approval-mozilla-esr38?
Attachment #8720975 - Flags: approval-mozilla-beta?
Attachment #8720975 - Flags: approval-mozilla-aurora?

Comment 22

3 years ago
I was able to remove the odd chunk of code that you weren't sure why it is there, in addition to (as I mentioned above) replacing the wgadget to force a GC/CC with just a call to special powers to do the same.

Obviously no hurry on the review here, but I figured I might as well put this up while it is still fresh in our minds.
Attachment #8721398 - Flags: review?(bzbarsky)


3 years ago
Attachment #8721080 - Attachment is obsolete: true
Comment on attachment 8721398 [details] [diff] [review]
Test case and comment.

Should mention that the relevant listeners would run when newBody is removed from its current parent, if any.

>+        for (var i = 0, n = html.childNodes.length; i < n; i++)
>+            html.removeChild(html.childNodes[0]);

  while (html.firstChild)

is a lot clearer, imo.

>+        html.parentNode.removeChild(html);


>+        ok(true, "GC without crashing");
>+        SimpleTest.finish();

This doesn't seem right.  The crash would happen when the body setter pressed on after firing this event, no?  So it seems like it would make more sense to finish() after the setter returns...

r=me with those fixed.
Attachment #8721398 - Flags: review?(bzbarsky) → review+
Last Resolved: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.

Fix a sec critical, taking it
Should be in 45 beta 9.
Attachment #8720975 - Flags: approval-mozilla-esr38?
Attachment #8720975 - Flags: approval-mozilla-esr38+
Attachment #8720975 - Flags: approval-mozilla-beta?
Attachment #8720975 - Flags: approval-mozilla-beta+
Carsten, Wes: Could you also land this on esr38 branch? Thanks!
Flags: needinfo?(wkocher)
Flags: needinfo?(cbook)
Looks like it was already done, just not marked: https://hg.mozilla.org/releases/mozilla-esr38/rev/e93aeb25e2a4
Flags: needinfo?(wkocher)
Flags: needinfo?(cbook)


3 years ago
Group: dom-core-security → core-security-release
Comment on attachment 8720975 [details] [diff] [review]
Hold a strong reference to |root| in nsHTMLDocument::SetBody.

We also want this in aurora!
Attachment #8720975 - Flags: approval-mozilla-aurora? → approval-mozilla-aurora+
Reproduced the issue on FX 44.0.2 Win 7.
Verified fixed 45 RC, 46.0a2 (2016-03-01), 47.0a1 (2016-02-29), 38.6.1esrpre (2016-03-01), 45esr(2016-03-01).
Whiteboard: dom-triaged btpp-fixnow → [adv-main45+][adv-esr38.7+] dom-triaged btpp-fixnow
Alias: CVE-2016-1961
Summary: nsHTMLDocument SetBody Use-After-Free RCE (ZDI-CAN-3574) → ZDI-CAN-3574: nsHTMLDocument SetBody Use-After-Free RCE
Version: unspecified → 20 Branch


3 years ago
Group: core-security-release
Component: DOM → DOM: Core & HTML
Product: Core → Core
You need to log in before you can comment on or make changes to this bug.