Closed Bug 765139 (CVE-2012-1954) Opened 12 years ago Closed 12 years ago

Heap-use-after-free in nsDocument::AdoptNode

Categories

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

x86_64
Linux
defect
Not set
critical

Tracking

()

VERIFIED FIXED
Tracking Status
firefox14 --- fixed
firefox15 --- fixed
firefox16 --- verified
firefox-esr10 14+ fixed

People

(Reporter: inferno, Assigned: smaug)

Details

(Keywords: crash, csectype-uaf, sec-critical, Whiteboard: [asan][advisory-tracking+][qa-])

Attachments

(2 files)

This bug reproduces quite frequently in my fuzzing, however there is not reliable reproduction or minimized testcase. The ASAN free and alloc stacks might be helpful in fixing the bug. I will update bug if i get a reliable repro.

20120613124512
http://hg.mozilla.org/mozilla-central/rev/00244ceddd42

=================================================================
==26295== ERROR: AddressSanitizer heap-use-after-free on address 0x7fe9741ba190 at pc 0x7fe983d5d952 bp 0x7fffbf205490 sp 0x7fffbf205488
READ of size 8 at 0x7fe9741ba190 thread T0
    #0 0x7fe983d5d952 in nsTArray_base<nsTArrayDefaultAllocator>::Length() const firefox/src/../../../dist/include/nsTArray.h:192
    #1 0x7fe984677dd2 in AdoptNodeIntoOwnerDoc(nsINode*, nsINode*) firefox/src/content/base/src/nsGenericElement.cpp:3743
    #2 0x7fe984679178 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*) firefox/src/content/base/src/nsGenericElement.cpp:4346
    #3 0x7fe984667ddc in nsINode::ReplaceOrInsertBefore(bool, nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) firefox/src/content/base/src/nsGenericElement.cpp:518
    #4 0x7fe984d5525d in DeleteElementTxn::UndoTransaction() firefox/src/editor/libeditor/base/DeleteElementTxn.cpp:159
    #5 0x7fe9855391fc in nsTransactionItem::UndoTransaction(nsTransactionManager*) firefox/src/editor/txmgr/src/nsTransactionItem.cpp:198
0x7fe9741ba190 is located 272 bytes inside of 1376-byte region [0x7fe9741ba080,0x7fe9741ba5e0)
freed by thread T0 here:
    #0 0x4244e2 in free 
    #1 0x7fe9846a1beb in nsNodeUtils::LastRelease(nsINode*) firefox/src/content/base/src/nsNodeUtils.cpp:252
    #2 0x7fe984610d22 in nsDocument::Release() firefox/src/content/base/src/nsDocument.cpp:1679
    #3 0x7fe98469c8af in nsNodeInfo::Release() firefox/src/content/base/src/nsNodeInfo.cpp:185
    #4 0x7fe984643c7a in nsNodeUtils::CloneAndAdopt(nsINode*, bool, bool, nsNodeInfoManager*, JSContext*, JSObject*, nsCOMArray<nsINode>&, nsIDOMNode**) firefox/src/../../../../dist/include/nsNodeUtils.h:272
    #5 0x7fe984628b5a in nsNodeUtils::Adopt(nsINode*, nsNodeInfoManager*, JSContext*, JSObject*, nsCOMArray<nsINode>&) firefox/src/content/base/src/nsNodeUtils.h:172
    #6 0x7fe984677dd2 in AdoptNodeIntoOwnerDoc(nsINode*, nsINode*) firefox/src/content/base/src/nsGenericElement.cpp:3743
    #7 0x7fe984679178 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*) firefox/src/content/base/src/nsGenericElement.cpp:4346
    #8 0x7fe984667ddc in nsINode::ReplaceOrInsertBefore(bool, nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) firefox/src/content/base/src/nsGenericElement.cpp:518
    #9 0x7fe984d5525d in DeleteElementTxn::UndoTransaction() firefox/src/editor/libeditor/base/DeleteElementTxn.cpp:159
    #10 0x7fe9855391fc in nsTransactionItem::UndoTransaction(nsTransactionManager*) firefox/src/editor/txmgr/src/nsTransactionItem.cpp:198
previously allocated by thread T0 here:
    #0 0x4245a2 in malloc 
    #1 0x7fe989dfe410 in moz_xmalloc firefox/src/memory/mozalloc/mozalloc.cpp:54
    #2 0x7fe9845c9f81 in nsContentUtils::CreateDocument(nsAString_internal const&, nsAString_internal const&, nsIDOMDocumentType*, nsIURI*, nsIURI*, nsIPrincipal*, nsIScriptGlobalObject*, DocumentFlavor, nsIDOMDocument**) firefox/src/content/base/src/nsContentUtils.cpp:4226
    #3 0x7fe98527552c in nsIDOMDOMImplementation_CreateDocument(JSContext*, unsigned int, JS::Value*) firefox/src/objdir-ff-asan/js/xpconnect/src/dom_quickstubs.cpp:6262
    #4 0x7fe98666809f in js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) firefox/src/js/src/jscntxtinlines.h:395
    #5 0x7fe98665e373 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) firefox/src/js/src/jsinterp.cpp:2435
    #6 0x7fe98664b168 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) firefox/src/js/src/jsinterp.cpp:267
    #7 0x7fe9866693c7 in js::ExecuteKernel(JSContext*, JSScript*, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) firefox/src/js/src/jsinterp.cpp:455
    #8 0x7fe986669721 in js::Execute(JSContext*, JSScript*, JSObject&, JS::Value*) firefox/src/js/src/jsinterp.cpp:492
    #9 0x7fe986586744 in EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, JS::Value*, JSVersion) firefox/src/js/src/jsapi.cpp:5356
    #10 0x7fe9865869e9 in JS_EvaluateUCScriptForPrincipalsVersionOrigin firefox/src/js/src/jsapi.cpp:5393
    #11 0x7fe984aa30ae in nsJSContext::EvaluateString(nsAString_internal const&, JSObject*, nsIPrincipal*, nsIPrincipal*, char const*, unsigned int, JSVersion, nsAString_internal*, bool*) firefox/src/dom/base/nsJSEnvironment.cpp:1463
    #12 0x7fe984afc51b in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) firefox/src/dom/base/nsGlobalWindow.cpp:9042
    #13 0x7fe984aedadc in nsGlobalWindow::RunTimeout(nsTimeout*) firefox/src/dom/base/nsGlobalWindow.cpp:9306
    #14 0x7fe984afb9d8 in nsGlobalWindow::TimerCallback(nsITimer*, void*) firefox/src/dom/base/nsGlobalWindow.cpp:9580
    #15 0x7fe985d542e6 in nsTimerImpl::Fire() firefox/src/xpcom/threads/nsTimerImpl.cpp:473
    #16 0x7fe985d54836 in nsTimerEvent::Run() firefox/src/xpcom/threads/nsTimerImpl.cpp:559
    #17 0x7fe985d4a914 in nsThread::ProcessNextEvent(bool, bool*) firefox/src/xpcom/threads/nsThread.cpp:624
    #18 0x7fe985cbb8fd in NS_ProcessNextEvent_P(nsIThread*, bool) firefox/src/objdir-ff-asan/xpcom/build/nsThreadUtils.cpp:216
    #19 0x7fe985acda2d in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) firefox/src/ipc/glue/MessagePump.cpp:82
    #20 0x7fe985dbb43f in MessageLoop::Run() firefox/src/ipc/chromium/src/base/message_loop.cc:176
    #21 0x7fe9858da96e in nsBaseAppShell::Run() firefox/src/widget/xpwidgets/nsBaseAppShell.cpp:165
    #22 0x7fe983d019c3 in XREMain::XRE_main(int, char**, nsXREAppData const*) firefox/src/toolkit/xre/nsAppRunner.cpp:3858
==26295== ABORTING
Stats: 204M malloced (270M for red zones) by 709938 calls
Stats: 38M realloced by 47616 calls
Stats: 171M freed by 456977 calls
Stats: 61M really freed by 86648 calls
Stats: 476M (121916 full pages) mmaped in 119 calls
  mmaps   by size class: 8:540639; 9:65528; 10:45045; 11:14329; 12:4096; 13:5120; 14:1792; 15:384; 16:768; 17:96; 18:176; 19:48; 20:16;
  mallocs by size class: 8:575429; 9:63598; 10:44465; 11:14417; 12:3815; 13:5233; 14:1576; 15:345; 16:719; 17:97; 18:183; 19:47; 20:14;
  frees   by size class: 8:346550; 9:48317; 10:40427; 11:11219; 12:2991; 13:4933; 14:1293; 15:295; 16:651; 17:78; 18:167; 19:44; 20:12;
  rfrees  by size class: 8:59414; 9:12639; 10:4862; 11:6621; 12:888; 13:574; 14:1048; 15:152; 16:347; 17:45; 18:25; 19:32; 20:1;
