heap-use-after-free of VRProcessParent
Categories
(Core :: WebVR, defect)
Tracking
()
People
(Reporter: bo13oy, Assigned: jld)
References
Details
(5 keywords, Whiteboard: [reporter-external] [client-bounty-form] [verif?][adv-esr91.8+][adv-main98+])
Attachments
(2 files)
48 bytes,
text/x-phabricator-request
|
RyanVM
:
approval-mozilla-esr91+
|
Details | Review |
221 bytes,
text/plain
|
Details |
Tested Version: Window 10 Pro 20H2 x64 memory 32G + win64-fuzzing-asan-opt(96.0.2)
There is no way to reproduce the vulnerability, temporarily can not provide poc samples,I feel that this is a conditional competition vulnerability,The conditions for triggering this vulnerability are demanding,the crash report is as follows:
=================================================================
==21636==ERROR: AddressSanitizer: heap-use-after-free on address 0x1254e68ea0b0 at pc 0x7fff352febc2 bp 0x00db761fc6a0 sp 0x00db761fc6e8
READ of size 8 at 0x1254e68ea0b0 thread T0
#0 0x7fff352febc1 in mozilla::gfx::VRProcessParent::InitAfterConnect /builds/worker/checkouts/gecko/gfx/vr/ipc/VRProcessParent.cpp:165
#1 0x7fff3360613d in mozilla::ipc::TaskFactory<mozilla::net::SocketProcessHost>::TaskWrapper<mozilla::ipc::TaskFactory<mozilla::net::SocketProcessHost>::RunnableMethod<void (mozilla::net::SocketProcessHost::*)(),Tuple0> >::Run /builds/worker/workspace/obj-build/dist/include/mozilla/ipc/TaskFactory.h:37
#2 0x7fff324c3c5e in mozilla::RunnableTask::Run /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:468
#3 0x7fff3247dc88 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:771
#4 0x7fff3247a62c in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:607
#5 0x7fff3247aff4 in mozilla::TaskController::ProcessPendingMTTask /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:391
#6 0x7fff324ca6a1 in mozilla::detail::RunnableFunction<`lambda at /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:124:7'>::Run /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:531
#7 0x7fff324a66d4 in nsThread::ProcessNextEvent /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1195
#8 0x7fff324b6b3c in NS_ProcessNextEvent /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:467
#9 0x7fff338c823d in mozilla::ipc::MessagePump::Run /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85
#10 0x7fff337e12d5 in MessageLoop::RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:324
#11 0x7fff337e10a5 in MessageLoop::Run /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:306
#12 0x7fff3b367e1a in nsBaseAppShell::Run /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:137
#13 0x7fff3b554d6a in nsAppShell::Run /builds/worker/checkouts/gecko/widget/windows/nsAppShell.cpp:603
#14 0x7fff3f3bb68b in nsAppStartup::Run /builds/worker/checkouts/gecko/toolkit/components/startup/nsAppStartup.cpp:295
#15 0x7fff3f66f01c in XREMain::XRE_mainRun /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5317
#16 0x7fff3f67518e in XREMain::XRE_main /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5502
#17 0x7fff3f67640a in XRE_main /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5561
#18 0x7ff7523e2588 in NS_internal_main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:395
#19 0x7ff7523e17ad in wmain /builds/worker/checkouts/gecko/toolkit/xre/nsWindowsWMain.cpp:147
#20 0x7ff7524dca27 in __scrt_common_main_seh d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#21 0x7fff8bc37033 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017033)
#22 0x7fff8d002650 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x180052650)
0x1254e68ea0b0 is located 560 bytes inside of 584-byte region [0x1254e68e9e80,0x1254e68ea0c8)
freed by thread T5 here:
#0 0x7fff58067cdb in free Z:\task_163722766350223\fetches\llvm-project\llvm\projects\compiler-rt\lib\asan\asan_malloc_win.cpp:82
#1 0x7fff352ff30c in mozilla::gfx::VRProcessParent::~VRProcessParent /builds/worker/checkouts/gecko/gfx/vr/ipc/VRProcessParent.cpp:45
#2 0x7fff33891303 in mozilla::MozPromise<void *,mozilla::ipc::LaunchError,0>::ThenValue<`lambda at /builds/worker/checkouts/gecko/ipc/glue/GeckoChildProcessHost.cpp:487:19'>::DoResolveOrRejectInternal /builds/worker/workspace/obj-build/dist/include/mozilla/MozPromise.h:914
#3 0x7fff3190552e in mozilla::MozPromise<bool,nsresult,1>::ThenValueBase::ResolveOrRejectRunnable::Run /builds/worker/workspace/obj-build/dist/include/mozilla/MozPromise.h:487
#4 0x7fff337e2ab4 in MessageLoop::DeferOrRunPendingTask /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:463
#5 0x7fff337e4120 in MessageLoop::DoWork /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:538
#6 0x7fff337b537b in base::MessagePumpForIO::DoRunLoop /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_pump_win.cc:419
#7 0x7fff337b6198 in base::MessagePumpWin::Run /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_pump_win.h:79
#8 0x7fff337e12d5 in MessageLoop::RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:324
#9 0x7fff337f1f9e in base::Thread::ThreadMain /builds/worker/checkouts/gecko/ipc/chromium/src/base/thread.cc:187
#10 0x7fff337b77d6 in `anonymous namespace'::ThreadFunc /builds/worker/checkouts/gecko/ipc/chromium/src/base/platform_thread_win.cc:19
#11 0x7fff58072273 in __asan::AsanThread::ThreadStart Z:\task_163722766350223\fetches\llvm-project\llvm\projects\compiler-rt\lib\asan\asan_thread.cpp:278
#12 0x7fff8bc37033 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017033)
#13 0x7fff66783817 in patched_BaseThreadInitThunk /builds/worker/checkouts/gecko/toolkit/xre/dllservices/mozglue/WindowsDllBlocklist.cpp:570
#14 0x7fff8d002650 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x180052650)
previously allocated by thread T0 here:
#0 0x7fff58067deb in malloc Z:\task_163722766350223\fetches\llvm-project\llvm\projects\compiler-rt\lib\asan\asan_malloc_win.cpp:98
#1 0x7fff6667134d in moz_xmalloc /builds/worker/checkouts/gecko/memory/mozalloc/mozalloc.cpp:52
#2 0x7fff352fc9a0 in mozilla::gfx::VRProcessManager::LaunchVRProcess /builds/worker/checkouts/gecko/gfx/vr/ipc/VRProcessManager.cpp:67
#3 0x7fff3529d926 in mozilla::gfx::GPUChild::RecvCreateVRProcess /builds/worker/checkouts/gecko/gfx/ipc/GPUChild.cpp:147
#4 0x7fff33c694f7 in mozilla::gfx::PGPUChild::OnMessageReceived /builds/worker/workspace/obj-build/ipc/ipdl/PGPUChild.cpp:1253
#5 0x7fff338becf4 in mozilla::ipc::MessageChannel::DispatchAsyncMessage /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:2043
#6 0x7fff338bb160 in mozilla::ipc::MessageChannel::DispatchMessage /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1968
#7 0x7fff338bcf37 in mozilla::ipc::MessageChannel::RunMessage /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1827
#8 0x7fff338bd4e8 in mozilla::ipc::MessageChannel::MessageTask::Run /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1855
#9 0x7fff324c3c5e in mozilla::RunnableTask::Run /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:468
#10 0x7fff3247dc88 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:771
#11 0x7fff3247a62c in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:607
#12 0x7fff3247aff4 in mozilla::TaskController::ProcessPendingMTTask /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:391
#13 0x7fff324ca6a1 in mozilla::detail::RunnableFunction<`lambda at /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:124:7'>::Run /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:531
#14 0x7fff324a66d4 in nsThread::ProcessNextEvent /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1195
#15 0x7fff324b6b3c in NS_ProcessNextEvent /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:467
#16 0x7fff338c823d in mozilla::ipc::MessagePump::Run /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85
#17 0x7fff337e12d5 in MessageLoop::RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:324
Thread T5 created by T0 here:
#0 0x7fff580731d2 in __asan_wrap_CreateThread Z:\task_163722766350223\fetches\llvm-project\llvm\projects\compiler-rt\lib\asan\asan_win.cpp:146
#1 0x7fff337b776c in PlatformThread::Create /builds/worker/checkouts/gecko/ipc/chromium/src/base/platform_thread_win.cc:57
#2 0x7fff337f15bc in base::Thread::StartWithOptions /builds/worker/checkouts/gecko/ipc/chromium/src/base/thread.cc:93
#3 0x7fff3253aa6a in NS_InitXPCOM /builds/worker/checkouts/gecko/xpcom/build/XPCOMInit.cpp:318
#4 0x7fff3f650270 in ScopedXPCOMStartup::Initialize /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:1731
#5 0x7fff3f67516f in XREMain::XRE_main /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5498
#6 0x7fff3f67640a in XRE_main /builds/worker/checkouts/gecko/toolkit/xre/nsAppRunner.cpp:5561
#7 0x7ff7523e2588 in NS_internal_main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:395
#8 0x7ff7523e17ad in wmain /builds/worker/checkouts/gecko/toolkit/xre/nsWindowsWMain.cpp:147
#9 0x7ff7524dca27 in __scrt_common_main_seh d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#10 0x7fff8bc37033 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017033)
#11 0x7fff8d002650 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x180052650)
SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/checkouts/gecko/gfx/vr/ipc/VRProcessParent.cpp:165 in mozilla::gfx::VRProcessParent::InitAfterConnect
Shadow bytes around the buggy address:
0x04738311d3c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x04738311d3d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x04738311d3e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x04738311d3f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x04738311d400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x04738311d410: fd fd fd fd fd fd[fd]fd fd fa fa fa fa fa fa fa
0x04738311d420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x04738311d430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x04738311d440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x04738311d450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x04738311d460: 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
==21636==ABORTING
This vuln is discovered by bo13oy of Cyber Kunlun Lab.
Thanks.
Updated•3 years ago
|
Comment 1•3 years ago
|
||
From skimming the stacks, it looks like starting the VR process failed, causing us to destroy a VRProcessParent, but then later we touch the VR process parent anyways. I see some SocketProcessHost in the stack, too, so maybe the socket process is involved somehow? Jed, given that we don't have anybody actively working on VR and this seems to be mostly about a process launch issue, maybe you could take a look? Thanks.
Assignee | ||
Comment 2•3 years ago
|
||
I don't think that's actually the socket process — that frame looks like some kind of runnable wrapper trampoline, so probably simple enough to be identical-code-folded. Some preliminary observations:
The location of the bad use is interesting: to reach that point aSucceeded
must be true (meaning the launch worked), and it's also not the first access to *this
, but note that the object is used on the main thread and freed on the IPC I/O thread (i.e., this is probably a race). Specifically, from the lack of other things on the stack above InitAfterConnect
, it looks like the use was via VRProcessParent::OnChannelConnectedTask
.
It's harder to see what's going on with the free, but MozPromise<void *,mozilla::ipc::LaunchError,0>
is ProcessHandlePromise
, and the demangled symbol name has the source location for the lambda (which is nice and I don't think we have that on Unix?): the delete this
in GeckoChildProcessHost::Destroy
. That's from VRProcessParent::DestroyProcess
, which has several call chains that can reach it.
Assignee | ||
Updated•3 years ago
|
Assignee | ||
Comment 3•3 years ago
|
||
Part of the problem here seems to be TaskFactory
, which dates back to the original Chromium IPC import in 2009. If I'm reading it right, it uses RevocableStore
to check that the TaskFactory
(in this case, owned by the VRProcessParent
) hasn't been destroyed before executing the runnable. But there's nothing to prevent the destruction happening after the Run
method has already been entered (i.e., RevokeAll
just sets a flag; it has no facility for observing that runnables are running, let alone blocking until they complete).
Updated•3 years ago
|
Assignee | ||
Comment 4•3 years ago
|
||
There's a similar pattern in the GPU process, but we revoke any tasks on the main thread and return to the event loop before calling Destroy
, and the task factory is used only to send runnables to the main thread. So that should be safe (assuming the runnables in question don't spin a nested event loop, but I don't think they do). The problem for the VR process is that the RevokeAll
is too late and on the wrong thread, but if we change VRProcessParent::DestroyProcess
to look more like GPUProcessHost::DestroyProcess
then that should fix this.
As far as a test case / STR: I think if the child process crashes immediately after connecting the IPC channel, that will set up the situation where this can happen, but it's still going to be timing-sensitive.
Assignee | ||
Comment 5•3 years ago
|
||
(In reply to Jed Davis [:jld] ⟨⏰|UTC-7⟩ ⟦he/him⟧ from comment #4)
As far as a test case / STR: I think if the child process crashes immediately after connecting the IPC channel, that will set up the situation where this can happen, but it's still going to be timing-sensitive.
On further inspection, no: I think it has to be a deliberate shutdown from the parent side, either via this branch in OnChannelClosed
or the !mVRChild
case in the Shutdown
method. So, maybe something like starting to use WebVR and then immediately closing the window / destroying the frame.
Assignee | ||
Comment 6•3 years ago
|
||
Updated•3 years ago
|
Assignee | ||
Comment 7•3 years ago
|
||
Have you been able to find a test case for this? Alternately, if this is something that reproduces randomly during testing, is it possible to see if the attached patch (D137359) fixes it?
The condition of trigger is too picky, i am not capable to provide test case, so far as i see the fixed patch is available, but i am not familiar with this part. Just for your information.
Comment 9•3 years ago
|
||
The severity field is not set for this bug.
:jimm, could you have a look please?
For more information, please visit auto_nag documentation.
Comment 10•3 years ago
|
||
WebVR has been disabled by default in bug 1750902 (filed after this issue), which should also effectively address this issue.
![]() |
||
Comment 11•3 years ago
|
||
r=nika
https://hg.mozilla.org/integration/autoland/rev/5333329a0f2abf6249576071ca78651e4b6a5b8f
https://hg.mozilla.org/mozilla-central/rev/5333329a0f2a
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Assignee | ||
Comment 12•3 years ago
|
||
Comment on attachment 9261368 [details]
Bug 1750679.
ESR Uplift Approval Request
- If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-moderate and very low risk (see below)
- User impact if declined: Possible exposure to a use-after-free bug — WebVR was preffed off on ESR91 in bug 1750902, but I'm not as sure as I'd like to be that a compromised content process couldn't cause the VR process to be spawned anyway (i.e., I'm concerned that there might not be checks of the pref in a trusted process on all paths).
- Fix Landed on Version: 98
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): There should be essentially no risk: the pref exposing this feature is turned off, so this code shouldn't be reachable in normal operation (unless it's changed in about:config, but we warn people not to do that).
Comment 13•3 years ago
|
||
Seems like a good fix to take in the upcoming 91.7.1esr build along with the WebGPU follow-up. Thanks for raising this.
Comment 14•3 years ago
|
||
(In reply to Ryan VanderMeulen [:RyanVM] from comment #13)
Seems like a good fix to take in the upcoming 91.7.1esr build along with the WebGPU follow-up. Thanks for raising this.
This missed the 91.7.1esr release unfortunately. Retargeting 91.8esr instead.
Comment 15•3 years ago
|
||
Comment on attachment 9261368 [details]
Bug 1750679.
Approved for 91.8esr.
Comment 16•3 years ago
|
||
uplift |
Comment 17•3 years ago
|
||
Updated•3 years ago
|
Updated•3 years ago
|
Updated•2 years ago
|
Updated•8 months ago
|
Description
•