Closed Bug 1277272 Opened 9 years ago Closed 8 years ago

heap-use-after-free in nsRefreshDriver::Tick

Categories

(Core :: DOM: Animation, defect)

49 Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla50
Tracking Status
firefox47 --- unaffected
firefox48 --- unaffected
firefox49 + fixed
firefox-esr45 --- unaffected
firefox50 + fixed

People

(Reporter: nils, Assigned: mantaroh)

References

Details

(Keywords: csectype-uaf, regression, sec-critical)

Attachments

(3 files, 4 obsolete files)

The following testcase crashes the latest ASAN build of Firefox (buildId 20160531170040). Requires the fuzzPriv extension (https://github.com/MozillaSecurity/funfuzz/tree/master/dom/extension). Might take a few reloads Testcase: <script> function start() { t={}; let t1 = window.t1; let t2 = window.t2; t.o0=window.document; t.o2=document.body; t.o40=t.o2.animate([{marks: 'crop'},{marks: 'crop'}],12); t.o0.write('<html><body></body></html>'); setTimeout(t1.bind(t),4); setTimeout(t2.bind(t),5); } function t1() { this.o40.play(); } function t2() { this.o40['timeline']=undefined; fuzzPriv.forceGC(); window.top.setTimeout('location.reload()',40);; } </script> <body onload="start()"></body> ASAN output: ================================================================= ==19706==ERROR: AddressSanitizer: heap-use-after-free on address 0x60e00009cd58 at pc 0x7f69813be76f bp 0x7ffef910da90 sp 0x7ffef910da88 READ of size 8 at 0x60e00009cd58 thread T0 (Web Content) #0 0x7f69813be76e in AddRef /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:36 #1 0x7f69813be76e in AddRef /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:374 #2 0x7f69813be76e in GetNext /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:110 #3 0x7f69813be76e in nsRefreshDriver::Tick(long, mozilla::TimeStamp) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsRefreshDriver.cpp:1700 #4 0x7f69813c912b in mozilla::RefreshDriverTimer::TickRefreshDrivers(long, mozilla::TimeStamp, nsTArray<RefPtr<nsRefreshDriver> >&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsRefreshDriver.cpp:246 #5 0x7f69813c8d10 in mozilla::RefreshDriverTimer::Tick(long, mozilla::TimeStamp) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsRefreshDriver.cpp:265 #6 0x7f69813c81f4 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsync(mozilla::TimeStamp) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsRefreshDriver.cpp:425 #7 0x7f6981d01700 in mozilla::layout::VsyncChild::RecvNotify(mozilla::TimeStamp const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/ipc/VsyncChild.cpp:64 #8 0x7f697bb779ca in mozilla::layout::PVsyncChild::OnMessageReceived(IPC::Message const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/ipc/ipdl/PVsyncChild.cpp:240 #9 0x7f697b696c81 in mozilla::ipc::PBackgroundChild::OnMessageReceived(IPC::Message const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/ipc/ipdl/PBackgroundChild.cpp:1968 #10 0x7f697b5ca873 in mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessageChannel.cpp:1657 #11 0x7f697b5c75d5 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessageChannel.cpp:1595 #12 0x7f697b5b4715 in mozilla::ipc::MessageChannel::OnMaybeDequeueOne() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessageChannel.cpp:1562 #13 0x7f697b5da720 in applyImpl<mozilla::ipc::MessageChannel, bool (mozilla::ipc::MessageChannel::*)()> /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsThreadUtils.h:715 #14 0x7f697b5da720 in apply<mozilla::ipc::MessageChannel, bool (mozilla::ipc::MessageChannel::*)()> /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsThreadUtils.h:721 #15 0x7f697b5da720 in nsRunnableMethodImpl<bool (mozilla::ipc::MessageChannel::*)(), false, true>::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsThreadUtils.h:749 #16 0x7f697b5db1ef in Run /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/ipc/MessageChannel.h:477 #17 0x7f697b5db1ef in mozilla::ipc::MessageChannel::DequeueTask::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/ipc/MessageChannel.h:496 #18 0x7f697a840274 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:1029 #19 0x7f697a8bacda in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:290 #20 0x7f697b5d1d9e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:100 #21 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #22 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #23 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #24 0x7f6980d3f057 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:156 #25 0x7f6982d62862 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:827 #26 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #27 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #28 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #29 0x7f6982d61f40 in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:657 #30 0x48dbf7 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:231 #31 0x7f69780a182f in __libc_start_main /build/glibc-GKVZIf/glibc-2.23/csu/../csu/libc-start.c:291 #32 0x48cb3c in _start (/home/nils/fuzzer3/firefox/plugin-container+0x48cb3c) 0x60e00009cd58 is located 120 bytes inside of 152-byte region [0x60e00009cce0,0x60e00009cd78) freed by thread T0 (Web Content) here: #0 0x474f51 in __interceptor_free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64 #1 0x7f697a720d98 in SnowWhiteKiller::~SnowWhiteKiller() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2687 #2 0x7f697a7209be in nsCycleCollector::FreeSnowWhite(bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2861 #3 0x7f697c17b929 in AsyncFreeSnowWhite::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/xpconnect/src/XPCJSRuntime.cpp:155 #4 0x7f697a840274 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:1029 #5 0x7f697a8bacda in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:290 #6 0x7f697b5d1d9e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:100 #7 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #8 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #9 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #10 0x7f6980d3f057 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:156 #11 0x7f6982d62862 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:827 #12 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #13 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #14 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #15 0x7f6982d61f40 in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:657 #16 0x48dbf7 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:231 #17 0x7f69780a182f in __libc_start_main /build/glibc-GKVZIf/glibc-2.23/csu/../csu/libc-start.c:291 previously allocated by thread T0 (Web Content) here: #0 0x475151 in __interceptor_malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x48e3fd in moz_xmalloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/memory/mozalloc/mozalloc.cpp:83 #2 0x7f697d42b196 in operator new /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:193 #3 0x7f697d42b196 in nsDocument::Timeline() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsDocument.cpp:3245 #4 0x7f69816711b3 in PresShell::Init(nsIDocument*, nsPresContext*, nsViewManager*, mozilla::StyleSetHandle) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsPresShell.cpp:966 #5 0x7f697d431f2d in nsDocument::doCreateShell(nsPresContext*, nsViewManager*, mozilla::StyleSetHandle) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsDocument.cpp:3835 #6 0x7f697f954b17 in nsHTMLDocument::CreateShell(nsPresContext*, nsViewManager*, mozilla::StyleSetHandle) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/html/nsHTMLDocument.cpp:274 #7 0x7f69815d3896 in nsDocumentViewer::InitPresentationStuff(bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsDocumentViewer.cpp:632 #8 0x7f69815d2e61 in nsDocumentViewer::InitInternal(nsIWidget*, nsISupports*, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const&, bool, bool, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsDocumentViewer.cpp:886 #9 0x7f69815d2197 in nsDocumentViewer::Init(nsIWidget*, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/layout/base/nsDocumentViewer.cpp:616 #10 0x7f698231c4e0 in nsDocShell::SetupNewViewer(nsIContentViewer*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/docshell/base/nsDocShell.cpp:9297 #11 0x7f698231add7 in nsDocShell::Embed(nsIContentViewer*, char const*, nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/docshell/base/nsDocShell.cpp:7164 #12 0x7f69822b7a03 in nsDocShell::CreateContentViewer(nsACString_internal const&, nsIRequest*, nsIStreamListener**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/docshell/base/nsDocShell.cpp:9105 #13 0x7f69822b5035 in nsDSURIContentListener::DoContent(nsACString_internal const&, bool, nsIRequest*, nsIStreamListener**, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/docshell/base/nsDSURIContentListener.cpp:129 #14 0x7f697c5f1bc2 in nsDocumentOpenInfo::TryContentListener(nsIURIContentListener*, nsIChannel*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/uriloader/base/nsURILoader.cpp:720 #15 0x7f697c5edc2b in nsDocumentOpenInfo::DispatchContent(nsIRequest*, nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/uriloader/base/nsURILoader.cpp:398 #16 0x7f697c5ec8c6 in nsDocumentOpenInfo::OnStartRequest(nsIRequest*, nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/uriloader/base/nsURILoader.cpp:259 #17 0x7f697a9bc29b in nsBaseChannel::OnStartRequest(nsIRequest*, nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/netwerk/base/nsBaseChannel.cpp:807 #18 0x7f697aa04eed in nsInputStreamPump::OnStateStart() /builds/slave/m-cen-l64-asan-000000000000000/build/src/netwerk/base/nsInputStreamPump.cpp:525 #19 0x7f697aa044f2 in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/netwerk/base/nsInputStreamPump.cpp:427 #20 0x7f697a7fb269 in nsInputStreamReadyEvent::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/io/nsStreamUtils.cpp:95 #21 0x7f697a840274 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:1029 #22 0x7f697a8bacda in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:290 #23 0x7f697b5d1d9e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:100 #24 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #25 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #26 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #27 0x7f6980d3f057 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:156 #28 0x7f6982d62862 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:827 #29 0x7f697b5424cc in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:235 #30 0x7f697b5424cc in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:228 #31 0x7f697b5424cc in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:208 #32 0x7f6982d61f40 in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:657 #33 0x48dbf7 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:231 #34 0x7f69780a182f in __libc_start_main /build/glibc-GKVZIf/glibc-2.23/csu/../csu/libc-start.c:291 SUMMARY: AddressSanitizer: heap-use-after-free /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:36 AddRef Shadow bytes around the buggy address: 0x0c1c8000b950: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa 0x0c1c8000b960: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 0x0c1c8000b970: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa 0x0c1c8000b980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c1c8000b990: 00 00 00 02 fa fa fa fa fa fa fa fa fd fd fd fd =>0x0c1c8000b9a0: fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fa 0x0c1c8000b9b0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x0c1c8000b9c0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa 0x0c1c8000b9d0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 0x0c1c8000b9e0: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa 0x0c1c8000b9f0: 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: ==19706==ABORTING
I'm debugging a couple of other security bugs in this area at the moment so I should probably look at this too.
Assignee: nobody → bbirtles
Status: NEW → ASSIGNED
It's going to be next week before I get to look at this properly.
Group: core-security → dom-core-security
Thanks Brian, when you get a chance can you also let us know what the regression may be from (and which versions are affected) Tracking for 49 since it's sec-critical.
Flags: needinfo?(bbirtles)
Mantaroh ran this test case on a debug build and found out we were failing this assertion: Assertion failure: !mIsObservingRefreshDriver (Timeline should have disassociated from the refresh driver before being destroyed), at /builds/slave/m-in-l64-asan-d-00000000000000/build/src/obj-firefox/dist/include/mozilla/dom/DocumentTimeline.h:42 Looking at the stack from comment 0, it seems most likely we're failing to disassociate the timeline from the refresh driver when it is destroyed. As a result, on the next tick, when we iterate through the refresh driver observers we access freed memory here: https://dxr.mozilla.org/mozilla-central/rev/f8e3b81a79f45ef8647c98281a9a00d1ddb28b73/layout/base/nsRefreshDriver.cpp#1458 If that's the case, this could be a long-standing regression. We did some work to fix timeline lifecycles at some point, but I'm not sure if that caused this or not. Mantaroh is going to try and create a mochitest for this so we can find a regression range for the assertion failure.
Attached file testcase.html (deleted) —
We can reproduce all platform using this crashtest. The regression result is as follow. Regression: https://hg.mozilla.org/integration/mozilla-inbound/pushloghtml?fromchange=eaf90fc6c08264b8fd26125f62178dee4cf2ce43&tochange=f2abcc29e65aa7a8fc3e0f48069a3491cd46a1a6 I think that cause of this problem is patch of part 7. As discussed with Brian, we should have refcounts to DocumentTimeline in Animation object. And, perhaps we should remove observer when releasing the relationship of animation and timeline.
Based on the regression range in comment 5, this regression appeared in Firefox 49.
Flags: needinfo?(bbirtles)
(In reply to Mantaroh Yoshinaga[:mantaroh] from comment #5) > Created attachment 8761927 [details] > testcase.html > > We can reproduce all platform using this crashtest. > The regression result is as follow. > > Regression: > https://hg.mozilla.org/integration/mozilla-inbound/ > pushloghtml?fromchange=eaf90fc6c08264b8fd26125f62178dee4cf2ce43&tochange=f2ab > cc29e65aa7a8fc3e0f48069a3491cd46a1a6 > > I think that cause of this problem is patch of part 7. > > As discussed with Brian, we should have refcounts to DocumentTimeline in > Animation object. And, perhaps we should remove observer when releasing the > relationship of animation and timeline. Looking at this more closely, it turns out we already do keep an owning reference from Animation to its AnimationTimeline. So perhaps the problem is simply that the last thing holding a reference to the timeline is the Animation, and when we call SetTimeline and release that reference, the timeline gets destroyed without unregistering from the refresh driver. I also notice that we're using the timeline as the Animation's parent object which doesn't seem right. We probably should update that to store an nsIDocument* (and check that makes sense in light of bug 1277456).
Thanks brian. I fixed the DocumentTimeline. And I added crashtest into dom/animation/test/crashtest. Could you please reiview this patch?
Assignee: bbirtles → mantaroh
Attachment #8763050 - Flags: review?(bbirtles)
Comment on attachment 8763050 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. Review of attachment 8763050 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/animation/DocumentTimeline.cpp @@ +185,5 @@ > +DocumentTimeline::RemoveAnimation(Animation* aAnimation) > +{ > + AnimationTimeline::RemoveAnimation(aAnimation); > + > + if (GetRefreshDriver() && mAnimations.IsEmpty()) { We should check if mIsObservingRefreshDriver is true first. e.g. if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) { nsRefreshDriver* refreshDriver = GetRefreshDriver(); if (refreshDriver) { ... } } ::: dom/animation/DocumentTimeline.h @@ +70,5 @@ > > void NotifyRefreshDriverCreated(nsRefreshDriver* aDriver); > void NotifyRefreshDriverDestroying(nsRefreshDriver* aDriver); > > + void RemoveAnimation(Animation* aAnimation) override; This should go after NotifyAnimationUpdated so that it is together with the other AnimationTimeline overrides. ::: dom/animation/test/crashtests/1277272.html @@ +1,1 @@ > +<html> Let's split this test into a separate patch we can land after the fix (so that no one can exploit this in the time between landing this patch and it reaching the branches / Nightly build).
Attachment #8763050 - Flags: review?(bbirtles)
Attachment #8763050 - Attachment is obsolete: true
Attachment #8763078 - Flags: review?(bbirtles)
Thanks Brian. I fixed previous patch, and separated test. Could you please review these patches again?
Attachment #8763080 - Flags: review?(bbirtles)
Comment on attachment 8763078 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. Review of attachment 8763078 [details] [diff] [review]: ----------------------------------------------------------------- r=me with changes made. ::: dom/animation/DocumentTimeline.cpp @@ +188,5 @@ > + > + if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) { > + nsRefreshDriver* refreshDriver = GetRefreshDriver(); > + if (refreshDriver) { > + GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style); This should just use |refreshDriver|. @@ +189,5 @@ > + if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) { > + nsRefreshDriver* refreshDriver = GetRefreshDriver(); > + if (refreshDriver) { > + GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style); > + mIsObservingRefreshDriver = false; On further thought, we should probably never have a situation where mIsObservingRefreshDriver and true and GetRefreshDriver() == nullptr. So let's just make this: if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) { MOZ_ASSERT(GetRefreshDriver(), "GetRefreshDriver() should not be null when" " mIsObservingRefreshDriver is true"); GetRefreshDriver()->RemoveRefreshObserver ... ... }
Attachment #8763078 - Flags: review?(bbirtles) → review+
Comment on attachment 8763080 [details] [diff] [review] Bug 1277272 - Add crashtest into dom/animation/test. Review of attachment 8763080 [details] [diff] [review]: ----------------------------------------------------------------- Can't we simplify this test further? ::: dom/animation/test/crashtests/crashtests.list @@ +5,5 @@ > pref(dom.animations-api.core.enabled,true) load 1216842-3.html > pref(dom.animations-api.core.enabled,true) load 1216842-4.html > pref(dom.animations-api.core.enabled,true) load 1216842-5.html > pref(dom.animations-api.core.enabled,true) load 1216842-6.html > +pref(dom.animations-api.core.enabled,true) load 1277272.html This should be 1277272-1.html. We name all tests like this so if we need to add additional tests for the same bug we don't have to rename existing tests.
Attachment #8763080 - Flags: review?(bbirtles)
Thanks Brian. I misled the specification of crashtest. We should reload testcase page in order to reproduce crash. So I implemented crashtest as iframe. Could you please confirm this patch?
Attachment #8763080 - Attachment is obsolete: true
Attachment #8763164 - Flags: review?(bbirtles)
(In reply to Mantaroh Yoshinaga[:mantaroh] from comment #15) > I misled the specification of crashtest. > We should reload testcase page in order to reproduce crash. So I implemented > crashtest as iframe. So, do you mean that otherwise it doesn't reproduce reliably?
Comment on attachment 8763164 [details] [diff] [review] Bug 1277272 - Add crashtest into dom/animation/test. Review of attachment 8763164 [details] [diff] [review]: ----------------------------------------------------------------- r=me with changes made (but please don't land this or push it to try until we've landed the fix in part 1) ::: dom/animation/test/crashtests/1277272-1-inner.html @@ +6,5 @@ > + t.animation = document.body.animate([{marks: 'crop'},{marks: 'crop'}], 12); > + > + document.write('<html><body></body></html>'); > + setTimeout(play.bind(t), 4); > + setTimeout(setTimelineWithGC.bind(t), 5); Just curious, is there any reason we need to write the test like this? Could we just write: var animation = document.body.animate(...); document.write(...); setTimeout(function() { animation.play() }, 4); setTimeout(function() { animation.timeline = undefined; SpecialPowers.Cu.forceGC(); window.top.continueTest(); }, 5); ? ::: dom/animation/test/crashtests/1277272-1.html @@ +9,5 @@ > + document.documentElement.className = ""; > + return; > + } > + > + let frame = document.getElementById("frame"); (Nit: let just means you can re-assign frame. If you want to use ES6 syntax here, this should probably be const) @@ +15,5 @@ > +} > + > +function continueTest() { > + setTimeout(start.bind(window), 40); > +} Is the 40, here, special? Or is 1 enough? Or would requestAnimationFrame, even, work?
Attachment #8763164 - Flags: review?(bbirtles) → review+
Comment on attachment 8763162 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. [Security approval request comment] > How easily could an exploit be constructed based on the patch? With some difficulty since this relies on the timing of GC. > Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem? No, although it is a simple patch so it wouldn't be hard to reason about the issue. > Which older supported branches are affected by this flaw? Aurora (49) > If not all supported branches, which bug introduced the flaw? Bug 1178662 > Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? Not yet, but this patch probably applies cleanly to Aurora (currently confirming). If it doesn't it will be easy to create. > How likely is this patch to cause regressions; how much testing does it need? Average likelihood. I'm not aware of any particular risks. There is an automated test available we can land later once this has been applied to all affected branches.
Attachment #8763162 - Flags: sec-approval?
(In reply to Brian Birtles (:birtles) from comment #18) > > Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? > Not yet, but this patch probably applies cleanly to Aurora (currently > confirming). If it doesn't it will be easy to create. Confirmed that this patch applies cleanly to aurora.
Thanks Brian. (In reply to Brian Birtles (:birtles) from comment #17) > r=me with changes made (but please don't land this or push it to try until > we've landed the fix in part 1) OK. I will not land until sec-approval+ and landing part 1 patch. > ::: dom/animation/test/crashtests/1277272-1.html > @@ +9,5 @@ > > + document.documentElement.className = ""; > > + return; > > + } > > + > > + let frame = document.getElementById("frame"); > > (Nit: let just means you can re-assign frame. If you want to use ES6 syntax > here, this should probably be const) I've fixed using var syntax for consistent with other crashtests. > @@ +15,5 @@ > > +} > > + > > +function continueTest() { > > + setTimeout(start.bind(window), 40); > > +} > > Is the 40, here, special? Or is 1 enough? Or would requestAnimationFrame, > even, work? No, We can use 1 ms. So I fixed using 1ms.
Attachment #8763164 - Attachment is obsolete: true
Attachment #8763257 - Flags: review+
Comment on attachment 8763162 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. sec-approval+. Let's get this nominated for Aurora as well to get it fixed there.
Attachment #8763162 - Flags: sec-approval? → sec-approval+
Blocks: 1178662
Has Regression Range: --- → yes
Flags: sec-bounty?
Keywords: regression
Comment on attachment 8763162 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. Approval Request Comment [Feature/regressing bug #]: Bug 1178662 [User impact if declined]: Potentially exploitable heap-use-after-free vulnerability will remain [Describe test coverage new/current, TreeHerder]: Will land on trunk soon. Automated test case will be landed after part 1 has landed on both trunk and aurora. [Risks and why]: Only the usual risk that this introduces some other unforeseen regression. There is no particular reason to suspect regressions in this case except for the fact that, due to the sensitive nature of the bug, it has not been thoroughly exercised on try server. [String/UUID change made/needed]: None.
Attachment #8763162 - Flags: approval-mozilla-aurora?
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
Flags: sec-bounty? → sec-bounty+
Group: dom-core-security → core-security-release
Comment on attachment 8763162 [details] [diff] [review] Bug 1277272 - Remove RefreshObserver when removing animation from timeline. Regression from 49, let's uplift so that we don't end up shiping this to release.
Attachment #8763162 - Flags: approval-mozilla-aurora? → approval-mozilla-aurora+
Sorry, I forgot adding leave-open flag. I landed the test code. https://hg.mozilla.org/integration/mozilla-inbound/rev/b3f29b3fa5ab
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Group: core-security-release
So what's actually going on here? Why is this open before it's RESOLVED FIXED?
Group: core-security-release
Flags: needinfo?(dveditz)
Was the intent here that this should have been resolved in comment 28, since the fix reached central in comment 24 and the test reached central in comment 28?
Flags: needinfo?(mantaroh)
This has been fixed since comment 24. Only the tests were yet to land since they were waiting until the fix had landed and shipped on all affected branches (which happened in comment 26). Since it was only tests that were missing this shouldn't have been reopened in comment 27 or marked leave-open. Now that this has shipped on all affected branches, this can be opened up (but I don't have the privileges to do so).
Status: REOPENED → RESOLVED
Closed: 8 years ago8 years ago
Flags: needinfo?(mantaroh)
Flags: needinfo?(dveditz)
Resolution: --- → FIXED
Keywords: leave-open
Removing sec group per comment #31.
Group: core-security-release
Attachment #8765535 - Attachment description: nils@vulndev.org,4000?,2016-06-01,2016-06-23,2016-06-27,true,,, → nils@vulndev.org,4000,2016-06-01,2016-06-23,2016-06-27,true,,,
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: