Bug 1478275 part 2 - Add a CompartmentPrivate::isSandboxCompartment flag and xpc::IsInSandboxCompartment(obj). r=bholley
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 26 Jul 2018 10:58:37 +0200
changeset 428567 4cd7934210ccceab2e4a8aa41dcca27b3cb22d87
parent 428566 49dceb93cc0c4fd78b378ddd89ea1144f99e21a1
child 428568 450f74df066e2f73ac4e8124f7885adc76cdd08d
push id34337
push userncsoregi@mozilla.com
push dateThu, 26 Jul 2018 21:58:45 +0000
treeherdermozilla-central@8f2f847b2f9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1478275
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1478275 part 2 - Add a CompartmentPrivate::isSandboxCompartment flag and xpc::IsInSandboxCompartment(obj). r=bholley Wrappers are per-compartment, not per-realm, so this will simplify the next patch. Also, considering the upcoming Realms proposal, it might eventually be possible to have multiple globals in a sandbox compartment.
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1107,16 +1107,17 @@ xpc::CreateSandboxObject(JSContext* cx, 
                                                      principal, realmOptions));
     if (!sandbox)
         return NS_ERROR_FAILURE;
 
     CompartmentPrivate* priv = CompartmentPrivate::Get(sandbox);
     priv->allowWaivers = options.allowWaivers;
     priv->isWebExtensionContentScript = options.isWebExtensionContentScript;
     priv->isContentXBLCompartment = options.isContentXBLScope;
+    priv->isSandboxCompartment = true;
 
     // Set up the wantXrays flag, which indicates whether xrays are desired even
     // for same-origin access.
     //
     // This flag has historically been ignored for chrome sandboxes due to
     // quirks in the wrapping implementation that have now been removed. Indeed,
     // same-origin Xrays for chrome->chrome access seems a bit superfluous.
     // Arguably we should just flip the default for chrome and still honor the
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -210,16 +210,17 @@ public:
 namespace xpc {
 
 CompartmentPrivate::CompartmentPrivate(JS::Compartment* c)
     : wantXrays(false)
     , allowWaivers(true)
     , isWebExtensionContentScript(false)
     , allowCPOWs(false)
     , isContentXBLCompartment(false)
+    , isSandboxCompartment(false)
     , universalXPConnectEnabled(false)
     , forcePermissiveCOWs(false)
     , wasNuked(false)
     , mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH))
 {
     MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
     mozilla::PodArrayZero(wrapperDenialWarnings);
 }
@@ -487,16 +488,26 @@ IsContentXBLScope(JS::Realm* realm)
 
 bool
 IsInContentXBLScope(JSObject* obj)
 {
     return IsContentXBLCompartment(js::GetObjectCompartment(obj));
 }
 
 bool
+IsInSandboxCompartment(JSObject* obj)
+{
+    JS::Compartment* comp = js::GetObjectCompartment(obj);
+
+    // We always eagerly create compartment privates for sandbox compartments.
+    CompartmentPrivate* priv = CompartmentPrivate::Get(comp);
+    return priv && priv->isSandboxCompartment;
+}
+
+bool
 IsUniversalXPConnectEnabled(JS::Compartment* compartment)
 {
     CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
     if (!priv)
         return false;
     return priv->universalXPConnectEnabled;
 }
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2868,16 +2868,19 @@ public:
     // to opt into CPOWs. It's necessary for the implementation of
     // RemoteAddonsParent.jsm.
     bool allowCPOWs;
 
     // True if this compartment is a content XBL compartment. Every global in
     // such a compartment is a content XBL scope.
     bool isContentXBLCompartment;
 
+    // True if this is a sandbox compartment. See xpc::CreateSandboxObject.
+    bool isSandboxCompartment;
+
     // This is only ever set during mochitest runs when enablePrivilege is called.
     // It's intended as a temporary stopgap measure until we can finish ripping out
     // enablePrivilege. Once set, this value is never unset (i.e., it doesn't follow
     // the old scoping rules of enablePrivilege).
     //
     // Using it in production is inherently unsafe.
     bool universalXPConnectEnabled;
 
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -80,16 +80,18 @@ TransplantObject(JSContext* cx, JS::Hand
 
 JSObject*
 TransplantObjectRetainingXrayExpandos(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
 
 bool IsContentXBLCompartment(JS::Compartment* compartment);
 bool IsContentXBLScope(JS::Realm* realm);
 bool IsInContentXBLScope(JSObject* obj);
 
+bool IsInSandboxCompartment(JSObject* obj);
+
 // Return a raw XBL scope object corresponding to contentScope, which must
 // be an object whose global is a DOM window.
 //
 // The return value is not wrapped into cx->compartment, so be sure to enter
 // its compartment before doing anything meaningful.
 //
 // Also note that XBL scopes are lazily created, so the return-value should be
 // null-checked unless the caller can ensure that the scope must already