UAF in Webgpu status manager [exploited in the wild]
Categories
(Core :: Graphics: WebGPU, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox-esr91 | 97+ | fixed |
firefox97 | + | fixed |
firefox98 | --- | unaffected |
firefox99 | --- | unaffected |
People
(Reporter: m.cooolie, Assigned: nical)
References
Details
(4 keywords, Whiteboard: [adv-main97.0.2+]{adv-esr91.6.1+][reporter-external] [client-bounty-form] [verif?][sec-survey])
Attachments
(4 files, 1 obsolete file)
135.00 KB,
image/png
|
Details | |
100.20 KB,
image/png
|
Details | |
48 bytes,
text/x-phabricator-request
|
RyanVM
:
approval-mozilla-release+
RyanVM
:
approval-mozilla-esr91+
tjr
:
sec-approval+
|
Details | Review |
286 bytes,
text/plain
|
Details |
#Summary
UAF in Webgpu status manager[exploited in the wild]
#Type
GPU process RCE
#NOTE
We have evidence that the following bug is being explot in the wild.
This problem has been fixed in the latest beta version,
the reason for the fix is an accident(https://bugzilla.mozilla.org/show_bug.cgi?id=1746538),
but the stable version (97.0.1) has not been synchronized.
Therefore, we think it is necessary to report this vulnerability in detail, so that the stable version can be fixed as soon as possible,
and at the same time apply for a CVE number to track this vulnerability
#CREDIT
wang gang&liu jialei&du sihang&huang yi&yang kang of 360 ATA
#MINIPOC
mov rax, [rsp+0E38h+var_DF8]
mov qword ptr [rax+198h], 0
mov rax, [rsp+0E38h+var_DF8]
add rax, 198h
xor edx, edx
mov rcx, rax
call [rsp+0E38h+mozilla::webgpu::Instance::Create] <<[1]
mov rax, [rsp+0E38h+var_DF8]
mov rax, [rax+198h]
mov rcx, [rax+20h]
call [rsp+0E38h+mozilla::webgpu::PWebGPUChild::SendShutdown] <<[2]
mov [rsp+0E38h+var_DEC], 0
#RCA
- Get Render side RCE,we already reported in https://bugzilla.mozilla.org/show_bug.cgi?id=1758062
- Run shellcode in compromised Render process call mozilla::webgpu::Instance::Create then call mozilla::webgpu::PWebGPUChild::SendShutdown
to get a webgpu with wrong status. - After a clever heap layout call mozilla::webgpu::PWebGPUChild::SendShaderModuleDestroy get RCE
ipc::IPCResult WebGPUParent::RecvShutdown() {
mTimer.Stop();
for (const auto& p : mCanvasMap) {
const wr::ExternalImageId extId = {p.first};
layers::TextureHost::DestroyRenderTexture(extId);
}
mCanvasMap.clear();
ffi::wgpu_server_poll_all_devices(mContext, true);
ffi::wgpu_server_delete(const_cast<ffi::WGPUGlobal*>(mContext)); <<
return IPC_OK();
}
Because the GPU process is a high-privileged process in Firefox on windows, attackers use this vulnerability for sandbox escape.
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Comment 2•3 years ago
|
||
We are still investigating this issue but there is one thing that is unclear to us: We already deployed a fix in Firefox 94 (and ESR91/78) that would check if WebGPU is enabled or not, and if not, it would never allocate a WebGPUParent
in the first place.
This fix landed here longer ago: https://hg.mozilla.org/mozilla-central/rev/33918b139eff#l2.17
Can you elaborate on how you are able to SendShutdown
to the parent when the parent cannot even be allocated? Note that WebGPU is disabled by default in all versions of Firefox.
Comment 3•3 years ago
|
||
The check is also still present in Firefox 97.0.1: https://hg.mozilla.org/releases/mozilla-release/file/FIREFOX_97_0_1_RELEASE/gfx/layers/ipc/CompositorBridgeParent.cpp#l1293
The debug looks like this function is called and left and returns, I will continue to analyze it in depth
xul!mozilla::layers::PCompositorBridgeParent::RecvPWebGPUConstructor
alloc in this function xul!mozilla::layers::ContentCompositorBridgeParent::AllocPWebGPUParent
Comment 7•3 years ago
|
||
What is surprising to us is that webgpu is disabled by default - Can you confirm the state of the preference dom.webgpu.enabled
in about:config?
Assignee | ||
Comment 8•3 years ago
|
||
Patched because compromised Render process
v29 = *mozilla::gfx::sConfig + 0x1760i64;
*v29 = 0;
*(v29 + 0x148) = 0x1D;
Updated•3 years ago
|
Assignee | ||
Comment 10•3 years ago
|
||
Comment on attachment 9266493 [details]
WIP: Bug 1758070 - Null out mContext during shutdown.
Beta/Release Uplift Approval Request
- User impact if declined: Exploitable sandbox escape
- Is this code covered by automated tests?: No
- Has the fix been verified in Nightly?: No
- Needs manual test from QE?: No
- If yes, steps to reproduce: We know how to reproduce the exploit.
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Not risky because
- Trivial change. we null out a pointer after calling a function that deallocates it.
- It affects a code path that is preffed off by default on release
- String changes made/needed:
Updated•3 years ago
|
Assignee | ||
Comment 11•3 years ago
|
||
Comment on attachment 9266493 [details]
WIP: Bug 1758070 - Null out mContext during shutdown.
ESR Uplift Approval Request
- If this is not a sec:{high,crit} bug, please state case for ESR consideration:
- User impact if declined: Exploitable sandbox escape
- Fix Landed on Version:
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): - Trivial change. we null out a pointer after calling a function that deallocates it.
- It affects a code path that is preffed off by default on release
Comment 12•3 years ago
|
||
Comment on attachment 9266493 [details]
WIP: Bug 1758070 - Null out mContext during shutdown.
Approved to land
Updated•3 years ago
|
Updated•3 years ago
|
Comment 13•3 years ago
|
||
Assignee | ||
Comment 14•3 years ago
|
||
Comment 15•3 years ago
|
||
When able, we would appreciate being able to see the "clever heap layout" steps in the exploit - we are very interested to see examples of cross-IPC heap grooming to see what may make those techniques more difficult/less reliable.
Reporter | ||
Comment 16•3 years ago
|
||
The attacker does a lot of preparation and then lays out the heap by calling mozilla::layers::PWebRenderBridgeChild::SendSetDisplayList.
Comment 17•3 years ago
•
|
||
uplift |
Bug 1758070 - Null out mContext during shutdown.
https://hg.mozilla.org/releases/mozilla-release/rev/8b52e7734a682de17e86bcec07f1c75663d13cd6 (97.0.2)
https://hg.mozilla.org/releases/mozilla-esr91/rev/a9d3c0f4732a9a62428089fff64ae8ff3d608918 (91.7esr+)
https://hg.mozilla.org/releases/mozilla-esr91/rev/15cd774afc2d29cce70c219573fea18491436f1d (91.6.1esr)
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Comment 18•3 years ago
|
||
Is there any way QA can verify this?
Comment 19•3 years ago
|
||
Comment on attachment 9266533 [details]
WIP: Bug 1758070 - Better check the webgpu pref.
Revision D140362 was moved to bug 1758156. Setting attachment 9266533 [details] to obsolete.
Comment 20•3 years ago
|
||
Follow-up work is happening in bug 1758156. Closing this out for the work which already landed for better tracking.
Updated•3 years ago
|
Comment 21•3 years ago
•
|
||
We currently do not understand how the exploit works in Firefox 97 if the WebGPU pref is disabled. We have a check in CompositorBridgeParent::AllocPWebGPUParent
which checks mOptions.UseWebGPU()
:
// We should only ever get this if WebGPU is enabled in this compositor.
MOZ_RELEASE_ASSERT(mOptions.UseWebGPU());
The only way to influence mOptions
is from the CompositorBridgeParent
constructor, which is only called from two places:
- In
CreateSameProcessWidgetCompositorBridge
, which is not callable from content - In
CompositorManagerParent::AllocPCompositorBridgeParent
which is triggered by a message from content.
But the call in CompositorManagerParent::AllocPCompositorBridgeParent
is in the CompositorBridgeOptions::TWidgetCompositorOptions
branch, which has the following check:
gfx::GPUParent* gpu = gfx::GPUParent::GetSingleton();
if (NS_WARN_IF(!gpu || OtherPid() != gpu->OtherPid())) {
MOZ_ASSERT_UNREACHABLE("Child cannot create widget compositor!");
break;
}
So if this method is called in response to a message from the content process, the OtherPid() != gpu->OtherPid()
check should fail, and we should bail out.
So I don't know how content can cause the creation of a CompositorBridgeParent
whose mOptions
has UseWebGPU() == true
, unless the WebGPU pref is enabled.
Comment 22•3 years ago
|
||
It would be great to get more insight regarding comment 21, can you provide more details as to how mOptions
got influenced here? Thanks!
Comment 23•3 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #21)
We currently do not understand how the exploit works in Firefox 97 if the WebGPU pref is disabled. We have a check in
CompositorBridgeParent::AllocPWebGPUParent
which checksmOptions.UseWebGPU()
:// We should only ever get this if WebGPU is enabled in this compositor. MOZ_RELEASE_ASSERT(mOptions.UseWebGPU());
Ah, this check is in the wrong AllocPWebGPUParent
method. It's only on CompositorBridgeParent::AllocPWebGPUParent
. But we also have ContentCompositorBridgeParent::AllocPWebGPUParent
, which does not have the check, and that's the one that's called by content:
webgpu::PWebGPUParent* ContentCompositorBridgeParent::AllocPWebGPUParent() {
webgpu::WebGPUParent* parent = new webgpu::WebGPUParent();
parent->AddRef(); // IPDL reference
return parent;
}
Comment 24•3 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #23)
But we also have
ContentCompositorBridgeParent::AllocPWebGPUParent
, which does not have the check, and that's the one that's called by content
And that's the one to which nical is adding the check, in bug 1758156.
Updated•3 years ago
|
Updated•3 years ago
|
Comment 25•3 years ago
|
||
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.
Assignee | ||
Updated•3 years ago
|
Updated•2 years ago
|
Updated•8 months ago
|
Description
•