Closed Bug 916576 (CVE-2013-5600) Opened 7 years ago Closed 7 years ago

[FIX] ASAN use-after-free in nsIOService::NewChannelFromURIWithProxyFlags with Blob URL


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

Not set



Tracking Status
firefox24 --- wontfix
firefox25 --- verified
firefox26 --- verified
firefox27 + verified
firefox-esr17 --- verified
firefox-esr24 --- verified
b2g18 --- fixed
b2g-v1.1hd --- fixed
b2g-v1.2 --- fixed


(Reporter: nils, Assigned: smaug)


(Keywords: csectype-uaf, sec-critical, Whiteboard: [asan][adv-main25+][adv-esr1710+][adv-esr24-1+])


(3 files)

The following testcase crashes the nightly ASAN build:

function start() {
o168=new Blob([], {'type': 'image/gif'});
function cb1() {
function cb2() {
<body onload="start()"></body>
ASAN output:

==26138==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d0001a6020 at pc 0x7f28f6133d56 bp 0x7fffca3cda30 sp 0x7fffca3cda28
READ of size 8 at 0x60d0001a6020 thread T0
    #0 0x7f28f6133d55 in nsIOService::NewChannelFromURIWithProxyFlags(nsIURI*, nsIURI*, unsigned int, nsIChannel**) /netwerk/base/src/nsIOService.cpp:582:0
    #1 0x7f28f613aa8f in NS_NewChannel(nsIChannel**, nsIURI*, nsIIOService*, nsILoadGroup*, nsIInterfaceRequestor*, unsigned int, nsIChannelPolicy*) /obj-firefox/widget/gtk2/../../dist/include/nsNetUtil.h:202:0
    #2 0x7f28f88a5b40 in nsDocShell::DoURILoad(nsIURI*, nsIURI*, bool, nsISupports*, char const*, nsAString_internal const&, nsIInputStream*, nsIInputStream*, bool, nsIDocShell**, nsIRequest**, bool, bool, bool, nsAString_internal const&) /docshell/base/nsDocShell.cpp:9522:0
    #3 0x7f28f88a2e5c in nsDocShell::InternalLoad(nsIURI*, nsIURI*, nsISupports*, unsigned int, unsigned short const*, char const*, nsAString_internal const&, nsIInputStream*, nsIInputStream*, unsigned int, nsISHEntry*, bool, nsAString_internal const&, nsIDocShell**, nsIRequest**) /docshell/base/nsDocShell.cpp:9382:0
    #4 0x7f28f88521bf in nsDocShell::LoadURI(nsIURI*, nsIDocShellLoadInfo*, unsigned int, bool) /docshell/base/nsDocShell.cpp:1510:0
    #5 0x7f28f72be6b7 in nsFrameLoader::ReallyStartLoadingInternal() /content/base/src/nsFrameLoader.cpp:507:0
    #6 0x7f28f72bd80a in nsFrameLoader::ReallyStartLoading() /content/base/src/nsFrameLoader.cpp:414:0
    #7 0x7f28f724e231 in nsDocument::MaybeInitializeFinalizeFrameLoaders() /content/base/src/nsDocument.cpp:6273:0
    #8 0x7f28f724daba in nsDocument::EndUpdate(unsigned int) /content/base/src/nsDocument.cpp:4455:0
    #9 0x7f28f7790432 in nsHTMLDocument::EndUpdate(unsigned int) /content/html/document/src/nsHTMLDocument.cpp:2519:0
    #10 0x7f28f730ad71 in ~mozAutoDocUpdate /content/base/src/mozAutoDocUpdate.h:38:0
    #11 0x7f28f9d97355 in nsINode::InsertBefore(nsINode&, nsINode*, mozilla::ErrorResult&) /obj-firefox/dom/bindings/../../dist/include/nsINode.h:1512:0
    #12 0x7f28f9d9009e in mozilla::dom::NodeBinding::genericMethod(JSContext*, unsigned int, JS::Value*) /obj-firefox/dom/bindings/NodeBinding.cpp:1182:0
    #13 0x7f28fbdb51fa in JSFunction::native() const /js/src/jscntxtinlines.h:219:0
    #14 0x7f28fbda81d8 in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:2459:0
    #15 0x7f28fbd969b1 in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:446:0
    #16 0x7f28fbdb5433 in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) /js/src/vm/Interpreter.cpp:508:0
    #17 0x7f28fbdb6218 in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) /js/src/vm/Interpreter.cpp:539:0
    #18 0x7f28fbfc1097 in JS_CallFunctionValue(JSContext*, JSObject*, JS::Value, unsigned int, JS::Value*, JS::Value*) /js/src/jsapi.cpp:5327:0
    #19 0x7f28f9a3190f in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JSObject*>, nsDOMEvent&, mozilla::ErrorResult&) /obj-firefox/dom/bindings/EventHandlerBinding.cpp:35:0
    #20 0x7f28f7d6f405 in JS::Value mozilla::dom::EventHandlerNonNull::Call<nsISupports*>(nsISupports* const&, nsDOMEvent&, mozilla::ErrorResult&, mozilla::dom::CallbackObject::ExceptionHandling) /obj-firefox/dom/src/events/../../../dist/include/mozilla/dom/EventHandlerBinding.h:59:0
    #21 0x7f28f7557997 in nsEventListenerManager::HandleEventSubType(nsListenerStruct*, mozilla::dom::CallbackObjectHolder<mozilla::dom::EventListener, nsIDOMEventListener> const&, nsIDOMEvent*, mozilla::dom::EventTarget*, nsCxPusher*) /content/events/src/nsEventListenerManager.cpp:962:0
    #22 0x7f28f75587c4 in nsEventListenerManager::HandleEventInternal(nsPresContext*, nsEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*, nsCxPusher*) /content/events/src/nsEventListenerManager.cpp:1033:0
    #23 0x7f28f7548411 in nsEventTargetChainItem::CurrentTarget() /content/events/src/nsEventListenerManager.h:325:0
    #24 0x7f28f75472dd in nsEventTargetChainItem::HandleEventTargetChain(nsTArray<nsEventTargetChainItem>&, nsEventChainPostVisitor&, nsDispatchingCallback*, ELMCreationDetector&, nsCxPusher*) /content/events/src/nsEventDispatcher.cpp:286:0
    #25 0x7f28f754b484 in nsEventDispatcher::Dispatch(nsISupports*, nsPresContext*, nsEvent*, nsIDOMEvent*, nsEventStatus*, nsDispatchingCallback*, nsCOMArray<mozilla::dom::EventTarget>*) /content/events/src/nsEventDispatcher.cpp:599:0
    #26 0x7f28f69ad67f in nsDocumentViewer::LoadComplete(tag_nsresult) /layout/base/nsDocumentViewer.cpp:995:0
    #27 0x7f28f8889cb7 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, tag_nsresult) /docshell/base/nsDocShell.cpp:6741:0
    #28 0x7f28f8886ad9 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, tag_nsresult) /docshell/base/nsDocShell.cpp:6538:0
    #29 0x7f28f888701c in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, tag_nsresult) /docshell/base/nsDocShell.cpp:6544:0
    #30 0x7f28f88d3f1f in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, tag_nsresult) /uriloader/base/nsDocLoader.cpp:1331:0
    #31 0x7f28f88d3273 in nsDocLoader::doStopDocumentLoad(nsIRequest*, tag_nsresult) /uriloader/base/nsDocLoader.cpp:865:0
    #32 0x7f28f88d0eef in nsDocLoader::DocLoaderIsEmpty(bool) /uriloader/base/nsDocLoader.cpp:755:0
    #33 0x7f28f88d247a in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, tag_nsresult) /uriloader/base/nsDocLoader.cpp:639:0
    #34 0x7f28f88d2d29 in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, tag_nsresult) /uriloader/base/nsDocLoader.cpp:642:0
    #35 0x7f28f61499f9 in nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, tag_nsresult) /netwerk/base/src/nsLoadGroup.cpp:688:0
    #36 0x7f28f72724e6 in nsDocument::DoUnblockOnload() /content/base/src/nsDocument.cpp:7960:0
    #37 0x7f28f727219b in nsDocument::UnblockOnload(bool) /content/base/src/nsDocument.cpp:7888:0
    #38 0x7f28f72509d2 in nsDocument::DispatchContentLoadedEvents() /content/base/src/nsDocument.cpp:4680:0
    #39 0x7f28f7297a7c in nsRunnableMethodImpl<void (nsDocument::*)(), void, true>::Run() /obj-firefox/content/base/src/../../../dist/include/nsThreadUtils.h:418:0
    #40 0x7f28fa541a69 in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:622:0
    #41 0x7f28fa4685b1 in NS_ProcessNextEvent(nsIThread*, bool) /obj-firefox/xpcom/build/nsThreadUtils.cpp:238:0
    #42 0x7f28f92a2a01 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:81:0
    #43 0x7f28fa666b53 in MessageLoop::RunInternal() /ipc/chromium/src/base/
    #44 0x7f28f908915c in nsBaseAppShell::Run() /widget/xpwidgets/nsBaseAppShell.cpp:161:0
    #45 0x7f28f8a6fc5e in nsAppStartup::Run() /toolkit/components/startup/nsAppStartup.cpp:269:0
    #46 0x7f28f5e5ac00 in XREMain::XRE_mainRun() /toolkit/xre/nsAppRunner.cpp:3869:0
    #47 0x7f28f5e5bb55 in XREMain::XRE_main(int, char**, nsXREAppData const*) /toolkit/xre/nsAppRunner.cpp:3937:0
    #48 0x7f28f5e5ca8b in XRE_main /toolkit/xre/nsAppRunner.cpp:4139:0
    #49 0x459c8d in do_main(int, char**, nsIFile*) /browser/app/nsBrowserApp.cpp:275:0
    #50 0x7f2905460ea4 (/lib/x86_64-linux-gnu/
    #51 0x45910c in ?? ??:0:0
0x60d0001a6020 is located 0 bytes inside of 136-byte region [0x60d0001a6020,0x60d0001a60a8)
freed by thread T0 here:
    #0 0x446015 in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/
    #1 0x7f28f6179d0f in nsSimpleURI::Release() /netwerk/base/src/nsSimpleURI.cpp:47:0
previously allocated by thread T0 here:
    #0 0x446155 in malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/
    #1 0x7f28ff4035c8 in moz_xmalloc /memory/mozalloc/mozalloc.cpp:54:0
    #2 0x7f28f6133021 in nsIOService::NewURI(nsACString_internal const&, char const*, nsIURI*, nsIURI**) /netwerk/base/src/nsIOService.cpp:545:0
    #3 0x7f28f72bc9e6 in NS_ConvertUTF16toUTF8 /obj-firefox/content/base/src/../../../dist/include/nsNetUtil.h:152:0
    #4 0x7f28f771e4a1 in nsGenericHTMLFrameElement::LoadSrc() /content/html/content/src/nsGenericHTMLFrameElement.cpp:175:0
Shadow bytes around the buggy address:
  0x0c1a8002cbb0: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
  0x0c1a8002cbc0: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x0c1a8002cbd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1a8002cbe0: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd
  0x0c1a8002cbf0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c1a8002cc00: fa fa fa fa[fd]fd fd fd fd fd fd fd fd fd fd fd
  0x0c1a8002cc10: fd fd fd fd fd fa fa fa fa fa fa fa fa fa 00 00
  0x0c1a8002cc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
  0x0c1a8002cc30: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c1a8002cc40: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa
  0x0c1a8002cc50: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
aURI is being used after free. Adding a nsCOMPtr<nsIURI> kungFuDeathGripURI to LoadURI helps, but there are still few assertions.
###!!! ASSERTION: Request list is not empty.: 'mRequests.entryCount == 0', file /home/smaug/mozilla/hg/mozilla/netwerk/base/src/nsLoadGroup.cpp, line 303
###!!! ASSERTION: Foreground URLs are active.: 'mForegroundCount == 0', file /home/smaug/mozilla/hg/mozilla/netwerk/base/src/nsLoadGroup.cpp, line 304
###!!! ASSERTION: Shouldn't be busy here: '!IsBusy()', file /home/smaug/mozilla/hg/mozilla/uriloader/base/nsDocLoader.cpp, line 290
###!!! ASSERTION: Overwriting an existing document channel!: '(loadFlags & nsIChannel::LOAD_REPLACE) || !(mDocumentRequest.get())', file /home/smaug/mozilla/hg/mozilla/uriloader/base/nsDocLoader.cpp, line 471
Keywords: sec-critical
Attached file testcase
Thanks Olli, can you find an owner? (mccr8 is away)
Assignee: nobody → bugs
This is mine sure.
Keywords: csec-uaf
Whiteboard: [asan]
Assignee: bugs → continuation
I looked at this a little, but I think this is more Olli's territory.
Assignee: continuation → bugs
I think we should do this for now (follow the COM rules).
There are still some assertions, but some of them are bogus and for other things
need to figure out what kind of behavior we want when
loading a new page causes stop on the previous load and that stop cause
a new load...
Attachment #813741 - Flags: review?(bzbarsky)
Comment on attachment 813741 [details] [diff] [review]
patch for the crash

Attachment #813741 - Flags: review?(bzbarsky) → review+
Summary: ASAN use-after-free in nsIOService::NewChannelFromURIWithProxyFlags with Blob URL → [FIX] ASAN use-after-free in nsIOService::NewChannelFromURIWithProxyFlags with Blob URL
Comment on attachment 813741 [details] [diff] [review]
patch for the crash

[Approval Request Comment]
Bug caused by (feature/regressing bug #): Old code
User impact if declined: possible security critical crash
Testing completed (on m-c, etc.): NA
Risk to taking this patch (and alternatives if risky): Should be super safe, and doesn't super
obviously show where the things go wrong. But effectively kungfuDeathGrip anyway. 
String or IDL/UUID changes made by this patch: NA
Attachment #813741 - Flags: approval-mozilla-esr24?
Attachment #813741 - Flags: approval-mozilla-esr17?
Attachment #813741 - Flags: approval-mozilla-beta?
Attachment #813741 - Flags: approval-mozilla-aurora?
Comment on attachment 813741 [details] [diff] [review]
patch for the crash

Correct me if I'm wrong, but I believe this requires sec-approval.
Attachment #813741 - Flags: sec-approval?
Comment on attachment 813741 [details] [diff] [review]
patch for the crash

It does but this is a super simple patch. This looks good to me.

sec-approval+ for trunk. We should take this on Aurora and Beta too as well as ESR.
Attachment #813741 - Flags: sec-approval?
Attachment #813741 - Flags: sec-approval+
Attachment #813741 - Flags: approval-mozilla-esr24?
Attachment #813741 - Flags: approval-mozilla-esr24+
Attachment #813741 - Flags: approval-mozilla-esr17?
Attachment #813741 - Flags: approval-mozilla-esr17+
Attachment #813741 - Flags: approval-mozilla-beta?
Attachment #813741 - Flags: approval-mozilla-beta+
Attachment #813741 - Flags: approval-mozilla-aurora?
Attachment #813741 - Flags: approval-mozilla-aurora+
Hey Olli, land this! :-) - Critsmash Triage
Flags: needinfo?(bugs)
Ah, this didn't have "[land after x/y]" like my other sec bugs.
Flags: needinfo?(bugs)
Attached patch for esr17Splinter Review
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla27
Confirmed crash on FF24.
Verified fixed on ASan builds of 17esr, 24esr, 25, 26 and 27, 2013-10-14.
Whiteboard: [asan] → [asan][adv-main25+][adv-esr1710+][adv-esr24-1+]
Alias: CVE-2013-5600
:smaug, is b2g18 affected here ? IN which case we would need to backport this patch on that branch.
Flags: needinfo?(bugs)
Yes, it should be affected. Either one of those patches should apply to b2g18
Flags: needinfo?(bugs)
Group: core-security
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.