The default bug view has changed. See this FAQ.
Bug 777578 (CVE-2012-1975)

Heap-use-after-free in PresShell::CompleteMove

RESOLVED FIXED in Firefox 15

Status

()

Core
Selection
--
critical
RESOLVED FIXED
5 years ago
4 months ago

People

(Reporter: Abhishek Arya, Assigned: mats)

Tracking

(4 keywords)

Trunk
mozilla17
crash, csectype-uaf, sec-critical, testcase
Points:
---
Bug Flags:
sec-bounty +
in-testsuite ?

Firefox Tracking Flags

(firefox14 wontfix, firefox15+ fixed, firefox16+ fixed, firefox-esr1015+ fixed)

Details

(Whiteboard: [asan][advisory-tracking+][qa?])

Attachments

(2 attachments, 1 obsolete attachment)

(Reporter)

Description

5 years ago
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

Updated

5 years ago
Component: General → Selection
Product: Firefox → Core

Comment 1

5 years ago
I think this is an old regression from bug 237964.

Updated

5 years ago
Assignee: nobody → bugs

Comment 2

5 years ago
Though, I can't reproduce in any easy way. But the code sure is scary looking.
(Assignee)

Comment 3

5 years ago
We're using a deleted nsINode and its nsIFrame - possibly exploitable.
It's the raw pointer nsFrameSelection::mAncestorLimiter that becomes stale.
Severity: normal → critical
Keywords: crash, sec-critical, testcase
Whiteboard: [asan]
(Assignee)

Comment 4

5 years ago
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.
Hmm, that is retarded.  mAncestorLimiter should be a strong reference (an nsCOMPtr/nsRefPtr).
(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

5 years ago
To mats. I was going to upload very similar patch :)
Assignee: bugs → matspal
(Assignee)

Comment 8

5 years ago
https://tbpl.mozilla.org/?usebuildbot=1&tree=Try&rev=233e10012c80
(Assignee)

Comment 9

5 years ago
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
Attachment #646163 - Attachment is obsolete: true
Attachment #646205 - Flags: review?(bugs)

Updated

5 years ago
Attachment #646205 - Flags: review?(bugs) → review+
(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?
(Assignee)

Comment 11

5 years ago
Yes, I was able to reproduce a crash in esr10 debug build (non-ASAN) on Linux64.
status-firefox-esr10: --- → affected
status-firefox14: --- → affected
status-firefox15: --- → affected
status-firefox16: --- → affected
tracking-firefox-esr10: --- → ?
tracking-firefox15: --- → ?
tracking-firefox16: --- → ?
(Assignee)

Comment 12

5 years ago
https://hg.mozilla.org/integration/mozilla-inbound/rev/90c5ff78ac36
Flags: in-testsuite?
Target Milestone: --- → mozilla17
(Assignee)

Comment 13

5 years ago
(filed follow-up bug 777953)
https://hg.mozilla.org/mozilla-central/rev/90c5ff78ac36
Status: NEW → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → FIXED
(Assignee)

Comment 15

5 years ago
Comment on attachment 646205 [details] [diff] [review]
crash fix

Low risk crash fix.
Attachment #646205 - Flags: approval-mozilla-esr10?
Attachment #646205 - Flags: approval-mozilla-beta?
Attachment #646205 - Flags: approval-mozilla-aurora?

Updated

5 years ago
tracking-firefox-esr10: ? → 15+
tracking-firefox15: ? → +
tracking-firefox16: ? → +
Comment on attachment 646205 [details] [diff] [review]
crash fix

[Triage Comment]
Low risk, sg:crit fix. Approved for all branches.
Attachment #646205 - Flags: approval-mozilla-esr10?
Attachment #646205 - Flags: approval-mozilla-esr10+
Attachment #646205 - Flags: approval-mozilla-beta?
Attachment #646205 - Flags: approval-mozilla-beta+
Attachment #646205 - Flags: approval-mozilla-aurora?
Attachment #646205 - Flags: approval-mozilla-aurora+
(Assignee)

Comment 17

5 years ago
https://hg.mozilla.org/releases/mozilla-aurora/rev/01dee641a05e
https://hg.mozilla.org/releases/mozilla-beta/rev/6f27ba134939
https://hg.mozilla.org/releases/mozilla-esr10/rev/8f7070bfefcb
status-firefox-esr10: affected → fixed
status-firefox14: affected → wontfix
status-firefox15: affected → fixed
status-firefox16: affected → fixed
Whiteboard: [asan] → [asan][advisory-tracking+]
I'm willing to write a patch to add the testcase to testsuite to serve as verification provided some mentorship.
QA Contact: anthony.s.hughes
Whiteboard: [asan][advisory-tracking+] → [asan][advisory-tracking+][qa+]
Keywords: verifyme
Alias: CVE-2012-1975
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?
Keywords: verifyme
Whiteboard: [asan][advisory-tracking+][qa+] → [asan][advisory-tracking+][qa?]
Group: core-security
Flags: sec-bounty+
Keywords: csectype-uaf
You need to log in before you can comment on or make changes to this bug.