Last Comment Bug 777578 - (CVE-2012-1975) Heap-use-after-free in PresShell::CompleteMove
(CVE-2012-1975)
: Heap-use-after-free in PresShell::CompleteMove
Status: RESOLVED FIXED
[asan][advisory-tracking+][qa?]
: crash, sec-critical, testcase
Product: Core
Classification: Components
Component: Selection (show other bugs)
: Trunk
: All All
: -- critical (vote)
: mozilla17
Assigned To: Mats Palmgren (:mats)
: Anthony Hughes (:ashughes) [GFX][QA][Mentor]
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-07-25 17:04 PDT by Abhishek Arya
Modified: 2014-07-24 13:43 PDT (History)
9 users (show)
rforbes: sec‑bounty+
mats: in‑testsuite?
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
wontfix
+
fixed
+
fixed
15+
fixed


Attachments
Testcase (762 bytes, text/html)
2012-07-25 17:04 PDT, Abhishek Arya
no flags Details
hack (4.70 KB, patch)
2012-07-26 09:04 PDT, Mats Palmgren (:mats)
no flags Details | Diff | Review
crash fix (3.78 KB, patch)
2012-07-26 10:47 PDT, Mats Palmgren (:mats)
bugs: review+
akeybl: approval‑mozilla‑aurora+
akeybl: approval‑mozilla‑beta+
akeybl: approval‑mozilla‑esr10+
Details | Diff | Review

Description Abhishek Arya 2012-07-25 17:04:07 PDT
Created attachment 645954 [details]
Testcase

Reproduces on trunk

=================================================================
==11961== ERROR: AddressSanitizer heap-use-after-free on address 0x7f13daaa3bac at pc 0x7f14059ca41d bp 0x7fffba074190 sp 0x7fffba074188
READ of size 4 at 0x7f13daaa3bac thread T0
    #0 0x7f14059ca41d in nsINode::GetBoolFlag(nsINode::BooleanFlag) const src/../../dist/include/nsINode.h:1315
    #1 0x7f14059ca188 in nsINode::IsInDoc() const src/../../dist/include/nsINode.h:449
    #2 0x7f14059bc9fe in nsIContent::GetPrimaryFrame() const src/../../dist/include/nsIContent.h:821
    #3 0x7f14061b2266 in PresShell::CompleteMove(bool, bool) src/layout/base/nsPresShell.cpp:2203
    #4 0x7f14061b2e4d in non-virtual thunk to PresShell::CompleteMove(bool, bool) asn1cmn.c:0
    #5 0x7f14068c696d in mozilla::Selection::Modify(nsAString_internal const&, nsAString_internal const&, nsAString_internal const&) src/layout/generic/nsSelection.cpp:5528
    #6 0x7f14113844ca in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
    #7 0x7f140c9906eb in CallMethodHelper::Call() src/js/xpconnect/src/XPCWrappedNative.cpp:2416
    #8 0x7f140c9f7a74 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1474
    #9 0x7f1417f21cc7 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:382
    #10 0x7f1417e959a1 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2424
    #11 0x7f1417e15ae5 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:302
    #12 0x7f1417f2eac6 in js::ExecuteKernel(JSContext*, JSScript*, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:488
    #13 0x7f1417f307c0 in js::Execute(JSContext*, JSScript*, JSObject&, JS::Value*) src/js/src/jsinterp.cpp:525
    #14 0x7f14176e97ec in EvaluateUCScriptForPrincipalsCommon(JSContext*, JSObject*, JSPrincipals*, JSPrincipals*, unsigned short const*, unsigned int, char const*, unsigned int, JS::Value*, JSVersion) src/js/src/jsapi.cpp:5439
    #15 0x7f14176eb6ac in JS_EvaluateUCScriptForPrincipalsVersionOrigin src/js/src/jsapi.cpp:5476
    #16 0x7f1409b568ff in nsJSContext::EvaluateString(nsAString_internal const&, JSObject*, nsIPrincipal*, nsIPrincipal*, char const*, unsigned int, JSVersion, nsAString_internal*, bool*) src/dom/base/nsJSEnvironment.cpp:1487
    #17 0x7f1409d0a81e in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) src/dom/base/nsGlobalWindow.cpp:9542
    #18 0x7f1409cc0e52 in nsGlobalWindow::RunTimeout(nsTimeout*) src/dom/base/nsGlobalWindow.cpp:9803
    #19 0x7f1409d08a2b in nsGlobalWindow::TimerCallback(nsITimer*, void*) src/dom/base/nsGlobalWindow.cpp:10071
    #20 0x7f14112c0f92 in nsTimerImpl::Fire() src/xpcom/threads/nsTimerImpl.cpp:474
    #21 0x7f14112c2bcc in nsTimerEvent::Run() src/xpcom/threads/nsTimerImpl.cpp:558
    #22 0x7f14112851fd in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:625
    #23 0x7f1410f13fad in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #24 0x7f140feae88b in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:117
    #25 0x7f141153749a in MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:209
    #26 0x7f14115372e3 in MessageLoop::RunHandler() src/ipc/chromium/src/base/message_loop.cc:202
    #27 0x7f14115371c8 in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:176
    #28 0x7f140f3b407e in nsBaseAppShell::Run() src/widget/xpwidgets/nsBaseAppShell.cpp:165
    #29 0x7f140e003158 in nsAppStartup::Run() src/toolkit/components/startup/nsAppStartup.cpp:271
    #30 0x7f140474fae0 in XREMain::XRE_mainRun() src/toolkit/xre/nsAppRunner.cpp:3798
    #31 0x7f1404756482 in XREMain::XRE_main(int, char**, nsXREAppData const*) src/toolkit/xre/nsAppRunner.cpp:3875
    #32 0x7f1404759952 in XRE_main src/toolkit/xre/nsAppRunner.cpp:3951
    #33 0x40c28f in do_main(int, char**) src/browser/app/nsBrowserApp.cpp:174
    #34 0x409cbd in main src/browser/app/nsBrowserApp.cpp:312
    #35 0x7f1421421c4d in ?? ??:0
0x7f13daaa3bac is located 44 bytes inside of 128-byte region [0x7f13daaa3b80,0x7f13daaa3c00)
freed by thread T0 here:
    #0 0x4a4392 in free ??:0
    #1 0x7f141e2ad5c3 in moz_free src/memory/mozalloc/mozalloc.cpp:49
    #2 0x7f1408b98586 in ~nsHTMLBodyElement src/content/html/content/src/nsHTMLBodyElement.cpp:279
    #3 0x7f1407d79ffd in nsNodeUtils::LastRelease(nsINode*) src/content/base/src/nsNodeUtils.cpp:252
    #4 0x7f1407c50acf in nsGenericElement::Release() src/content/base/src/nsGenericElement.cpp:3509
    #5 0x7f1408b98c94 in nsHTMLBodyElement::Release() src/content/html/content/src/nsHTMLBodyElement.cpp:283
    #6 0x7f140c8482a9 in _ZL17DoDeferredReleaseIP11nsISupportsEvR8nsTArrayIT_24nsTArrayDefaultAllocatorE src/js/xpconnect/src/XPCJSRuntime.cpp:563
    #7 0x7f140c847ac9 in XPCJSRuntime::GCCallback(JSRuntime*, JSGCStatus) src/js/xpconnect/src/XPCJSRuntime.cpp:598
    #8 0x7f1417c42e07 in Collect(JSRuntime*, bool, long, js::JSGCInvocationKind, js::gcreason::Reason) src/js/src/jsgc.cpp:4016
    #9 0x7f1417c38e35 in js::GCSlice(JSRuntime*, js::JSGCInvocationKind, js::gcreason::Reason) src/js/src/jsgc.cpp:4044
    #10 0x7f1417b940db in js::IncrementalGC(JSRuntime*, js::gcreason::Reason) src/js/src/jsfriendapi.cpp:168
    #11 0x7f1409b3dca3 in nsJSContext::GarbageCollectNow(js::gcreason::Reason, nsJSContext::IsIncremental, nsJSContext::IsCompartment, nsJSContext::IsShrinking) src/dom/base/nsJSEnvironment.cpp:2918
    #12 0x7f1409b8305e in GCTimerFired(nsITimer*, void*) src/dom/base/nsJSEnvironment.cpp:3214
    #13 0x7f14112c0f92 in nsTimerImpl::Fire() src/xpcom/threads/nsTimerImpl.cpp:474
    #14 0x7f14112c2bcc in nsTimerEvent::Run() src/xpcom/threads/nsTimerImpl.cpp:558
    #15 0x7f14112851fd in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:625
    #16 0x7f1410f13fad in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #17 0x7f140feae88b in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:117
    #18 0x7f141153749a in MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:209
    #19 0x7f14115372e3 in MessageLoop::RunHandler() src/ipc/chromium/src/base/message_loop.cc:202
    #20 0x7f14115371c8 in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:176
    #21 0x7f140f3b407e in nsBaseAppShell::Run() src/widget/xpwidgets/nsBaseAppShell.cpp:165
    #22 0x7f140e003158 in nsAppStartup::Run() src/toolkit/components/startup/nsAppStartup.cpp:271
    #23 0x7f140474fae0 in XREMain::XRE_mainRun() src/toolkit/xre/nsAppRunner.cpp:3798
    #24 0x7f1404756482 in XREMain::XRE_main(int, char**, nsXREAppData const*) src/toolkit/xre/nsAppRunner.cpp:3875
    #25 0x7f1404759952 in XRE_main src/toolkit/xre/nsAppRunner.cpp:3951
    #26 0x40c28f in do_main(int, char**) src/browser/app/nsBrowserApp.cpp:174
    #27 0x409cbd in main src/browser/app/nsBrowserApp.cpp:312
    #28 0x7f1421421c4d in ?? ??:0
previously allocated by thread T0 here:
    #0 0x4a4452 in __interceptor_malloc ??:0
    #1 0x7f141e2ad717 in moz_xmalloc src/memory/mozalloc/mozalloc.cpp:54
    #2 0x7f1408b97b79 in NS_NewHTMLBodyElement(already_AddRefed<nsINodeInfo>, mozilla::dom::FromParser) src/content/html/content/src/nsHTMLBodyElement.cpp:264
    #3 0x7f140932b2ee in CreateHTMLElement(unsigned int, already_AddRefed<nsINodeInfo>, mozilla::dom::FromParser) src/content/html/document/src/nsHTMLContentSink.cpp:497
    #4 0x7f140932bbb0 in NS_NewHTMLElement(nsIContent**, already_AddRefed<nsINodeInfo>, mozilla::dom::FromParser) src/content/html/document/src/nsHTMLContentSink.cpp:480
    #5 0x7f1407d4b5f8 in NS_NewElement(nsIContent**, already_AddRefed<nsINodeInfo>, mozilla::dom::FromParser) src/content/base/src/nsNameSpaceManager.cpp:201
    #6 0x7f1407a2b8bd in nsDocument::CreateElementNS(nsAString_internal const&, nsAString_internal const&, nsIContent**) src/content/base/src/nsDocument.cpp:4410
    #7 0x7f140caf1c8c in nsIDOMDocument_CreateElementNS(JSContext*, unsigned int, JS::Value*) src/objdir-ff-asan-sym/js/xpconnect/src/dom_quickstubs.cpp:3242
    #8 0x7f1417f21cc7 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:382
    #9 0x7f1417e959a1 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2424
    #10 0x7f1417e15ae5 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:302
    #11 0x7f1417f220e9 in js::InvokeKernel(JSContext*, JS::CallArgs, js::MaybeConstruct) src/js/src/jsinterp.cpp:356
    #12 0x7f141784a890 in js::Invoke(JSContext*, js::InvokeArgsGuard&, js::MaybeConstruct) src/js/src/jsinterp.h:119
    #13 0x7f1417f2724d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) src/js/src/jsinterp.cpp:388
    #14 0x7f14176f2a49 in JS_CallFunctionValue src/js/src/jsapi.cpp:5569
    #15 0x7f1409b63b15 in nsJSContext::CallEventHandler(nsISupports*, JSObject*, JSObject*, nsIArray*, nsIVariant**) src/dom/base/nsJSEnvironment.cpp:1907
    #16 0x7f140a309606 in nsJSEventListener::HandleEvent(nsIDOMEvent*) src/dom/src/events/nsJSEventListener.cpp:188
    #17 0x7f140878b7b3 in nsEventListenerManager::HandleEventSubType(nsListenerStruct*, nsIDOMEventListener*, nsIDOMEvent*, nsIDOMEventTarget*, unsigned int, nsCxPusher*) src/content/events/src/nsEventListenerManager.cpp:794
    #18 0x7f140878cc7a in nsEventListenerManager::HandleEventInternal(nsPresContext*, nsEvent*, nsIDOMEvent**, nsIDOMEventTarget*, unsigned int, nsEventStatus*, nsCxPusher*) src/content/events/src/nsEventListenerManager.cpp:867
    #19 0x7f1408928b67 in nsEventListenerManager::HandleEvent(nsPresContext*, nsEvent*, nsIDOMEvent**, nsIDOMEventTarget*, unsigned int, nsEventStatus*, nsCxPusher*) src/content/events/src/nsEventListenerManager.h:144
    #20 0x7f1408917806 in nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor&, unsigned int, bool, nsCxPusher*) src/content/events/src/nsEventDispatcher.cpp:184
    #21 0x7f140891536c in nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor&, unsigned int, nsDispatchingCallback*, bool, nsCxPusher*) src/content/events/src/nsEventDispatcher.cpp:312
    #22 0x7f140891ae80 in nsEventDispatcher::Dispatch(nsISupports*, nsPresContext*, nsEvent*, nsIDOMEvent*, nsEventStatus*, nsDispatchingCallback*, nsCOMArray<nsIDOMEventTarget>*) src/content/events/src/nsEventDispatcher.cpp:633
    #23 0x7f1405fd5dbf in DocumentViewerImpl::LoadComplete(unsigned int) src/layout/base/nsDocumentViewer.cpp:1017
    #24 0x7f140da6f3a8 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, unsigned int) src/docshell/base/nsDocShell.cpp:6300
==11961== ABORTING
Stats: 261M malloced (268M for red zones) by 547279 calls
Stats: 87M realloced by 38827 calls
Stats: 230M freed by 421350 calls
Stats: 99M really freed by 214956 calls
Stats: 444M (113737 full pages) mmaped in 111 calls
  mmaps   by size class: 8:294894; 9:57337; 10:20475; 11:16376; 12:4096; 13:3584; 14:1536; 15:384; 16:512; 17:128; 18:272; 19:112; 20:40;
  mallocs by size class: 8:425683; 9:65265; 10:24573; 11:20475; 12:3931; 13:3838; 14:1797; 15:448; 16:637; 17:146; 18:323; 19:118; 20:45;
  frees   by size class: 8:315274; 9:56823; 10:21534; 11:17730; 12:3193; 13:3642; 14:1616; 15:395; 16:575; 17:120; 18:298; 19:109; 20:41;
  rfrees  by size class: 8:164321; 9:27420; 10:9917; 11:10072; 12:968; 13:626; 14:933; 15:164; 16:340; 17:69; 18:56; 19:47; 20:23;
Stats: malloc large: 632 small slow: 2649
Shadow byte and word:
  0x1fe27b554775: fd
  0x1fe27b554770: fd fd fd fd fd fd fd fd
More shadow bytes:
  0x1fe27b554750: fd fd fd fd fd fd fd fd
  0x1fe27b554758: fd fd fd fd fd fd fd fd
  0x1fe27b554760: fa fa fa fa fa fa fa fa
  0x1fe27b554768: fa fa fa fa fa fa fa fa
=>0x1fe27b554770: fd fd fd fd fd fd fd fd
  0x1fe27b554778: fd fd fd fd fd fd fd fd
  0x1fe27b554780: fa fa fa fa fa fa fa fa
  0x1fe27b554788: fa fa fa fa fa fa fa fa
  0x1fe27b554790: fd fd fd fd fd fd fd fd
Comment 1 Olli Pettay [:smaug] 2012-07-26 08:35:23 PDT
I think this is an old regression from bug 237964.
Comment 2 Olli Pettay [:smaug] 2012-07-26 08:47:16 PDT
Though, I can't reproduce in any easy way. But the code sure is scary looking.
Comment 3 Mats Palmgren (:mats) 2012-07-26 09:01:08 PDT
We're using a deleted nsINode and its nsIFrame - possibly exploitable.
It's the raw pointer nsFrameSelection::mAncestorLimiter that becomes stale.
Comment 4 Mats Palmgren (:mats) 2012-07-26 09:04:45 PDT
Created attachment 646163 [details] [diff] [review]
hack

This patch seems to fix it in my Linux64 ASAN build.
Perhaps editor should update these pointers though, not the shell.
Comment 5 :Ehsan Akhgari (busy, don't ask for review please) 2012-07-26 09:05:07 PDT
Hmm, that is retarded.  mAncestorLimiter should be a strong reference (an nsCOMPtr/nsRefPtr).
Comment 6 :Ehsan Akhgari (busy, don't ask for review please) 2012-07-26 09:07:12 PDT
(In reply to Mats Palmgren [:mats] from comment #4)
> Created attachment 646163 [details] [diff] [review]
> hack
> 
> This patch seems to fix it in my Linux64 ASAN build.
> Perhaps editor should update these pointers though, not the shell.

I'm not entirely sure what the implications of removing the ancestor pointers in ContentRemoved is.  Can you please post this to the try server?
Comment 7 Olli Pettay [:smaug] 2012-07-26 09:16:13 PDT
To mats. I was going to upload very similar patch :)
Comment 9 Mats Palmgren (:mats) 2012-07-26 10:47:10 PDT
Created attachment 646205 [details] [diff] [review]
crash fix

The pres shell change doesn't feel right, so let's just make
these members strong refs for now - that should fix the crash.

I'll file a follow-up bug for investigating what to do about
mutations involving these nodes.

https://tbpl.mozilla.org/?usebuildbot=1&tree=Try&rev=a5cd51b12427
Comment 10 David Bolter [:davidb] 2012-07-26 13:34:33 PDT
(In reply to Olli Pettay [:smaug] (limited connectivity July 26-29) from comment #1)
> I think this is an old regression from bug 237964.

Safe to assume everything affected then?
Comment 11 Mats Palmgren (:mats) 2012-07-26 14:51:45 PDT
Yes, I was able to reproduce a crash in esr10 debug build (non-ASAN) on Linux64.
Comment 13 Mats Palmgren (:mats) 2012-07-26 15:11:39 PDT
(filed follow-up bug 777953)
Comment 14 :Ehsan Akhgari (busy, don't ask for review please) 2012-07-27 08:57:15 PDT
https://hg.mozilla.org/mozilla-central/rev/90c5ff78ac36
Comment 15 Mats Palmgren (:mats) 2012-07-29 13:21:40 PDT
Comment on attachment 646205 [details] [diff] [review]
crash fix

Low risk crash fix.
Comment 16 Alex Keybl [:akeybl] 2012-07-30 11:31:29 PDT
Comment on attachment 646205 [details] [diff] [review]
crash fix

[Triage Comment]
Low risk, sg:crit fix. Approved for all branches.
Comment 18 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-08-14 15:29:03 PDT
I'm willing to write a patch to add the testcase to testsuite to serve as verification provided some mentorship.
Comment 19 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-08-23 15:48:17 PDT
I can't seem to get the testcase to reproduce using an ASAN build built from 9f3cc040e41a. Is anyone on this bug able to reproduce the testcase? If so, can you please verify the bug is fixed?

Note You need to log in before you can comment on or make changes to this bug.