mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Backed out 2 changesets (bug 1471496) for causing CycleCollectedJSRuntime.cpp perma failures CLOSED TREE
Backed out changeset 9658187a54fb (bug 1471496) Backed out changeset 2ff333373fe4 (bug 1471496)
This commit is contained in:
parent
8b79b7ce3e
commit
9c86f4019d
@ -41,8 +41,7 @@ bool MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(JSContext* cx,
|
||||
|
||||
BasePrincipal* subjectPrincipal =
|
||||
BasePrincipal::Cast(nsContentUtils::SubjectPrincipal(cx));
|
||||
BasePrincipal* objectPrincipal =
|
||||
BasePrincipal::Cast(nsContentUtils::ObjectPrincipal(obj));
|
||||
nsIPrincipal* objectPrincipal = nsContentUtils::ObjectPrincipal(obj);
|
||||
|
||||
// The spec effectively has an EqualsConsideringDomain check here,
|
||||
// because the spec has no concept of asymmetric security
|
||||
@ -54,25 +53,11 @@ bool MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(JSContext* cx,
|
||||
// SubsumesConsideringDomain give the same results and use
|
||||
// EqualsConsideringDomain for the check we actually do, since it's
|
||||
// stricter and more closely matches the spec.
|
||||
//
|
||||
// That said, if the (not very well named)
|
||||
// OriginAttributes::IsRestrictOpenerAccessForFPI() method returns
|
||||
// false, we want to use FastSubsumesConsideringDomainIgnoringFPD
|
||||
// instead of FastEqualsConsideringDomain, because in that case we
|
||||
// still want to treat things which are in different first-party
|
||||
// contexts as same-origin.
|
||||
MOZ_ASSERT(
|
||||
subjectPrincipal->FastEqualsConsideringDomain(objectPrincipal) ==
|
||||
subjectPrincipal->FastSubsumesConsideringDomain(objectPrincipal),
|
||||
"Why are we in an asymmetric case here?");
|
||||
if (OriginAttributes::IsRestrictOpenerAccessForFPI()) {
|
||||
return subjectPrincipal->FastEqualsConsideringDomain(objectPrincipal);
|
||||
}
|
||||
|
||||
return subjectPrincipal->FastSubsumesConsideringDomainIgnoringFPD(
|
||||
objectPrincipal) &&
|
||||
objectPrincipal->FastSubsumesConsideringDomainIgnoringFPD(
|
||||
subjectPrincipal);
|
||||
return subjectPrincipal->FastEqualsConsideringDomain(objectPrincipal);
|
||||
}
|
||||
|
||||
bool MaybeCrossOriginObjectMixins::CrossOriginGetOwnPropertyHelper(
|
||||
|
@ -89,12 +89,18 @@ bool AccessCheck::isChrome(JSObject* obj) {
|
||||
return isChrome(js::GetObjectCompartment(obj));
|
||||
}
|
||||
|
||||
bool IsCrossOriginAccessibleObject(JSObject* obj) {
|
||||
CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj) {
|
||||
obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
|
||||
const js::Class* clasp = js::GetObjectClass(obj);
|
||||
|
||||
return (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) ||
|
||||
(clasp->name[0] == 'W' && !strcmp(clasp->name, "Window"));
|
||||
if (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) {
|
||||
return CrossOriginLocation;
|
||||
}
|
||||
if (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window")) {
|
||||
return CrossOriginWindow;
|
||||
}
|
||||
|
||||
return CrossOriginOpaque;
|
||||
}
|
||||
|
||||
bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper,
|
||||
|
@ -35,13 +35,12 @@ class AccessCheck {
|
||||
const nsACString& accessType);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given object (which is expected to be stripped of
|
||||
* cross-compartment wrappers in practice, but this function doesn't assume
|
||||
* that) is a WindowProxy or Location object, which need special wrapping
|
||||
* behavior due to being usable cross-origin in limited ways.
|
||||
*/
|
||||
bool IsCrossOriginAccessibleObject(JSObject* obj);
|
||||
enum CrossOriginObjectType {
|
||||
CrossOriginWindow,
|
||||
CrossOriginLocation,
|
||||
CrossOriginOpaque
|
||||
};
|
||||
CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj);
|
||||
|
||||
struct Policy {
|
||||
static bool checkCall(JSContext* cx, JS::HandleObject wrapper,
|
||||
|
@ -339,16 +339,13 @@ static void DEBUG_CheckUnwrapSafety(HandleObject obj,
|
||||
} else if (AccessCheck::isChrome(target) ||
|
||||
xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
// If the caller is chrome (or effectively so), unwrap should always be
|
||||
// allowed, but we might have a CrossOriginObjectWrapper here which allows
|
||||
// it dynamically.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy() ||
|
||||
handler == &CrossOriginObjectWrapper::singleton);
|
||||
// allowed.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy());
|
||||
} 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. Again, it might be allowed dynamically.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy() ||
|
||||
handler == &CrossOriginObjectWrapper::singleton);
|
||||
// be allowed.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy());
|
||||
} else {
|
||||
// Otherwise, it should depend on whether the target subsumes the origin.
|
||||
JS::Compartment* originComp = JS::GetCompartmentForRealm(origin);
|
||||
@ -357,17 +354,7 @@ static void DEBUG_CheckUnwrapSafety(HandleObject obj,
|
||||
? AccessCheck::subsumesConsideringDomain(target, originComp)
|
||||
: AccessCheck::subsumesConsideringDomainIgnoringFPD(target,
|
||||
originComp));
|
||||
if (!subsumes) {
|
||||
// If the target (which is where the wrapper lives) does not subsume the
|
||||
// origin (which is where the wrapped object lives), then we should have a
|
||||
// security check on the wrapper here.
|
||||
MOZ_ASSERT(handler->hasSecurityPolicy());
|
||||
} else {
|
||||
// Even if target subsumes origin, we might have a wrapper with a security
|
||||
// policy here, if it happens to be a CrossOriginObjectWrapper.
|
||||
MOZ_ASSERT(!handler->hasSecurityPolicy() ||
|
||||
handler == &CrossOriginObjectWrapper::singleton);
|
||||
}
|
||||
MOZ_ASSERT(handler->hasSecurityPolicy() == !subsumes);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -417,6 +404,12 @@ static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType,
|
||||
return &PermissiveXrayOpaque::singleton;
|
||||
}
|
||||
|
||||
// This is a security wrapper. Use the security versions and filter.
|
||||
if (xrayType == XrayForDOMObject &&
|
||||
IdentifyCrossOriginObject(obj) != CrossOriginOpaque) {
|
||||
return &CrossOriginObjectWrapper::singleton;
|
||||
}
|
||||
|
||||
// There's never any reason to expose other objects to non-subsuming actors.
|
||||
// Just use an opaque wrapper in these cases.
|
||||
//
|
||||
@ -508,18 +501,6 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing,
|
||||
}
|
||||
}
|
||||
|
||||
// Special handling for the web's cross-origin objects (WindowProxy and
|
||||
// Location). We only need or want to do this in web-like contexts, where all
|
||||
// security relationships are symmetric and there are no forced Xrays.
|
||||
else if (originSubsumesTarget == targetSubsumesOrigin &&
|
||||
// Check for the more rare case of cross-origin objects before doing
|
||||
// the more-likely-to-pass checks for wantXrays.
|
||||
IsCrossOriginAccessibleObject(obj) &&
|
||||
(!targetSubsumesOrigin || (!originCompartmentPrivate->wantXrays &&
|
||||
!targetCompartmentPrivate->wantXrays))) {
|
||||
wrapper = &CrossOriginObjectWrapper::singleton;
|
||||
}
|
||||
|
||||
//
|
||||
// Now, handle the regular cases.
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user