[wasm-gc] WASM type confusion due to broken js::wasm::ArrayType::canBeSubtypeOf() check
Categories
(Core :: JavaScript: WebAssembly, defect, P1)
Tracking
()
People
(Reporter: seunghyun3288, Assigned: rhunt)
References
(Regression)
Details
(Keywords: regression, reporter-external, sec-high, Whiteboard: [adv-main130+][adv-esr128.2+][client-bounty-form])
Attachments
(9 files)
|
75.37 KB,
text/html
|
Details | |
|
77.18 KB,
text/html
|
Details | |
|
432 bytes,
application/x-javascript
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
dveditz
:
approval-mozilla-beta+
dveditz
:
sec-approval+
|
Details | Review |
|
2.93 KB,
patch
|
Details | Diff | Splinter Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-beta+
|
Details | Review |
|
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-esr128+
|
Details | Review |
|
198 bytes,
text/plain
|
Details |
Vulnerability Details
Summary
WASM type confusion due to broken js::wasm::ArrayType::canBeSubtypeOf() check.
Details
js::wasm::ArrayType::canBeSubtypeOf() always returns true if array mutability is different, resulting in arbitrary type confusion between array elements.
// https://searchfox.org/mozilla-central/source/js/src/wasm/WasmTypeDef.h#457
static bool canBeSubTypeOf(const ArrayType& subType,
const ArrayType& superType) {
// Mutable fields are invariant w.r.t. field types
if (subType.isMutable_ && superType.isMutable_) {
return subType.elementType_ == superType.elementType_;
}
// Immutable fields are covariant w.r.t. field types
if (!subType.isMutable_ && !superType.isMutable_) {
return StorageType::isSubTypeOf(subType.elementType_,
superType.elementType_);
}
return true;
}
This allows an attacker to acquire traditional JS exploit primitives such as addrof/fakeobj, as well as arbitrary read/write primitives.
Bug discovered through code audit.
Version / Bisect
Existed since the implementation of Bug 1774827 (108 Branch), up to latest.
Repro
Attached poc.html, visit the html file in Firefox for an immediate renderer crash.
This PoC uses the bug to confuse:
- anyref -> I64 (addrof)
- I64 -> anyref (fakeobj)
- I64 -> struct ( I64 ) (arbitrary RW)
...and obtain corresponding memory corruption primitives. The PoC attempts to console.log() on a fakeobj(0x424242424242n), resulting in a renderer crash.
Note that arbitrary read/write operations do work, but with invalid addresses it does not immediately crash the renderer. This is likely due to WASM trap handling incorrectly capturing the segfault as a null pointer dereference - the read/write attempt can easily be verified by a debugger.
Some info regarding submission
I've initially submitted this to security@mozilla.org over PGP-encrypted email, following this Mozilla docs, but another docs suggest that I shouldn't have...? Quite confusing (report via email? bug bounty form? or just new bug w/ security checked in Bugzilla?), but anyways note that the vulnerability details & PoC has already been sent over PGP-encrypted email (and delete them if necessary). Also, please tell me where & in what format I should submit my future bugs so that everything works out clean :)
Updated•1 year ago
|
| Reporter | ||
Comment 1•1 year ago
|
||
Added exp.html that pops calc from an unsandboxed renderer. Run the following commands in cmd to disable content sandbox and test the exploit:
set MOZ_DISABLE_CONTENT_SANDBOX=1<path to firefox.exe> <path to exp.html>
I thought Firefox has W^X, but somehow wasm code region is RWX? The exploit simply overwrites the JITed code of an exported wasm function to shellcode and runs it.
| Reporter | ||
Updated•1 year ago
|
Updated•1 year ago
|
Comment 3•1 year ago
|
||
Here is a reduced version of poc.html, suitable for use in the shell. It's a remarkably simple exploit.
Comment 4•1 year ago
|
||
Quite confusing (report via email? bug bounty form? or just new bug w/ security checked in Bugzilla?) ... Also, please tell me where & in what format I should submit my future bugs so that everything works out clean :)
If you're specifically interested in the Bug Bounty you should definitely use the Bug Bounty form on bugzilla. The normal bugzilla bug entry form is great, too, but you have to remember to manually check the security issue box; if you don't the bug will be public, and the security team likely won't notice the report. Either form directly creates an issue in bugzilla, which is our preference.
Encrypted mail is our least favorite way, but it's an option if necessary.
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 5•1 year ago
|
||
The spec has the notion of a 'FieldType' which both struct fields
and array types share. This commit refactors them to use the same
type.
Comment 6•1 year ago
|
||
This makes D218753 (the patch in comment 5) apply to m-release.
First apply D218753, then apply this on top.
| Assignee | ||
Comment 7•1 year ago
|
||
Depends on D218753
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 8•1 year ago
|
||
This has been an issue since we implemented declared subtyping in wasm-gc. Marking the regressed by bug for shipping wasm-gc, which happened in Fx120.
| Assignee | ||
Comment 9•1 year ago
|
||
Comment on attachment 9418159 [details]
Bug 1911909 - wasm: Refactor structs and arrays to more closely match the spec. r?bvisness
Security Approval Request
- How easily could an exploit be constructed based on the patch?: Moderate difficulty. The real issue is that this line [1] should return false instead of true. This patch accomplishes this by doing a reasonable refactoring to change our ArrayType code to shared code with our StructField code (as the wasm spec does), which fixes the issue. But with a motivated enough attacker, they may be able to diff through the methods to figure out what really changed. And if they can isolate the real change an exploit is easy to construct.
- 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 branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: ESR, Beta, and Release. Release status flags are correct.
- 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?: It was easy to create a patch for release, these changes are very mechanical.
- How likely is this patch to cause regressions; how much testing does it need?: Unlikely. It's a simple change, but just with a lot of lines to update. I've done a try run by melding it into some other unrelated work.
- Is the patch ready to land after security approval is given?: Yes
- Is Android affected?: Yes
Comment 10•1 year ago
|
||
Comment on attachment 9418159 [details]
Bug 1911909 - wasm: Refactor structs and arrays to more closely match the spec. r?bvisness
sec-approval+ = dveditz. Also approving uplift to beta -- earlier is better: it will look like planned work that missed the deadline but was safe enough for promotion
Updated•1 year ago
|
Comment 11•1 year ago
•
|
||
[Tracking Requested - why for this release]:
We should keep an eye on this one and consider taking it if there's a mid-cycle release of both 129.0.x and ESR-128.1.x. The patch does a great job of looking like a refactor and doesn't directly change the incorrect line of code (the entire method body it's in is removed in favor of calling a more generic version of the method), but once discovered the vulnerability can be triggered easily and reliably (see Ben's test in attachment 9418135 [details]).
I realize that may not be possible in an effectively short cycle with so many people out on vacations and conferences. Waiting until 130 should be safe enough.
Comment 12•1 year ago
|
||
Comment 13•1 year ago
|
||
| Assignee | ||
Comment 14•1 year ago
|
||
The spec has the notion of a 'FieldType' which both struct fields
and array types share. This commit refactors them to use the same
type.
Original Revision: https://phabricator.services.mozilla.com/D218753
Updated•1 year ago
|
Comment 15•1 year ago
|
||
beta Uplift Approval Request
- User impact if declined: Exploitable security issue, see sec-approval request for details.
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing: None
- Risk associated with taking this patch: Low
- Explanation of risk level: Mostly mechanical patch covered well by tests
- String changes made/needed: None
- Is Android affected?: yes
| Assignee | ||
Comment 16•1 year ago
|
||
Just created a formal beta uplift request and revision for this. Dan, do you need to transfer your beta approval over to that one?
Comment 17•1 year ago
|
||
(In reply to Ryan Hunt [:rhunt] from comment #16)
Just created a formal beta uplift request and revision for this. Dan, do you need to transfer your beta approval over to that one?
It's ok, relman will take care of approving that request.
:rhunt could you add an esr128 request also?
| Assignee | ||
Comment 18•1 year ago
|
||
The spec has the notion of a 'FieldType' which both struct fields
and array types share. This commit refactors them to use the same
type.
Original Revision: https://phabricator.services.mozilla.com/D218753
Updated•1 year ago
|
Comment 19•1 year ago
|
||
esr128 Uplift Approval Request
- User impact if declined: Exploitable security issue, see sec-approval request for details
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing: None
- Risk associated with taking this patch: Low
- Explanation of risk level: Mostly mechanical patch covered well by tests
- String changes made/needed: None
- Is Android affected?: yes
Updated•1 year ago
|
Updated•1 year ago
|
Comment 20•1 year ago
|
||
Comment on attachment 9418570 [details]
Bug 1911909 - wasm: Refactor structs and arrays to more closely match the spec. r?bvisness
:rhunt this failed to land in beta due to conflicts.
Could you please take a look and rebase the patch?
Updated•1 year ago
|
Comment 22•1 year ago
|
||
| uplift | ||
Updated•1 year ago
|
Updated•1 year ago
|
Comment 23•1 year ago
|
||
Comment on attachment 9418625 [details]
Bug 1911909 - wasm: Refactor structs and arrays to more closely match the spec. r?bvisness
:rhunt I added a comment on the esr128 patch, it needs to be rebased.
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 25•1 year ago
|
||
| uplift | ||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
| Reporter | ||
Comment 26•1 year ago
|
||
Please donate the bounty to a charity of your choice, thanks :)
Updated•1 year ago
|
Comment 27•1 year ago
|
||
Updated•1 year ago
|
Comment 28•1 year ago
|
||
2 months ago, dveditz placed a reminder on the bug using the whiteboard tag [reminder-test 2024-10-15] .
rhunt, please refer to the original comment to better understand the reason for the reminder.
| Reporter | ||
Comment 29•1 year ago
|
||
Hi, I would like to disclose information about this bug on Nov. 7 at POC2024 conference, based on the standard 90-day disclosure deadline. Please let me know if you need more time, thanks.
Comment 30•1 year ago
|
||
Thank you for reaching out to us Seunghyun Lee. I see no concerns with you talking about this bug in public given that we have addressed the bug 8 weeks ago in Firefox 130. Good luck with your presentation.
Updated•7 months ago
|
Comment 31•2 months ago
|
||
Comment 32•2 months ago
|
||
| bugherder | ||
| Assignee | ||
Updated•2 months ago
|
Description
•