Stats: malloc large: 341 small slow: 3125
Shadow byte and word:
  0x1ffd2e837432: fd
  0x1ffd2e837430: fd fd fd fd fd fd fd fd
More shadow bytes:
  0x1ffd2e837410: fd fd fd fd fd fd fd fd
  0x1ffd2e837418: fd fd fd fd fd fd fd fd
  0x1ffd2e837420: fd fd fd fd fd fd fd fd
  0x1ffd2e837428: fd fd fd fd fd fd fd fd
=>0x1ffd2e837430: fd fd fd fd fd fd fd fd
  0x1ffd2e837438: fd fd fd fd fd fd fd fd
  0x1ffd2e837440: fd fd fd fd fd fd fd fd
  0x1ffd2e837448: fd fd fd fd fd fd fd fd
  0x1ffd2e837450: fd fd fd fd fd fd fd fd
Looks like a bug in AdoptNodeIntoOwnerDoc to me, assuming that the free and the use are the same call.
Component: General → DOM
Product: Firefox → Core
QA Contact: general → general
Just a fyi, some stack frames would be missing since it is an optimized build [if i had a repro, i would have used a fully symbolized build as in other bugs i usually file]. I think the use-after-free is happening in nsDocument::AdoptNode.

The raw oldDocument pointer [nsIDocument *oldDocument = adoptedNode->OwnerDoc();] is probably getting freed here
rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nsnull : mNodeInfoManager,
6114                           cx, newScope, nodesWithProperties);

and later accessed here - 6122       for (PRUint32 j = 0; j < oldDocument->GetPropertyTableCount(); ++j) {

see PRUint32 GetPropertyTableCount()
953   { return mExtraPropertyTables.Length() + 1; } 
and we crash while accessing Length(). [#0 0x7fe983d5d952 in nsTArray_base<nsTArrayDefaultAllocator>::Length() const firefox/src/../../../dist/include/nsTArray.h:192]

This is just my cursory look, someone more familiar should take a closer look :)
Summary: Heap-use-after-free in AdoptNodeIntoOwnerDoc → Heap-use-after-free in nsDocument::AdoptNode
Whiteboard: [asan]
Severity: normal → critical
Keywords: crash
speculatively marking this sec-critical
Keywords: sec-critical
Olli, could you please take a look at this?  It looks like there's a raw pointer to an OwnerDoc(), and maybe the underlying doc is going away.  You last touched that line, though it was just a rename. ;)
Assignee: nobody → bugs
Attached file Testcase
Reproducible testcase and fully symbolized stack::


=================================================================
==19471== ERROR: AddressSanitizer heap-use-after-free on address 0x7f0f7a9c8190 at pc 0x7f0fa5c9d952 bp 0x7fff2c0c9130 sp 0x7fff2c0c9128
READ of size 8 at 0x7f0f7a9c8190 thread T0
    #0 0x7f0fa5c9d952 in nsTArray_base<nsTArrayDefaultAllocator>::Length() const ../../../dist/include/nsTArray.h:192
    #1 0x7f0fa8c9dddd in nsIDocument::GetPropertyTableCount() ../../../dist/include/nsIDocument.h:953
    #2 0x7f0fa8d054fa in nsDocument::AdoptNode(nsIDOMNode*, nsIDOMNode**) content/base/src/nsDocument.cpp:6126
    #3 0x7f0fa8d0aff7 in non-virtual thunk to nsDocument::AdoptNode(nsIDOMNode*, nsIDOMNode**) modules/zlib/src/inffast.c:0
    #4 0x7f0fa8f89f5f in AdoptNodeIntoOwnerDoc(nsINode*, nsINode*) content/base/src/nsINode.cpp:1256
    #5 0x7f0fa8f8e612 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*) content/base/src/nsINode.cpp:1808
    #6 0x7f0fa8f73b2e in nsINode::ReplaceOrInsertBefore(bool, nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) content/base/src/nsINode.cpp:470
    #7 0x7f0fa8e22169 in nsGenericElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) ../../../../dist/include/nsGenericElement.h:392
    #8 0x7f0fa9e7a3f4 in nsHTMLBodyElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) content/html/content/src/nsHTMLBodyElement.cpp:68
    #9 0x7f0fa9e7ec6f in non-virtual thunk to nsHTMLBodyElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) modules/zlib/src/inffast.c:0
    #10 0x7f0fabddc9b6 in DeleteElementTxn::UndoTransaction() editor/libeditor/base/DeleteElementTxn.cpp:159
    #11 0x7f0faf02ceeb in nsTransactionItem::UndoTransaction(nsTransactionManager*) editor/txmgr/src/nsTransactionItem.cpp:198
    #12 0x7f0faf0404ec in nsTransactionManager::UndoTransaction() editor/txmgr/src/nsTransactionManager.cpp:134
    #13 0x7f0fabcb2882 in nsEditor::Undo(unsigned int) editor/libeditor/base/nsEditor.cpp:802
    #14 0x7f0fabc512c6 in nsPlaintextEditor::Undo(unsigned int) editor/libeditor/text/nsPlaintextEditor.cpp:1082
    #15 0x7f0fabd5156c in nsUndoCommand::DoCommand(char const*, nsISupports*) editor/libeditor/base/nsEditorCommands.cpp:57
    #16 0x7f0faeec79bd in nsControllerCommandTable::DoCommand(char const*, nsISupports*) embedding/components/commandhandler/src/nsControllerCommandTable.cpp:158
    #17 0x7f0faee9a2c4 in nsBaseCommandController::DoCommand(char const*) embedding/components/commandhandler/src/nsBaseCommandController.cpp:137
    #18 0x7f0faeeb2701 in nsCommandManager::DoCommand(char const*, nsICommandParams*, nsIDOMWindow*) embedding/components/commandhandler/src/nsCommandManager.cpp:239
    #19 0x7f0faa64073e in nsHTMLDocument::ExecCommand(nsAString_internal const&, bool, nsAString_internal const&, bool*) content/html/document/src/nsHTMLDocument.cpp:3193
    #20 0x7f0faa642fae in non-virtual thunk to nsHTMLDocument::ExecCommand(nsAString_internal const&, bool, nsAString_internal const&, bool*) modules/zlib/src/inffast.c:0
    #21 0x7f0fb222755a in NS_InvokeByIndex_P xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
    #22 0x7f0fadb9521b in CallMethodHelper::Call() js/xpconnect/src/XPCWrappedNative.cpp:2405
    #23 0x7f0fadbfc5f4 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1474
    #24 0x7f0fb754b53d in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), js::CallArgs const&) js/src/jscntxtinlines.h:400
    #25 0x7f0fb74bf71d in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) js/src/jsinterp.cpp:2437
    #26 0x7f0fb7444ef7 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) js/src/jsinterp.cpp:267
    #27 0x7f0fb755834d in js::ExecuteKernel(JSContext*, JSScript*, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) js/src/jsinterp.cpp:455
    #28 0x7f0fb755a050 in js::Execute(JSContext*, JSScript*, JSObject&, JS::Value*) js/src/jsinterp.cpp:492
    #29 0x7f0fb6d89ba6 in EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, JS::Value*, JSVersion) js/src/jsapi.cpp:5371
    #30 0x7f0fb6d8bacc in JS_EvaluateUCScriptForPrincipalsVersionOrigin js/src/jsapi.cpp:5408
    #31 0x7f0faadedcba in nsJSContext::EvaluateString(nsAString_internal const&, JSObject*, nsIPrincipal*, nsIPrincipal*, char const*, unsigned int, JSVersion, nsAString_internal*, bool*) dom/base/nsJSEnvironment.cpp:1463
    #32 0x7f0faaf9012e in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) dom/base/nsGlobalWindow.cpp:9057
    #33 0x7f0faaf50212 in nsGlobalWindow::RunTimeout(nsTimeout*) dom/base/nsGlobalWindow.cpp:9321
    #34 0x7f0faaf8e33b in nsGlobalWindow::TimerCallback(nsITimer*, void*) dom/base/nsGlobalWindow.cpp:9593
    #35 0x7f0fb2163fc2 in nsTimerImpl::Fire() xpcom/threads/nsTimerImpl.cpp:474
    #36 0x7f0fb2165bfc in nsTimerEvent::Run() xpcom/threads/nsTimerImpl.cpp:558
    #37 0x7f0fb21282b3 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:625
    #38 0x7f0fb1db855d in NS_ProcessNextEvent_P(nsIThread*, bool) objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #39 0x7f0fb0f15ff6 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:82
    #40 0x7f0fb23da88a in MessageLoop::RunInternal() ipc/chromium/src/base/message_loop.cc:209
    #41 0x7f0fb23da6d3 in MessageLoop::RunHandler() ipc/chromium/src/base/message_loop.cc:202
    #42 0x7f0fb23da5b8 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:176
    #43 0x7f0fb045391e in nsBaseAppShell::Run() widget/xpwidgets/nsBaseAppShell.cpp:165
    #44 0x7f0faf09d518 in nsAppStartup::Run() toolkit/components/startup/nsAppStartup.cpp:256
    #45 0x7f0fa5a8f6d7 in XREMain::XRE_mainRun() toolkit/xre/nsAppRunner.cpp:3786
    #46 0x7f0fa5a96092 in XREMain::XRE_main(int, char**, nsXREAppData const*) toolkit/xre/nsAppRunner.cpp:3863
    #47 0x7f0fa5a9954b in XRE_main toolkit/xre/nsAppRunner.cpp:3939
    #48 0x40a91f in do_main(int, char**) browser/app/nsBrowserApp.cpp:160
    #49 0x40834d in main browser/app/nsBrowserApp.cpp:330
    #50 0x7f0fc02dbc4d in ?? ??:0
0x7f0f7a9c8190 is located 272 bytes inside of 1376-byte region [0x7f0f7a9c8080,0x7f0f7a9c85e0)
freed by thread T0 here:
    #0 0x4a2ed2 in free ??:0
    #1 0x7f0fbd1695c3 in moz_free memory/mozalloc/mozalloc.cpp:49
    #2 0x7f0fa8c891c2 in nsIDocument::operator delete(void*) ../../../../dist/include/nsIDocument.h:125
    #3 0x7f0faa6f8d18 in ~nsXMLDocument content/xml/document/src/nsXMLDocument.cpp:226
    #4 0x7f0fa9022b5d in nsNodeUtils::LastRelease(nsINode*) content/base/src/nsNodeUtils.cpp:252
    #5 0x7f0fa8c97fdf in nsDocument::Release() content/base/src/nsDocument.cpp:1678
    #6 0x7f0faa6fa814 in nsXMLDocument::Release() content/xml/document/src/nsXMLDocument.cpp:241
    #7 0x7f0fa901192f in nsNodeInfoManager::RemoveNodeInfo(nsNodeInfo*) content/base/src/nsNodeInfoManager.cpp:387
    #8 0x7f0fa90021ff in ~nsNodeInfo content/base/src/nsNodeInfo.cpp:74
    #9 0x7f0fa900559d in nsNodeInfo::LastRelease() content/base/src/nsNodeInfo.cpp:236
    #10 0x7f0fa900519c in nsNodeInfo::Release() content/base/src/nsNodeInfo.cpp:185
    #11 0x7f0fb1d6ee10 in ~nsCOMPtr_base objdir-ff-asan-sym/xpcom/build/nsCOMPtr.cpp:48
    #12 0x7f0fa6f61706 in ~nsCOMPtr ../../../dist/include/nsCOMPtr.h:442
    #13 0x7f0fa6f615f3 in ~nsCOMPtr ../../../dist/include/nsCOMPtr.h:442
    #14 0x7f0fa902a7ee in nsNodeUtils::CloneAndAdopt(nsINode*, bool, bool, nsNodeInfoManager*, JSContext*, JSObject*, nsCOMArray<nsINode>&, nsINode*, nsINode**) content/base/src/nsNodeUtils.cpp:597
    #15 0x7f0fa8dcdfaa in nsNodeUtils::CloneAndAdopt(nsINode*, bool, bool, nsNodeInfoManager*, JSContext*, JSObject*, nsCOMArray<nsINode>&, nsIDOMNode**) ../../../../dist/include/nsNodeUtils.h:272
    #16 0x7f0fa8d09fb9 in nsNodeUtils::Adopt(nsINode*, nsNodeInfoManager*, JSContext*, JSObject*, nsCOMArray<nsINode>&) content/base/src/nsNodeUtils.h:172
    #17 0x7f0fa8d04e91 in nsDocument::AdoptNode(nsIDOMNode*, nsIDOMNode**) content/base/src/nsDocument.cpp:6103
    #18 0x7f0fa8d0aff7 in non-virtual thunk to nsDocument::AdoptNode(nsIDOMNode*, nsIDOMNode**) modules/zlib/src/inffast.c:0
    #19 0x7f0fa8f89f5f in AdoptNodeIntoOwnerDoc(nsINode*, nsINode*) content/base/src/nsINode.cpp:1256
    #20 0x7f0fa8f8e612 in nsINode::ReplaceOrInsertBefore(bool, nsINode*, nsINode*) content/base/src/nsINode.cpp:1808
    #21 0x7f0fa8f73b2e in nsINode::ReplaceOrInsertBefore(bool, nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) content/base/src/nsINode.cpp:470
    #22 0x7f0fa8e22169 in nsGenericElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) ../../../../dist/include/nsGenericElement.h:392
    #23 0x7f0fa9e7a3f4 in nsHTMLBodyElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) content/html/content/src/nsHTMLBodyElement.cpp:68
    #24 0x7f0fa9e7ec6f in non-virtual thunk to nsHTMLBodyElement::InsertBefore(nsIDOMNode*, nsIDOMNode*, nsIDOMNode**) modules/zlib/src/inffast.c:0
    #25 0x7f0fabddc9b6 in DeleteElementTxn::UndoTransaction() editor/libeditor/base/DeleteElementTxn.cpp:159
    #26 0x7f0faf02ceeb in nsTransactionItem::UndoTransaction(nsTransactionManager*) editor/txmgr/src/nsTransactionItem.cpp:198
    #27 0x7f0faf0404ec in nsTransactionManager::UndoTransaction() editor/txmgr/src/nsTransactionManager.cpp:134
    #28 0x7f0fabcb2882 in nsEditor::Undo(unsigned int) editor/libeditor/base/nsEditor.cpp:802
    #29 0x7f0fabc512c6 in nsPlaintextEditor::Undo(unsigned int) editor/libeditor/text/nsPlaintextEditor.cpp:1082
previously allocated by thread T0 here:
    #0 0x4a2f92 in malloc ??:0
    #1 0x7f0fbd169717 in moz_xmalloc memory/mozalloc/mozalloc.cpp:54
    #2 0x7f0faa5fa30a in nsIDocument::operator new(unsigned long) ../../../../dist/include/nsIDocument.h:125
    #3 0x7f0faa6f70e7 in NS_NewXMLDocument(nsIDocument**) content/xml/document/src/nsXMLDocument.cpp:174
    #4 0x7f0faa6f4186 in NS_NewDOMDocument(nsIDOMDocument**, nsAString_internal const&, nsAString_internal const&, nsIDOMDocumentType*, nsIURI*, nsIURI*, nsIPrincipal*, bool, nsIScriptGlobalObject*, DocumentFlavor) content/xml/document/src/nsXMLDocument.cpp:120
    #5 0x7f0fa8ae543b in nsContentUtils::CreateDocument(nsAString_internal const&, nsAString_internal const&, nsIDOMDocumentType*, nsIURI*, nsIURI*, nsIPrincipal*, nsIScriptGlobalObject*, DocumentFlavor, nsIDOMDocument**) content/base/src/nsContentUtils.cpp:4228
    #6 0x7f0fa8c80937 in nsDOMImplementation::CreateDocument(nsAString_internal const&, nsAString_internal const&, nsIDOMDocumentType*, nsIDOMDocument**) content/base/src/nsDocument.cpp:1400
    #7 0x7f0fadd4c7d1 in nsIDOMDOMImplementation_CreateDocument(JSContext*, unsigned int, JS::Value*) objdir-ff-asan-sym/js/xpconnect/src/dom_quickstubs.cpp:6262
    #8 0x7f0fb754b53d in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), js::CallArgs const&) js/src/jscntxtinlines.h:400
    #9 0x7f0fb74bf71d in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) js/src/jsinterp.cpp:2437
    #10 0x7f0fb7444ef7 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) js/src/jsinterp.cpp:267
    #11 0x7f0fb755834d in js::ExecuteKernel(JSContext*, JSScript*, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) js/src/jsinterp.cpp:455
    #12 0x7f0fb755a050 in js::Execute(JSContext*, JSScript*, JSObject&, JS::Value*) js/src/jsinterp.cpp:492
    #13 0x7f0fb6d89ba6 in EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, JS::Value*, JSVersion) js/src/jsapi.cpp:5371
    #14 0x7f0fb6d8bacc in JS_EvaluateUCScriptForPrincipalsVersionOrigin js/src/jsapi.cpp:5408
    #15 0x7f0faadedcba in nsJSContext::EvaluateString(nsAString_internal const&, JSObject*, nsIPrincipal*, nsIPrincipal*, char const*, unsigned int, JSVersion, nsAString_internal*, bool*) dom/base/nsJSEnvironment.cpp:1463
    #16 0x7f0faaf9012e in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) dom/base/nsGlobalWindow.cpp:9057
    #17 0x7f0faaf50212 in nsGlobalWindow::RunTimeout(nsTimeout*) dom/base/nsGlobalWindow.cpp:9321
    #18 0x7f0faaf8e33b in nsGlobalWindow::TimerCallback(nsITimer*, void*) dom/base/nsGlobalWindow.cpp:9593
    #19 0x7f0fb2163fc2 in nsTimerImpl::Fire() xpcom/threads/nsTimerImpl.cpp:474
    #20 0x7f0fb2165bfc in nsTimerEvent::Run() xpcom/threads/nsTimerImpl.cpp:558
    #21 0x7f0fb21282b3 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:625
    #22 0x7f0fb1db855d in NS_ProcessNextEvent_P(nsIThread*, bool) objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
==19471== ABORTING
Stats: 161M malloced (195M for red zones) by 477865 calls
Stats: 42M realloced by 21082 calls
Stats: 133M freed by 253158 calls
Stats: 4M really freed by 26640 calls
Stats: 384M (98355 full pages) mmaped in 96 calls
  mmaps   by size class: 8:393192; 9:57337; 10:20475; 11:18423; 12:3072; 13:2560; 14:1536; 15:384; 16:576; 17:128; 18:176; 19:48; 20:16;
  mallocs by size class: 8:386642; 9:48905; 10:17303; 11:17596; 12:2614; 13:2059; 14:1468; 15:368; 16:564; 17:120; 18:172; 19:41; 20:13;
  frees   by size class: 8:179728; 9:38690; 10:14192; 11:14505; 12:1788; 13:1848; 14:1286; 15:315; 16:494; 17:105; 18:159; 19:38; 20:10;
  rfrees  by size class: 8:24250; 9:1147; 10:583; 11:312; 12:57; 13:183; 14:90; 15:9; 16:6; 17:3;
Stats: malloc large: 346 small slow: 2155
Shadow byte and word:
  0x1fe1ef539032: fd
  0x1fe1ef539030: fd fd fd fd fd fd fd fd
More shadow bytes:
  0x1fe1ef539010: fd fd fd fd fd fd fd fd
  0x1fe1ef539018: fd fd fd fd fd fd fd fd
  0x1fe1ef539020: fd fd fd fd fd fd fd fd
  0x1fe1ef539028: fd fd fd fd fd fd fd fd
=>0x1fe1ef539030: fd fd fd fd fd fd fd fd
  0x1fe1ef539038: fd fd fd fd fd fd fd fd
  0x1fe1ef539040: fd fd fd fd fd fd fd fd
  0x1fe1ef539048: fd fd fd fd fd fd fd fd
  0x1fe1ef539050: fd fd fd fd fd fd fd fd
(In reply to Abhishek Arya from comment #5)
> Created attachment 636186 [details]
> Testcase
> 
> Reproducible testcase and fully symbolized stack::


Doesn't work here :(
(In reply to Olli Pettay [:smaug] from comment #6)
> (In reply to Abhishek Arya from comment #5)
> > Created attachment 636186 [details]
> > Testcase
> > 
> > Reproducible testcase and fully symbolized stack::
> 
> 
> Doesn't work here :(

Did you try with an ASANified release build from https://people.mozilla.com/~choller/firefox/asan/ ? It reproduces for me on multiple machines. Also, the new symbolized stack seems to match my analysis in c#2.
No. Never heard of ASANified builds before :)
Anyhow, I'll post a patch soon.
(In reply to Olli Pettay [:smaug] from comment #8)
> No. Never heard of ASANified builds before :)

Some context :)

http://blog.chromium.org/2012/04/fuzzing-for-security.html
http://blog.chromium.org/2011/06/testing-chromium-addresssanitizer-fast.html
http://blog.mozilla.org/decoder/2012/01/27/trying-new-code-analysis-techniques/

> Anyhow, I'll post a patch soon.
Attached patch possible patchSplinter Review
Based on the comments here, and looking at the code, this might work.
But since I can't reproduce, can't be sure.
Could anyone, who can reproduce the problem, try this.
Ok, I can see the crash using Nightly ASAN build. Unfortunately it doesn't crash when
run in gdb.
And looks like I managed to reproduce the crash only once.
Attachment #636260 - Flags: review?(peterv)
(In reply to Olli Pettay [:smaug] from comment #10)
> Created attachment 636260 [details] [diff] [review]
> possible patch
> 
> Based on the comments here, and looking at the code, this might work.
> But since I can't reproduce, can't be sure.
> Could anyone, who can reproduce the problem, try this.

Yes, your patch fixes the UAF crash.
Do you know what versions this affects?
Comment on attachment 636260 [details] [diff] [review]
possible patch

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

So I guess what happens is that we adopt into an empty document and then adopt into another document, so the first document becomes empty again and it's destroyed during the second adopt? It's a bit scary to fix this without really understanding what happens :-(.
Attachment #636260 - Flags: review?(peterv) → review+
Comment on attachment 636260 [details] [diff] [review]
possible patch

[Approval Request Comment]
Regression caused by (bug #): NA
User impact if declined: crash
Testing completed (on m-c, etc.): Hasn't landed yet 
Risk to taking this patch (and alternatives if risky): Should be super safe
Attachment #636260 - Flags: approval-mozilla-release?
Attachment #636260 - Flags: approval-mozilla-esr10?
Attachment #636260 - Flags: approval-mozilla-beta?
Comment on attachment 636260 [details] [diff] [review]
possible patch

a=dveditz for all the branches. The problem is pretty obvious from the patch, and if it's popping out of fuzzing often then it's got a reasonable chance of being rediscovered in the next 6 weeks.
Attachment #636260 - Flags: approval-mozilla-release?
Attachment #636260 - Flags: approval-mozilla-release+
Attachment #636260 - Flags: approval-mozilla-esr10?
Attachment #636260 - Flags: approval-mozilla-esr10+
Attachment #636260 - Flags: approval-mozilla-beta?
Attachment #636260 - Flags: approval-mozilla-beta+
https://hg.mozilla.org/mozilla-central/rev/5b77d71ed927
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Whiteboard: [asan] → [asan][advisory-tracking+]
I'm unable to reproduce this crash using the attached testcase and an ASAN debug Nightly based off mozilla-central 2012-07-08. Unless a more reproducible testcase can be provided, I'm not sure QA will be able to verify this bug is fixed. Can anyone provide any insight or assistance in verify this fix?
Whiteboard: [asan][advisory-tracking+] → [asan][advisory-tracking+][qa?]
I remember testing this fix (c#13) and the testcase was 100% reproducible for me.
(In reply to Abhishek Arya from comment #22)
> I remember testing this fix (c#13) and the testcase was 100% reproducible
> for me.

It's 0% reproducible for me. Would you mind verifying if this is fixed with a latest Nightly build?
Alias: CVE-2012-1954
(In reply to Anthony Hughes, Mozilla QA (irc: ashughes) from comment #23)
> (In reply to Abhishek Arya from comment #22)
> > I remember testing this fix (c#13) and the testcase was 100% reproducible
> > for me.
> 
> It's 0% reproducible for me. Would you mind verifying if this is fixed with
> a latest Nightly build?

Verified.
Crashes on 46362775ce79 (opt), built on 20120630
Does not crash on d070bd19c526 (opt), built on 20120711

Used builds from https://people.mozilla.com/~choller/firefox/asan/
Thanks! Marking this verified against Nightly. We won't be able to verify this against Beta/Release/ESR due to technical constraints.
Status: RESOLVED → VERIFIED
Whiteboard: [asan][advisory-tracking+][qa?] → [asan][advisory-tracking+][qa-]
Group: core-security
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: