Bug 1233497 - Fix infrastructure for disallowing unsafe CPOWs in browser code. r=mrbkap
This commit is contained in:
@@ -16,6 +16,12 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
||||
SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
|
||||
});
|
||||
|
||||
function done() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "JavaScriptParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jswrapper.h"
|
||||
@@ -68,8 +69,11 @@ JavaScriptParent::allowMessage(JSContext* cx)
|
||||
return true;
|
||||
|
||||
if (ForbidUnsafeBrowserCPOWs()) {
|
||||
if (JSObject* global = JS::CurrentGlobalOrNull(cx)) {
|
||||
if (!JS::AddonIdOfObject(global)) {
|
||||
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) {
|
||||
JS_ReportError(cx, "unsafe CPOW usage forbidden");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ interface ScheduledGCCallback : nsISupports
|
||||
/**
|
||||
* interface of Components.utils
|
||||
*/
|
||||
[scriptable, uuid(3ce3a6f8-2b59-439c-a57e-74e7b122fb3c)]
|
||||
[scriptable, uuid(86003fe3-ee9a-4620-91dc-eef8b1e58815)]
|
||||
interface nsIXPCComponents_Utils : nsISupports
|
||||
{
|
||||
|
||||
@@ -444,6 +444,15 @@ interface nsIXPCComponents_Utils : nsISupports
|
||||
*/
|
||||
ACString getCrossProcessWrapperTag(in jsval obj);
|
||||
|
||||
/**
|
||||
* If CPOWs are disabled for browser code via the
|
||||
* dom.ipc.cpows.forbid-unsafe-from-browser preferences, then only
|
||||
* add-ons can use CPOWs. This function allows a non-addon scope
|
||||
* to opt into CPOWs. It's necessary for the implementation of
|
||||
* RemoteAddonsParent.jsm.
|
||||
*/
|
||||
void permitCPOWsInScope(in jsval obj);
|
||||
|
||||
/*
|
||||
* To be called from JS only. This is for Gecko internal use only, and may
|
||||
* disappear at any moment.
|
||||
|
||||
@@ -2860,6 +2860,17 @@ nsXPCComponents_Utils::GetCrossProcessWrapperTag(HandleValue obj, nsACString& ou
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::PermitCPOWsInScope(HandleValue obj)
|
||||
{
|
||||
if (!obj.isObject())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
JSObject* scopeObj = js::UncheckedUnwrap(&obj.toObject());
|
||||
CompartmentPrivate::Get(scopeObj)->allowCPOWs = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext* cx)
|
||||
{
|
||||
|
||||
@@ -202,6 +202,7 @@ CompartmentPrivate::CompartmentPrivate(JSCompartment* c)
|
||||
, skipWriteToGlobalPrototype(false)
|
||||
, isWebExtensionContentScript(false)
|
||||
, waiveInterposition(false)
|
||||
, allowCPOWs(false)
|
||||
, universalXPConnectEnabled(false)
|
||||
, forcePermissiveCOWs(false)
|
||||
, scriptability(c)
|
||||
|
||||
@@ -3730,6 +3730,13 @@ public:
|
||||
// scope.
|
||||
bool waiveInterposition;
|
||||
|
||||
// If CPOWs are disabled for browser code via the
|
||||
// dom.ipc.cpows.forbid-unsafe-from-browser preferences, then only
|
||||
// add-ons can use CPOWs. This flag allows a non-addon scope
|
||||
// to opt into CPOWs. It's necessary for the implementation of
|
||||
// RemoteAddonsParent.jsm.
|
||||
bool allowCPOWs;
|
||||
|
||||
// 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
|
||||
|
||||
@@ -22,6 +22,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Prefetcher",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CompatWarning",
|
||||
"resource://gre/modules/CompatWarning.jsm");
|
||||
|
||||
Cu.permitCPOWsInScope(this);
|
||||
|
||||
// Similar to Python. Returns dict[key] if it exists. Otherwise,
|
||||
// sets dict[key] to default_ and returns default_.
|
||||
function setDefault(dict, key, default_)
|
||||
@@ -851,7 +853,7 @@ function getContentDocument(addon, browser)
|
||||
return doc;
|
||||
}
|
||||
|
||||
return browser.contentDocumentAsCPOW;
|
||||
return browser.contentWindowAsCPOW.document;
|
||||
}
|
||||
|
||||
function getSessionHistory(browser) {
|
||||
|
||||
Reference in New Issue
Block a user