Closed Bug 1631618 (CVE-2020-12405) Opened 5 years ago Closed 4 years ago

[TALOS-2020-1053] use-after-free in SharedWorkerService

Categories

(Core :: DOM: Service Workers, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla78
Tracking Status
firefox-esr68 77+ fixed
firefox76 --- wontfix
firefox77 + fixed
firefox78 + fixed

People

(Reporter: dveditz, Assigned: edenchuang)

References

Details

(4 keywords, Whiteboard: [post-critsmash-triage][adv-main77+][adv-esr68.9+][sec-survey])

Attachments

(5 files)

[from mail to security@ from Talos, some boilerplate snipped]

Mozilla Firefox SharedWorkerService Code Execution Vulnerability

An exploitable code execution vulnerability exists in the SharedWorkerService functionality of Mozilla Firefox 76.0a1 (2020-04-01) x64. A specially crafted HTML web page can cause a use after free condition, resulting in a remote code execution. The victim needs to visit malicious web site to trigger the vulnerability.

Tested Versions

Mozilla Firefox 76.0a1 (2020-04-01) x64

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-416 - Use After Free

Details

Mozilla Firefox is one of the most popular web browsers on the world available for a variety of the different platforms : Windows, Linux, OSX, Android and more. Its active development ensure support for the newest web technologies like HTML5 or CSS3.

The vulnerability is related with the SharedWorker component and objects internaly related with it. A malicious web page can lead to a race condition situation which can cause a use-after-free vulnerability and remote code execution.

Tracking an SharedWorkerService object life cycle we can notice that there is an allocation made :

	previously allocated by thread T46 (IPDL Background) here:
		#0 0x55b699485b0d in malloc /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:145:3
		#1 0x55b6994bb4fd in moz_xmalloc /builds/worker/checkouts/gecko/memory/mozalloc/mozalloc.cpp:52:15
		#2 0x7fa306effc46 in operator new /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:33:10
		#3 0x7fa306effc46 in mozilla::dom::SharedWorkerService::GetOrCreate() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:126:42
		#4 0x7fa306effa77 in mozilla::dom::SharedWorkerParent::Initialize(mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerParent.cpp:50:41
		#5 0x7fa3014c45aa in mozilla::ipc::BackgroundParentImpl::RecvPSharedWorkerConstructor(mozilla::dom::PSharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long const&, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/ipc/glue/BackgroundParentImpl.cpp:552:10
		#6 0x7fa301c6538f in mozilla::ipc::PBackgroundParent::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PBackgroundParent.cpp:5068:28
		#7 0x7fa30153813c in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2187:25
		#8 0x7fa301535255 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2111:9
		#9 0x7fa3015366cf in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1959:3
		#10 0x7fa301536ede in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1990:13
		#11 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
		#12 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
		#13 0x7fa301540ec9 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:332:5
		#14 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
		#15 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
		#16 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
		#17 0x7fa3004bf245 in nsThread::ThreadFunc(void*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:464:10
		#18 0x7fa3169a51fe in _pt_root /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:201:5
		#19 0x7fa31a2c2668 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x9668)

Further, in a consequence of handling the next event inside another thread, the SharedWorkerService object gets deallocated:

	0x606000315770 is located 48 bytes inside of 64-byte region [0x606000315740,0x606000315780)
	freed by thread T0 here:
		#0 0x55b69948588d in free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:123:3
		#1 0x7fa306eff34c in operator delete /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:51:10
		#2 0x7fa306eff34c in Release /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.h:31:3
		#3 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
		#4 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
		#5 0x7fa306eff34c in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
		#6 0x7fa306eff34c in mozilla::dom::SharedWorkerManagerHolder::~SharedWorkerManagerHolder() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerManager.cpp:285:1
		#7 0x7fa306f04611 in mozilla::dom::SharedWorkerManagerHolder::Release() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerManager.h:32:3
		#8 0x7fa306f0853a in detail::ProxyReleaseEvent<mozilla::dom::SharedWorkerManagerHolder>::Run() /builds/worker/workspace/obj-build/dist/include/nsProxyRelease.h:36:5
		#9 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
		#10 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
		#11 0x7fa30153fe6a in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:87:21
		#12 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
		#13 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
		#14 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
		#15 0x7fa307562ff8 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:137:27
		#16 0x7fa30aafa5bb in nsAppStartup::Run() /builds/worker/checkouts/gecko/toolkit/components/startup/nsAppStartup.cpp:271:30
		#17 0x7fa30ad00546 in XREMain::XRE_mainRun() /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4614:22
		#18 0x7fa30ad023b1 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4749:8
		#19 0x7fa30ad030f3 in XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4800:21
		#20 0x55b6994b8726 in do_main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:217:22
		#21 0x55b6994b8726 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:331:16
		#22 0x7fa319d851e2 in __libc_start_main /build/glibc-t7JzpG/glibc-2.30/csu/../csu/libc-start.c:308:16

"Simultaneously" execution of thread T46 continues which in the final result leads to a use-after-free of the SharedWorkerService object:

==12981==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000315770 at pc 0x7fa306f0022f bp 0x7fa2e155f5f0 sp 0x7fa2e155f5e8
WRITE of size 8 at 0x606000315770 thread T46 (IPDL Background)
    #0 0x7fa306f0022e in fetch_add /builds/worker/fetches/clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/atomic_base.h:514:16
    #1 0x7fa306f0022e in operator++ /builds/worker/workspace/obj-build/dist/include/nsISupportsImpl.h:331:19
    #2 0x7fa306f0022e in AddRef /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.h:31:3
    #3 0x7fa306f0022e in AddRef /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:49:39
    #4 0x7fa306f0022e in AddRef /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:380:35
    #5 0x7fa306f0022e in RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:109:7
    #6 0x7fa306f0022e in GetOrCreateWorkerManagerRunnable /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:37:9
    #7 0x7fa306f0022e in mozilla::dom::SharedWorkerService::GetOrCreateWorkerManager(mozilla::dom::SharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:159:11
    #8 0x7fa306effaa7 in mozilla::dom::SharedWorkerParent::Initialize(mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerParent.cpp:52:12
    #9 0x7fa3014c45aa in mozilla::ipc::BackgroundParentImpl::RecvPSharedWorkerConstructor(mozilla::dom::PSharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long const&, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/ipc/glue/BackgroundParentImpl.cpp:552:10
    #10 0x7fa301c6538f in mozilla::ipc::PBackgroundParent::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PBackgroundParent.cpp:5068:28
    #11 0x7fa30153813c in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2187:25
    #12 0x7fa301535255 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2111:9
    #13 0x7fa3015366cf in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1959:3
    #14 0x7fa301536ede in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1990:13
    #15 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
    #16 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
    #17 0x7fa301540ed4 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:302:20
    #18 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
    #19 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
    #20 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
    #21 0x7fa3004bf245 in nsThread::ThreadFunc(void*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:464:10
    #22 0x7fa3169a51fe in _pt_root /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:201:5
    #23 0x7fa31a2c2668 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x9668)
    #24 0x7fa319e80322 in clone /build/glibc-t7JzpG/glibc-2.30/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Further analysis revealed that the root cause of that vulnerability seems to be a lack of Mutex object in the GetOrCreateWorkerManager method:
https://github.com/mozilla/gecko-dev/blob/5a52cec97c41ae1eda9412dfe6f4099a9af4c7dd/dom/workers/sharedworkers/SharedWorkerService.cpp#L152

	Line 152	void SharedWorkerService::GetOrCreateWorkerManager(
	Line 153		SharedWorkerParent* aActor, const RemoteWorkerData& aData,
	Line 154		uint64_t aWindowID, const MessagePortIdentifier& aPortIdentifier) {
	Line 155	  AssertIsOnBackgroundThread();
	Line 156
	Line 157	  // The real check happens on main-thread.
	Line 158	  RefPtr<GetOrCreateWorkerManagerRunnable> r =
	Line 159		  new GetOrCreateWorkerManagerRunnable(this, aActor, aData, aWindowID,
	Line 160											   aPortIdentifier);

In line 159 the SharedWorkerService object, represented by this, is passed as an argument to the GetOrCreateWorkerManagerRunnable method.
Meanwhile it is destroyed via the ~SharedWorkerManagerHolder() destructor.

	0x606000315770 is located 48 bytes inside of 64-byte region [0x606000315740,0x606000315780)
	freed by thread T0 here:
		#0 0x55b69948588d in free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:123:3
		#1 0x7fa306eff34c in operator delete /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:51:10
		#2 0x7fa306eff34c in Release /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.h:31:3
		#3 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
		#4 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
		#5 0x7fa306eff34c in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
		#6 0x7fa306eff34c in mozilla::dom::SharedWorkerManagerHolder::~SharedWorkerManagerHolder() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerManager.cpp:285:1

Proper heap grooming can give an attacker full control of this use-after-free vulnerability and as a result could allow it to be turned into arbitrary code execution.

Crash Information

=================================================================
	==12981==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000315770 at pc 0x7fa306f0022f bp 0x7fa2e155f5f0 sp 0x7fa2e155f5e8
	WRITE of size 8 at 0x606000315770 thread T46 (IPDL Background)
		#0 0x7fa306f0022e in fetch_add /builds/worker/fetches/clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/atomic_base.h:514:16
		#1 0x7fa306f0022e in operator++ /builds/worker/workspace/obj-build/dist/include/nsISupportsImpl.h:331:19
		#2 0x7fa306f0022e in AddRef /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.h:31:3
		#3 0x7fa306f0022e in AddRef /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:49:39
		#4 0x7fa306f0022e in AddRef /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:380:35
		#5 0x7fa306f0022e in RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:109:7
		#6 0x7fa306f0022e in GetOrCreateWorkerManagerRunnable /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:37:9
		#7 0x7fa306f0022e in mozilla::dom::SharedWorkerService::GetOrCreateWorkerManager(mozilla::dom::SharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:159:11
		#8 0x7fa306effaa7 in mozilla::dom::SharedWorkerParent::Initialize(mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerParent.cpp:52:12
		#9 0x7fa3014c45aa in mozilla::ipc::BackgroundParentImpl::RecvPSharedWorkerConstructor(mozilla::dom::PSharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long const&, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/ipc/glue/BackgroundParentImpl.cpp:552:10
		#10 0x7fa301c6538f in mozilla::ipc::PBackgroundParent::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PBackgroundParent.cpp:5068:28
		#11 0x7fa30153813c in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2187:25
		#12 0x7fa301535255 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2111:9
		#13 0x7fa3015366cf in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1959:3
		#14 0x7fa301536ede in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1990:13
		#15 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
		#16 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
		#17 0x7fa301540ed4 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:302:20
		#18 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
		#19 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
		#20 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
		#21 0x7fa3004bf245 in nsThread::ThreadFunc(void*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:464:10
		#22 0x7fa3169a51fe in _pt_root /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:201:5
		#23 0x7fa31a2c2668 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x9668)
		#24 0x7fa319e80322 in clone /build/glibc-t7JzpG/glibc-2.30/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

	0x606000315770 is located 48 bytes inside of 64-byte region [0x606000315740,0x606000315780)
	freed by thread T0 here:
		#0 0x55b69948588d in free /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:123:3
		#1 0x7fa306eff34c in operator delete /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:51:10
		#2 0x7fa306eff34c in Release /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.h:31:3
		#3 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:50:40
		#4 0x7fa306eff34c in Release /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:381:36
		#5 0x7fa306eff34c in ~RefPtr /builds/worker/workspace/obj-build/dist/include/mozilla/RefPtr.h:81:7
		#6 0x7fa306eff34c in mozilla::dom::SharedWorkerManagerHolder::~SharedWorkerManagerHolder() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerManager.cpp:285:1
		#7 0x7fa306f04611 in mozilla::dom::SharedWorkerManagerHolder::Release() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerManager.h:32:3
		#8 0x7fa306f0853a in detail::ProxyReleaseEvent<mozilla::dom::SharedWorkerManagerHolder>::Run() /builds/worker/workspace/obj-build/dist/include/nsProxyRelease.h:36:5
		#9 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
		#10 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
		#11 0x7fa30153fe6a in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:87:21
		#12 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
		#13 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
		#14 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
		#15 0x7fa307562ff8 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:137:27
		#16 0x7fa30aafa5bb in nsAppStartup::Run() /builds/worker/checkouts/gecko/toolkit/components/startup/nsAppStartup.cpp:271:30
		#17 0x7fa30ad00546 in XREMain::XRE_mainRun() /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4614:22
		#18 0x7fa30ad023b1 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4749:8
		#19 0x7fa30ad030f3 in XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4800:21
		#20 0x55b6994b8726 in do_main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:217:22
		#21 0x55b6994b8726 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:331:16
		#22 0x7fa319d851e2 in __libc_start_main /build/glibc-t7JzpG/glibc-2.30/csu/../csu/libc-start.c:308:16

	previously allocated by thread T46 (IPDL Background) here:
		#0 0x55b699485b0d in malloc /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:145:3
		#1 0x55b6994bb4fd in moz_xmalloc /builds/worker/checkouts/gecko/memory/mozalloc/mozalloc.cpp:52:15
		#2 0x7fa306effc46 in operator new /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:33:10
		#3 0x7fa306effc46 in mozilla::dom::SharedWorkerService::GetOrCreate() /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerService.cpp:126:42
		#4 0x7fa306effa77 in mozilla::dom::SharedWorkerParent::Initialize(mozilla::dom::RemoteWorkerData const&, unsigned long, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/dom/workers/sharedworkers/SharedWorkerParent.cpp:50:41
		#5 0x7fa3014c45aa in mozilla::ipc::BackgroundParentImpl::RecvPSharedWorkerConstructor(mozilla::dom::PSharedWorkerParent*, mozilla::dom::RemoteWorkerData const&, unsigned long const&, mozilla::dom::MessagePortIdentifier const&) /builds/worker/checkouts/gecko/ipc/glue/BackgroundParentImpl.cpp:552:10
		#6 0x7fa301c6538f in mozilla::ipc::PBackgroundParent::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PBackgroundParent.cpp:5068:28
		#7 0x7fa30153813c in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2187:25
		#8 0x7fa301535255 in mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2111:9
		#9 0x7fa3015366cf in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1959:3
		#10 0x7fa301536ede in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1990:13
		#11 0x7fa3004c58ce in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1220:14
		#12 0x7fa3004d035c in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:481:10
		#13 0x7fa301540ec9 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:332:5
		#14 0x7fa30146cfe7 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:315:10
		#15 0x7fa30146cfe7 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:308:3
		#16 0x7fa30146cfe7 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:290:3
		#17 0x7fa3004bf245 in nsThread::ThreadFunc(void*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:464:10
		#18 0x7fa3169a51fe in _pt_root /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:201:5
		#19 0x7fa31a2c2668 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x9668)

	Thread T46 (IPDL Background) created by T0 here:
		#0 0x55b69947029a in pthread_create /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:209:3
		#1 0x7fa316995655 in _PR_CreateThread /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:458:14
		#2 0x7fa31698651e in PR_CreateThread /builds/worker/checkouts/gecko/nsprpub/pr/src/pthreads/ptthread.c:533:12
		#3 0x7fa3004c1c0c in nsThread::Init(nsTSubstring<char> const&) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:670:8
		#4 0x7fa3004cf251 in nsThreadManager::NewNamedThread(nsTSubstring<char> const&, unsigned int, nsIThread**) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadManager.cpp:621:12
		#5 0x7fa3004d3183 in NS_NewNamedThread(nsTSubstring<char> const&, nsIThread**, nsIRunnable*, unsigned int) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:139:57
		#6 0x7fa3014f4e7e in NS_NewNamedThread<16> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:65:10
		#7 0x7fa3014f4e7e in (anonymous namespace)::ParentImpl::CreateBackgroundThread() /builds/worker/checkouts/gecko/ipc/glue/BackgroundImpl.cpp:1325:7
		#8 0x7fa3014f66c4 in CreateActorForSameProcess /builds/worker/checkouts/gecko/ipc/glue/BackgroundImpl.cpp:1235:32
		#9 0x7fa3014f66c4 in ParentContentActorCreateFunc((anonymous namespace)::ChildImpl::ThreadLocalInfo*, unsigned int, nsIEventTarget*, (anonymous namespace)::ChildImpl**) /builds/worker/checkouts/gecko/ipc/glue/BackgroundImpl.cpp:864:9
		#10 0x7fa3014fefdb in (anonymous namespace)::ChildImpl::ThreadInfoWrapper::GetOrCreateForCurrentThread(nsIEventTarget*) /builds/worker/checkouts/gecko/ipc/glue/BackgroundImpl.cpp:420:7
		#11 0x7fa30573ce17 in mozilla::dom::ClientManager::ClientManager() /builds/worker/checkouts/gecko/dom/clients/manager/ClientManager.cpp:50:7
		#12 0x7fa30573f310 in mozilla::dom::ClientManager::GetOrCreateForCurrentThread() /builds/worker/checkouts/gecko/dom/clients/manager/ClientManager.cpp:212:14
		#13 0x7fa30573fd12 in mozilla::dom::ClientManager::CreateSource(mozilla::dom::ClientType, nsISerialEventTarget*, nsIPrincipal*) /builds/worker/checkouts/gecko/dom/clients/manager/ClientManager.cpp:268:31
		#14 0x7fa30a2cc552 in nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal*) /builds/worker/checkouts/gecko/docshell/base/nsDocShell.cpp:2527:26
		#15 0x7fa30a2fa1b5 in nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal*, nsIPrincipal*, nsIContentSecurityPolicy*, nsIURI*, bool, bool, mozilla::dom::WindowGlobalChild*) /builds/worker/checkouts/gecko/docshell/base/nsDocShell.cpp:6554:5
		#16 0x7fa30a2fba9c in CreateAboutBlankContentViewer /builds/worker/checkouts/gecko/docshell/base/nsDocShell.cpp:6612:10
		#17 0x7fa30a2fba9c in non-virtual thunk to nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal*, nsIPrincipal*, nsIContentSecurityPolicy*) /builds/worker/checkouts/gecko/docshell/base/nsDocShell.cpp
		#18 0x7fa30a3bdc13 in mozilla::AppWindow::Initialize(nsIAppWindow*, nsIAppWindow*, nsIURI*, int, int, bool, nsIRemoteTab*, mozIDOMWindowProxy*, nsWidgetInitData&) /builds/worker/checkouts/gecko/xpfe/appshell/AppWindow.cpp:298:21
		#19 0x7fa30a3dfccb in nsAppShellService::JustCreateTopWindow(nsIAppWindow*, nsIURI*, unsigned int, int, int, bool, nsIRemoteTab*, mozIDOMWindowProxy*, mozilla::AppWindow**) /builds/worker/checkouts/gecko/xpfe/appshell/nsAppShellService.cpp:679:25
		#20 0x7fa30a3e13c7 in nsAppShellService::CreateTopLevelWindow(nsIAppWindow*, nsIURI*, unsigned int, int, int, nsIRemoteTab*, mozIDOMWindowProxy*, nsIAppWindow**) /builds/worker/checkouts/gecko/xpfe/appshell/nsAppShellService.cpp:172:8
		#21 0x7fa30aafc911 in nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome*, unsigned int, nsIRemoteTab*, mozIDOMWindowProxy*, unsigned long, bool*, nsIWebBrowserChrome**) /builds/worker/checkouts/gecko/toolkit/components/startup/nsAppStartup.cpp:634:15
		#22 0x7fa30ac75086 in nsWindowWatcher::CreateChromeWindow(nsTSubstring<char> const&, nsIWebBrowserChrome*, unsigned int, nsIRemoteTab*, mozIDOMWindowProxy*, unsigned long, nsIWebBrowserChrome**) /builds/worker/checkouts/gecko/toolkit/components/windowwatcher/nsWindowWatcher.cpp:424:33
		#23 0x7fa30ac72ee6 in nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy*, char const*, char const*, char const*, bool, bool, bool, nsIArray*, bool, bool, bool, nsDocShellLoadState*, mozilla::dom::BrowsingContext**) /builds/worker/checkouts/gecko/toolkit/components/windowwatcher/nsWindowWatcher.cpp:910:12
		#24 0x7fa30ac6ddec in nsWindowWatcher::OpenWindow(mozIDOMWindowProxy*, char const*, char const*, char const*, nsISupports*, mozIDOMWindowProxy**) /builds/worker/checkouts/gecko/toolkit/components/windowwatcher/nsWindowWatcher.cpp:292:3
		#25 0x7fa3005085c1 in NS_InvokeByIndex /builds/worker/checkouts/gecko/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S:106
		#26 0x7fa301ed7cfb in Invoke /builds/worker/checkouts/gecko/js/xpconnect/src/XPCWrappedNative.cpp:1634:10
		#27 0x7fa301ed7cfb in Call /builds/worker/checkouts/gecko/js/xpconnect/src/XPCWrappedNative.cpp:1175:19
		#28 0x7fa301ed7cfb in XPCWrappedNative::CallMethod(XPCCallContext&, XPCWrappedNative::CallMode) /builds/worker/checkouts/gecko/js/xpconnect/src/XPCWrappedNative.cpp:1141:23
		#29 0x7fa301edcd02 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:947:10
		#30 0x7fa30af3c9e7 in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:476:13
		#31 0x7fa30af3c9e7 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:568:12
		#32 0x7fa30af3e69a in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:631:10
		#33 0x7fa30af2504a in CallFromStack /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:635:10
		#34 0x7fa30af2504a in Interpret(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:3026:16
		#35 0x7fa30af0aff3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:448:10
		#36 0x7fa30af40998 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::AbstractFramePtr, JS::Value*) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:824:13
		#37 0x7fa30b0108ec in ExecuteInExtensibleLexicalEnvironment(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Eval.cpp:499:10
		#38 0x7fa30b01130c in js::ExecuteInJSMEnvironment(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::Handle<JS::StackGCVector<JSObject*, js::TempAllocPolicy> >) /builds/worker/checkouts/gecko/js/src/builtin/Eval.cpp:606:10
		#39 0x7fa30b010f62 in js::ExecuteInJSMEnvironment(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>) /builds/worker/checkouts/gecko/js/src/builtin/Eval.cpp:561:10
		#40 0x7fa301dcb5db in mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo&, nsIFile*, JS::MutableHandle<JSObject*>, JS::MutableHandle<JSScript*>, char**, bool, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/xpconnect/loader/mozJSComponentLoader.cpp:929:19
		#41 0x7fa301dd3f8a in mozJSComponentLoader::Import(JSContext*, nsTSubstring<char> const&, JS::MutableHandle<JSObject*>, JS::MutableHandle<JSObject*>, bool) /builds/worker/checkouts/gecko/js/xpconnect/loader/mozJSComponentLoader.cpp:1343:12
		#42 0x7fa300447f93 in mozilla::xpcom::ConstructJSMComponent(nsTSubstring<char> const&, char const*, nsISupports**) /builds/worker/workspace/obj-build/xpcom/components/StaticComponents.cpp:1586:3
		#43 0x7fa300438740 in mozilla::xpcom::CreateInstanceImpl(mozilla::xpcom::ModuleID, nsISupports*, nsID const&, void**) /builds/worker/workspace/obj-build/xpcom/components/StaticComponents.cpp:11097:7
		#44 0x7fa3004754c5 in CreateInstance /builds/worker/checkouts/gecko/xpcom/components/nsComponentManager.cpp:219:46
		#45 0x7fa3004754c5 in nsComponentManagerImpl::GetServiceLocked((anonymous namespace)::MutexLock&, (anonymous namespace)::EntryWrapper&, nsID const&, void**) /builds/worker/checkouts/gecko/xpcom/components/nsComponentManager.cpp:1372:17
		#46 0x7fa30046bc3e in nsComponentManagerImpl::GetServiceByContractID(char const*, nsID const&, void**) /builds/worker/checkouts/gecko/xpcom/components/nsComponentManager.cpp:1559:10
		#47 0x7fa30047cfa2 in CallGetService /builds/worker/checkouts/gecko/xpcom/components/nsComponentManagerUtils.cpp:61:43
		#48 0x7fa30047cfa2 in nsGetServiceByContractIDWithError::operator()(nsID const&, void**) const /builds/worker/checkouts/gecko/xpcom/components/nsComponentManagerUtils.cpp:253:21
		#49 0x7fa3002f4756 in nsCOMPtr_base::assign_from_gs_contractid_with_error(nsGetServiceByContractIDWithError const&, nsID const&) /builds/worker/checkouts/gecko/xpcom/base/nsCOMPtr.cpp:91:7
		#50 0x7fa30ad0e17d in operator= /builds/worker/workspace/obj-build/dist/include/nsCOMPtr.h:1054:5
		#51 0x7fa30ad0e17d in nsAppStartupNotifier::NotifyObservers(char const*) /builds/worker/checkouts/gecko/toolkit/xre/nsAppStartupNotifier.cpp:42:23
		#52 0x7fa30acff9ea in XREMain::XRE_mainRun() /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4396:3
		#53 0x7fa30ad023b1 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4749:8
		#54 0x7fa30ad030f3 in XRE_main(int, char**, mozilla::BootstrapConfig const&) /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:4800:21
		#55 0x55b6994b8726 in do_main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:217:22
		#56 0x55b6994b8726 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:331:16
		#57 0x7fa319d851e2 in __libc_start_main /build/glibc-t7JzpG/glibc-2.30/csu/../csu/libc-start.c:308:16

	SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/fetches/clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/atomic_base.h:514:16 in fetch_add
	Shadow bytes around the buggy address:
	  0x0c0c8005aa90: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
	  0x0c0c8005aaa0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
	  0x0c0c8005aab0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00
	  0x0c0c8005aac0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
	  0x0c0c8005aad0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
	=>0x0c0c8005aae0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd[fd]fd
	  0x0c0c8005aaf0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
	  0x0c0c8005ab00: fd fd fd fd fd fd fd fd fa fa fa fa 00 00 00 00
	  0x0c0c8005ab10: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
	  0x0c0c8005ab20: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
	  0x0c0c8005ab30: fd fd fd fd fd fd fd fd fa fa fa fa 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
	  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
	==12981==ABORTING
	Exiting due to channel error.
	Exiting due to channel error.

Credit

Discovered by Marcin 'Icewall' Noga of Cisco Talos.

https://talosintelligence.com/vulnerability_reports/

Note: POC doesn't work, most likely because it's missing a couple of included files. Will request. Hopefully their analysis is enough to get started.

Summary: [TALOS-2020-1053] Mozilla Firefox SharedWorkerService Code Execution Vulnerability → [TALOS-2020-1053] use-after-free in SharedWorkerService

I didn't test using an ASAN build. Maybe under ASAN the error is detected even without their memory-munging harness files.

See Also: → 1612617

I am also unable to reproduce the issue with an ASan build.

Unless we know otherwise we must assume, their exploit works. Eden, can you please give this analysis a look?

Severity: -- → critical
Flags: needinfo?(echuang)
Priority: -- → P1

The SharedWorkerService is a singleton but the assumption of the comment that the SharedWorkerParent holds this alife long enough seems broken. The destructor already uses the sSharedWorkerMutex and nulls the pointer. As the UAF happens in SharedWorkerService::GetOrCreateWorkerManager, we probably do not just want to check the mutex here but need to know, that we are in the destruction phase of the SharedWorkerService and thus return an error.

Presumably this happens during the tear down of the process, so I think it would be hard to really exploit this (but maybe some seconds remain due to some AsyncShutdown magic).

Assignee: nobody → echuang
Flags: needinfo?(echuang)

I tried to reproduce this by substituting the missing files with those from the web platform tests but was unable to do so. Dan, can you reach out to Marcin and see if he can provide us with any more details on how we might reproduce this?

Flags: needinfo?(dveditz)
Flags: needinfo?(dveditz)

Marcin: the testcase is missing test harness files and we cannot reproduce this crash. Can you share those with us please?

Flags: needinfo?(manoga)
Attached file testharnessreport.js
Flags: needinfo?(manoga)
Attached file testharness-helpers.js

Hi guys,
Files attached but basically these files have not been modified anyhow and come from : https://github.com/web-platform-tests/wpt/blob/master/resources/testharness.js ,etc.

Unfortunately I was not able to reproduce this bug later on after I have caught it, so its hard for me to tell anything more about it.
Information in an advisory are just my assumptions but I hope that ASAN log will tell you something more.

After analyzing from the stack and the codebase, the root cause might be the ~SharedWorkerService() is blocked by the lock here.

https://searchfox.org/mozilla-central/rev/41c3ea3ee8eab9ce7b82932257cb80b703cbba67/dom/workers/sharedworkers/SharedWorkerService.cpp#146

It means there is another SharedWorkerSerivce::GetOrCreate() or SharedWorkerSerivce::Get() at the same time, then ~SharedWorkerService() release the memory after these methods finishes. Then UAF happens when accessing the pointer from these methods.

The possible solution is making ~SharedWorkerService() be an atomic operation by getting the lock before entering into ~SharedWorkerService().

However, I could not reproduce the bug, could not give a proof for my guessing. But we can still apply the solution for investigation.

Keywords: sec-high
Severity: critical → S2
Attachment #9143074 - Attachment description: Bug 1631618 - Customize the AddRef() and Release() of SharedWorkerService with sSharedWorkerMutex. → Bug 1631618 - Make SharedWorkerService be alive until shutdown

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Not easy, since it is not easy to contorl os thread execution in to a specific sequence.
  • 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?:
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: Yes
  • If not, how different, hard to create, and risky will they be?:
  • How likely is this patch to cause regressions; how much testing does it need?: In basic, it should not cause any regression. All the tests should be passed with the patch.
Attachment #9143074 - Flags: sec-approval?

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

sec-approval=dveditz

Attachment #9143074 - Flags: sec-approval? → sec-approval+

Is there a timeline for the fix/release?

Group: dom-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla78

As this is tracking Firefox 77 and 68.9esr, please submit an uplift request.

Flags: needinfo?(echuang)

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

Beta/Release Uplift Approval Request

  • User impact if declined: May fit UAF when browsing with SharedWorker.
  • Is this code covered by automated tests?: Unknown
  • 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 is low risk. It simplifies the life cycle of SharedWorkerService and avoids maintaining the complex accessing control on a mutex.
  • String changes made/needed:
Flags: needinfo?(echuang)
Attachment #9143074 - Flags: approval-mozilla-beta?

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration:
  • User impact if declined: May hit UAF when browsing web with SharedWorkers
  • Fix Landed on Version: 78
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The patch is low risk. It simplifies the life cycle of SharedWorkerService and avoids maintaining the complex accessing control on a mutex.
  • String or UUID changes made by this patch:
Attachment #9143074 - Flags: approval-mozilla-esr68?

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

Uplift approved for beta and esr, thanks.

Attachment #9143074 - Flags: approval-mozilla-esr68?
Attachment #9143074 - Flags: approval-mozilla-esr68+
Attachment #9143074 - Flags: approval-mozilla-beta?
Attachment #9143074 - Flags: approval-mozilla-beta+

https://hg.mozilla.org/releases/mozilla-esr68/rev/dcfa7eaa9049

The patch had conflicts with bug 1617993, hopefully the end result is fine.

Backed out of esr68 for build failures:
https://hg.mozilla.org/releases/mozilla-esr68/rev/53e86f11003d7b8048c84d166b9b6a3beb9826c8

Example failure: https://treeherder.mozilla.org/#/jobs?repo=mozilla-esr68&revision=dcfa7eaa9049f6c177fa4f171b48eca7c44089a3&selectedTaskRun=MMfL1Aj7RX27UdhH9qgwng-0

/builds/worker/workspace/build/src/dom/workers/sharedworkers/SharedWorkerService.cpp:168:35: error: call to non-static member function without an object argument

As far as I can tell this depends on bug 1561715 making SchedulerGroup::Dispatch static.

Flags: needinfo?(echuang)

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

Clearing the ESR68 approval until a rebased patch is ready.

Attachment #9143074 - Flags: approval-mozilla-esr68+
Flags: qe-verify-
Whiteboard: [post-critsmash-triage]
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main77+]
Whiteboard: [post-critsmash-triage][adv-main77+] → [post-critsmash-triage][adv-main77+][adv-esr68.9+]

(In reply to Cisco Talos from comment #15)

Is there a timeline for the fix/release?

While we could not reproduce the exact issue as described in your report (comment 6, comment 10, comment 11), we still found a likely culprit. It will be in Firefox 77 and Firefox ESR 68.9 scheduled for next Tuesday.

Attached file advisory.txt

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration:
  • User impact if declined: Hit UAF on SharedWorkerService
  • Fix Landed on Version:
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The patch is low risk. It simplifies the life cycle of SharedWorkerService and avoids maintaining the complex accessing control on a mutex.
  • String or UUID changes made by this patch:
Flags: needinfo?(echuang)
Attachment #9143074 - Flags: approval-mozilla-esr68?

Comment on attachment 9143074 [details]
Bug 1631618 - Make SharedWorkerService be alive until shutdown

Approved for 68.9esr. Thanks for the rebased patch!

Attachment #9143074 - Flags: approval-mozilla-esr68? → approval-mozilla-esr68+
Alias: CVE-2020-12405

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?(echuang)
Whiteboard: [post-critsmash-triage][adv-main77+][adv-esr68.9+] → [post-critsmash-triage][adv-main77+][adv-esr68.9+][sec-survey]
Flags: needinfo?(echuang)
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: