Heap-use-after-free in mozilla::css::SheetLoadData::ScheduleLoadEventIfNeeded

VERIFIED FIXED in Firefox 33, Firefox OS v2.1

Status

()

Core
CSS Parsing and Computation
VERIFIED FIXED
4 years ago
3 years ago

People

(Reporter: Abhishek Arya, Assigned: heycam)

Tracking

({csectype-uaf, regression, sec-critical})

Trunk
mozilla34
x86_64
All
csectype-uaf, regression, sec-critical
Points:
---
Bug Flags:
sec-bounty +
qe-verify +

Firefox Tracking Flags

(firefox32 unaffected, firefox33+ verified, firefox34+ verified, firefox-esr24 unaffected, firefox-esr31 unaffected, b2g-v1.3 unaffected, b2g-v1.3T unaffected, b2g-v1.4 unaffected, b2g-v2.0 unaffected, b2g-v2.1 fixed)

Details

(Whiteboard: [asan])

Attachments

(2 attachments)

(Reporter)

Description

4 years ago
Created attachment 8465199 [details]
test.html

Install fuzzPriv extension from https://www.squarefree.com/extensions/domFuzzLite3.xpi

Load firefox with testcase in multiple tabs. For me, fully reproducible if i just pass testcase path 3 times, loading it in three tabs.

