Bug 1196975 - part4: waiveInterposition. r=billm
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1020,16 +1020,17 @@ xpc::CreateSandboxObject(JSContext* cx,
principal, compartmentOptions));
if (!sandbox)
return NS_ERROR_FAILURE;
CompartmentPrivate* priv = CompartmentPrivate::Get(sandbox);
priv->allowWaivers = options.allowWaivers;
priv->writeToGlobalPrototype = options.writeToGlobalPrototype;
priv->isWebExtensionContentScript = options.isWebExtensionContentScript;
+ priv->waiveInterposition = options.waiveInterposition;
// 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
@@ -1486,16 +1487,17 @@ bool
SandboxOptions::Parse()
{
bool ok = ParseObject("sandboxPrototype", &proto) &&
ParseBoolean("wantXrays", &wantXrays) &&
ParseBoolean("allowWaivers", &allowWaivers) &&
ParseBoolean("wantComponents", &wantComponents) &&
ParseBoolean("wantExportHelpers", &wantExportHelpers) &&
ParseBoolean("isWebExtensionContentScript", &isWebExtensionContentScript) &&
+ ParseBoolean("waiveInterposition", &waiveInterposition) &&
ParseString("sandboxName", sandboxName) &&
ParseObject("sameZoneAs", &sameZoneAs) &&
ParseBoolean("freshZone", &freshZone) &&
ParseBoolean("invisibleToDebugger", &invisibleToDebugger) &&
ParseBoolean("discardSource", &discardSource) &&
ParseJSString("addonId", &addonId) &&
ParseBoolean("writeToGlobalPrototype", &writeToGlobalPrototype) &&
ParseGlobalProperties() &&
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -189,16 +189,17 @@ public:
namespace xpc {
CompartmentPrivate::CompartmentPrivate(JSCompartment* c)
: wantXrays(false)
, allowWaivers(true)
, writeToGlobalPrototype(false)
, skipWriteToGlobalPrototype(false)
, isWebExtensionContentScript(false)
+ , waiveInterposition(false)
, universalXPConnectEnabled(false)
, forcePermissiveCOWs(false)
, scriptability(c)
, scope(nullptr)
, mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH))
{
MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
mozilla::PodArrayZero(wrapperDenialWarnings);
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -134,19 +134,21 @@ XPCWrappedNativeScope::XPCWrappedNativeS
}
if (mUseContentXBLScope) {
mUseContentXBLScope = principal && !nsContentUtils::IsSystemPrincipal(principal);
}
JSAddonId* addonId = JS::AddonIdOfObject(aGlobal);
if (gInterpositionMap) {
bool isSystem = nsContentUtils::IsSystemPrincipal(principal);
- if (InterpositionMap::Ptr p = gInterpositionMap->lookup(addonId)) {
+ bool waiveInterposition = priv->waiveInterposition;
+ InterpositionMap::Ptr interposition = gInterpositionMap->lookup(addonId);
+ if (!waiveInterposition && interposition) {
MOZ_RELEASE_ASSERT(isSystem);
- mInterposition = p->value();
+ mInterposition = interposition->value();
}
// We also want multiprocessCompatible add-ons to have a default interposition.
if (!mInterposition && addonId && isSystem) {
bool interpositionEnabled = mozilla::Preferences::GetBool(
"extensions.interposition.enabled", false);
if (interpositionEnabled) {
mInterposition = do_GetService("@mozilla.org/addons/default-addon-shims;1");
MOZ_ASSERT(mInterposition);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3470,16 +3470,17 @@ public:
explicit SandboxOptions(JSContext* cx = xpc_GetSafeJSContext(),
JSObject* options = nullptr)
: OptionsBase(cx, options)
, wantXrays(true)
, allowWaivers(true)
, wantComponents(true)
, wantExportHelpers(false)
, isWebExtensionContentScript(false)
+ , waiveInterposition(false)
, proto(cx)
, addonId(cx)
, writeToGlobalPrototype(false)
, sameZoneAs(cx)
, freshZone(false)
, invisibleToDebugger(false)
, discardSource(false)
, metadata(cx)
@@ -3487,16 +3488,17 @@ public:
virtual bool Parse();
bool wantXrays;
bool allowWaivers;
bool wantComponents;
bool wantExportHelpers;
bool isWebExtensionContentScript;
+ bool waiveInterposition;
JS::RootedObject proto;
nsCString sandboxName;
JS::RootedString addonId;
bool writeToGlobalPrototype;
JS::RootedObject sameZoneAs;
bool freshZone;
bool invisibleToDebugger;
bool discardSource;
@@ -3727,16 +3729,21 @@ public:
// disable the writeToGlobalPrototype behavior (when resolving standard
// classes, for example).
bool skipWriteToGlobalPrototype;
// This scope corresponds to a WebExtension content script, and receives
// various bits of special compatibility behavior.
bool isWebExtensionContentScript;
+ // Even if an add-on needs interposition, it does not necessary need it
+ // for every scope. If this flag is set we waive interposition for this
+ // scope.
+ bool waiveInterposition;
+
// 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;