Bug 1481640 - Remove forcePermissiveCOWs(). r=kmag, a=jcristau DEVEDITION_78_0b2_BUILD1 DEVEDITION_78_0b2_RELEASE FIREFOX_78_0b2_BUILD1 FIREFOX_78_0b2_RELEASE
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Mon, 01 Jun 2020 18:04:20 +0000
changeset 596929 c142ca0065bd39146dcefbcb5f7da635a02e59bf
parent 596928 2c3de98db65bde8748d070b82868929d1f9772ef
child 596930 642408cea587e455204a2fb4fd844f1d04dfa317
push id13200
push userjcristau@mozilla.com
push dateTue, 02 Jun 2020 13:44:12 +0000
treeherdermozilla-beta@c142ca0065bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag, jcristau
bugs1481640
milestone78.0
Bug 1481640 - Remove forcePermissiveCOWs(). r=kmag, a=jcristau Differential Revision: https://phabricator.services.mozilla.com/D77612
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -457,24 +457,16 @@ interface nsIXPCComponents_Utils : nsISu
      * indicated by |vscope|. All outgoing wrappers are recomputed.
      *
      * This must not be called on chrome (system-principal) scopes.
      */
     [implicit_jscontext]
     void setWantXrays(in jsval vscope);
 
     /*
-     * For gecko internal automation use only. Calling this in production code
-     * would result in security vulnerabilities, so it will crash if used outside
-     * of automation.
-     */
-    [implicit_jscontext]
-    void forcePermissiveCOWs();
-
-    /*
      * Dispatches a runnable to the current/main thread. If |scope| is passed,
      * the runnable will be dispatch in the compartment of |scope|, which
      * affects which error reporter gets called.
      */
     [implicit_jscontext]
     void dispatch(in jsval runnable, [optional] in jsval scope);
 
     /*
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2004,28 +2004,16 @@ nsXPCComponents_Utils::SetWantXrays(Hand
   CompartmentPrivate::Get(scopeObj)->wantXrays = true;
   bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
                                   js::AllCompartments());
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::ForcePermissiveCOWs(JSContext* cx) {
-  xpc::CrashIfNotInAutomation();
-  RootedObject global(cx, GetScriptedCallerGlobal(cx));
-  MOZ_ASSERT(global);
-  MOZ_DIAGNOSTIC_ASSERT(
-      !mozJSComponentLoader::Get()->IsLoaderGlobal(global),
-      "Don't call Cu.forcePermissiveCOWs() in a JSM that shares its global");
-  RealmPrivate::Get(global)->forcePermissiveCOWs = true;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
                                 JSContext* cx) {
   RootedValue runnable(cx, runnableArg);
   // Enter the given realm, if any, and rewrap runnable.
   Maybe<JSAutoRealm> ar;
   if (scope.isObject()) {
     JSObject* scopeObj = js::UncheckedUnwrap(&scope.toObject());
     if (!scopeObj) {
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2701,24 +2701,16 @@ class RealmPrivate {
   static RealmPrivate* Get(JSObject* object) {
     JS::Realm* realm = JS::GetObjectRealmOrNull(object);
     return Get(realm);
   }
 
   // The scriptability of this realm.
   Scriptability scriptability;
 
-  // 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;
-
   // Whether we've emitted a warning about a property that was filtered out
   // by a security wrapper. See XrayWrapper.cpp.
   bool wrapperDenialWarnings[WrapperDenialTypeCount];
 
   const nsACString& GetLocation() {
     if (location.IsEmpty() && locationURI) {
       nsCOMPtr<nsIXPConnectWrappedJS> jsLocationURI =
           do_QueryInterface(locationURI);
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -391,22 +391,16 @@ static void DEBUG_CheckUnwrapSafety(Hand
     // shouldn't even get here.
     MOZ_ASSERT_UNREACHABLE("CheckUnwrapSafety called for a dead wrapper");
   } else if (AccessCheck::isChrome(targetCompartment)) {
     // 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);
-  } 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);
   } else {
     // Otherwise, it should depend on whether the target subsumes the origin.
     bool subsumes =
         (OriginAttributes::IsRestrictOpenerAccessForFPI()
              ? AccessCheck::subsumesConsideringDomain(target, origin)
              : AccessCheck::subsumesConsideringDomainIgnoringFPD(target,
                                                                  origin));
     if (!subsumes) {
@@ -518,34 +512,26 @@ JSObject* WrapperFactory::Rewrap(JSConte
 
   const Wrapper* wrapper;
 
   CompartmentPrivate* originCompartmentPrivate =
       CompartmentPrivate::Get(origin);
   CompartmentPrivate* targetCompartmentPrivate =
       CompartmentPrivate::Get(target);
 
-  RealmPrivate* originRealmPrivate = RealmPrivate::Get(origin);
-
   // Track whether we decided to use a transparent wrapper because of
   // document.domain usage, so we don't override that decision.
   bool isTransparentWrapperDueToDocumentDomain = false;
 
   //
   // First, handle the special cases.
   //
 
-  // Let the SpecialPowers scope make its stuff easily accessible to content.
-  if (originRealmPrivate->forcePermissiveCOWs) {
-    CrashIfNotInAutomation();
-    wrapper = &CrossCompartmentWrapper::singleton;
-  }
-
   // Special handling for chrome objects being exposed to content.
-  else if (originIsChrome && !targetIsChrome) {
+  if (originIsChrome && !targetIsChrome) {
     // If this is a chrome function being exposed to content, we need to allow
     // call (but nothing else).
     if ((IdentifyStandardInstance(obj) == JSProto_Function)) {
       wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
                                   OpaqueWithCall>::singleton;
     }
 
     // For vanilla JSObjects exposed from chrome to content, we use a wrapper
@@ -614,21 +600,19 @@ JSObject* WrapperFactory::Rewrap(JSConte
     // wrappers (unless explicitly forbidden from doing so).
     bool waiveXrays = wantXrays && !securityWrapper &&
                       targetCompartmentPrivate->allowWaivers &&
                       HasWaiveXrayFlag(obj);
 
     wrapper = SelectWrapper(securityWrapper, xrayType, waiveXrays, obj);
   }
 
-  if (!targetSubsumesOrigin && !originRealmPrivate->forcePermissiveCOWs &&
-      !isTransparentWrapperDueToDocumentDomain) {
+  if (!targetSubsumesOrigin && !isTransparentWrapperDueToDocumentDomain) {
     // 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.
+    // non-subsuming content.
     if (JSFunction* fun = JS_GetObjectFunction(obj)) {
       if (JS_IsBuiltinEvalFunction(fun) ||
           JS_IsBuiltinFunctionConstructor(fun)) {
         NS_WARNING(
             "Trying to expose eval or Function to non-subsuming content!");
         wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
                                     Opaque>::singleton;
       }