From 6048128013745eb399dc56a36366bfd1bd24f5cf Mon Sep 17 00:00:00 2001 From: Sander van Veen Date: Sun, 21 Aug 2011 16:02:24 -0700 Subject: [PATCH] Bug 673331 - Add identifying information to system compartments. r=mrbkap. --- browser/components/feeds/src/FeedWriter.js | 3 ++- .../content/aboutSessionRestore.js | 2 +- .../sessionstore/src/nsSessionStartup.js | 2 +- browser/devtools/scratchpad/scratchpad.js | 6 +++-- js/src/xpconnect/src/nsXPConnect.cpp | 3 ++- js/src/xpconnect/src/xpccomponents.cpp | 27 +++++++++++++++++-- js/src/xpconnect/src/xpcjsruntime.cpp | 16 ++++++++--- js/src/xpconnect/src/xpcprivate.h | 3 ++- netwerk/base/src/nsProxyAutoConfig.js | 3 ++- toolkit/mozapps/extensions/XPIProvider.jsm | 10 ++++--- 10 files changed, 58 insertions(+), 17 deletions(-) diff --git a/browser/components/feeds/src/FeedWriter.js b/browser/components/feeds/src/FeedWriter.js index 4f4040cad5ea..e858fa09eabd 100644 --- a/browser/components/feeds/src/FeedWriter.js +++ b/browser/components/feeds/src/FeedWriter.js @@ -256,7 +256,8 @@ FeedWriter.prototype = { __contentSandbox: null, get _contentSandbox() { if (!this.__contentSandbox) - this.__contentSandbox = new Cu.Sandbox(this._window); + this.__contentSandbox = new Cu.Sandbox(this._window, + {sandboxName: 'FeedWriter'}); return this.__contentSandbox; }, diff --git a/browser/components/sessionstore/content/aboutSessionRestore.js b/browser/components/sessionstore/content/aboutSessionRestore.js index dc98407a44b1..d2793e6716f8 100644 --- a/browser/components/sessionstore/content/aboutSessionRestore.js +++ b/browser/components/sessionstore/content/aboutSessionRestore.js @@ -59,7 +59,7 @@ window.onload = function() { gStateObject = JSON.parse(sessionData.value); } catch (exJSON) { - var s = new Cu.Sandbox("about:blank"); + var s = new Cu.Sandbox("about:blank", {sandboxName: 'aboutSessionRestore'}); gStateObject = Cu.evalInSandbox("(" + sessionData.value + ")", s); // If we couldn't parse the string with JSON.parse originally, make sure // that the value in the textbox will be parsable. diff --git a/browser/components/sessionstore/src/nsSessionStartup.js b/browser/components/sessionstore/src/nsSessionStartup.js index 684bd8aeaa07..b59e4ec65831 100644 --- a/browser/components/sessionstore/src/nsSessionStartup.js +++ b/browser/components/sessionstore/src/nsSessionStartup.js @@ -135,7 +135,7 @@ SessionStartup.prototype = { this._initialState = JSON.parse(iniString); } catch (exJSON) { - var s = new Cu.Sandbox("about:blank"); + var s = new Cu.Sandbox("about:blank", {sandboxName: 'nsSessionStartup'}); this._initialState = Cu.evalInSandbox("(" + iniString + ")", s); } diff --git a/browser/devtools/scratchpad/scratchpad.js b/browser/devtools/scratchpad/scratchpad.js index 807b15439931..7d4edd073eb2 100644 --- a/browser/devtools/scratchpad/scratchpad.js +++ b/browser/devtools/scratchpad/scratchpad.js @@ -178,7 +178,8 @@ var Scratchpad = { this._previousLocation != this.gBrowser.contentWindow.location.href) { let contentWindow = this.gBrowser.selectedBrowser.contentWindow; this._contentSandbox = new Cu.Sandbox(contentWindow, - { sandboxPrototype: contentWindow, wantXrays: false }); + { sandboxPrototype: contentWindow, wantXrays: false, + sandboxName: 'scratchpad-content'}); this._previousBrowserWindow = this.browserWindow; this._previousBrowser = this.gBrowser.selectedBrowser; @@ -211,7 +212,8 @@ var Scratchpad = { if (!this._chromeSandbox || this.browserWindow != this._previousBrowserWindow) { this._chromeSandbox = new Cu.Sandbox(this.browserWindow, - { sandboxPrototype: this.browserWindow, wantXrays: false }); + { sandboxPrototype: this.browserWindow, wantXrays: false, + sandboxName: 'scratchpad-chrome'}); this._previousBrowserWindow = this.browserWindow; } diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 12e938c8ff4e..7ad2b28aa4fc 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -2073,7 +2073,8 @@ nsXPConnect::CreateSandbox(JSContext *cx, nsIPrincipal *principal, jsval rval = JSVAL_VOID; AUTO_MARK_JSVAL(ccx, &rval); - nsresult rv = xpc_CreateSandboxObject(cx, &rval, principal, NULL, false); + nsresult rv = xpc_CreateSandboxObject(cx, &rval, principal, NULL, false, + EmptyCString()); NS_ASSERTION(NS_FAILED(rv) || !JSVAL_IS_PRIMITIVE(rval), "Bad return value from xpc_CreateSandboxObject()!"); diff --git a/js/src/xpconnect/src/xpccomponents.cpp b/js/src/xpconnect/src/xpccomponents.cpp index 5fac1d3f6f3f..ea5e9dddbbe1 100644 --- a/js/src/xpconnect/src/xpccomponents.cpp +++ b/js/src/xpconnect/src/xpccomponents.cpp @@ -3153,7 +3153,7 @@ NS_IMPL_ISUPPORTS0(Identity) nsresult xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSObject *proto, - bool wantXrays) + bool wantXrays, const nsACString &sandboxName) { // Create the sandbox global object nsresult rv; @@ -3240,6 +3240,10 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSOb } } + xpc::CompartmentPrivate *compartmentPrivate = + static_cast(JS_GetCompartmentPrivate(cx, compartment)); + compartmentPrivate->location = sandboxName; + return NS_OK; } @@ -3351,6 +3355,8 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe JSObject *proto = nsnull; bool wantXrays = true; + nsCString sandboxName; + if (argc > 1) { if (!JSVAL_IS_OBJECT(argv[1])) return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); @@ -3382,9 +3388,26 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe wantXrays = JSVAL_TO_BOOLEAN(option); } + + if (!JS_HasProperty(cx, optionsObject, "sandboxName", &found)) + return NS_ERROR_INVALID_ARG; + + if (found) { + if (!JS_GetProperty(cx, optionsObject, "sandboxName", &option) || + !JSVAL_IS_STRING(option)) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + char *tmp = JS_EncodeString(cx, JSVAL_TO_STRING(option)); + if (!tmp) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + sandboxName.Adopt(tmp, strlen(tmp)); + } } - rv = xpc_CreateSandboxObject(cx, vp, prinOrSop, proto, wantXrays); + rv = xpc_CreateSandboxObject(cx, vp, prinOrSop, proto, wantXrays, sandboxName); if (NS_FAILED(rv)) { return ThrowAndFail(rv, cx, _retval); diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index cbcdb1933ae2..3c3791f5b911 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -1578,22 +1578,30 @@ CompartmentStats::CompartmentStats(JSContext *cx, JSCompartment *c) { if(c->principals->codebase) { - // A hack: replace forward slashes with '\\' so they aren't - // treated as path separators. Users of the reporters - // (such as about:memory) have to undo this change. name.Assign(c->principals->codebase); - name.ReplaceChar('/', '\\'); // If it's the system compartment, append the address. // This means that multiple system compartments (and there // can be many) can be distinguished. if(c->isSystemCompartment) { + if (c->data && + !((xpc::CompartmentPrivate*)c->data)->location.IsEmpty()) + { + name.AppendLiteral(", "); + name.Append(((xpc::CompartmentPrivate*)c->data)->location); + } + // ample; 64-bit address max is 18 chars static const int maxLength = 31; nsPrintfCString address(maxLength, ", 0x%llx", PRUint64(c)); name.Append(address); } + + // A hack: replace forward slashes with '\\' so they aren't + // treated as path separators. Users of the reporters + // (such as about:memory) have to undo this change. + name.ReplaceChar('/', '\\'); } else { diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index e70aa0cf721e..592f88de998b 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -4315,7 +4315,7 @@ xpc_GetJSPrivate(JSObject *obj) // and used. nsresult xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, - JSObject *proto, bool preferXray); + JSObject *proto, bool preferXray, const nsACString &sandboxName); // Helper for evaluating scripts in a sandbox object created with // xpc_CreateSandboxObject(). The caller is responsible of ensuring @@ -4394,6 +4394,7 @@ struct CompartmentPrivate JSObject2JSObjectMap *waiverWrapperMap; // NB: we don't want this map to hold a strong reference to the wrapper. nsDataHashtable, JSObject *> *expandoMap; + nsCString location; bool RegisterExpandoObject(XPCWrappedNative *wn, JSObject *expando) { if (!expandoMap) { diff --git a/netwerk/base/src/nsProxyAutoConfig.js b/netwerk/base/src/nsProxyAutoConfig.js index cd80422cdfe8..84b08dcbc29e 100644 --- a/netwerk/base/src/nsProxyAutoConfig.js +++ b/netwerk/base/src/nsProxyAutoConfig.js @@ -75,7 +75,8 @@ nsProxyAutoConfig.prototype = { } // allocate a fresh Sandbox to clear global scope for new PAC script - this._sandBox = new Components.utils.Sandbox(pacURI); + this._sandBox = new Components.utils.Sandbox(pacURI, + {sandboxName: 'nsProxyAutoConfig'}); Components.utils.evalInSandbox(pacUtils, this._sandBox); // add predefined functions to pac diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index 93533f60c493..0bb75a172493 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -3461,13 +3461,18 @@ var XPIProvider = { let principal = Cc["@mozilla.org/systemprincipal;1"]. createInstance(Ci.nsIPrincipal); - this.bootstrapScopes[aId] = new Components.utils.Sandbox(principal); if (!aFile.exists()) { + this.bootstrapScopes[aId] = new Components.utils.Sandbox(principal, + {sandboxName: aFile.path}); ERROR("Attempted to load bootstrap scope from missing directory " + bootstrap.path); return; } + let uri = getURIForResourceInFile(aFile, "bootstrap.js").spec; + this.bootstrapScopes[aId] = new Components.utils.Sandbox(principal, + {sandboxName: uri}); + let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. createInstance(Ci.mozIJSSubScriptLoader); @@ -3475,8 +3480,7 @@ var XPIProvider = { // As we don't want our caller to control the JS version used for the // bootstrap file, we run loadSubScript within the context of the // sandbox with the latest JS version set explicitly. - this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = - getURIForResourceInFile(aFile, "bootstrap.js").spec; + this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = uri; Components.utils.evalInSandbox( "Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \ .createInstance(Components.interfaces.mozIJSSubScriptLoader) \