>==2680==ERROR: AddressSanitizer: heap-use-after-free on address 0x61c000067880 at pc 0x7f640be5c80b bp 0x7fff071f1470 sp 0x7fff071f1468
>READ of size 8 at 0x61c000067880 thread T0
>    #0 0x7f640be5c80a in mozilla::css::SheetLoadData::ScheduleLoadEventIfNeeded(tag_nsresult) layout/style/Loader.cpp:495:7
>    #1 0x7f640be67abc in mozilla::css::Loader::DoSheetComplete(mozilla::css::SheetLoadData*, tag_nsresult, nsTArray<nsRefPtr<mozilla::css::SheetLoadData> >&) layout/style/Loader.cpp:1777:7
>    #2 0x7f640be6387e in mozilla::css::Loader::SheetComplete(mozilla::css::SheetLoadData*, tag_nsresult) layout/style/Loader.cpp:1703:3
>    #3 0x7f640be61e4e in mozilla::css::SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader*, nsISupports*, tag_nsresult, nsAString_internal const&) layout/style/Loader.cpp:811:5
>    #4 0x7f6406f44a25 in nsUnicharStreamLoader::OnStopRequest(nsIRequest*, nsISupports*, tag_nsresult) netwerk/base/src/nsUnicharStreamLoader.cpp:99:5
>    #5 0x7f6406e94dc4 in nsBaseChannel::OnStopRequest(nsIRequest*, nsISupports*, tag_nsresult) netwerk/base/src/nsBaseChannel.cpp:751:7
>    #6 0x7f6406e94fbf in non-virtual thunk to nsBaseChannel::OnStopRequest(nsIRequest*, nsISupports*, tag_nsresult) netwerk/base/src/nsBaseChannel.cpp:765:1
>    #7 0x7f6406ec5316 in nsInputStreamPump::OnStateStop() netwerk/base/src/nsInputStreamPump.cpp:711:9
>    #8 0x7f6406ec3896 in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) netwerk/base/src/nsInputStreamPump.cpp:440:25
>    #9 0x7f6406ce22f9 in nsInputStreamReadyEvent::Run() xpcom/io/nsStreamUtils.cpp:88:9
>    #10 0x7f6406d19dd0 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:770:7
>    #11 0x7f6406d70aaa in NS_ProcessNextEvent(nsIThread*, bool) xpcom/glue/nsThreadUtils.cpp:265:10
>    #12 0x7f6407639613 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:99:21
>    #13 0x7f64075a7c31 in RunInternal ipc/chromium/src/base/message_loop.cc:229:3
>    #14 0x7f64075a7c31 in RunHandler ipc/chromium/src/base/message_loop.cc:222
>    #15 0x7f64075a7c31 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:196
>    #16 0x7f640a9ba2d7 in nsBaseAppShell::Run() widget/xpwidgets/nsBaseAppShell.cpp:164:3
>    #17 0x7f640cfe58d4 in nsAppStartup::Run() toolkit/components/startup/nsAppStartup.cpp:278:19
>    #18 0x7f640cdcb5e0 in XREMain::XRE_mainRun() toolkit/xre/nsAppRunner.cpp:4013:10
>    #19 0x7f640cdcc3ed in XREMain::XRE_main(int, char**, nsXREAppData const*) toolkit/xre/nsAppRunner.cpp:4084:8
>    #20 0x7f640cdcd1dc in XRE_main toolkit/xre/nsAppRunner.cpp:4298:16
>    #21 0x4bd530 in do_main browser/app/nsBrowserApp.cpp:282:12
>    #22 0x4bd530 in main browser/app/nsBrowserApp.cpp:643
>    #23 0x7f64169a976c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
>    #24 0x4bcb9c in _start
>
>0x61c000067880 is located 0 bytes inside of 1896-byte region [0x61c000067880,0x61c000067fe8)
>freed by thread T0 here:
>    #0 0x49c981 in __interceptor_free _asan_rtl_
>    #1 0x7f6406c27015 in SnowWhiteKiller::~SnowWhiteKiller() xpcom/base/nsCycleCollector.cpp:2619:9
>    #2 0x7f6406c26c38 in nsCycleCollector::FreeSnowWhite(bool) xpcom/base/nsCycleCollector.cpp:2786:3
>    #3 0x7f6407f55b0c in AsyncFreeSnowWhite::Run() js/xpconnect/src/XPCJSRuntime.cpp:222:34
>    #4 0x7f6406d19dd0 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:770:7
>    #5 0x7f6406d70aaa in NS_ProcessNextEvent(nsIThread*, bool) xpcom/glue/nsThreadUtils.cpp:265:10
>    #6 0x7f6407639613 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:99:21
>    #7 0x7f64075a7c31 in RunInternal ipc/chromium/src/base/message_loop.cc:229:3
>    #8 0x7f64075a7c31 in RunHandler ipc/chromium/src/base/message_loop.cc:222
>    #9 0x7f64075a7c31 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:196
>    #10 0x7f640a9ba2d7 in nsBaseAppShell::Run() widget/xpwidgets/nsBaseAppShell.cpp:164:3
>    #11 0x7f640cfe58d4 in nsAppStartup::Run() toolkit/components/startup/nsAppStartup.cpp:278:19
>    #12 0x7f640cdcb5e0 in XREMain::XRE_mainRun() toolkit/xre/nsAppRunner.cpp:4013:10
>    #13 0x7f640cdcc3ed in XREMain::XRE_main(int, char**, nsXREAppData const*) toolkit/xre/nsAppRunner.cpp:4084:8
>    #14 0x7f640cdcd1dc in XRE_main toolkit/xre/nsAppRunner.cpp:4298:16
>    #15 0x4bd530 in do_main browser/app/nsBrowserApp.cpp:282:12
>    #16 0x4bd530 in main browser/app/nsBrowserApp.cpp:643
>    #17 0x7f64169a976c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
>
>previously allocated by thread T0 here:
>    #0 0x49cc59 in malloc _asan_rtl_
>    #1 0x7f6413f37aed in moz_xmalloc memory/mozalloc/mozalloc.cpp:52:17
>    #2 0x7f640b13838d in operator new objdir-ff-asan/content/html/document/src/../../../../dist/include/mozilla/mozalloc.h:201:12
>    #3 0x7f640b13838d in operator new objdir-ff-asan/content/html/document/src/../../../../dist/include/nsIDocument.h:172
>    #4 0x7f640b13838d in NS_NewHTMLDocument(nsIDocument**, bool) content/html/document/src/nsHTMLDocument.cpp:169
>    #5 0x7f640b8fe2bc in CreateHTMLDocument(nsISupports*, nsID const&, void**) layout/build/nsLayoutModule.cpp:509:1
>    #6 0x7f6406cfc677 in nsComponentManagerImpl::CreateInstance(nsID const&, nsISupports*, nsID const&, void**) xpcom/components/nsComponentManager.cpp:998:14
>    #7 0x7f6406d5b247 in CallCreateInstance xpcom/glue/nsComponentManagerUtils.cpp:135:10
>    #8 0x7f6406d5b247 in nsCreateInstanceByCID::operator()(nsID const&, void**) const xpcom/glue/nsComponentManagerUtils.cpp:183
>    #9 0x7f6406d5764d in nsCOMPtr_base::assign_from_helper(nsCOMPtr_helper const&, nsID const&) xpcom/glue/nsCOMPtr.cpp:123:7
>    #10 0x7f640b8fa5b1 in nsCOMPtr objdir-ff-asan/layout/build/../../dist/include/nsCOMPtr.h:657:5
>    #11 0x7f640b8fa5b1 in nsContentDLF::CreateDocument(char const*, nsIChannel*, nsILoadGroup*, nsIDocShell*, nsID const&, nsIStreamListener**, nsIContentViewer**) layout/build/nsContentDLF.cpp:393
>    #12 0x7f640b8fa012 in nsContentDLF::CreateInstance(char const*, nsIChannel*, nsILoadGroup*, char const*, nsIDocShell*, nsISupports*, nsIStreamListener**, nsIContentViewer**) layout/build/nsContentDLF.cpp:224:14
>    #13 0x7f640c90f3a9 in nsDocShell::NewContentViewerObj(char const*, nsIRequest*, nsILoadGroup*, nsIStreamListener**, nsIContentViewer**) docshell/base/nsDocShell.cpp:8512:19
>    #14 0x7f640c90bd02 in nsDocShell::CreateContentViewer(char const*, nsIRequest*, nsIStreamListener**) docshell/base/nsDocShell.cpp:8312:19
>    #15 0x7f640c9425b4 in nsDSURIContentListener::DoContent(char const*, bool, nsIRequest*, nsIStreamListener**, bool*) docshell/base/nsDSURIContentListener.cpp:122:10
>    #16 0x7f640849f30b in nsDocumentOpenInfo::TryContentListener(nsIURIContentListener*, nsIChannel*) uriloader/base/nsURILoader.cpp:725:17
>    #17 0x7f640849c999 in nsDocumentOpenInfo::DispatchContent(nsIRequest*, nsISupports*) uriloader/base/nsURILoader.cpp:401:30
>    #18 0x7f640849bfde in nsDocumentOpenInfo::OnStartRequest(nsIRequest*, nsISupports*) uriloader/base/nsURILoader.cpp:262:8
>    #19 0x7f6406e93ee6 in nsBaseChannel::OnStartRequest(nsIRequest*, nsISupports*) netwerk/base/src/nsBaseChannel.cpp:734:14
>    #20 0x7f6406ec410d in nsInputStreamPump::OnStateStart() netwerk/base/src/nsInputStreamPump.cpp:521:14
>    #21 0x7f6406ec37bb in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) netwerk/base/src/nsInputStreamPump.cpp:433:25
>    #22 0x7f6406ce22f9 in nsInputStreamReadyEvent::Run() xpcom/io/nsStreamUtils.cpp:88:9
>    #23 0x7f6406d19dd0 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:770:7
>    #24 0x7f6406d70aaa in NS_ProcessNextEvent(nsIThread*, bool) xpcom/glue/nsThreadUtils.cpp:265:10
>    #25 0x7f6407639613 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:99:21
>    #26 0x7f64075a7c31 in RunInternal ipc/chromium/src/base/message_loop.cc:229:3
>    #27 0x7f64075a7c31 in RunHandler ipc/chromium/src/base/message_loop.cc:222
>    #28 0x7f64075a7c31 in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:196
>    #29 0x7f640a9ba2d7 in nsBaseAppShell::Run() widget/xpwidgets/nsBaseAppShell.cpp:164:3
>    #30 0x7f640cfe58d4 in nsAppStartup::Run() toolkit/components/startup/nsAppStartup.cpp:278:19
>    #31 0x7f640cdcb5e0 in XREMain::XRE_mainRun() toolkit/xre/nsAppRunner.cpp:4013:10
>    #32 0x7f640cdcc3ed in XREMain::XRE_main(int, char**, nsXREAppData const*) toolkit/xre/nsAppRunner.cpp:4084:8
>    #33 0x7f640cdcd1dc in XRE_main toolkit/xre/nsAppRunner.cpp:4298:16
>    #34 0x4bd530 in do_main browser/app/nsBrowserApp.cpp:282:12
>    #35 0x4bd530 in main browser/app/nsBrowserApp.cpp:643
>    #36 0x7f64169a976c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
>
>SUMMARY: AddressSanitizer: heap-use-after-free ??:0 ??
>Shadow bytes around the buggy address:
>  0x0c3880004ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  0x0c3880004ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  0x0c3880004ee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  0x0c3880004ef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa
>  0x0c3880004f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>=>0x0c3880004f10:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>  0x0c3880004f20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>  0x0c3880004f30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>  0x0c3880004f40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>  0x0c3880004f50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>  0x0c3880004f60: 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
>  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
>  Container overflow:      fc
>  ASan internal:           fe
>==2680==ABORTING
>
>
What's supposed to prevent mozilla::css::Loader::mDocument from being a dangling pointer?
Flags: needinfo?(bzbarsky)
Oh, I guess it's Loader::DropDocumentReference().
This looks like a straightforward bug in nsDocument's UNLINK macros; it unlinks mCSSLoader without calling DropDocumentReference.
Flags: needinfo?(bzbarsky)
heycam, you willing to patch this?  Looks to me like a regression from bug 1031967.
Blocks: 1031967
Flags: needinfo?(cam)
[Tracking Requested - why for this release]:
status-firefox32: --- → unaffected
status-firefox33: --- → affected
status-firefox34: --- → affected
tracking-firefox33: --- → ?
tracking-firefox34: --- → ?
(Assignee)

