Bug 1512655 part 1 - Move forcePermissiveCOWs from CompartmentPrivate to RealmPrivate. r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D14694

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2018-12-18 18:39:04 +00:00
parent c6e9319e51
commit 84fe725407
4 changed files with 26 additions and 21 deletions

View File

@ -1992,11 +1992,12 @@ nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext* cx) {
NS_IMETHODIMP
nsXPCComponents_Utils::ForcePermissiveCOWs(JSContext* cx) {
xpc::CrashIfNotInAutomation();
JSObject* currentGlobal = CurrentGlobalOrNull(cx);
RootedObject currentGlobal(cx, CurrentGlobalOrNull(cx));
MOZ_DIAGNOSTIC_ASSERT(
!mozJSComponentLoader::Get()->IsLoaderGlobal(currentGlobal),
"Don't call Cu.forcePermissiveCOWs() in a JSM that shares its global");
CompartmentPrivate::Get(currentGlobal)->forcePermissiveCOWs = true;
MOZ_RELEASE_ASSERT(currentGlobal == JS::GetScriptedCallerGlobal(cx));
RealmPrivate::Get(currentGlobal)->forcePermissiveCOWs = true;
return NS_OK;
}

View File

@ -194,7 +194,6 @@ CompartmentPrivate::CompartmentPrivate(JS::Compartment* c,
isUAWidgetCompartment(false),
hasExclusiveExpandos(false),
universalXPConnectEnabled(false),
forcePermissiveCOWs(false),
wasShutdown(false),
mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH)) {
MOZ_COUNT_CTOR(xpc::CompartmentPrivate);

View File

@ -2799,14 +2799,6 @@ class CompartmentPrivate {
// Using it in production is inherently unsafe.
bool universalXPConnectEnabled;
// This is only ever set during mochitest runs when enablePrivilege is called.
// It allows the SpecialPowers scope to waive the normal chrome security
// wrappers and expose properties directly to content. This lets us avoid a
// bunch of overhead and complexity in our SpecialPowers automation glue.
//
// Using it in production is inherently unsafe.
bool forcePermissiveCOWs;
// Whether SystemIsBeingShutDown has been called on this compartment.
bool wasShutdown;
@ -2868,6 +2860,14 @@ class RealmPrivate {
// XPConnect realm.
XPCWrappedNativeScope* scope;
// This is only ever set during mochitest runs when enablePrivilege is called.
// It allows the SpecialPowers scope to waive the normal chrome security
// wrappers and expose properties directly to content. This lets us avoid a
// bunch of overhead and complexity in our SpecialPowers automation glue.
//
// Using it in production is inherently unsafe.
bool forcePermissiveCOWs = false;
const nsACString& GetLocation() {
if (location.IsEmpty() && locationURI) {
nsCOMPtr<nsIXPConnectWrappedJS> jsLocationURI =

View File

@ -329,7 +329,7 @@ void WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope,
#ifdef DEBUG
static void DEBUG_CheckUnwrapSafety(HandleObject obj,
const js::Wrapper* handler,
JS::Compartment* origin,
JS::Realm* origin,
JS::Compartment* target) {
if (!js::AllowNewWrapper(target, obj)) {
// The JS engine should have returned a dead wrapper in this case and we
@ -340,18 +340,20 @@ static void DEBUG_CheckUnwrapSafety(HandleObject obj,
// If the caller is chrome (or effectively so), unwrap should always be
// allowed.
MOZ_ASSERT(!handler->hasSecurityPolicy());
} else if (CompartmentPrivate::Get(origin)->forcePermissiveCOWs) {
} else if (RealmPrivate::Get(origin)->forcePermissiveCOWs) {
// Similarly, if this is a privileged scope that has opted to make itself
// accessible to the world (allowed only during automation), unwrap should
// be allowed.
MOZ_ASSERT(!handler->hasSecurityPolicy());
} else {
// Otherwise, it should depend on whether the target subsumes the origin.
MOZ_ASSERT(handler->hasSecurityPolicy() ==
!(OriginAttributes::IsRestrictOpenerAccessForFPI()
? AccessCheck::subsumesConsideringDomain(target, origin)
: AccessCheck::subsumesConsideringDomainIgnoringFPD(
target, origin)));
JS::Compartment* originComp = JS::GetCompartmentForRealm(origin);
bool subsumes =
(OriginAttributes::IsRestrictOpenerAccessForFPI()
? AccessCheck::subsumesConsideringDomain(target, originComp)
: AccessCheck::subsumesConsideringDomainIgnoringFPD(target,
originComp));
MOZ_ASSERT(handler->hasSecurityPolicy() == !subsumes);
}
}
#else
@ -442,6 +444,9 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing,
CompartmentPrivate* targetCompartmentPrivate =
CompartmentPrivate::Get(target);
JS::Realm* originRealm = js::GetNonCCWObjectRealm(obj);
RealmPrivate* originRealmPrivate = RealmPrivate::Get(originRealm);
//
// First, handle the special cases.
//
@ -454,7 +459,7 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing,
}
// Let the SpecialPowers scope make its stuff easily accessible to content.
else if (originCompartmentPrivate->forcePermissiveCOWs) {
else if (originRealmPrivate->forcePermissiveCOWs) {
CrashIfNotInAutomation();
wrapper = &CrossCompartmentWrapper::singleton;
}
@ -517,7 +522,7 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing,
wrapper = SelectWrapper(securityWrapper, xrayType, waiveXrays, obj);
}
if (!targetSubsumesOrigin && !originCompartmentPrivate->forcePermissiveCOWs) {
if (!targetSubsumesOrigin && !originRealmPrivate->forcePermissiveCOWs) {
// Do a belt-and-suspenders check against exposing eval()/Function() to
// non-subsuming content. But don't worry about doing it in the
// SpecialPowers case.
@ -532,7 +537,7 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing,
}
}
DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target);
DEBUG_CheckUnwrapSafety(obj, wrapper, originRealm, target);
if (existing) {
return Wrapper::Renew(existing, obj, wrapper);