mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1273251: Part 1 - Mark nuked sandboxes as nuked and non-scriptable. r=bholley
MozReview-Commit-ID: tq9nExa1P7 --HG-- extra : rebase_source : 3c0e856335b8585457e2679b30177bd1df9ac6bb
This commit is contained in:
parent
71398a8500
commit
e51f27d8cb
@ -3017,11 +3017,17 @@ nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx)
|
||||
NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
|
||||
JSObject* wrapper = &obj.toObject();
|
||||
NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
|
||||
JSObject* sb = UncheckedUnwrap(wrapper);
|
||||
RootedObject sb(cx, UncheckedUnwrap(wrapper));
|
||||
NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
|
||||
NukeCrossCompartmentWrappers(cx, AllCompartments(),
|
||||
SingleCompartment(GetObjectCompartment(sb)),
|
||||
NukeWindowReferences);
|
||||
|
||||
// Now mark the compartment as nuked and non-scriptable.
|
||||
auto compartmentPrivate = xpc::CompartmentPrivate::Get(sb);
|
||||
compartmentPrivate->wasNuked = true;
|
||||
compartmentPrivate->scriptability.Block();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -199,6 +199,7 @@ CompartmentPrivate::CompartmentPrivate(JSCompartment* c)
|
||||
, allowCPOWs(false)
|
||||
, universalXPConnectEnabled(false)
|
||||
, forcePermissiveCOWs(false)
|
||||
, wasNuked(false)
|
||||
, scriptability(c)
|
||||
, scope(nullptr)
|
||||
, mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH))
|
||||
|
@ -3183,6 +3183,10 @@ public:
|
||||
// Using it in production is inherently unsafe.
|
||||
bool forcePermissiveCOWs;
|
||||
|
||||
// True if this compartment has been nuked. If true, any wrappers into or
|
||||
// out of it should be considered invalid.
|
||||
bool wasNuked;
|
||||
|
||||
// Whether we've emitted a warning about a property that was filtered out
|
||||
// by a security wrapper. See XrayWrapper.cpp.
|
||||
bool wrapperDenialWarnings[WrapperDenialTypeCount];
|
||||
|
@ -324,7 +324,10 @@ static void
|
||||
DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper* handler,
|
||||
JSCompartment* origin, JSCompartment* target)
|
||||
{
|
||||
if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
if (CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked) {
|
||||
// If either compartment has already been nuked, we should have an opaque wrapper.
|
||||
MOZ_ASSERT(handler->hasSecurityPolicy());
|
||||
} else if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
// If the caller is chrome (or effectively so), unwrap should always be allowed.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy());
|
||||
} else if (CompartmentPrivate::Get(origin)->forcePermissiveCOWs) {
|
||||
@ -443,9 +446,21 @@ WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj)
|
||||
// First, handle the special cases.
|
||||
//
|
||||
|
||||
// If we've somehow gotten to this point after either the source or target
|
||||
// compartment has been nuked, return an opaque wrapper to prevent further
|
||||
// access.
|
||||
// Ideally, we should return a DeadProxyObject instead of a wrapper in this
|
||||
// case (bug 1322273).
|
||||
if (CompartmentPrivate::Get(origin)->wasNuked ||
|
||||
CompartmentPrivate::Get(target)->wasNuked) {
|
||||
NS_WARNING("Trying to create a wrapper into or out of a nuked compartment");
|
||||
|
||||
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
|
||||
}
|
||||
|
||||
// If UniversalXPConnect is enabled, this is just some dumb mochitest. Use
|
||||
// a vanilla CCW.
|
||||
if (xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
else if (xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
CrashIfNotInAutomation();
|
||||
wrapper = &CrossCompartmentWrapper::singleton;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user