AddressSanitizer: heap-use-after-free /builds/worker/workspace/build/src/obj-firefox/dist/include/js/RootingAPI.h:339:56 in operator bool
Categories
(Core :: DOM: File, defect, P1)
Tracking
()
Tracking | Status | |
---|---|---|
firefox-esr60 | --- | unaffected |
firefox-esr68 | --- | unaffected |
firefox67 | --- | unaffected |
firefox68 | --- | unaffected |
firefox69 | --- | wontfix |
firefox70 | + | verified |
firefox71 | + | verified |
People
(Reporter: jkratzer, Assigned: tt)
References
(Blocks 2 open bugs, Regression)
Details
(5 keywords, Whiteboard: [adv-main70+][adv-main70+r][post-critsmash-triage])
Attachments
(6 files)
(deleted),
text/html
|
Details | |
(deleted),
application/x-javascript
|
Details | |
(deleted),
application/x-javascript
|
Details | |
(deleted),
text/plain
|
Details | |
(deleted),
text/x-phabricator-request
|
lizzard
:
approval-mozilla-beta+
abillings
:
sec-approval+
|
Details |
(deleted),
text/x-phabricator-request
|
RyanVM
:
approval-mozilla-beta+
tjr
:
sec-approval+
|
Details |
Testcase found while fuzzing mozilla-central rev 546d1fd47c9a. This bug appears to be due to a race condition and may require up to a minute to trigger. Further, due to the use of XHR, the testcase must be served via a local webserver.
Also note, that the top contents of worker.js is not relevant to the bug but it appears that the load time of workers.js is related and the additional content delays loading enough to trigger the crash.
==28067==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000741778 at pc 0x7fc3444f05a2 bp 0x7fc3314fd100 sp 0x7fc3314fd0f8
READ of size 8 at 0x603000741778 thread T41 (DOM Worker)
#0 0x7fc3444f05a1 in operator bool /builds/worker/workspace/build/src/obj-firefox/dist/include/js/RootingAPI.h:339:56
#1 0x7fc3444f05a1 in TraceCallbackFunc::Trace(JS::Heap<JSObject*>*, char const*, void*) const /builds/worker/workspace/build/src/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp:48
#2 0x7fc3444a70ee in mozilla::CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:797:15
#3 0x7fc3444a8e97 in mozilla::CycleCollectedJSRuntime::TraverseRoots(nsCycleCollectionNoteRootCallback&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:1140:3
#4 0x7fc3444ec0de in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3611:19
#5 0x7fc3444eb300 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3413:9
#6 0x7fc3444eee6c in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3949:21
#7 0x7fc352d7ee17 in callGCCallback /builds/worker/workspace/build/src/js/src/gc/GC.cpp:1488:3
#8 0x7fc352d7ee17 in js::gc::GCRuntime::maybeCallGCCallback(JSGCStatus) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:6986
#9 0x7fc352d7fe70 in ~AutoCallGCCallbacks /builds/worker/workspace/build/src/js/src/gc/GC.cpp:6965:32
#10 0x7fc352d7fe70 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7076
#11 0x7fc352d83759 in js::gc::GCRuntime::collect(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7247:9
#12 0x7fc352d1ae8f in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7329:3
#13 0x7fc34d221ad1 in mozilla::dom::workerinternals::(anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/worker/workspace/build/src/dom/workers/RuntimeService.cpp:2342:5
#14 0x7fc3446a23a0 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1225:14
#15 0x7fc3446a83e8 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:486:10
#16 0x7fc3458a79f4 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:333:5
#17 0x7fc3457a1202 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#18 0x7fc3457a1202 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#19 0x7fc3457a1202 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#20 0x7fc34469bcea in nsThread::ThreadFunc(void*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:458:11
#21 0x7fc3674db0bd in _pt_root /builds/worker/workspace/build/src/nsprpub/pr/src/pthreads/ptthread.c:198:5
#22 0x7fc36711f6da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
#23 0x7fc3660fd88e in clone /build/glibc-OTsEL5/glibc-2.27/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
0x603000741778 is located 24 bytes inside of 32-byte region [0x603000741760,0x603000741780)
freed by thread T41 (DOM Worker) here:
#0 0x5569afb3e942 in __interceptor_free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:124:3
#1 0x7fc3444e3876 in SnowWhiteKiller::~SnowWhiteKiller() /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2416:7
#2 0x7fc3444e255e in nsCycleCollector::FreeSnowWhite(bool) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2609:3
#3 0x7fc3444ebd18 in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3584:3
#4 0x7fc3444eb300 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3413:9
#5 0x7fc3444eee6c in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3949:21
#6 0x7fc352d7ee17 in callGCCallback /builds/worker/workspace/build/src/js/src/gc/GC.cpp:1488:3
#7 0x7fc352d7ee17 in js::gc::GCRuntime::maybeCallGCCallback(JSGCStatus) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:6986
#8 0x7fc352d7fe70 in ~AutoCallGCCallbacks /builds/worker/workspace/build/src/js/src/gc/GC.cpp:6965:32
#9 0x7fc352d7fe70 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7076
#10 0x7fc352d83759 in js::gc::GCRuntime::collect(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7247:9
#11 0x7fc352d1ae8f in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::GCReason) /builds/worker/workspace/build/src/js/src/gc/GC.cpp:7329:3
#12 0x7fc34d221ad1 in mozilla::dom::workerinternals::(anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/worker/workspace/build/src/dom/workers/RuntimeService.cpp:2342:5
#13 0x7fc3446a23a0 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1225:14
#14 0x7fc3446a83e8 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:486:10
#15 0x7fc3458a79f4 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:333:5
#16 0x7fc3457a1202 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#17 0x7fc3457a1202 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#18 0x7fc3457a1202 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#19 0x7fc34469bcea in nsThread::ThreadFunc(void*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:458:11
#20 0x7fc3674db0bd in _pt_root /builds/worker/workspace/build/src/nsprpub/pr/src/pthreads/ptthread.c:198:5
#21 0x7fc36711f6da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
previously allocated by thread T41 (DOM Worker) here:
#0 0x5569afb3ecc3 in __interceptor_malloc /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:146:3
#1 0x5569afb73a2d in moz_xmalloc /builds/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:52:15
#2 0x7fc34b8e8ce1 in operator new /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/cxxalloc.h:33:10
#3 0x7fc34b8e8ce1 in mozilla::dom::Blob::Stream(JSContext*, JS::MutableHandle<JSObject*>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/file/Blob.cpp:362
#4 0x7fc348d2c051 in mozilla::dom::Blob_Binding::stream(JSContext*, JS::Handle<JSObject*>, mozilla::dom::Blob*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/BlobBinding.cpp:745:24
#5 0x7fc34b07179d in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3163:13
#6 0x7fc351c6df07 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:447:13
#7 0x7fc351c6df07 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:539
#8 0x7fc351c561ac in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:598:10
#9 0x7fc351c561ac in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3084
#10 0x7fc351c3784f in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:424:10
#11 0x7fc351c6ea0f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:567:13
#12 0x7fc351c70c32 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:610:8
#13 0x7fc352782368 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jsapi.cpp:2722:10
#14 0x7fc34a8d5a24 in mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:267:37
#15 0x7fc34b83afb1 in Call<nsCOMPtr<mozilla::dom::EventTarget> > /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:363:12
#16 0x7fc34b83afb1 in mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*) /builds/worker/workspace/build/src/dom/events/JSEventHandler.cpp:205
#17 0x7fc34b7ff59c in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1041:22
#18 0x7fc34b80103e in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1233:17
#19 0x7fc34b7e7a5a in HandleEvent /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/EventListenerManager.h:353:5
#20 0x7fc34b7e7a5a in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:349
#21 0x7fc34b7e6272 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:551:16
#22 0x7fc34b7ebc3b in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:1047:11
#23 0x7fc34b7f2cb0 in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp
#24 0x7fc34b7ae01d in mozilla::DOMEventTargetHelper::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/events/DOMEventTargetHelper.cpp:166:17
Thread T41 (DOM Worker) created by T0 (file:// Content) here:
#0 0x5569afb2729d in __interceptor_pthread_create /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:210:3
#1 0x7fc3674cd1b8 in _PR_CreateThread /builds/worker/workspace/build/src/nsprpub/pr/src/pthreads/ptthread.c:430:14
#2 0x7fc3674b6d9e in PR_CreateThread /builds/worker/workspace/build/src/nsprpub/pr/src/pthreads/ptthread.c:503:12
#3 0x7fc34469e1d9 in nsThread::Init(nsTSubstring<char> const&) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:672:8
#4 0x7fc34d2829c8 in mozilla::dom::WorkerThread::Create(mozilla::dom::WorkerThreadFriendKey const&) /builds/worker/workspace/build/src/dom/workers/WorkerThread.cpp:92:7
#5 0x7fc34d1f293d in mozilla::dom::workerinternals::RuntimeService::ScheduleWorker(mozilla::dom::WorkerPrivate*) /builds/worker/workspace/build/src/dom/workers/RuntimeService.cpp:1431:14
#6 0x7fc34d1f0fb4 in mozilla::dom::workerinternals::RuntimeService::RegisterWorker(mozilla::dom::WorkerPrivate*) /builds/worker/workspace/build/src/dom/workers/RuntimeService.cpp:1296:19
#7 0x7fc34d251202 in mozilla::dom::WorkerPrivate::Constructor(JSContext*, nsTSubstring<char16_t> const&, bool, mozilla::dom::WorkerType, nsTSubstring<char16_t> const&, nsTSubstring<char> const&, mozilla::dom::WorkerLoadInfo*, mozilla::ErrorResult&, nsTString<char16_t>) /builds/worker/workspace/build/src/dom/workers/WorkerPrivate.cpp:2327:24
#8 0x7fc34d201765 in mozilla::dom::Worker::Constructor(mozilla::dom::GlobalObject const&, nsTSubstring<char16_t> const&, mozilla::dom::WorkerOptions const&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/workers/Worker.cpp:30:41
#9 0x7fc34a5be50c in mozilla::dom::Worker_Binding::_constructor(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/WorkerBinding.cpp:1141:52
#10 0x7fc351c71bf7 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:447:13
#11 0x7fc351c71bf7 in CallJSNativeConstructor /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:463
#12 0x7fc351c71bf7 in InternalConstruct(JSContext*, js::AnyConstructArgs const&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:656
#13 0x7fc352f59829 in js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICCall_Fallback*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jit/BaselineIC.cpp:3210:10
#14 0x2384695c8797 (<unknown module>)
#15 0x62100044c1ff (<unknown module>)
#16 0x2384695c648e (<unknown module>)
#17 0x7fc35315ee3d in EnterBaseline /builds/worker/workspace/build/src/js/src/jit/BaselineJIT.cpp:111:5
#18 0x7fc35315ee3d in js::jit::EnterBaselineInterpreterAtBranch(JSContext*, js::InterpreterFrame*, unsigned char*) /builds/worker/workspace/build/src/js/src/jit/BaselineJIT.cpp:184
#19 0x7fc351c5e167 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:1991:17
#20 0x7fc351c3784f in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:424:10
#21 0x7fc351c6ea0f in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:567:13
#22 0x7fc351c70c32 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:610:8
#23 0x7fc352782368 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jsapi.cpp:2722:10
#24 0x7fc34a8dad40 in mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/EventListenerBinding.cpp:52:8
#25 0x7fc34b7ff565 in HandleEvent<mozilla::dom::EventTarget *> /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/EventListenerBinding.h:66:12
#26 0x7fc34b7ff565 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1035
#27 0x7fc34b800fe0 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1233:17
#28 0x7fc34b7e7a5a in HandleEvent /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/EventListenerManager.h:353:5
#29 0x7fc34b7e7a5a in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:349
#30 0x7fc34b7e6272 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:551:16
#31 0x7fc34b7ebc3b in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:1047:11
#32 0x7fc34b7f2cb0 in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp
#33 0x7fc348ad2fca in nsINode::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1061:17
#34 0x7fc348470559 in nsContentUtils::DispatchEvent(mozilla::dom::Document*, nsISupports*, nsTSubstring<char16_t> const&, mozilla::CanBubble, mozilla::Cancelable, mozilla::Composed, mozilla::Trusted, bool*, mozilla::ChromeOnlyDispatch) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:3973:28
#35 0x7fc348470323 in nsContentUtils::DispatchTrustedEvent(mozilla::dom::Document*, nsISupports*, nsTSubstring<char16_t> const&, mozilla::CanBubble, mozilla::Cancelable, mozilla::Composed, bool*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:3943:10
#36 0x7fc3487ba9b2 in mozilla::dom::Document::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/Document.cpp:7060:3
#37 0x7fc3488a2484 in applyImpl<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1124:12
#38 0x7fc3488a2484 in apply<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1130
#39 0x7fc3488a2484 in mozilla::detail::RunnableMethodImpl<mozilla::dom::Document*, void (mozilla::dom::Document::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1176
#40 0x7fc344670451 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:295:32
#41 0x7fc3446a23a0 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1225:14
#42 0x7fc3446a83e8 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:486:10
#43 0x7fc3458a602f in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:88:21
#44 0x7fc3457a1202 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#45 0x7fc3457a1202 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#46 0x7fc3457a1202 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#47 0x7fc34dab8d99 in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:137:27
#48 0x7fc3519b68df in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:934:20
#49 0x7fc3457a1202 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#50 0x7fc3457a1202 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#51 0x7fc3457a1202 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#52 0x7fc3519b6186 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:769:34
#53 0x5569afb71d73 in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:56:28
#54 0x5569afb71d73 in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:267
#55 0x7fc365ffdb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/workspace/build/src/obj-firefox/dist/include/js/RootingAPI.h:339:56 in operator bool
Shadow bytes around the buggy address:
0x0c06800e0290: fa fa fd fd fd fa fa fa 00 00 00 fa fa fa 00 00
0x0c06800e02a0: 00 fa fa fa fd fd fd fa fa fa fd fd fd fd fa fa
0x0c06800e02b0: fd fd fd fa fa fa fd fd fd fd fa fa fd fd fd fd
0x0c06800e02c0: fa fa 00 00 00 00 fa fa fd fd fd fd fa fa fd fd
0x0c06800e02d0: fd fa fa fa fd fd fd fd fa fa fd fd fd fd fa fa
=>0x0c06800e02e0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd[fd]
0x0c06800e02f0: fa fa fd fd fd fd fa fa fd fd fd fa fa fa fd fd
0x0c06800e0300: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
0x0c06800e0310: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
0x0c06800e0320: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
0x0c06800e0330: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
Shadow gap: cc
==28067==ABORTING
Reporter | ||
Comment 1•5 years ago
|
||
Reporter | ||
Comment 2•5 years ago
|
||
Reporter | ||
Comment 3•5 years ago
|
||
The attached testcase bisects back to the original implementation of Blob.stream() which was introduced in bug 1557121.
Updated•5 years ago
|
Comment 4•5 years ago
|
||
It seems (though I have no proof), that during the same call to:
#3 0x7fc3444ebd18 in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:3584:3
first a SnowWhiteKiller deletes some object without removing it from the mJSHolders Vectror of JSHolderInfo (containing raw pointers):
#1 0x7fc3444e3876 in SnowWhiteKiller::~SnowWhiteKiller() /builds/worker/workspace/build/src/xpcom/base/nsCycleCollector.cpp:2416:7
then mCCJSRuntime->TraverseRoots(*mBuilder);
is iterating that vector and crashes:
#2 0x7fc3444a70ee in mozilla::CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:797:15
But I am not sure, if the expected behavior of the SnowWhiteKiller in nsCycleCollector.cpp should be to keep in sync the private vector mJSHolders in CycleCollectedRuntime.cpp, though. This might need some further investigation.
Updated•5 years ago
|
Comment 5•5 years ago
|
||
This bug is a dup of bug 1571037.
Reporter | ||
Comment 6•5 years ago
|
||
This doesn't appear to be the same bug as the attached testcase still reproduces this issue using the latest nightly (6b93a83735ed).
Comment 7•5 years ago
|
||
Tyson, do you think it's possible to record this too?
Updated•5 years ago
|
Updated•5 years ago
|
Comment 8•5 years ago
|
||
Here is a trace from a debug build:
BuildID=20190919094654
SourceStamp=6b93a83735ed3ab3b57b46c1b768814b1a1af5d6
Assertion failure: T::cycleCollection::CheckForRightISupports(s) (not the nsISupports pointer we expect), at /builds/worker/workspace/build/src/obj-firefox/dist/include/nsCycleCollectionParticipant.h:357
rax = 0x000055e9d27f5340 rdx = 0x0000000000000000
rcx = 0x00007f9bd006758e rbx = 0x00007f9ba4fbf310
rsi = 0x00007f9bdcfd5770 rdi = 0x00007f9bdcfd4540
rbp = 0x00007f9bc03fdf70 rsp = 0x00007f9bc03fdf60
r8 = 0x00007f9bdcfd5770 r9 = 0x00007f9bc03ff700
r10 = 0x0000000000000000 r11 = 0x0000000000000000
r12 = 0x00007f9bc03fdfd8 r13 = 0x00007f9bc03fdfd7
r14 = 0x00007f9bd2badf60 r15 = 0x00007f9bd2badf60
rip = 0x00007f9bccc44cfc
OS|Linux|0.0.0 Linux 4.15.0-64-generic #73~16.04.1-Ubuntu SMP Fri Sep 13 09:56:18 UTC 2019 x86_64
CPU|amd64|family 6 model 158 stepping 9|1
GPU|||
Crash|SIGSEGV|0x0|33
33|0|libxul.so|DowncastCCParticipantImpl<mozilla::dom::(anonymous namespace)::BlobBodyStreamHolder, true>::Run|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollectionParticipant.h:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|356|0x32
33|1|libxul.so|BlobBodyStreamHolder::cycleCollection::Trace|hg:hg.mozilla.org/mozilla-central:dom/file/Blob.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|326|0x24
33|2|libxul.so|mozilla::CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback&)|hg:hg.mozilla.org/mozilla-central:xpcom/base/CycleCollectedJSRuntime.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|799|0xb
33|3|libxul.so|mozilla::CycleCollectedJSRuntime::TraverseRoots(nsCycleCollectionNoteRootCallback&)|hg:hg.mozilla.org/mozilla-central:xpcom/base/CycleCollectedJSRuntime.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|1138|0x5
33|4|libxul.so|nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|3611|0x15
33|5|libxul.so|nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|3413|0xf
33|6|libxul.so|nsCycleCollector_collect(nsICycleCollectorListener*)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|3949|0x1e
33|7|libxul.so|js::gc::GCRuntime::maybeCallGCCallback(JSGCStatus)|hg:hg.mozilla.org/mozilla-central:js/src/gc/GC.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|7060|0xb
33|8|libxul.so|js::gc::GCRuntime::gcCycle(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason)|hg:hg.mozilla.org/mozilla-central:js/src/gc/GC.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|7089|0xd
33|9|libxul.so|js::gc::GCRuntime::collect(bool, js::SliceBudget, mozilla::Maybe<JSGCInvocationKind> const&, JS::GCReason)|hg:hg.mozilla.org/mozilla-central:js/src/gc/GC.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|7321|0x1d
33|10|libxul.so|js::gc::GCRuntime::gc(JSGCInvocationKind, JS::GCReason)|hg:hg.mozilla.org/mozilla-central:js/src/gc/GC.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|7403|0x24
33|11|libxul.so|WorkerThreadPrimaryRunnable::Run|hg:hg.mozilla.org/mozilla-central:dom/workers/RuntimeService.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|2342|0x5
33|12|libxul.so|nsThread::ProcessNextEvent(bool, bool*)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThread.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|1225|0x15
33|13|libxul.so|NS_ProcessNextEvent(nsIThread*, bool)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThreadUtils.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|486|0x11
33|14|libxul.so|mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessagePump.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|333|0xd
33|15|libxul.so|MessageLoop::RunInternal()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|315|0x17
33|16|libxul.so|MessageLoop::Run()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|290|0x8
33|17|libxul.so|nsThread::ThreadFunc(void*)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThread.cpp:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|458|0x38
33|18|libnspr4.so|_pt_root|hg:hg.mozilla.org/mozilla-central:nsprpub/pr/src/pthreads/ptthread.c:6b93a83735ed3ab3b57b46c1b768814b1a1af5d6|198|0x7
33|19|libpthread-2.23.so|start_thread|/build/glibc-LK5gWL/glibc-2.23/nptl/pthread_create.c|333|0x11
33|20|libc-2.23.so|clone|||0x6d
Comment 9•5 years ago
|
||
Sorry for my probably very incomplete knowledge of our toolchain, but is there a way to see (always regarding Comment 4) if it is actually the same call to BeginCollection? It is definitely the same Thread and the same stack trace up to that call, but it might be always different moments in time. Do we have a possibility to see this (from timestamps, log information or whatever) ?
But in the end probably it does not even make a real difference: The memory has been freed by that same function in that same thread, so I would exclude strange side effects and look straight into the implementation of the SnowWhiteKiller and surroundings also in the implementing classes.
Comment 10•5 years ago
|
||
The debug information just tells us, that we have a BlobBodyStreamHolder object, that gets corrupted:
326 CRASH--> NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BlobBodyStreamHolder,
BodyStreamHolder)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mStream)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
The BlobBodyStreamHolder is held as a RefPtr by a BodyStream (mStreamHolder), which is in turn held by Blob, which itself is a Cycle Collector participant.
I assume, this nested situation leads to a situation, in which:
- CycleCollector collects all potential objects in a vector
- while looking on them, the Blob is evicted
- This removes (obscure to the cycle collector) also the nested BlobBodyStreamHolder
- which then the Cycle Collector wants to remove
As I am new to Cycle Collectors: Is it a foreseen usage, to nest those Cycle Collector participants and to delete them through the owner rather than leave deletion to the Collector itself?
Updated•5 years ago
|
Comment 11•5 years ago
|
||
Comment 12•5 years ago
|
||
Probably BlobBodyStreamHolder should not just declare NS_DECL_ISUPPORTS_INHERITED
but a cycle collector variant one? Which?
Updated•5 years ago
|
Comment 13•5 years ago
|
||
Actually, I don't see anything wrong with the CC macros. BlobBodyStreamHolder uses NS_DECL_ISUPPORTS_INHERITED and NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED, which should be fine. It might need to |mozilla::DropJSObjects(this);| in its destructor and unlink though.
Comment 14•5 years ago
|
||
(In reply to Peter Van der Beken [:peterv] from comment #14)
Actually, I don't see anything wrong with the CC macros. BlobBodyStreamHolder uses NS_DECL_ISUPPORTS_INHERITED and NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED, which should be fine. It might need to |mozilla::DropJSObjects(this);| in its destructor and unlink though.
Thanks for that hint! In fact, the unlink function and the destructor look incomplete.
Assignee | ||
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 15•5 years ago
|
||
(In reply to Peter Van der Beken [:peterv] from comment #14)
Actually, I don't see anything wrong with the CC macros. BlobBodyStreamHolder uses NS_DECL_ISUPPORTS_INHERITED and NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED, which should be fine. It might need to |mozilla::DropJSObjects(this);| in its destructor and unlink though.
Apply this comment can fix the issue. However, I also found in BlobBodyStreamHolder::NullifyStream()
[1] would call that as well and it's called by BodyStream::ReleaseObjects()
. I wonder if something (XHR) blocks the normal calls for cleaning up/releasing objects and thus we have UAF in this case. I need to dig into the code path more.
Comment 16•5 years ago
|
||
I would strongly recommend to implement in any case the expected unlink functions directly into the holder object and not to rely on BodyStream::ReleaseObjects()
, because I suspect, that the order of deletion might not be in a way, that BodyStream::ReleaseObjects()
is ever called before trying to delete the Holder through the Cycle Collector. It might be a good idea, though, to guide all flows to the same implementing function (from the holder's destructor and the BodyStream::ReleaseObjects()
/BlobBodyStreamHolder::NullifyStream()
path), which could be directly the unlink function implemented by the macro (and with the right content).
Assignee | ||
Comment 17•5 years ago
|
||
So, the issue caught by this test is:
- It failed at the
BodyStream::Create()
[1] BlobBodyStreamHolder
tells CC it holds a JSObject in [2] (before [1])- Thus,
BodyStream
is deleted right afterBodyStream::Create()
(because it fails and doesn't call the addref) - And thus,
BlobBodyStreamHolder
is called after that (ref count is zero; on snow white) - The second access is probably when CC check the registered object and then UAF
Normally, BodyStream::Close()
would be called (and thus BlodyStream::ReleaseObject()
, NullifyStream()
, DropJSObject
would be called) before it's deleted. However, in the case here, the BlodyStream::ReleaseObject()
was not called before it got destructed.
To fix this, we should clean up (calling Close()
) when we fail on the creation of the BodyStream. I'll update a patch for that.
[1] https://searchfox.org/mozilla-central/rev/45f30e1d19bde27bf07e47a0a5dd0962dd27ba18/dom/base/BodyStream.cpp#115
[2] https://searchfox.org/mozilla-central/rev/f43ae7e1c43a4a940b658381157a6ea6c5a185c1/dom/file/Blob.cpp#362
Assignee | ||
Comment 18•5 years ago
|
||
(In reply to Jens Stutte [:jstutte] from comment #17)
I would strongly recommend to implement in any case the expected unlink functions directly into the holder object and not to rely on
BodyStream::ReleaseObjects()
, because I suspect, that the order of deletion might not be in a way, thatBodyStream::ReleaseObjects()
is ever called before trying to delete the Holder through the Cycle Collector. It might be a good idea, though, to guide all flows to the same implementing function (from the holder's destructor and theBodyStream::ReleaseObjects()
/BlobBodyStreamHolder::NullifyStream()
path), which could be directly the unlink function implemented by the macro (and with the right content).
In this case, the unlink function for the BlobBodyStreamHolder
wasn't called. So, if it's what we suppose to do, we should open another bug for that.
Assignee | ||
Comment 19•5 years ago
|
||
Assignee | ||
Comment 20•5 years ago
|
||
I could reproduce the issue on my desktop. After applying the patch I attached, I cannot hit the issue by the provided testcase.
Assignee | ||
Comment 21•5 years ago
|
||
(In reply to Tom Tung [:tt, :ttung] from comment #19)
In this case, the unlink function for the
BlobBodyStreamHolder
wasn't called. So, if it's what we suppose to do, we should open another bug for that.
Talked with Jens this morning, we suspect the reason for that is probably because the SnowWhiteKiller
doesn't have any way to understand these stuff. Thus the holder is killed and its work inside unlink is not called.
Also, we should probably call DropJSObjects
on the holder's destructor to avoid another edge case in the future. And we have checked DropJSObjects
is safe to be called multiple times.
The only thing we are not so sure about is that usage for also calling DropJSObjects
on unlink function if we will do that on the destructor.
(In reply to Peter Van der Beken [:peterv] from comment #14)
Actually, I don't see anything wrong with the CC macros. BlobBodyStreamHolder uses NS_DECL_ISUPPORTS_INHERITED and NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED, which should be fine. It might need to |mozilla::DropJSObjects(this);| in its destructor and unlink though.
Peter, could you shed the light on the usage for doing that in unlink? My question is more like why it's not enough for calling that on destructor. Would it happen like we need to DropJSObjects
at the point of unlink? Thank you in advance!
Updated•5 years ago
|
Assignee | ||
Comment 22•5 years ago
|
||
Depends on D47118
Assignee | ||
Comment 23•5 years ago
|
||
Comment on attachment 9095244 [details]
Bug 1577311 - Close the stream if there is a failure during the creation; r=baku
Security Approval Request
- How easily could an exploit be constructed based on the patch?: The attacker might understand it's probably related to not close the stream on the creation, but they cannot understand the way for making that fail on the creation.
- Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
- Which older supported branches are affected by this flaw?: 69
- If not all supported branches, which bug introduced the flaw?: Bug 1557121
- Do you have backports for the affected branches?: No
- If not, how different, hard to create, and risky will they be?: Not really sure about the answer to this. Again, the attacker might understand it's probably related to not close the stream on the creation, but they cannot understand the way for making that fail on the creation
- How likely is this patch to cause regressions; how much testing does it need?: The code path itself is for the failure cases and it only close the stream on the failure cases. So, I guess it should be hard.
Comment 24•5 years ago
|
||
sec-approval+ for trunk. We'll want this nominated for beta as well.
Updated•5 years ago
|
Assignee | ||
Comment 25•5 years ago
|
||
Jason, could you help me to verify if P1 solves the issue? It works on my machine. Thanks!
Assignee | ||
Comment 26•5 years ago
|
||
Land Patch 1 first since I cannot reproduce the issue once I apply that.
Comment 27•5 years ago
|
||
Initial landing: https://hg.mozilla.org/integration/autoland/rev/7d1f6ed3ccf56db2f558bd8aaf352543122e09a2
Backed out for build bustage in dom/file/Blob.cpp::
https://hg.mozilla.org/integration/autoland/rev/9ffde0fb448b092c0b931610ee26d26e0ddb30a7
Push with bustage: https://treeherder.mozilla.org/#/jobs?repo=autoland&group_state=expanded&selectedJob=269255700&resultStatus=testfailed%2Cbusted%2Cexception%2Csuperseded%2Cretry%2Cusercancel&revision=7d1f6ed3ccf56db2f558bd8aaf352543122e09a2
Failure log: https://treeherder.mozilla.org/logviewer.html#?job_id=269251355&repo=autoland
[task 2019-10-01T17:08:45.937Z] 17:08:45 ERROR - /builds/worker/workspace/build/src/dom/file/Blob.cpp:362:41: error: variable of type 'mozilla::dom::(anonymous namespace)::BlobBodyStreamHolder' only valid on the stack
[task 2019-10-01T17:08:45.937Z] 17:08:45 INFO - RefPtr<BlobBodyStreamHolder> holder = new BlobBodyStreamHolder();
[task 2019-10-01T17:08:45.937Z] 17:08:45 INFO - ^
[task 2019-10-01T17:08:45.937Z] 17:08:45 INFO - /builds/worker/workspace/build/src/dom/file/Blob.cpp:362:41: note: value incorrectly allocated on the heap
[task 2019-10-01T17:08:45.937Z] 17:08:45 INFO - /builds/worker/workspace/build/src/dom/file/Blob.cpp:295:7: note: 'mozilla::dom::(anonymous namespace)::BlobBodyStreamHolder' is a stack type because it inherits from a stack type 'mozilla::dom::BodyStreamHolder'
[task 2019-10-01T17:08:45.938Z] 17:08:45 INFO - class BlobBodyStreamHolder final : public BodyStreamHolder {
[task 2019-10-01T17:08:45.939Z] 17:08:45 INFO - ^
[task 2019-10-01T17:08:45.939Z] 17:08:45 INFO - /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/BodyStream.h:55:19: note: 'mozilla::dom::BodyStreamHolder' is a stack type because member 'mStreamCreated' is a stack type 'DebugOnly<bool>'
[task 2019-10-01T17:08:45.939Z] 17:08:45 INFO - DebugOnly<bool> mStreamCreated = false;
[task 2019-10-01T17:08:45.939Z] 17:08:45 INFO - ^
[task 2019-10-01T17:08:45.939Z] 17:08:45 INFO - 1 error generated.
Reporter | ||
Comment 28•5 years ago
|
||
(In reply to Tom Tung [:tt, :ttung] from comment #26)
Jason, could you help me to verify if P1 solves the issue? It works on my machine. Thanks!
I can confirm that this issue no longer reproduces using the patch in comment 24.
Updated•5 years ago
|
Comment 30•5 years ago
|
||
(In reply to Peter Van der Beken [:peterv] from comment #14)
Actually, I don't see anything wrong with the CC macros. BlobBodyStreamHolder uses NS_DECL_ISUPPORTS_INHERITED and NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED, which should be fine. It might need to |mozilla::DropJSObjects(this);| in its destructor and unlink though.
Peter, could you shed the light on the usage for doing that in unlink? My question is more like why it's not enough for calling that on destructor. Would it happen like we need to
DropJSObjects
at the point of unlink? Thank you in advance!
Not doing it in unlink might lead to leaks, the easiest to understand case is that there's a cycle between the BlobBodyStreamHolder and a JS object, with one edge from BlobBodyStreamHolder to the JS object and one edge from the JS object to the BlobBodyStreamHolder. If you don't DropJSObjects in unlink, then the JS object will not be collected by the JS GC (because the JS holder, the BlobBodyStreamHolder in this case, still has a reference to it). In turn, we will not release the BlobBodyStreamHolder because it's held alive by a JS object. So the destructor for BlobBodyStreamHolder might not even be run in this case.
Note that the cycles and edges involved might be much more complicated, but incomplete unlinking can definitely lead to leaks.
Comment 31•5 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/9898a46a96539cf58de81a2be6bacd9ee4b761b1
https://hg.mozilla.org/mozilla-central/rev/9898a46a9653
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 32•5 years ago
|
||
(In reply to Peter Van der Beken [:peterv] from comment #31)
Not doing it in unlink might lead to leaks, the easiest to understand case is that there's a cycle between the BlobBodyStreamHolder and a JS object, with one edge from BlobBodyStreamHolder to the JS object and one edge from the JS object to the BlobBodyStreamHolder. If you don't DropJSObjects in unlink, then the JS object will not be collected by the JS GC (because the JS holder, the BlobBodyStreamHolder in this case, still has a reference to it). In turn, we will not release the BlobBodyStreamHolder because it's held alive by a JS object. So the destructor for BlobBodyStreamHolder might not even be run in this case.
Note that the cycles and edges involved might be much more complicated, but incomplete unlinking can definitely lead to leaks.
Thanks for the explanation! That clear on thought and I will call DropJSObject in the unlink fucntion in D47218.
Updated•5 years ago
|
Assignee | ||
Comment 33•5 years ago
|
||
Comment on attachment 9095443 [details]
Bug 1577311 - Ensure the js object is dropped while the holder is unlinked and destructored;
Security Approval Request
- How easily could an exploit be constructed based on the patch?: This patch cleanup the link between the holder and the js object in unlink function and dtor of the holder. It's a safeguard to prevent leaking in the worst case in theory. So, it should be hard to attack based on this patch.
- Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
- Which older supported branches are affected by this flaw?: 69
- If not all supported branches, which bug introduced the flaw?: Bug 1557121
- Do you have backports for the affected branches?: No
- If not, how different, hard to create, and risky will they be?: So this patch prevents the worst case in theory so it should be hard to attack.
- How likely is this patch to cause regressions; how much testing does it need?: Shouldn't be since it only calls cleanup function in its dtor and unlink function
Assignee | ||
Comment 34•5 years ago
|
||
I will uplift these two patches to the beta once the second stay in m-c for more than two days without reporting any issue.
Assignee | ||
Comment 35•5 years ago
|
||
(In reply to Jason Kratzer [:jkratzer] from comment #29)
(In reply to Tom Tung [:tt, :ttung] from comment #26)
Jason, could you help me to verify if P1 solves the issue? It works on my machine. Thanks!
I can confirm that this issue no longer reproduces using the patch in comment 24.
Thanks for the verify! (And sorry that I somehow missed this comment : (
Comment 36•5 years ago
|
||
Comment on attachment 9095443 [details]
Bug 1577311 - Ensure the js object is dropped while the holder is unlinked and destructored;
sec-approval+ for trunk and I'll copy Al and ask to please nominate for beta as well.
Can you request beta uplift please (and provide a rebased patch for beta if necessary?) Thanks!
Comment 38•5 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/9e3d328e63acdba002c3f4b4305fec205857c0cb
Patch applies cleanly to beta.
Comment 39•5 years ago
|
||
Assignee | ||
Comment 40•5 years ago
|
||
Comment on attachment 9095244 [details]
Bug 1577311 - Close the stream if there is a failure during the creation; r=baku
Beta/Release Uplift Approval Request
- User impact if declined: UAF if run the script provided by the reporter
- Is this code covered by automated tests?: No
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): The patch calls the cleanup function while there is a failure in the creation of a
Stream
object. In general, this code path is not easy to be run (because, normally, it is not easy to have a failure during the creation). Note that this patch fixes the reported issue and confirmed by the reporter.
Another patch (Ensure the js ...) is a cleanup function to ensure there is no other similar case that is not covered by the previous patch. Note, it was pushed to m-c only for one day, but I think it should be safe to uplift.
- String changes made/needed:
Assignee | ||
Updated•5 years ago
|
Comment on attachment 9095244 [details]
Bug 1577311 - Close the stream if there is a failure during the creation; r=baku
Fix for sec-high issue, OK for beta 14 uplift.
Updated•5 years ago
|
Comment 42•5 years ago
|
||
uplift |
Assignee | ||
Updated•5 years ago
|
Assignee | ||
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 43•5 years ago
|
||
Hey Tom,
Are there any steps to reproduce this issue and the expected result?
Based on what is here so far I loaded the testcase on a local webserver, opened it in Firefox and expected it to crash after 1-2 minutes but nothing happened. I'm also getting an error in cmd so not quite sure if I can verify this fix..
Assignee | ||
Comment 44•5 years ago
|
||
(In reply to Timea Cernea [:tbabos] from comment #44)
Hey Tom,
Are there any steps to reproduce this issue and the expected result?
Based on what is here so far I loaded the testcase on a local webserver, opened it in Firefox and expected it to crash after 1-2 minutes but nothing happened. I'm also getting an error in cmd so not quite sure if I can verify this fix..
Hi Timea,
IIRC, if the web page doesn't crashing, then the fix is verified. Before the fixed is landed, it crashed immedicately on my machine.
Comment 45•5 years ago
|
||
That sounds good, but I can't reproduce the crash on affected Nightly 69 either.
If you could find the time to verify Nightly and Beta for uplift, that would be great. I can't vouch for the fix if I can't reproduce it on affected builds :(
Assignee | ||
Comment 46•5 years ago
|
||
(In reply to Timea Cernea [:tbabos] from comment #46)
That sounds good, but I can't reproduce the crash on affected Nightly 69 either.
Did you enable the fuzzy mode? (ac_add_options --enable-fuzzing
)
The testcase is 100% reproducible to me while I was testing (both Mac Book Pro and Linux machine). And I used an ASAN build with enable fuzzy mode.
I put the command I ran below:
python -m ffpuppet -p prefs.js --xvfb -d -l log ~/Work/mozilla-central/objdir-ff-asan/dist/bin/firefox -u http://localhost:8000/testcase.html
If you are curious about ffpuppet you can go to this https://github.com/MozillaSecurity/ffpuppet
Please let me know if you need more information.
If you could find the time to verify Nightly and Beta for uplift, that would be great. I can't vouch for the fix if I can't reproduce it on affected builds :(
Could you elaborate more? I guess you are asking for the reversion number? I put that below:
(In reply to Sebastian Hengst [:aryx] (needinfo on intermittent or backout) from comment #43)
https://hg.mozilla.org/releases/mozilla-beta/rev/d18091b73cc4
https://hg.mozilla.org/releases/mozilla-beta/rev/a465465b5d98
Updated•5 years ago
|
Comment 47•5 years ago
|
||
Thanks for the help Tom!
Managed to reproduce the crash on 69 Nightly on linux and macOS, it required some setup I was not aware of and had to do some research.
Verified - fixed on fuzzing asan builds on latest Beta 71.0b7 and latest Release 70.0.2 on Ubuntu 18.04 and MacOS 10.14.
Updated•5 years ago
|
Updated•4 years ago
|
Updated•3 years ago
|
Description
•