Bug 532124 - Set aside the frame chain when wrapping for chrome so we don't get confused by any content code on the stack. r=jst

This commit is contained in:
Blake Kaplan 2009-12-11 10:33:32 -08:00
parent b7cbf88c7e
commit 91fd0fb306
2 changed files with 37 additions and 2 deletions

View File

@ -451,15 +451,27 @@ XPC_COW_RewrapForChrome(JSContext *cx, JSObject *wrapperObj, jsval *vp)
} }
XPCWrappedNative *wn; XPCWrappedNative *wn;
JSBool ok;
// Set aside the frame chain so that we'll be able to wrap this object for
// chrome's use.
JSStackFrame *fp = JS_SaveFrameChain(cx);
if (IS_WN_WRAPPER(obj) && if (IS_WN_WRAPPER(obj) &&
(wn = (XPCWrappedNative*)xpc_GetJSPrivate(obj)) && (wn = (XPCWrappedNative*)xpc_GetJSPrivate(obj)) &&
!nsXPCWrappedJSClass::IsWrappedJS(wn->Native())) { !nsXPCWrappedJSClass::IsWrappedJS(wn->Native())) {
// Return an explicit XPCNativeWrapper in case "chrome" code happens to be // Return an explicit XPCNativeWrapper in case "chrome" code happens to be
// XBL code cloned into an untrusted context. // XBL code cloned into an untrusted context.
return XPCNativeWrapper::CreateExplicitWrapper(cx, wn, JS_TRUE, vp); ok = XPCNativeWrapper::CreateExplicitWrapper(cx, wn, JS_TRUE, vp);
} else {
// Note: we're passing the wrapped chrome object as the scope for the SJOW.
ok = XPCSafeJSObjectWrapper::WrapObject(cx, GetWrappedObject(cx, wrapperObj),
*vp, vp);
} }
return XPCSafeJSObjectWrapper::WrapObject(cx, obj, *vp, vp); JS_RestoreFrameChain(cx, fp);
return ok;
} }
JSBool JSBool

View File

@ -35,6 +35,13 @@ sandbox.getCOW = getCOW;
const TEST_API = ['is', 'isnot', 'ok', 'todo_is', 'todo_isnot', 'todo']; const TEST_API = ['is', 'isnot', 'ok', 'todo_is', 'todo_isnot', 'todo'];
TEST_API.forEach(function(name) { sandbox[name] = window[name]; }); TEST_API.forEach(function(name) { sandbox[name] = window[name]; });
sandbox.alienObject = test_utils.getCOWForObject(sandbox, {
__exposedProps__: {funProp: 'r'},
funProp: function foo(x) {
return x + 1;
}
});
function COWTests() { function COWTests() {
// This function is actually decompiled and run inside a // This function is actually decompiled and run inside a
// sandbox with content privileges. // sandbox with content privileges.
@ -149,6 +156,22 @@ function COWTests() {
} catch (e) { } catch (e) {
ok(false, "Readable function exposed props should be callable" + e); ok(false, "Readable function exposed props should be callable" + e);
} }
try {
is(alienObject.funProp(1), 2,
"COWs wrapping objects from different principals should work");
} catch (e) {
ok(false, "COWs wrapping objs from different principals " +
"shouldn't throw " + e);
}
try {
is(alienObject.funProp(1), 2,
"COWs wrapping objs from different principals should work twice");
} catch (e) {
ok(false, "COWs wrapping objs from different principals " +
"shouldn't throw on second access but not first: " + e);
}
} }
// Decompile the COW test suite, re-evaluate it in the sandbox and execute it. // Decompile the COW test suite, re-evaluate it in the sandbox and execute it.