mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Back out 14928a6b38f3 (bug 1214824) for leaking an nsStringBuffer in debug e10s devtools
This commit is contained in:
parent
cb3e27e060
commit
ef87dff4e9
@ -63,88 +63,26 @@ ForbidUnsafeBrowserCPOWs()
|
||||
return result;
|
||||
}
|
||||
|
||||
// Should we allow CPOWs in aAddonId, even though it's marked as multiprocess
|
||||
// compatible? This is controlled by two prefs:
|
||||
// If dom.ipc.cpows.forbid-cpows-in-compat-addons is false, then we allow the CPOW.
|
||||
// If dom.ipc.cpows.forbid-cpows-in-compat-addons is true:
|
||||
// We check if aAddonId is listed in dom.ipc.cpows.allow-cpows-in-compat-addons
|
||||
// (which should be a comma-separated string). If it's present there, we allow
|
||||
// the CPOW. Otherwise we forbid the CPOW.
|
||||
static bool
|
||||
ForbidCPOWsInCompatibleAddon(const nsACString& aAddonId)
|
||||
{
|
||||
static bool forbid;
|
||||
static nsCString allow;
|
||||
static bool cached = false;
|
||||
if (!cached) {
|
||||
cached = true;
|
||||
Preferences::AddBoolVarCache(&forbid, "dom.ipc.cpows.forbid-cpows-in-compat-addons", false);
|
||||
|
||||
allow.Assign(',');
|
||||
allow.Append(Preferences::GetCString("dom.ipc.cpows.allow-cpows-in-compat-addons"));
|
||||
allow.Append(',');
|
||||
}
|
||||
|
||||
if (!forbid) {
|
||||
return false;
|
||||
}
|
||||
nsCString searchString(",");
|
||||
searchString.Append(aAddonId);
|
||||
searchString.Append(',');
|
||||
return allow.Find(searchString) == kNotFound;
|
||||
}
|
||||
|
||||
bool
|
||||
JavaScriptParent::allowMessage(JSContext* cx)
|
||||
{
|
||||
// If we're running browser code, then we allow all safe CPOWs and forbid
|
||||
// unsafe CPOWs based on a pref (which defaults to forbidden). We also allow
|
||||
// CPOWs unconditionally in selected globals (based on
|
||||
// Cu.permitCPOWsInScope).
|
||||
//
|
||||
// If we're running add-on code, then we check if the add-on is multiprocess
|
||||
// compatible (which eventually translates to a given setting of allowCPOWs
|
||||
// on the scopw). If it's not compatible, then we allow the CPOW but
|
||||
// warn. If it is marked as compatible, then we check the
|
||||
// ForbidCPOWsInCompatibleAddon; see the comment there.
|
||||
|
||||
MessageChannel* channel = GetIPCChannel();
|
||||
bool isSafe = channel->IsInTransaction();
|
||||
if (channel->IsInTransaction())
|
||||
return true;
|
||||
|
||||
bool warn = !isSafe;
|
||||
nsIGlobalObject* global = dom::GetIncumbentGlobal();
|
||||
JSObject* jsGlobal = global ? global->GetGlobalJSObject() : nullptr;
|
||||
if (jsGlobal) {
|
||||
JSAutoCompartment ac(cx, jsGlobal);
|
||||
JSAddonId* addonId = JS::AddonIdOfObject(jsGlobal);
|
||||
|
||||
if (!xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) {
|
||||
if (!addonId && ForbidUnsafeBrowserCPOWs() && !isSafe) {
|
||||
if (ForbidUnsafeBrowserCPOWs()) {
|
||||
nsIGlobalObject* global = dom::GetIncumbentGlobal();
|
||||
JSObject* jsGlobal = global ? global->GetGlobalJSObject() : nullptr;
|
||||
if (jsGlobal) {
|
||||
JSAutoCompartment ac(cx, jsGlobal);
|
||||
if (!JS::AddonIdOfObject(jsGlobal) && !xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) {
|
||||
Telemetry::Accumulate(Telemetry::BROWSER_SHIM_USAGE_BLOCKED, 1);
|
||||
JS_ReportError(cx, "unsafe CPOW usage forbidden");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (addonId) {
|
||||
JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(addonId));
|
||||
nsString addonIdString;
|
||||
AssignJSFlatString(addonIdString, flat);
|
||||
NS_ConvertUTF16toUTF8 addonIdCString(addonIdString);
|
||||
Telemetry::Accumulate(Telemetry::ADDON_FORBIDDEN_CPOW_USAGE, addonIdCString);
|
||||
|
||||
if (ForbidCPOWsInCompatibleAddon(addonIdCString)) {
|
||||
JS_ReportError(cx, "CPOW usage forbidden in this add-on");
|
||||
return false;
|
||||
}
|
||||
|
||||
warn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!warn)
|
||||
return true;
|
||||
|
||||
static bool disableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
|
||||
if (!disableUnsafeCPOWWarnings) {
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
@ -153,7 +91,7 @@ JavaScriptParent::allowMessage(JSContext* cx)
|
||||
uint32_t lineno = 0, column = 0;
|
||||
nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column);
|
||||
nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
|
||||
error->Init(NS_LITERAL_STRING("unsafe/forbidden CPOW usage"), filename,
|
||||
error->Init(NS_LITERAL_STRING("unsafe CPOW usage"), filename,
|
||||
EmptyString(), lineno, column,
|
||||
nsIScriptError::warningFlag, "chrome javascript");
|
||||
console->LogMessage(error);
|
||||
|
@ -679,9 +679,6 @@ interface nsIXPCComponents_Utils : nsISupports
|
||||
[implicit_jscontext]
|
||||
void setAddonCallInterposition(in jsval target);
|
||||
|
||||
[implicit_jscontext]
|
||||
void allowCPOWsInAddon(in ACString addonId, in bool allow);
|
||||
|
||||
/*
|
||||
* Return a fractional number of milliseconds from process
|
||||
* startup, measured with a monotonic clock.
|
||||
|
@ -3358,20 +3358,6 @@ nsXPCComponents_Utils::SetAddonCallInterposition(HandleValue target,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::AllowCPOWsInAddon(const nsACString& addonIdStr,
|
||||
bool allow,
|
||||
JSContext* cx)
|
||||
{
|
||||
JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
|
||||
if (!addonId)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!XPCWrappedNativeScope::AllowCPOWsInAddon(cx, addonId, allow))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::Now(double* aRetval)
|
||||
{
|
||||
|
@ -26,10 +26,8 @@ using namespace JS;
|
||||
|
||||
XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr;
|
||||
XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr;
|
||||
bool XPCWrappedNativeScope::gShutdownObserverInitialized = false;
|
||||
XPCWrappedNativeScope::InterpositionMap* XPCWrappedNativeScope::gInterpositionMap = nullptr;
|
||||
InterpositionWhitelistArray* XPCWrappedNativeScope::gInterpositionWhitelists = nullptr;
|
||||
XPCWrappedNativeScope::AddonSet* XPCWrappedNativeScope::gAllowCPOWAddonSet = nullptr;
|
||||
|
||||
NS_IMPL_ISUPPORTS(XPCWrappedNativeScope::ClearInterpositionsObserver, nsIObserver)
|
||||
|
||||
@ -54,11 +52,6 @@ XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports* subject
|
||||
gInterpositionWhitelists = nullptr;
|
||||
}
|
||||
|
||||
if (gAllowCPOWAddonSet) {
|
||||
delete gAllowCPOWAddonSet;
|
||||
gAllowCPOWAddonSet = nullptr;
|
||||
}
|
||||
|
||||
nsContentUtils::UnregisterShutdownObserver(this);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -163,11 +156,6 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext* cx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addonId) {
|
||||
// We forbid CPOWs unless they're specifically allowed.
|
||||
priv->allowCPOWs = gAllowCPOWAddonSet ? gAllowCPOWAddonSet->has(addonId) : false;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@ -716,10 +704,9 @@ XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx,
|
||||
bool ok = gInterpositionMap->init();
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
|
||||
if (!gShutdownObserverInitialized) {
|
||||
gShutdownObserverInitialized = true;
|
||||
nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver());
|
||||
}
|
||||
// Make sure to clear the map at shutdown.
|
||||
// Note: this will take care of gInterpositionWhitelists too.
|
||||
nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver());
|
||||
}
|
||||
if (interp) {
|
||||
bool ok = gInterpositionMap->put(addonId, interp);
|
||||
@ -731,30 +718,6 @@ XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
XPCWrappedNativeScope::AllowCPOWsInAddon(JSContext* cx,
|
||||
JSAddonId* addonId,
|
||||
bool allow)
|
||||
{
|
||||
if (!gAllowCPOWAddonSet) {
|
||||
gAllowCPOWAddonSet = new AddonSet();
|
||||
bool ok = gAllowCPOWAddonSet->init();
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
|
||||
if (!gShutdownObserverInitialized) {
|
||||
gShutdownObserverInitialized = true;
|
||||
nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver());
|
||||
}
|
||||
}
|
||||
if (allow) {
|
||||
bool ok = gAllowCPOWAddonSet->put(addonId);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
} else {
|
||||
gAllowCPOWAddonSet->remove(addonId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAddonInterposition>
|
||||
XPCWrappedNativeScope::GetInterposition()
|
||||
{
|
||||
|
@ -1287,20 +1287,6 @@ SetAddonInterposition(const nsACString& addonIdStr, nsIAddonInterposition* inter
|
||||
return XPCWrappedNativeScope::SetAddonInterposition(jsapi.cx(), addonId, interposition);
|
||||
}
|
||||
|
||||
bool
|
||||
AllowCPOWsInAddon(const nsACString& addonIdStr, bool allow)
|
||||
{
|
||||
JSAddonId* addonId;
|
||||
// We enter the junk scope just to allocate a string, which actually will go
|
||||
// in the system zone.
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init(xpc::PrivilegedJunkScope());
|
||||
addonId = NewAddonId(jsapi.cx(), addonIdStr);
|
||||
if (!addonId)
|
||||
return false;
|
||||
return XPCWrappedNativeScope::AllowCPOWsInAddon(jsapi.cx(), addonId, allow);
|
||||
}
|
||||
|
||||
} // namespace xpc
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -997,10 +997,6 @@ public:
|
||||
js::PointerHasher<JSAddonId*, 3>,
|
||||
js::SystemAllocPolicy> InterpositionMap;
|
||||
|
||||
typedef js::HashSet<JSAddonId*,
|
||||
js::PointerHasher<JSAddonId*, 3>,
|
||||
js::SystemAllocPolicy> AddonSet;
|
||||
|
||||
// Gets the appropriate scope object for XBL in this scope. The context
|
||||
// must be same-compartment with the global upon entering, and the scope
|
||||
// object is wrapped into the compartment of the global.
|
||||
@ -1032,8 +1028,6 @@ public:
|
||||
void SetAddonCallInterposition() { mHasCallInterpositions = true; }
|
||||
bool HasCallInterposition() { return mHasCallInterpositions; };
|
||||
|
||||
static bool AllowCPOWsInAddon(JSContext* cx, JSAddonId* addonId, bool allow);
|
||||
|
||||
protected:
|
||||
virtual ~XPCWrappedNativeScope();
|
||||
|
||||
@ -1051,9 +1045,7 @@ private:
|
||||
static XPCWrappedNativeScope* gScopes;
|
||||
static XPCWrappedNativeScope* gDyingScopes;
|
||||
|
||||
static bool gShutdownObserverInitialized;
|
||||
static InterpositionMap* gInterpositionMap;
|
||||
static AddonSet* gAllowCPOWAddonSet;
|
||||
|
||||
static InterpositionWhitelistArray* gInterpositionWhitelists;
|
||||
|
||||
|
@ -503,9 +503,6 @@ SharedMemoryEnabled();
|
||||
bool
|
||||
SetAddonInterposition(const nsACString& addonId, nsIAddonInterposition* interposition);
|
||||
|
||||
bool
|
||||
AllowCPOWsInAddon(const nsACString& addonId, bool allow);
|
||||
|
||||
bool
|
||||
ExtraWarningsForSystemJS();
|
||||
|
||||
|
@ -42,14 +42,6 @@
|
||||
"keyed": true,
|
||||
"description": "Reasons why add-on shims were used, keyed by add-on ID."
|
||||
},
|
||||
"ADDON_FORBIDDEN_CPOW_USAGE": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "Counts the number of times a given add-on used CPOWs when it was marked as e10s compatible.",
|
||||
"bug_numbers": [1214824],
|
||||
"alert_emails": ["wmccloskey@mozilla.com"]
|
||||
},
|
||||
"BROWSER_SHIM_USAGE_BLOCKED": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
|
@ -4606,7 +4606,6 @@ this.XPIProvider = {
|
||||
let interposition = Cc["@mozilla.org/addons/multiprocess-shims;1"].
|
||||
getService(Ci.nsIAddonInterposition);
|
||||
Cu.setAddonInterposition(aId, interposition);
|
||||
Cu.allowCPOWsInAddon(aId, true);
|
||||
}
|
||||
|
||||
if (!aFile.exists()) {
|
||||
@ -4683,7 +4682,6 @@ this.XPIProvider = {
|
||||
// In case the add-on was not multiprocess-compatible, deregister
|
||||
// any interpositions for it.
|
||||
Cu.setAddonInterposition(aId, null);
|
||||
Cu.allowCPOWsInAddon(aId, false);
|
||||
|
||||
this.activeAddons.delete(aId);
|
||||
delete this.bootstrappedAddons[aId];
|
||||
|
@ -669,9 +669,6 @@ RegisterExtensionInterpositions(nsINIParser &parser)
|
||||
|
||||
if (!xpc::SetAddonInterposition(addonId, interposition))
|
||||
continue;
|
||||
|
||||
if (!xpc::AllowCPOWsInAddon(addonId, true))
|
||||
continue;
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user