Bug 1052096 - Move CPOW targets into the privileged/unprivileged junk scope of the child/parent. r=billm

This commit is contained in:
Bobby Holley 2014-09-12 17:41:18 -07:00
parent e5da9d6f66
commit 5d41b32105
6 changed files with 17 additions and 30 deletions

View File

@ -67,7 +67,9 @@ JavaScriptChild::finalize()
}
JSObject *
JavaScriptChild::defaultScope()
JavaScriptChild::scopeForTargetObjects()
{
// CPOWs from the parent need to point into the child's privileged junk
// scope so that they can benefit from XrayWrappers in the child.
return xpc::PrivilegedJunkScope();
}

View File

@ -27,7 +27,7 @@ class JavaScriptChild : public JavaScriptBase<PJavaScriptChild>
protected:
virtual bool isParent() { return false; }
virtual JSObject *defaultScope() MOZ_OVERRIDE;
virtual JSObject *scopeForTargetObjects() MOZ_OVERRIDE;
private:
bool fail(JSContext *cx, ReturnStatus *rs);

View File

@ -64,8 +64,12 @@ JavaScriptParent::trace(JSTracer *trc)
}
JSObject *
JavaScriptParent::defaultScope()
JavaScriptParent::scopeForTargetObjects()
{
// CPWOWs from the child need to point into the parent's unprivileged junk
// scope so that a compromised child cannot compromise the parent. In
// practice, this means that a child process can only (a) hold parent
// objects alive and (b) invoke them if they are callable.
return xpc::UnprivilegedJunkScope();
}

View File

@ -30,7 +30,7 @@ class JavaScriptParent : public JavaScriptBase<PJavaScriptParent>
protected:
virtual bool isParent() { return true; }
virtual JSObject *defaultScope() MOZ_OVERRIDE;
virtual JSObject *scopeForTargetObjects() MOZ_OVERRIDE;
};
} // jsipc

View File

@ -377,31 +377,11 @@ JavaScriptShared::findObjectById(JSContext *cx, uint32_t objId)
return nullptr;
}
// Objects are stored in objects_ unwrapped. We want to wrap the object
// before returning it so that all operations happen on Xray wrappers. If
// the object is a DOM element, we try to obtain the corresponding
// TabChildGlobal and wrap in that.
RootedObject global(cx, GetGlobalForObjectCrossCompartment(obj));
nsCOMPtr<nsIGlobalObject> nativeGlobal = xpc::GetNativeForGlobal(global);
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(nativeGlobal);
if (window) {
dom::TabChild *tabChild = dom::TabChild::GetFrom(window);
if (tabChild) {
nsCOMPtr<nsIContentFrameMessageManager> mm;
tabChild->GetMessageManager(getter_AddRefs(mm));
nsCOMPtr<nsIGlobalObject> tabChildNativeGlobal = do_QueryInterface(mm);
RootedObject tabChildGlobal(cx, tabChildNativeGlobal->GetGlobalJSObject());
JSAutoCompartment ac(cx, tabChildGlobal);
if (!JS_WrapObject(cx, &obj))
return nullptr;
return obj;
}
}
// If there's no TabChildGlobal, we use the junk scope. In the parent we use
// the unprivileged junk scope to prevent security vulnerabilities. In the
// child we use the privileged junk scope.
JSAutoCompartment ac(cx, defaultScope());
// Each process has a dedicated compartment for CPOW targets. All CPOWs
// from the other process point to objects in this scope. From there, they
// can access objects in other compartments using cross-compartment
// wrappers.
JSAutoCompartment ac(cx, scopeForTargetObjects());
if (!JS_WrapObject(cx, &obj))
return nullptr;
return obj;

View File

@ -138,7 +138,8 @@ class JavaScriptShared
friend class Logging;
virtual bool isParent() = 0;
virtual JSObject *defaultScope() = 0;
virtual JSObject *scopeForTargetObjects() = 0;
protected:
JSRuntime *rt_;