Bug 1319773 - Part 3: Making the WrapperFactory ignores the First Party Domain of the originAttributes when rewrapping the wrapper. r?mrbkap draft
authorTim Huang <tihuang@mozilla.com>
Wed, 18 Jan 2017 20:34:31 +0800
changeset 464880 ce61e5e68269503d31583c2c27f59e35049bd9c5
parent 464879 f463a0db8bd48b1d8ac59500cdc8fcc1e97d6c95
child 543027 1f35e512970ac0acecde9c95f0aaf487564ddb03
push id42468
push userbmo:tihuang@mozilla.com
push dateMon, 23 Jan 2017 07:30:07 +0000
reviewersmrbkap
bugs1319773
milestone53.0a1
Bug 1319773 - Part 3: Making the WrapperFactory ignores the First Party Domain of the originAttributes when rewrapping the wrapper. r?mrbkap
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/AccessCheck.h
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -59,16 +59,25 @@ AccessCheck::subsumes(JSObject* a, JSObj
 bool
 AccessCheck::subsumesConsideringDomain(JSCompartment* a, JSCompartment* b)
 {
     nsIPrincipal* aprin = GetCompartmentPrincipal(a);
     nsIPrincipal* bprin = GetCompartmentPrincipal(b);
     return aprin->SubsumesConsideringDomain(bprin);
 }
 
+bool
+AccessCheck::subsumesConsideringDomainIgnoringFPD(JSCompartment* a,
+                                                  JSCompartment* b)
+{
+    nsIPrincipal* aprin = GetCompartmentPrincipal(a);
+    nsIPrincipal* bprin = GetCompartmentPrincipal(b);
+    return aprin->SubsumesConsideringDomainIgnoringFPD(bprin);
+}
+
 // Does the compartment of the wrapper subsumes the compartment of the wrappee?
 bool
 AccessCheck::wrapperSubsumes(JSObject* wrapper)
 {
     MOZ_ASSERT(js::IsWrapper(wrapper));
     JSObject* wrapped = js::UncheckedUnwrap(wrapper);
     return AccessCheck::subsumes(js::GetObjectCompartment(wrapper),
                                  js::GetObjectCompartment(wrapped));
--- a/js/xpconnect/wrappers/AccessCheck.h
+++ b/js/xpconnect/wrappers/AccessCheck.h
@@ -15,16 +15,18 @@ class nsIPrincipal;
 namespace xpc {
 
 class AccessCheck {
   public:
     static bool subsumes(JSCompartment* a, JSCompartment* b);
     static bool subsumes(JSObject* a, JSObject* b);
     static bool wrapperSubsumes(JSObject* wrapper);
     static bool subsumesConsideringDomain(JSCompartment* a, JSCompartment* b);
+    static bool subsumesConsideringDomainIgnoringFPD(JSCompartment* a,
+                                                     JSCompartment* b);
     static bool isChrome(JSCompartment* compartment);
     static bool isChrome(JSObject* obj);
     static nsIPrincipal* getPrincipal(JSCompartment* compartment);
     static bool isCrossOriginAccessPermitted(JSContext* cx, JS::HandleObject obj,
                                              JS::HandleId id, js::Wrapper::Action act);
     static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
                                           JS::HandleValue value);
     static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -329,17 +329,19 @@ DEBUG_CheckUnwrapSafety(HandleObject obj
         MOZ_ASSERT(!handler->hasSecurityPolicy());
     } else if (CompartmentPrivate::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() == !AccessCheck::subsumesConsideringDomain(target, origin));
+        MOZ_ASSERT(handler->hasSecurityPolicy() == !(OriginAttributes::IsRestrictOpenerAccessForFPI() ?
+                                                       AccessCheck::subsumesConsideringDomain(target, origin) :
+                                                       AccessCheck::subsumesConsideringDomainIgnoringFPD(target, origin)));
     }
 }
 #else
 #define DEBUG_CheckUnwrapSafety(obj, handler, origin, target) {}
 #endif
 
 static const Wrapper*
 SelectWrapper(bool securityWrapper, bool wantXrays, XrayType xrayType,
@@ -427,18 +429,22 @@ WrapperFactory::Rewrap(JSContext* cx, Ha
     MOZ_ASSERT(!js::IsWindow(obj));
     MOZ_ASSERT(dom::IsJSAPIActive());
 
     // Compute the information we need to select the right wrapper.
     JSCompartment* origin = js::GetObjectCompartment(obj);
     JSCompartment* target = js::GetContextCompartment(cx);
     bool originIsChrome = AccessCheck::isChrome(origin);
     bool targetIsChrome = AccessCheck::isChrome(target);
-    bool originSubsumesTarget = AccessCheck::subsumesConsideringDomain(origin, target);
-    bool targetSubsumesOrigin = AccessCheck::subsumesConsideringDomain(target, origin);
+    bool originSubsumesTarget = OriginAttributes::IsRestrictOpenerAccessForFPI() ?
+                                  AccessCheck::subsumesConsideringDomain(origin, target) :
+                                  AccessCheck::subsumesConsideringDomainIgnoringFPD(origin, target);
+    bool targetSubsumesOrigin = OriginAttributes::IsRestrictOpenerAccessForFPI() ?
+                                  AccessCheck::subsumesConsideringDomain(target, origin) :
+                                  AccessCheck::subsumesConsideringDomainIgnoringFPD(target, origin);
     bool sameOrigin = targetSubsumesOrigin && originSubsumesTarget;
     XrayType xrayType = GetXrayType(obj);
 
     const Wrapper* wrapper;
 
     //
     // First, handle the special cases.
     //