Closed Bug 1740797 Opened 2 years ago Closed 2 years ago

AddressSanitizer: heap-use-after-free [@ __asan_memcpy] with READ of size 32768

Categories

(Core :: DOM: File, defect, P1)

defect

Tracking

()

RESOLVED FIXED
97 Branch
Tracking Status
firefox-esr91 96+ fixed
firefox94 --- wontfix
firefox95 --- wontfix
firefox96 + fixed
firefox97 + fixed

People

(Reporter: jkratzer, Assigned: nika)

References

(Blocks 1 open bug)

Details

(Keywords: csectype-uaf, sec-high, testcase, Whiteboard: [bugmon:confirm][sec-survey][adv-main96+r][adv-ESR91.5+r])

Crash Data

Attachments

(2 files)

Testcase found while fuzzing mozilla-central rev 300fc6bd088e (built with: --enable-address-sanitizer --enable-fuzzing).

Testcase can be reproduced using the following commands:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch --build 300fc6bd088e --asan --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.zip
AddressSanitizer: heap-use-after-free [@ __asan_memcpy] with READ of size 32768

    =================================================================
    ==1238264==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f79a8c86800 at pc 0x5576cedc6387 bp 0x7f7978adeb70 sp 0x7f7978ade338
    READ of size 32768 at 0x7f79a8c86800 thread T30 (StreamTrans #3)
        #0 0x5576cedc6386 in __asan_memcpy /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
        #1 0x7f7ac3d972a4 in nsReadFromRawBuffer(nsIOutputStream*, void*, char*, unsigned int, unsigned int, unsigned int*) /xpcom/io/nsPipe3.cpp:1726:3
        #2 0x7f7ac3d96db2 in nsPipeOutputStream::WriteSegments(nsresult (*)(nsIOutputStream*, void*, char*, unsigned int, unsigned int, unsigned int*), void*, unsigned int, unsigned int*) /xpcom/io/nsPipe3.cpp:1695:12
        #3 0x7f7ac3dac1ad in nsStreamCopierIB::ConsumeInputBuffer(nsIInputStream*, void*, char const*, unsigned int, unsigned int, unsigned int*) /xpcom/io/nsStreamUtils.cpp:501:33
        #4 0x7f7ac3da35f0 in nsStringInputStream::ReadSegments(nsresult (*)(nsIInputStream*, void*, char const*, unsigned int, unsigned int, unsigned int*), void*, unsigned int, unsigned int*) /xpcom/io/nsStringStream.cpp:316:17
        #5 0x7f7ac3dabbc0 in nsStreamCopierIB::DoCopy(nsresult*, nsresult*) /xpcom/io/nsStreamUtils.cpp:519:18
        #6 0x7f7ac3dacdc7 in nsAStreamCopier::Process() /xpcom/io/nsStreamUtils.cpp:302:22
        #7 0x7f7ac3da829e in nsAStreamCopier::Run() /xpcom/io/nsStreamUtils.cpp:418:5
        #8 0x7f7ac3e6671b in nsThreadPool::Run() /xpcom/threads/nsThreadPool.cpp:305:14
        #9 0x7f7ac3e5871b in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1169:16
        #10 0x7f7ac3e6300c in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:467:10
        #11 0x7f7ac5341b9d in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:300:20
        #12 0x7f7ac51bfe91 in RunInternal /ipc/chromium/src/base/message_loop.cc:331:10
        #13 0x7f7ac51bfe91 in RunHandler /ipc/chromium/src/base/message_loop.cc:324:3
        #14 0x7f7ac51bfe91 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:306:3
        #15 0x7f7ac3e50caf in nsThread::ThreadFunc(void*) /xpcom/threads/nsThread.cpp:391:10
        #16 0x7f7ae0afd09e in _pt_root /nsprpub/pr/src/pthreads/ptthread.c:201:5
        #17 0x7f7ae2412608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477:8
        #18 0x7f7ae1fda292 in __clone /build/glibc-eX1tMB/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
    
    0x7f79a8c86800 is located 790036480 bytes inside of 1547994324-byte region [0x7f7979b16800,0x7f79d5f5ecd4)
    freed by thread T0 (Isolated Web Co) here:
        #0 0x5576cedc6d62 in __interceptor_free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:111:3
        #1 0x7f7ac9b60af3 in mozilla::dom::MemoryBlobImpl::DataOwner::~DataOwner() /dom/file/MemoryBlobImpl.h:90:7
        #2 0x7f7ac9b5e0c5 in Release /dom/file/MemoryBlobImpl.h:67:5
        #3 0x7f7ac9b5e0c5 in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
        #4 0x7f7ac9b5e0c5 in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
        #5 0x7f7ac9b5e0c5 in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
        #6 0x7f7ac9b5e0c5 in mozilla::dom::MemoryBlobImpl::~MemoryBlobImpl() /dom/file/MemoryBlobImpl.h:165:29
        #7 0x7f7ac9b5e0fd in mozilla::dom::MemoryBlobImpl::~MemoryBlobImpl() /dom/file/MemoryBlobImpl.h:165:29
        #8 0x7f7ac9b3f436 in mozilla::dom::BlobImpl::Release() /dom/file/BlobImpl.cpp:97:1
        #9 0x7f7ac61b6eab in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
        #10 0x7f7ac61b6eab in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
        #11 0x7f7ac61b6eab in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
        #12 0x7f7ac61b6eab in Destruct /builds/worker/workspace/obj-build/dist/include/nsTArray.h:642:45
        #13 0x7f7ac61b6eab in nsTArray_Impl<RefPtr<mozilla::dom::BlobImpl>, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long) /builds/worker/workspace/obj-build/dist/include/nsTArray.h:2403:7
        #14 0x7f7ac61b6d2f in ClearAndRetainStorage /builds/worker/workspace/obj-build/dist/include/nsTArray.h:1479:5
        #15 0x7f7ac61b6d2f in nsTArray_Impl<RefPtr<mozilla::dom::BlobImpl>, nsTArrayInfallibleAllocator>::~nsTArray_Impl() /builds/worker/workspace/obj-build/dist/include/nsTArray.h:1034:7
        #16 0x7f7ac9b5e90e in ~MultipartBlobImpl /dom/file/MultipartBlobImpl.h:94:32
        #17 0x7f7ac9b5e90e in mozilla::dom::MultipartBlobImpl::~MultipartBlobImpl() /dom/file/MultipartBlobImpl.h:94:32
        #18 0x7f7ac9b3f436 in mozilla::dom::BlobImpl::Release() /dom/file/BlobImpl.cpp:97:1
        #19 0x7f7ac9b3b19f in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
        #20 0x7f7ac9b3b19f in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
        #21 0x7f7ac9b3b19f in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
        #22 0x7f7ac9b3b19f in mozilla::dom::File::~File() /dom/file/Blob.cpp:119:13
        #23 0x7f7ac9b3b22d in mozilla::dom::Blob::~Blob() /dom/file/Blob.cpp:119:13
        #24 0x7f7ac3c9a1c5 in SnowWhiteKiller::Visit(nsPurpleBuffer&, nsPurpleBufferEntry*) /xpcom/base/nsCycleCollector.cpp:2446:9
        #25 0x7f7ac3c7a8ed in void nsPurpleBuffer::VisitEntries<SnowWhiteKiller>(SnowWhiteKiller&) /xpcom/base/nsCycleCollector.cpp:954:27
        #26 0x7f7ac3c7b1a2 in nsCycleCollector::FreeSnowWhiteWithBudget(js::SliceBudget&) /xpcom/base/nsCycleCollector.cpp:2614:14
        #27 0x7f7ac61cd39c in AsyncFreeSnowWhite::Run() /js/xpconnect/src/XPCJSRuntime.cpp:149:9
        #28 0x7f7ac3e70c89 in IdleRunnableWrapper::Run() /xpcom/threads/nsThreadUtils.cpp:311:22
        #29 0x7f7ac3e721c2 in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:468:16
        #30 0x7f7ac3e37b8d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:771:26
        #31 0x7f7ac3e35405 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:649:15
        #32 0x7f7ac3e357f9 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:391:36
    
    previously allocated by thread T0 (Isolated Web Co) here:
        #0 0x5576cedc6fcd in __interceptor_malloc /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
        #1 0x7f7ac9b3f532 in mozilla::dom::BlobSet::AppendVoidPtr(void const*, unsigned int) /dom/file/BlobSet.cpp:22:16
        #2 0x7f7ac9b3e3f6 in mozilla::dom::MultipartBlobImpl::InitializeBlob(mozilla::dom::Sequence<mozilla::dom::OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString> const&, nsTSubstring<char16_t> const&, bool, bool, mozilla::ErrorResult&) /dom/file/MultipartBlobImpl.cpp:224:21
        #3 0x7f7ac9b3dd93 in mozilla::dom::Blob::Constructor(mozilla::dom::GlobalObject const&, mozilla::dom::Optional<mozilla::dom::Sequence<mozilla::dom::OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString> > const&, mozilla::dom::BlobPropertyBag const&, mozilla::ErrorResult&) /dom/file/Blob.cpp:225:11
        #4 0x7f7ac7987372 in mozilla::dom::Blob_Binding::_constructor(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/obj-build/dom/bindings/BlobBinding.cpp:1156:50
        #5 0x7f7ad0aac2c5 in CallJSNative /js/src/vm/Interpreter.cpp:387:13
        #6 0x7f7ad0aac2c5 in CallJSNativeConstructor /js/src/vm/Interpreter.cpp:403:8
        #7 0x7f7ad0aac2c5 in InternalConstruct(JSContext*, js::AnyConstructArgs const&) /js/src/vm/Interpreter.cpp:598:10
        #8 0x7f7ad0a95a8e in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:3232:16
        #9 0x7f7ad0a7ab41 in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:356:13
        #10 0x7f7ad0aa95cc in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:506:13
        #11 0x7f7ad0aab71b in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /js/src/vm/Interpreter.cpp:551:8
        #12 0x7f7ad0d1e8ad in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /js/src/vm/CallAndConstruct.cpp:117:10
        #13 0x7f7ac8e7fa79 in mozilla::dom::EventListener::HandleEvent(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /builds/worker/workspace/obj-build/dom/bindings/EventListenerBinding.cpp:62:8
        #14 0x7f7ac9a58f64 in void mozilla::dom::EventListener::HandleEvent<mozilla::dom::EventTarget*>(mozilla::dom::EventTarget* const&, mozilla::dom::Event&, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) /builds/worker/workspace/obj-build/dist/include/mozilla/dom/EventListenerBinding.h:65:12
        #15 0x7f7ac9a58a20 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /dom/events/EventListenerManager.cpp:1117:43
        #16 0x7f7ac9a5a0cc in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /dom/events/EventListenerManager.cpp:1314:17
        #17 0x7f7ac9a4823e in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:348:17
        #18 0x7f7ac9a46a4d in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:550:16
        #19 0x7f7ac9a4acc5 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /dom/events/EventDispatcher.cpp:1085:11
        #20 0x7f7acc3ad73f in nsDocumentViewer::LoadComplete(nsresult) /layout/base/nsDocumentViewer.cpp:1087:7
        #21 0x7f7acfb72463 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /docshell/base/nsDocShell.cpp:6333:20
    
    Thread T30 (StreamTrans #3) created by T0 (Isolated Web Co) here:
        #0 0x5576cedb16cc in __interceptor_pthread_create /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cpp:207:3
        #1 0x7f7ae0aed124 in _PR_CreateThread /nsprpub/pr/src/pthreads/ptthread.c:458:14
        #2 0x7f7ae0ade3ce in PR_CreateThread /nsprpub/pr/src/pthreads/ptthread.c:533:12
        #3 0x7f7ac3e53f75 in nsThread::Init(nsTSubstring<char> const&) /xpcom/threads/nsThread.cpp:607:18
        #4 0x7f7ac3e611bf in nsThreadManager::NewNamedThread(nsTSubstring<char> const&, unsigned int, nsIThread**) /xpcom/threads/nsThreadManager.cpp:581:12
        #5 0x7f7ac3e6c2f1 in NS_NewNamedThread(nsTSubstring<char> const&, nsIThread**, already_AddRefed<nsIRunnable>, unsigned int) /xpcom/threads/nsThreadUtils.cpp:163:57
        #6 0x7f7ac3e65330 in NS_NewNamedThread /xpcom/threads/nsThreadUtils.cpp:155:10
        #7 0x7f7ac3e65330 in nsThreadPool::PutEvent(already_AddRefed<nsIRunnable>, unsigned int) /xpcom/threads/nsThreadPool.cpp:120:17
        #8 0x7f7ac3e67608 in nsThreadPool::Dispatch(already_AddRefed<nsIRunnable>, unsigned int) /xpcom/threads/nsThreadPool.cpp:357:5
        #9 0x7f7ac427cf3c in mozilla::net::nsStreamTransportService::Dispatch(already_AddRefed<nsIRunnable>, unsigned int) /netwerk/base/nsStreamTransportService.cpp:308:16
        #10 0x7f7ac3dac85d in Dispatch /builds/worker/workspace/obj-build/dist/include/nsIEventTarget.h:41:14
        #11 0x7f7ac3dac85d in nsAStreamCopier::PostContinuationEvent_Locked() /xpcom/io/nsStreamUtils.cpp:450:21
        #12 0x7f7ac3d9efec in PostContinuationEvent /xpcom/io/nsStreamUtils.cpp:442:12
        #13 0x7f7ac3d9efec in nsAStreamCopier::Start(nsIInputStream*, nsIOutputStream*, nsIEventTarget*, void (*)(void*, nsresult), void*, unsigned int, bool, bool, void (*)(void*, unsigned int)) /xpcom/io/nsStreamUtils.cpp:266:12
        #14 0x7f7ac3d9ec4e in NS_AsyncCopy(nsIInputStream*, nsIOutputStream*, nsIEventTarget*, nsAsyncCopyMode, unsigned int, void (*)(void*, nsresult), void*, bool, bool, nsISupports**, void (*)(void*, unsigned int)) /xpcom/io/nsStreamUtils.cpp:590:16
        #15 0x7f7ac53227be in SerializeInputStreamAsPipeInternal<mozilla::ipc::ChildToParentStreamActorManager> /ipc/glue/InputStreamUtils.cpp:106:10
        #16 0x7f7ac53227be in mozilla::ipc::InputStreamHelper::SerializeInputStreamAsPipe(nsIInputStream*, mozilla::ipc::InputStreamParams&, bool, mozilla::ipc::ChildToParentStreamActorManager*) /ipc/glue/InputStreamUtils.cpp:154:3
        #17 0x7f7ac3da4486 in void nsStringInputStream::SerializeInternal<mozilla::ipc::ChildToParentStreamActorManager>(mozilla::ipc::InputStreamParams&, bool, unsigned int, unsigned int*, mozilla::ipc::ChildToParentStreamActorManager*) /xpcom/io/nsStringStream.cpp:435:5
        #18 0x7f7ac5321610 in SerializeInputStreamInternal<mozilla::ipc::ChildToParentStreamActorManager> /ipc/glue/InputStreamUtils.cpp:63:17
        #19 0x7f7ac5321610 in mozilla::ipc::InputStreamHelper::SerializeInputStream(nsIInputStream*, mozilla::ipc::InputStreamParams&, nsTArray<mozilla::ipc::FileDescriptor>&, bool, unsigned int, unsigned int*, mozilla::ipc::ChildToParentStreamActorManager*) /ipc/glue/InputStreamUtils.cpp:140:3
        #20 0x7f7ac3d8751b in void nsMultiplexInputStream::SerializeInternal<mozilla::ipc::ChildToParentStreamActorManager>(mozilla::ipc::InputStreamParams&, nsTArray<mozilla::ipc::FileDescriptor>&, bool, unsigned int, unsigned int*, mozilla::ipc::ChildToParentStreamActorManager*) /xpcom/io/nsMultiplexInputStream.cpp:985:7
        #21 0x7f7ac535c488 in bool mozilla::ipc::(anonymous namespace)::SerializeInputStreamWithFdsChild<mozilla::dom::ContentChild>(nsIIPCSerializableInputStream*, mozilla::ipc::IPCStream&, bool, mozilla::dom::ContentChild*) /ipc/glue/IPCStreamUtils.cpp:52:12
        #22 0x7f7ac531818d in SerializeInputStreamChild<mozilla::dom::ContentChild> /xpcom/base/nsCOMPtr.h
        #23 0x7f7ac531818d in mozilla::ipc::AutoIPCStream::Serialize(nsIInputStream*, mozilla::dom::ContentChild*) /ipc/glue/IPCStreamUtils.cpp:403:8
        #24 0x7f7ac9b802da in mozilla::RemoteLazyInputStreamUtils::SerializeInputStream(nsIInputStream*, unsigned long, mozilla::RemoteLazyStream&, mozilla::dom::ContentChild*) /dom/file/ipc/RemoteLazyInputStreamUtils.cpp:98:18
        #25 0x7f7ac9b69ae5 in nsresult mozilla::dom::IPCBlobUtils::SerializeInternal<mozilla::dom::ContentChild>(mozilla::dom::BlobImpl*, mozilla::dom::ContentChild*, mozilla::dom::IPCBlob&) /dom/file/ipc/IPCBlobUtils.cpp:133:8
        #26 0x7f7acb571cdc in bool mozilla::dom::ipc::BuildClonedMessageData<mozilla::dom::ContentChild>(mozilla::dom::ContentChild*, mozilla::dom::ipc::StructuredCloneData&, mozilla::dom::ClonedMessageData&) /dom/ipc/StructuredCloneData.cpp:174:21
        #27 0x7f7acfc56d61 in mozilla::ipc::IPDLParamTraits<mozilla::dom::SessionHistoryInfo>::Write(IPC::Message*, mozilla::ipc::IProtocol*, mozilla::dom::SessionHistoryInfo const&) /docshell/shistory/SessionHistoryEntry.cpp:1427:11
        #28 0x7f7ac5596ba2 in mozilla::dom::PContentChild::SendSetActiveSessionHistoryEntry(mozilla::dom::MaybeDiscarded<mozilla::dom::BrowsingContext> const&, mozilla::Maybe<nsPoint> const&, mozilla::dom::SessionHistoryInfo const&, unsigned int const&, unsigned int const&, nsID const&) /builds/worker/workspace/obj-build/ipc/ipdl/PContentChild.cpp:6842:5
        #29 0x7f7acfaf376f in mozilla::dom::BrowsingContext::SetActiveSessionHistoryEntry(mozilla::Maybe<nsPoint> const&, mozilla::dom::SessionHistoryInfo*, unsigned int, unsigned int) /docshell/base/BrowsingContext.cpp:3524:35
        #30 0x7f7acfba0303 in nsDocShell::UpdateActiveEntry(bool, mozilla::Maybe<nsPoint> const&, nsIURI*, nsIURI*, nsIPrincipal*, nsIContentSecurityPolicy*, nsTSubstring<char16_t> const&, bool, nsIStructuredCloneContainer*, bool) /docshell/base/nsDocShell.cpp:11789:23
        #31 0x7f7acfb9eed5 in nsDocShell::UpdateURLAndHistory(mozilla::dom::Document*, nsIURI*, nsIStructuredCloneContainer*, nsTSubstring<char16_t> const&, bool, nsIURI*, bool) /docshell/base/nsDocShell.cpp:11281:7
        #32 0x7f7acfb9db20 in nsDocShell::AddState(JS::Handle<JS::Value>, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, bool, JSContext*) /docshell/base/nsDocShell.cpp:11198:8
        #33 0x7f7ac7788034 in nsHistory::PushOrReplaceState(JSContext*, JS::Handle<JS::Value>, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, mozilla::dom::CallerType, mozilla::ErrorResult&, bool) /dom/base/nsHistory.cpp:294:19
        #34 0x7f7ac7787d6d in nsHistory::PushState(JSContext*, JS::Handle<JS::Value>, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /dom/base/nsHistory.cpp:245:3
        #35 0x7f7ac9226d55 in mozilla::dom::History_Binding::pushState(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/HistoryBinding.cpp:394:24
        #36 0x7f7ac92662cd in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /dom/bindings/BindingUtils.cpp:3300:13
        #37 0x7f7ad0aa9491 in CallJSNative /js/src/vm/Interpreter.cpp:387:13
        #38 0x7f7ad0aa9491 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:474:12
        #39 0x7f7ad0a95add in CallFromStack /js/src/vm/Interpreter.cpp:538:10
        #40 0x7f7ad0a95add in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:3242:16
        #41 0x7f7ad0a7ab41 in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:356:13
        #42 0x7f7ad0aa95cc in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:506:13
        #43 0x7f7ad0aab71b in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /js/src/vm/Interpreter.cpp:551:8
        #44 0x7f7ad0d1e8ad in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /js/src/vm/CallAndConstruct.cpp:117:10
        #45 0x7f7ac8e7fa79 in mozilla::dom::EventListener::HandleEvent(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /builds/worker/workspace/obj-build/dom/bindings/EventListenerBinding.cpp:62:8
        #46 0x7f7ac9a58f64 in void mozilla::dom::EventListener::HandleEvent<mozilla::dom::EventTarget*>(mozilla::dom::EventTarget* const&, mozilla::dom::Event&, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) /builds/worker/workspace/obj-build/dist/include/mozilla/dom/EventListenerBinding.h:65:12
        #47 0x7f7ac9a58a20 in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /dom/events/EventListenerManager.cpp:1117:43
        #48 0x7f7ac9a5a0cc in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /dom/events/EventListenerManager.cpp:1314:17
        #49 0x7f7ac9a4823e in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:348:17
        #50 0x7f7ac9a46a4d in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:550:16
        #51 0x7f7ac9a4acc5 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /dom/events/EventDispatcher.cpp:1085:11
        #52 0x7f7acc3ad73f in nsDocumentViewer::LoadComplete(nsresult) /layout/base/nsDocumentViewer.cpp:1087:7
        #53 0x7f7acfb72463 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /docshell/base/nsDocShell.cpp:6333:20
        #54 0x7f7acfb7175b in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /docshell/base/nsDocShell.cpp:5722:7
        #55 0x7f7acfb7372f in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /docshell/base/nsDocShell.cpp
        #56 0x7f7ac63e3f00 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /uriloader/base/nsDocLoader.cpp:1376:3
        #57 0x7f7ac63e2b14 in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /uriloader/base/nsDocLoader.cpp:974:14
        #58 0x7f7ac63df342 in nsDocLoader::DocLoaderIsEmpty(bool, mozilla::Maybe<nsresult> const&) /uriloader/base/nsDocLoader.cpp:793:9
        #59 0x7f7ac63e1505 in nsDocLoader::OnStopRequest(nsIRequest*, nsresult) /uriloader/base/nsDocLoader.cpp:676:5
        #60 0x7f7acfbab96b in nsDocShell::OnStopRequest(nsIRequest*, nsresult) /docshell/base/nsDocShell.cpp:13586:23
        #61 0x7f7ac41af50e in mozilla::net::nsLoadGroup::NotifyRemovalObservers(nsIRequest*, nsresult) /netwerk/base/nsLoadGroup.cpp:614:22
        #62 0x7f7ac41b1f53 in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /netwerk/base/nsLoadGroup.cpp:518:10
        #63 0x7f7ac74ebb80 in mozilla::dom::Document::DoUnblockOnload() /dom/base/Document.cpp:11555:18
        #64 0x7f7ac74a62a6 in mozilla::dom::Document::UnblockOnload(bool) /dom/base/Document.cpp:11485:9
        #65 0x7f7ac74ca02c in mozilla::dom::Document::DispatchContentLoadedEvents() /dom/base/Document.cpp:7987:3
        #66 0x7f7ac758fc4f in applyImpl<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1147:12
        #67 0x7f7ac758fc4f in apply<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1153:12
        #68 0x7f7ac758fc4f in mozilla::detail::RunnableMethodImpl<mozilla::dom::Document*, void (mozilla::dom::Document::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1200:13
        #69 0x7f7ac3e25acf in mozilla::SchedulerGroup::Runnable::Run() /xpcom/threads/SchedulerGroup.cpp:144:20
        #70 0x7f7ac3e721c2 in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:468:16
        #71 0x7f7ac3e37b8d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:771:26
        #72 0x7f7ac3e350e8 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:607:15
        #73 0x7f7ac3e357f9 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:391:36
        #74 0x7f7ac3e7b801 in operator() /xpcom/threads/TaskController.cpp:124:37
        #75 0x7f7ac3e7b801 in mozilla::detail::RunnableFunction<mozilla::TaskController::InitializeInternal()::$_0>::Run() /xpcom/threads/nsThreadUtils.h:531:5
        #76 0x7f7ac3e57ee7 in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1175:16
        #77 0x7f7ac3e6300c in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:467:10
        #78 0x7f7ac53404ef in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:85:21
        #79 0x7f7ac51bfe91 in RunInternal /ipc/chromium/src/base/message_loop.cc:331:10
        #80 0x7f7ac51bfe91 in RunHandler /ipc/chromium/src/base/message_loop.cc:324:3
        #81 0x7f7ac51bfe91 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:306:3
        #82 0x7f7acbd33de7 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:137:27
        #83 0x7f7ad07c731f in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:917:20
        #84 0x7f7ac51bfe91 in RunInternal /ipc/chromium/src/base/message_loop.cc:331:10
        #85 0x7f7ac51bfe91 in RunHandler /ipc/chromium/src/base/message_loop.cc:324:3
        #86 0x7f7ac51bfe91 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:306:3
        #87 0x7f7ad07c6552 in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:749:34
        #88 0x5576cedfb92d in content_process_main(mozilla::Bootstrap*, int, char**) /browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
        #89 0x5576cedfbd58 in main /browser/app/nsBrowserApp.cpp:327:18
        #90 0x7f7ae1edf0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    
    SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
    Shadow bytes around the buggy address:
      0x0fefb5188cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    =>0x0fefb5188d00:[00]00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0fefb5188d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    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
    ==1238264==ABORTING
Attached file Testcase

I looked at crashes where the proto signature contained nsStringInputStream and the signature contained memcpy and I found this crash which looks very similar: bp-6d318432-3cd8-419d-a4af-36b760211109

Not only is the crashing stack similar to the crashing stack in the ASan report, but the main thread is in the middle of destroying a multi part blob, which is the same as the "freed by" stack in the ASan report.

It looks like we have a previous bug on file for this or a similar crash: bug 1687269.

Here are two more crashes where the crashing thread matches the use thread and the main thread is similar to the free stack from ASan:
bp-bd47e012-c704-49b2-899a-431870211107
bp-6d318432-3cd8-419d-a4af-36b760211109

Crash Signature: [@ memcpy_repmovs | nsReadFromRawBuffer ] [@ memcpy | nsReadFromRawBuffer ] [@ __memcpy_ssse3 | nsReadFromRawBuffer ]
See Also: → 1687269

The crashes in the wild don't have poison values as far as I can see, but they still look very similar.

OS: Linux → All
Hardware: x86_64 → All

Bugmon Analysis
Bugmon was unable to identify a testcase that reproduces this issue.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

Keywords: bugmon

(In reply to Jason Kratzer [:jkratzer] from comment #0)

Testcase found while fuzzing mozilla-central rev 300fc6bd088e (built with: --enable-address-sanitizer --enable-fuzzing).

Testcase can be reproduced using the following commands:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch --build 300fc6bd088e --asan --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.zip

I tried to reproduce this, but it says:

$ python -m grizzly.replay ./firefox/firefox testcase.zip
[2021-11-12 09:49:42] Starting Grizzly Replay
[2021-11-12 09:49:42] Ignoring: log-limit, timeout
[2021-11-12 09:49:42] Using time limit: 15s, timeout: 30s
[2021-11-12 09:49:42] Repeat: 1, Minimum crashes: 1, Relaunch 1
[2021-11-12 09:49:51] Running test (1/1)...
[2021-11-12 09:49:53] Failed to reproduce results
[2021-11-12 09:49:53] Shutting down...
[2021-11-12 09:49:53] Done.

Maybe timing is important, I am on pretty fast AMD Ryzen 9 3900XT here?

Flags: needinfo?(jkratzer)

It would be interesting to see, who actually has called NS_AsyncCopy out of the given options. Most of the options with NS_ASYNCCOPY_VIA_READSEGMENTS (which is happening here) are in networking land, it seems.

Flags: needinfo?(dd.mozilla)

:jstutte, I suspect that this is due to an outdated version of ffpuppet which grizzly uses as a dependency. Can you pip install from that repository rather than PyPi and try again?

Flags: needinfo?(jkratzer)

(In reply to Jason Kratzer [:jkratzer] from comment #8)

:jens, I suspect that this is due to an outdated version of ffpuppet which grizzly uses as a dependency. Can you pip install from that repository rather than PyPi and try again?

Still I was not able to reproduce it on two different machines. Would it be possible to have a pernosco session here?

Flags: needinfo?(jkratzer)

:jstutte, I've been trying to get a pernosco session since Friday. Unfortunately, the testcase is triggering a separate bug under RR before the use-after-free occurs. I'll keep trying but I'm unsure if I'll be successful. I'll keep the NI for now.

Group: core-security → dom-core-security
Flags: needinfo?(dd.mozilla)

I think I am wrong here, I do not think that http log will help.

I see SendSetActiveSessionHistoryEntry and there was some work on that recently (I may be wrong, though).

I will need-info Nika.

Flags: needinfo?(nika)

After doing some reading of the code here, I think I understand what the bug is.

So it looks vaguely to me like we're attempting to serialize a Blob to send to another process, and the data buffer which we're reading from to write into that pipe has been freed due to a cc/gc causing the object to be destroyed. That somewhat matches with the read being of 32768 bytes, which is the size of each buffer in our pipe we're writing into: https://searchfox.org/mozilla-central/rev/df18dd52da04ee2bad434b0ba2d9fcb196d4d15e/ipc/glue/InputStreamUtils.cpp#93

Assuming that the stack for creating this thread in the STS threadpool is the stack which started the copy, it would appear that we're serializing a nsMultiplexInputStream which contains a large nsStringInputStream, which is then forced to use the string input stream fallback to serializing using a pipe. The multiplex input stream creation code seems fairly non-suspect (https://searchfox.org/mozilla-central/rev/df18dd52da04ee2bad434b0ba2d9fcb196d4d15e/dom/file/MultipartBlobImpl.cpp#54), so I'm not too worried about it, however I am a bit worried about the code which is used under the hood to create the underlying nsStringInputStream.

If the blob is created using MemoryBlobImpl, the data it contains is owned by a threadsafe-refcounted DataOwner type (which is credited as being destroyed, leading to the UAF): https://searchfox.org/mozilla-central/rev/1e5b6b30d96e9bd7d63eb22bda6f43cf212b5819/dom/file/MemoryBlobImpl.h#65-105. In order to perform a read from this DataOwner as a nsIInputStream, the call to CreateInputStream will create a DataOwnerAdapter: https://searchfox.org/mozilla-central/rev/df18dd52da04ee2bad434b0ba2d9fcb196d4d15e/dom/file/MemoryBlobImpl.cpp#52-71,88-89.

This is a new nsIInputStream type which wraps around a nsStringInputStream which does not own it's data (due to NS_ASSIGNMENT_DEPEND in the NS_NewByteInputStream constructor: https://searchfox.org/mozilla-central/rev/df18dd52da04ee2bad434b0ba2d9fcb196d4d15e/dom/file/MemoryBlobImpl.cpp#64), but keeps the relevant data alive by holding a reference to the DataOwner itself. DataOwnerAdapter implements nsIIPCSerializableInputStream using NS_FORWARD_*, to the inner non-owning stream, which will then call InputStreamHelper::SerializeInputStreamAsPipe if the string is too large to send inline in an IPC message: https://searchfox.org/mozilla-central/rev/1e5b6b30d96e9bd7d63eb22bda6f43cf212b5819/xpcom/io/nsStringStream.cpp#435-436. This call only keeps the inner nsStringInputStream alive, and not the outer wrapper which is keeping the DataOwner alive, leading to a use-after-free when the pipe is copying from the nsStringInputStream because the DataOwner is going away.

There are two potential things we should be doing here, though there's a good chance we should be doing both of them:

  1. When nsStringInputStream is being serialized, if it's internal string is borrowed and not owned, it should make a new owning nsStringInputStream to serialize with InputStreamHelper::SerializeInputStreamAsPipe. This would work around the core issue and make creating a non-owning nsStringInputStream a bit less risky, but adds an extra copy when serializing these large blobs which may be unnecessary.
  2. Implement a custom nsIIPCSerializableInputStream on DataOwnerAdapter so that it can directly handle handing off to InputStreamHelper::SerializeInputStreamAsPipe when necessary.
Assignee: nobody → nika
Flags: needinfo?(nika)
Crash Signature: [@ memcpy_repmovs | nsReadFromRawBuffer ] [@ memcpy | nsReadFromRawBuffer ] [@ __memcpy_ssse3 | nsReadFromRawBuffer ] → [@ memcpy_repmovs | nsReadFromRawBuffer ] [@ memcpy | nsReadFromRawBuffer ] [@ __memcpy_ssse3 | nsReadFromRawBuffer ] [@ __memcpy_sse2_unaligned_erms | nsReadFromRawBuffer] [@ __memcpy_ssse3_back | nsReadFromRawBuffer] [@ __memmove_avx_unaligned_erms | ns…
Crash Signature: [@ memcpy_repmovs | nsReadFromRawBuffer ] [@ memcpy | nsReadFromRawBuffer ] [@ __memcpy_ssse3 | nsReadFromRawBuffer ] [@ __memcpy_sse2_unaligned_erms | nsReadFromRawBuffer] [@ __memcpy_ssse3_back | nsReadFromRawBuffer] [@ __memmove_avx_unaligned_erms | ns… → [@ memcpy_repmovs | nsReadFromRawBuffer ] [@ memcpy | nsReadFromRawBuffer ] [@ __memcpy_ssse3 | nsReadFromRawBuffer ] [@ __memcpy_sse2_unaligned_erms | nsReadFromRawBuffer] [@ __memcpy_ssse3_back | nsReadFromRawBuffer] [@ __memmove_avx_unaligned_erms |…
Flags: needinfo?(jkratzer)
Severity: -- → S2
Priority: -- → P1
See Also: → 1743214

Comment on attachment 9251251 [details]
Bug 1740797 - Use an owning string when serializing nsStringInputStream as a pipe, r=asuth

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: The patch doesn't directly point at Blob as the source of the issue, however someone may be able to discover the callsite by auditing places which create non-owning nsStringInputStream instances.
  • 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?: all
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: I believe this patch should apply directly to all branches
  • How likely is this patch to cause regressions; how much testing does it need?: This patch is very unlikely to cause regressions as it should not meaningfully change semantics.
Attachment #9251251 - Flags: sec-approval?
Blocks: 1743214

Comment on attachment 9251251 [details]
Bug 1740797 - Use an owning string when serializing nsStringInputStream as a pipe, r=asuth

Approved to land and uplift.

Attachment #9251251 - Flags: sec-approval?
Attachment #9251251 - Flags: sec-approval+
Attachment #9251251 - Flags: approval-mozilla-esr91+
Attachment #9251251 - Flags: approval-mozilla-beta+
Group: dom-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 97 Branch

As part of a security bug pattern analysis, we are requesting your help with a high level analysis of this bug. It is our hope to develop static analysis (or potentially runtime/dynamic analysis) in the future to identify classes of bugs.

Please visit this google form to reply.

Flags: needinfo?(nika)
Whiteboard: [bugmon:confirm] → [bugmon:confirm][sec-survey]
Flags: needinfo?(nika)
Flags: qe-verify-
Whiteboard: [bugmon:confirm][sec-survey] → [bugmon:confirm][sec-survey][adv-main96+r][adv-ESR91.5+r]

:nika, since this bug contains a bisection range, could you fill (if possible) the regressed_by field?
For more information, please visit auto_nag documentation.

Flags: needinfo?(nika)

This bug does not contain a bisection range.

Flags: needinfo?(nika)
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: