diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 69675c257c3..c32f40e90dc 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -1386,8 +1386,20 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj, getter_AddRefs(subject)); //-- If subject is null, get a principal from the function object's scope. if (NS_SUCCEEDED(rv) && !subject) + { +#ifdef DEBUG + { + JSFunction *fun = + (JSFunction *)JS_GetPrivate(aCx, (JSObject *)aFunObj); + JSScript *script = JS_GetFunctionScript(aCx, fun); + + NS_ASSERTION(!script, "Null principal for non-native function!"); + } +#endif + rv = doGetObjectPrincipal(aCx, (JSObject*)aFunObj, getter_AddRefs(subject)); + } if (NS_FAILED(rv)) return rv; if (!subject) return NS_ERROR_FAILURE; @@ -1811,16 +1823,20 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx, nsCOMPtr scriptPrincipal; if (script) - if (NS_FAILED(GetScriptPrincipal(cx, script, getter_AddRefs(scriptPrincipal)))) + { + if (JS_GetFunctionObject(fun) != obj) + { + // Function is a clone, its prototype was precompiled from + // brutally shared chrome. For this case only, get the + // principals from the clone's scope since there's no + // reliable principals compiled into the function. + return doGetObjectPrincipal(cx, obj, result); + } + + if (NS_FAILED(GetScriptPrincipal(cx, script, + getter_AddRefs(scriptPrincipal)))) return NS_ERROR_FAILURE; - if (script && (JS_GetFunctionObject(fun) != obj) && - (scriptPrincipal.get() == mSystemPrincipal)) - { - // Function is brutally-shared chrome. For this case only, - // get a principal from the object's scope instead of the - // principal compiled into the function. - return doGetObjectPrincipal(cx, obj, result); } *result = scriptPrincipal.get(); @@ -1840,7 +1856,20 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx, JSScript *script = JS_GetFrameScript(cx, fp); return GetScriptPrincipal(cx, script, result); } - return GetFunctionObjectPrincipal(cx, obj, result); + + nsresult rv = GetFunctionObjectPrincipal(cx, obj, result); + +#ifdef DEBUG + if (NS_SUCCEEDED(rv) && !*result) + { + JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj); + JSScript *script = JS_GetFunctionScript(cx, fun); + + NS_ASSERTION(!script, "Null principal for non-native function!"); + } +#endif + + return rv; } nsresult diff --git a/mozilla/dom/src/base/nsJSEnvironment.cpp b/mozilla/dom/src/base/nsJSEnvironment.cpp index b80c3d809f2..6dbf208a499 100644 --- a/mozilla/dom/src/base/nsJSEnvironment.cpp +++ b/mozilla/dom/src/base/nsJSEnvironment.cpp @@ -120,6 +120,7 @@ static PRBool sDidShutdown = PR_FALSE; static PRInt32 sContextCount = 0; +static nsIScriptSecurityManager *sSecurityManager = nsnull; void JS_DLL_CALLBACK NS_ScriptErrorReporter(JSContext *cx, @@ -436,8 +437,6 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE) nsJSContext::~nsJSContext() { - mSecurityManager = nsnull; // Force release - // Cope with JS_NewContext failure in ctor (XXXbe move NewContext to Init?) if (!mContext) return; @@ -469,9 +468,12 @@ nsJSContext::~nsJSContext() if (!sContextCount && sDidShutdown) { // The last context is being deleted, and we're already in the - // process of shutting down, release the JS runtime service. + // process of shutting down, release the JS runtime service, and + // the security manager. NS_IF_RELEASE(sRuntimeService); + + NS_IF_RELEASE(sSecurityManager); } } @@ -930,25 +932,35 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName, const nsAString& aBody, PRBool aShared, void** aHandler) { + if (!sSecurityManager) { + NS_ERROR("Huh, we need a script security manager to compile " + "an event handler!"); + + return NS_ERROR_UNEXPECTED; + } + + JSObject *target = (JSObject*)aTarget; + JSPrincipals *jsprin = nsnull; - nsCOMPtr global; - GetGlobalObject(getter_AddRefs(global)); - if (global) { - // XXXbe why the two-step QI? speed up via a new GetGlobalObjectData func? - nsCOMPtr globalData = do_QueryInterface(global); - if (globalData) { - nsCOMPtr prin; - if (NS_FAILED(globalData->GetPrincipal(getter_AddRefs(prin)))) - return NS_ERROR_FAILURE; - prin->GetJSPrincipals(&jsprin); - } + if (target) { + // Get the principal of the event target (the object principal), + // don't get the principal of the global object in this context + // since that opens up security exploits with delayed event + // handler compilation on stale DOM objects (objects that live in + // a document that has already been unloaded). + nsCOMPtr prin; + nsresult rv = sSecurityManager->GetObjectPrincipal(mContext, target, + getter_AddRefs(prin)); + NS_ENSURE_SUCCESS(rv, rv); + + prin->GetJSPrincipals(&jsprin); + NS_ENSURE_TRUE(jsprin, NS_ERROR_NOT_AVAILABLE); } char charName[64]; AtomToEventHandlerName(aName, charName, sizeof charName); - JSObject *target = (JSObject*)aTarget; JSFunction* fun = ::JS_CompileUCFunctionForPrincipals(mContext, target, jsprin, charName, 1, gEventArgv, @@ -957,10 +969,12 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName, //XXXbe filename, lineno: nsnull, 0); - if (jsprin) + if (jsprin) { JSPRINCIPALS_DROP(mContext, jsprin); - if (!fun) + } + if (!fun) { return NS_ERROR_FAILURE; + } JSObject *handler = ::JS_GetFunctionObject(fun); if (aHandler) @@ -1522,14 +1536,12 @@ nsJSContext::ScriptEvaluated(PRBool aTerminated) NS_IMETHODIMP nsJSContext::GetSecurityManager(nsIScriptSecurityManager **aInstancePtr) { - if (!mSecurityManager) { - nsresult rv = NS_OK; + *aInstancePtr = sSecurityManager; - mSecurityManager = do_GetService(kScriptSecurityManagerContractID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + if (!sSecurityManager) { + return NS_ERROR_NOT_AVAILABLE; } - *aInstancePtr = mSecurityManager; NS_ADDREF(*aInstancePtr); return NS_OK; @@ -1679,9 +1691,7 @@ nsresult nsJSEnvironment::Init() return NS_OK; } - nsresult rv = nsServiceManager::GetService(kJSRuntimeServiceContractID, - NS_GET_IID(nsIJSRuntimeService), - (nsISupports**)&sRuntimeService); + nsresult rv = CallGetService(kJSRuntimeServiceContractID, &sRuntimeService); // get the JSRuntime from the runtime svc, if possible NS_ENSURE_SUCCESS(rv, rv); @@ -1732,6 +1742,8 @@ nsresult nsJSEnvironment::Init() } #endif /* OJI */ + rv = CallGetService(kScriptSecurityManagerContractID, &sSecurityManager); + isInitialized = NS_SUCCEEDED(rv); return rv; @@ -1754,9 +1766,10 @@ void nsJSEnvironment::ShutDown() if (!sContextCount) { // We're being shutdown, and there are no more contexts - // alive, release the JS runtime service. + // alive, release the JS runtime service and the security manager. NS_IF_RELEASE(sRuntimeService); + NS_IF_RELEASE(sSecurityManager); } sDidShutdown = PR_TRUE; diff --git a/mozilla/dom/src/base/nsJSEnvironment.h b/mozilla/dom/src/base/nsJSEnvironment.h index 7a3be515315..fb76255dc50 100644 --- a/mozilla/dom/src/base/nsJSEnvironment.h +++ b/mozilla/dom/src/base/nsJSEnvironment.h @@ -144,7 +144,6 @@ private: JSContext *mContext; PRUint32 mNumEvaluations; - nsCOMPtr mSecurityManager; // [OWNER] nsIScriptContextOwner* mOwner; /* NB: weak reference, not ADDREF'd */ nsScriptTerminationFunc mTerminationFunc;