Closed
Bug 784730
Opened 13 years ago
Closed 12 years ago
"ASSERTION: wrapper already in new scope" with canvas, adoptNode
Categories
(Core :: XPConnect, defect)
Tracking
()
People
(Reporter: jruderman, Assigned: mccr8)
References
Details
(Keywords: assertion, sec-high, testcase, Whiteboard: [adv-main20+][adv-esr1705+])
Attachments
(3 files)
|
436 bytes,
text/html
|
Details | |
|
11.33 KB,
text/plain
|
Details | |
|
2.12 KB,
patch
|
bholley
:
review+
lsblakk
:
approval-mozilla-beta+
lsblakk
:
approval-mozilla-esr17+
lsblakk
:
approval-mozilla-b2g18+
dveditz
:
sec-approval+
|
Details | Diff | Splinter Review |
With:
user_pref("gfx.canvas.azure.enabled", false);
The testcase triggers:
###!!! ASSERTION: wrapper already in new scope!: '!newMap->Find(wrapper->GetIdentityObject())', file js/xpconnect/src/XPCWrappedNative.cpp, line 1651
| Reporter | ||
Comment 1•13 years ago
|
||
Updated•13 years ago
|
Assignee: nobody → continuation
| Assignee | ||
Comment 2•13 years ago
|
||
Azure is on by default everywhere in 18, so marking this unaffected for 18...
status-firefox18:
--- → unaffected
| Assignee | ||
Updated•13 years ago
|
| Assignee | ||
Comment 3•13 years ago
|
||
I looked at this a little. Something seems funny with the interaction of getContext and adoptNode. When I add this alert, it alerts "false", but if I comment out |frameDoc.adoptNode(canvas)|, then it alerts "true".
var frameDoc = document.getElementById("f").contentDocument;
var canvas = document.createElement('canvas');
var ctxA = canvas.getContext('2d');
frameDoc.adoptNode(canvas);
var ctxB = canvas.getContext('2d');
alert(ctxA === ctxB);
I guess because of the adoptNode it is creating two XPCWNs for the nsCanvasRenderingContext2D, and then when we do the write, RescueOrphan attempts to reconcile things, and discovers the duplication?
Maybe this is expected behavior of the old DOM bindings we get with Azure disabled?
Comment 4•13 years ago
|
||
Ugh, so this is a pain. Continuing drama from bug 751995.
So, the canvas rendering context is parented to the canvas element:
http://mxr.mozilla.org/mozilla-central/source/content/canvas/public/nsICanvasRenderingContextInternal.h#53 (this is called by nsNewDOMBindingSH<T, BaseType>::PreCreate)
We first create a wrapper for the context in scope A. Then, we move the canvas to scope B. This orphans ctxA (in the sense that its parent object becomes a cross-compartment wrapper). Our solution for this over in bug 751995 was just leave to leave it that way until something like a document.open came along where this would be a problem, and then fix them on demand when we run into them. Unfortunately, we didn't think about the possibility of a new wrapper (in the other scope) having already been created by then.
Once we have two wrappers floating around, we're in kind of bad shape. At minimum, we've got two different steps of expandos floating around, and we have no clear algorithm on how to merge them.
If possible, I think the best solution is to implement nsWrapperCache for anything that has the potential to be orphaned. That way, XPCConvert::NativeInterface2JSObject will just find the existing wrapper on the nsISupports* and avoid calling into XPCWrappedNative::GetNewOrUsed, which won't find the existing wrapper because it's only looking in |Scope|.
This applies to all non-element objects parented to elements that the element doesn't fix up in CloneAndAdopt: .style, nodelists, canvas contexts, possibly other stuff. Some of them (like nodelists) already implement nsWrapperCache. Peter, do you know the full list here?
| Assignee | ||
Comment 5•13 years ago
|
||
I guess with the new DOM bindings for 2d contexts, which requires Azure being on, IIRC, we wrappercache them, which is why this example only fails with Azure off.
Blocks: 751995
status-firefox-esr10:
--- → unaffected
status-firefox15:
--- → wontfix
status-firefox16:
--- → affected
status-firefox17:
--- → affected
| Assignee | ||
Comment 6•13 years ago
|
||
Bobby: is there any kind of mitigation we can take that could be backported? Wrappercaching a bunch of classes doesn't sound simple. How bad of a security problem do you think this is? Losing expandos doesn't seem security sensitive, but I could imagine there being badness if you end up with multiple wrappers floating around.
| Assignee | ||
Updated•13 years ago
|
Component: DOM → XPConnect
Comment 7•13 years ago
|
||
(In reply to Andrew McCreight [:mccr8] from comment #6)
> Losing expandos doesn't seem security
> sensitive, but I could imagine there being badness if you end up with
> multiple wrappers floating around.
Yeah, that's what worries me. I'm sure there are ways to crash the browser in interesting ways when doing that.
Would wrapper caching canvas contexts really be all that bad? Too much to backport to beta at this point, but we could at least do it on aurora and such.
Also note that the regular CPG-esr10 story applies here.
| Assignee | ||
Comment 8•13 years ago
|
||
I think canvas contexts were converted to the new DOM bindings in 15 (bug 748266), but they are only used with Azure. I think Azure is only enabled everywhere as of 18, but I think it has been on Windows for longer?
Comment 9•13 years ago
|
||
(In reply to Andrew McCreight [:mccr8] from comment #8)
> I think canvas contexts were converted to the new DOM bindings in 15 (bug
> 748266), but they are only used with Azure. I think Azure is only enabled
> everywhere as of 18, but I think it has been on Windows for longer?
All correct. Azure canvas has also been enabled on mac for longer, I'm not sure exactly when it got turned on for mac/windows. The plan is for 19 to only have Azure canvas, 18 will have Thebes canvas, but it won't be used by default.
Comment 10•13 years ago
|
||
Azure on Windows was only available if you had direct2d, until recently, I thought. So not on WinXP and not if your drivers were blacklisted...
Mac had Azure canvas before we landed the new DOM bindings.
| Assignee | ||
Comment 11•13 years ago
|
||
I don't really know much about this wrapper context stuff. Maybe bholley has a better idea what to do here...
Assignee: continuation → bobbyholley+bmo
Comment 12•13 years ago
|
||
The best idea I've got is to wrapper-cache anything that can be orphaned: .style, nodelists, canvas contexts, what else?
Peter, can you brainstorm such a list?
Updated•13 years ago
|
Flags: needinfo?(peterv)
Comment 13•13 years ago
|
||
since comment 4 says "continuing drama from bug 751995" I'm just going to guess this gets the same rating.
Keywords: sec-critical
Comment 14•13 years ago
|
||
peterv, any updates re comment 12?
Comment 15•13 years ago
|
||
Updating tracking.
status-firefox19:
--- → affected
status-firefox20:
--- → affected
status-firefox-esr17:
--- → affected
Comment 16•13 years ago
|
||
Maybe bz can answer instead.
Flags: needinfo?(peterv) → needinfo?(bzbarsky)
Updated•13 years ago
|
Comment 17•13 years ago
|
||
(In reply to Bobby Holley (:bholley) from comment #12)
> The best idea I've got is to wrapper-cache anything that can be orphaned:
> .style, nodelists, canvas contexts, what else?
>
> Peter, can you brainstorm such a list?
It's not easy, things are pretty spread out. Here's the list of DOM interfaces I have for now based on trunk code, but it's incomplete:
CanvasRenderingContext2D
DOMImplementation
DOMCSSDeclarationImpl
DOMSVGLengthList
DOMSVGNumberList
DOMSVGPathSegList
DOMSVGPointList
DOMSVGTransformList
HTMLPropertiesCollection
nsAnonymousContentList
nsClientRectList
nsComputedDOMStyle
nsCSSFontFaceStyleDecl
nsDOMCSSAttributeDeclaration
nsDOMFileList
nsDOMStringMap
nsDOMTokenList
nsFormControlList
nsHTMLOptionCollection
PropertyNodeList
TableRowsCollection
WebGLContext
Note that most of these are wrapper-cached on trunk (and converted to new bindings). We'd have to check for each whether they are actually affected on branches if we want to fix it there. Especially since we changed some of these to be parented to a node as part of wrapper-caching them, so even if they're not wrapper-cached on a branch that might not be a problem.
Comment 18•13 years ago
|
||
The only sane way to get such a list is to grep for all interface names mentioned in any IDL inheriting from Node....
Flags: needinfo?(bzbarsky)
Comment 19•13 years ago
|
||
(In reply to Boris Zbarsky (:bz) from comment #18)
> The only sane way to get such a list is to grep for all interface names
> mentioned in any IDL inheriting from Node....
Are we going to do this? Are we moving towards an approach to a patch for this?
Comment 21•12 years ago
|
||
Andrew, any updates?
| Assignee | ||
Comment 22•12 years ago
|
||
nope
Updated•12 years ago
|
status-b2g18:
--- → affected
status-firefox21:
--- → affected
tracking-firefox21:
--- → +
Keywords: sec-critical → sec-high
| Assignee | ||
Comment 23•12 years ago
|
||
I met with bholley, bz, peterv and mrbkap on this issue. Apparently it is not a big deal to have two XPCWNs in different compartments. Problems only arise when we attempt to create a wrapper in a compartment where there already is one, but that is easy to detect. The new plan, then, is to make this assertion into a MOZ_CRASH(), thereby converting a security problem into a stability problem. We can fix particular stability problems that show up by wrapper caching as needed, and otherwise just let this gradually happen as things are converted to the new DOM bindings. Wrapper caching in general could have weird effects, so it may not be suitable for backporting.
| Assignee | ||
Comment 24•12 years ago
|
||
| Assignee | ||
Comment 25•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
This had a clean Linux64 debug try run.
Attachment #710625 -
Flags: review?(bobbyholley+bmo)
Comment 26•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
Add a comment to the MOZ_CRASH. r=bholley
Attachment #710625 -
Flags: review?(bobbyholley+bmo) → review+
| Assignee | ||
Comment 27•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
[Security approval request comment]
How easily could an exploit be constructed based on the patch? Well, this is just converting an existing assertion to be fatal in release. So we're not exposing a new issue per se, but it does indicate that for some reason we started caring about this more, which could make somebody look at this more. If somebody understands orphan rescue, it probably isn't too hard to recreate the test case (with something besides the azure stuff).
Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem? Not particularly, the comments are just the same as the assert comment.
Which older supported branches are affected by this flaw? At this point, probably most or all of them.
If not all supported branches, which bug introduced the flaw?
Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? Just converting an old assertion, should be easy to update the patch.
How likely is this patch to cause regressions; how much testing does it need? The basic problem here is that we're aren't fixing a problem, we're turning it from a security hazard into a controlled crash. If this starts showing up in crash stats, then we'll have to land further patches that wrapper cache to fix the actual problem to fix the crashes, and those could be risky. I'm not sure how common it is to adoptNode the same node repeatedly into multiple documents.
Attachment #710625 -
Flags: sec-approval?
| Assignee | ||
Updated•12 years ago
|
status-firefox-esr10:
unaffected → ---
status-firefox15:
wontfix → ---
status-firefox16:
wontfix → ---
status-firefox17:
wontfix → ---
Updated•12 years ago
|
tracking-firefox20:
--- → +
tracking-firefox-esr17:
--- → ?
Comment 28•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
sec-appproval+
Attachment #710625 -
Flags: sec-approval? → sec-approval+
| Assignee | ||
Comment 29•12 years ago
|
||
| Assignee | ||
Comment 30•12 years ago
|
||
Oops, I forgot to add the comment. I'll land a followup in the next day or two.
Flags: needinfo?(continuation)
| Assignee | ||
Comment 31•12 years ago
|
||
Flags: needinfo?(continuation)
Comment 32•12 years ago
|
||
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla21
Comment 33•12 years ago
|
||
Comment 34•12 years ago
|
||
Batch edit: Bugs still affected on b2g18 after 2/13 merge to v1.0.1 branch are affected on v1.0.1 branch.
status-b2g18-v1.0.1:
--- → affected
Updated•12 years ago
|
tracking-b2g18:
--- → 20+
| Assignee | ||
Comment 35•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
[Approval Request Comment]
Bug caused by (feature/regressing bug #): pretty old
User impact if declined: possible security problems
Testing completed: it has been on Nightly for a few weeks
Risk to taking this patch (and alternatives if risky): low. any badness will show up in crash stats, and we can trivially back out the patch
String or UUID changes made by this patch: none
This has been on Nightly for a week or two, and I don't see any instances of crashes with "rescue" or "reparent" in the top 300 on crash stats for Nightly, so I think we're not hitting this in the wild, so this should be okay to uplift.
Attachment #710625 -
Flags: approval-mozilla-esr17?
Attachment #710625 -
Flags: approval-mozilla-beta?
Attachment #710625 -
Flags: approval-mozilla-b2g18?
| Assignee | ||
Comment 36•12 years ago
|
||
Note to me or whoever lands this: make sure to land both patches. The second one just adds a comment.
Comment 37•12 years ago
|
||
Comment on attachment 710625 [details] [diff] [review]
crash in ReparentWrapperIfFound if wrapper already in new scope
Approving for uplift, let's get this in now so we have time, if needed, to back out. For b2g18 this can be uplift to v1-train.
Attachment #710625 -
Flags: approval-mozilla-esr17?
Attachment #710625 -
Flags: approval-mozilla-esr17+
Attachment #710625 -
Flags: approval-mozilla-beta?
Attachment #710625 -
Flags: approval-mozilla-beta+
Attachment #710625 -
Flags: approval-mozilla-b2g18?
Attachment #710625 -
Flags: approval-mozilla-b2g18+
Updated•12 years ago
|
Comment 38•12 years ago
|
||
https://hg.mozilla.org/releases/mozilla-beta/rev/aeea02f63cb2
https://hg.mozilla.org/releases/mozilla-b2g18/rev/923fe8fd8a32
https://hg.mozilla.org/releases/mozilla-esr17/rev/f00cf94f3cb8
FWIW, I qfolded the two csets into one for the uplifts.
Comment 39•12 years ago
|
||
I've been trying to reproduce this issue on Firefox 20b1 (regular and debug builds), but it's not happening.
gfx.canvas.azure.enabled doesn't exist in about:config anymore, so I tried to reproduce this without it, and with it added manually.
Does anybody have any ideas about how else I could reproduce it?
| Assignee | ||
Comment 40•12 years ago
|
||
It is probably okay to not reproduce it. My patch just turns an assertion into a runtime check. I'm not sure why the particular test case doesn't reproduce.
Updated•12 years ago
|
Whiteboard: [adv-main20+][adv-esr1705+]
Comment 41•12 years ago
|
||
This crashes in 17.0.5 ESR, are you sure this issue is fixed there?
| Assignee | ||
Comment 42•12 years ago
|
||
(In reply to Huzaifa Sidhpurwala from comment #41)
> This crashes in 17.0.5 ESR, are you sure this issue is fixed there?
My patch here is kind of weird in that it takes potentially undefined behavior and turns it into a controlled crash. If you look at the stack in the crash report in about:crashes, it should have MOZ_CRASH or something at the top.
As an aside, I looked at the list of crashes a little while ago, and didn't see anything that looked like the crash I introduced here, so fortunately this isn't something that people are getting in a normal browsing scenario.
Comment 43•12 years ago
|
||
Since Firefox 20 is now released, v1.0.1 branches are still open, and this is considered low risk, we can uplift to v1.0.1. Marking as tef+ and flipping status-b2g18-v1.0.1 to affected.
blocking-b2g: --- → tef+
Comment 44•12 years ago
|
||
Updated•12 years ago
|
Group: core-security
You need to log in
before you can comment on or make changes to this bug.
Description
•