Bug 1186409 - Check to make sure we don't set some weird XPConnect flags on the shared global. draft
authorAndrew McCreight <continuation@gmail.com>
Tue, 06 Jun 2017 14:41:27 -0700
changeset 650165 f6d8ece5a7fc45a806fc1b7f4ecefd6e4982cffe
parent 650164 af6038d85613a88468404dc6f63e40120a77aaa4
child 727315 8675fb134faeb1a453d0547f6cc3347ec9b4867c
push id75288
push userbmo:continuation@gmail.com
push dateMon, 21 Aug 2017 22:42:18 +0000
bugs1186409
milestone57.0a1
Bug 1186409 - Check to make sure we don't set some weird XPConnect flags on the shared global. I added the predicate so people can't just start grabbing the loader global and doing scary things with it. MozReview-Commit-ID: HzPtMzEm0Ln
js/xpconnect/loader/mozJSComponentLoader.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -51,16 +51,19 @@ class mozJSComponentLoader : public mozi
                           JS::MutableHandleObject aTargetObject);
 
     static mozJSComponentLoader* Get() { return sSelf; }
 
     nsresult Import(const nsACString& aResourceURI, JS::HandleValue aTargetObj,
                     JSContext* aCx, uint8_t aArgc, JS::MutableHandleValue aRetval);
     nsresult Unload(const nsACString& aResourceURI);
     nsresult IsModuleLoaded(const nsACString& aResourceURI, bool* aRetval);
+    bool IsLoaderGlobal(JSObject* aObj) {
+        return mLoaderGlobal == aObj;
+    }
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
  protected:
     virtual ~mozJSComponentLoader();
 
     static mozJSComponentLoader* sSelf;
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2877,16 +2877,18 @@ nsXPCComponents_Utils::GetCrossProcessWr
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::PermitCPOWsInScope(HandleValue obj)
 {
     if (!obj.isObject())
         return NS_ERROR_INVALID_ARG;
 
     JSObject* scopeObj = js::UncheckedUnwrap(&obj.toObject());
+    MOZ_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(scopeObj),
+               "Don't call Cu.PermitCPOWsInScope() in a JSM that shares its global");
     CompartmentPrivate::Get(scopeObj)->allowCPOWs = true;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext* cx)
 {
     // Determine the compartment of the given object, if any.
@@ -2906,29 +2908,34 @@ nsXPCComponents_Utils::RecomputeWrappers
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext* cx)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
+    MOZ_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(scopeObj),
+               "Don't call Cu.setWantXrays() in a JSM that shares its global");
     JSCompartment* compartment = js::GetObjectCompartment(scopeObj);
     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();
-    CompartmentPrivate::Get(CurrentGlobalOrNull(cx))->forcePermissiveCOWs = true;
+    JSObject* currentGlobal = CurrentGlobalOrNull(cx);
+    MOZ_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(currentGlobal),
+               "Don't call Cu.forcePermissiveCOWs() in a JSM that shares its global");
+    CompartmentPrivate::Get(currentGlobal)->forcePermissiveCOWs = true;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(HandleValue vscope,
                                                          JSContext* cx)
 {
     if (!vscope.isObject())
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -10,16 +10,17 @@
 #include "XPCWrapper.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "ExpandedPrincipal.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
 #include "nsIAddonInterposition.h"
 #include "nsIXULRuntime.h"
+#include "mozJSComponentLoader.h"
 
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
 using namespace xpc;
 using namespace JS;
 
 /***************************************************************************/
@@ -161,16 +162,18 @@ XPCWrappedNativeScope::XPCWrappedNativeS
             UpdateInterpositionWhitelist(cx, mInterposition);
           }
         }
     }
 
     if (addonId) {
         // We forbid CPOWs unless they're specifically allowed.
         priv->allowCPOWs = gAllowCPOWAddonSet ? gAllowCPOWAddonSet->has(addonId) : false;
+        MOZ_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(aGlobal),
+                   "Don't load addons into the shared JSM global");
     }
 }
 
 // static
 bool
 XPCWrappedNativeScope::IsDyingScope(XPCWrappedNativeScope* scope)
 {
     for (XPCWrappedNativeScope* cur = gDyingScopes; cur; cur = cur->mNext) {