Comment 6

4 years ago
Created attachment 8465263 [details] [diff] [review]
patch

Thanks for pointing out where the bug lay.
Assignee: nobody → cam
Status: NEW → ASSIGNED
Attachment #8465263 - Flags: review?(dbaron)
Flags: needinfo?(cam)
Attachment #8465263 - Flags: review?(dbaron) → review+
(Assignee)

Comment 7

4 years ago
Comment on attachment 8465263 [details] [diff] [review]
patch

[Security approval request comment]
How easily could an exploit be constructed based on the patch?

Not easily.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?

I don't think the patch makes it obvious what's going on.

Which older supported branches are affected by this flaw?

33

If not all supported branches, which bug introduced the flaw?

bug 1031967

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?

Patch applies cleanly to Aurora.

How likely is this patch to cause regressions; how much testing does it need?

Unlikely to cause regressions.  As the use-after-free was easily reproduced, I think manual testing of the patch is sufficient.
Attachment #8465263 - Flags: sec-approval?
Comment on attachment 8465263 [details] [diff] [review]
patch

sec-approval+ for trunk. Let's get this nominated for Aurora as well and checked in after trunk is green.
Attachment #8465263 - Flags: sec-approval? → sec-approval+
Keywords: csectype-uaf, sec-critical
Whiteboard: [asan]
https://hg.mozilla.org/mozilla-central/rev/481d03d19f2f
Status: ASSIGNED → RESOLVED
Last Resolved: 4 years ago
status-firefox34: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla34
You should request aurora approval for this as well.
Flags: needinfo?(cam)
(Assignee)

Comment 12

4 years ago
Comment on attachment 8465263 [details] [diff] [review]
patch

Approval Request Comment
[Feature/regressing bug #]: bug 1031967
[User impact if declined]: pages might be able to exploit a use-after-free bug
[Describe test coverage new/current, TBPL]: patch has been on mozilla-central for a day or so
[Risks and why]: low risk, the fix just clears out a pointer that should have been cleared
[String/UUID change made/needed]: N/A
Attachment #8465263 - Flags: approval-mozilla-aurora?
Flags: needinfo?(cam)
tracking-firefox33: ? → +
tracking-firefox34: ? → +
Attachment #8465263 - Flags: approval-mozilla-aurora? → approval-mozilla-aurora+
status-b2g-v1.3: --- → unaffected
status-b2g-v1.3T: --- → unaffected
status-b2g-v1.4: --- → unaffected
status-b2g-v2.0: --- → unaffected
status-b2g-v2.1: --- → fixed
status-firefox-esr24: --- → unaffected
status-firefox-esr31: --- → unaffected
Adding sec-bounty nomination per reporter's request
Flags: sec-bounty?
Flags: qe-verify+
Flags: sec-bounty? → sec-bounty+
Keywords: regression
Group: core-security

Comment 16

3 years ago
Couldn't reproduce with Nightly asan build from 2014-07-30 on Ubuntu 12.04 and 13.10, both 64-bit.
With STR from comment 0, Nightly 2014-07-30 instantly crashes on Windows 7 64-bit:
bp-e84b2735-4a0f-4ab0-a8ad-f170b2140930
bp-48159a45-1fa5-4bd3-a3ec-f31b72140930

No crash with Aurora 34.0a2 (Build ID: 20140929004005) nor with Firefox 33 beta 8 (Build ID: 20140929180120) on Windows 7x64, Ubuntu 12.04 64-bit and Mac OS X 10.9.5.
Status: RESOLVED → VERIFIED
status-firefox33: fixed → verified
status-firefox34: fixed → verified
You need to log in before you can comment on or make changes to this bug.