mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 871262 - Fix rooting hazards in the CAPS code; r=till
This commit is contained in:
parent
c2468980c6
commit
b4be6ea2b3
@ -409,7 +409,8 @@ private:
|
||||
uint32_t aAction);
|
||||
|
||||
nsresult
|
||||
LookupPolicy(nsIPrincipal* principal,
|
||||
LookupPolicy(JSContext* cx,
|
||||
nsIPrincipal* principal,
|
||||
ClassInfoData& aClassData, jsid aProperty,
|
||||
uint32_t aAction,
|
||||
ClassPolicy** aCachedClassPolicy,
|
||||
|
@ -91,8 +91,9 @@ nsScriptSecurityManager::SubjectIsPrivileged()
|
||||
///////////////////////////
|
||||
// Result of this function should not be freed.
|
||||
static inline const PRUnichar *
|
||||
IDToString(JSContext *cx, jsid id)
|
||||
IDToString(JSContext *cx, jsid id_)
|
||||
{
|
||||
JS::RootedId id(cx, id_);
|
||||
if (JSID_IS_STRING(id))
|
||||
return JS_GetInternedStringChars(JSID_TO_STRING(id));
|
||||
|
||||
@ -610,6 +611,8 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
void** aCachedClassPolicy)
|
||||
{
|
||||
nsresult rv;
|
||||
JS::RootedObject jsObject(cx, aJSObject);
|
||||
JS::RootedId property(cx, aProperty);
|
||||
nsIPrincipal* subjectPrincipal = GetSubjectPrincipal(cx, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -626,13 +629,13 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
|
||||
//-- Look up the security policy for this class and subject domain
|
||||
SecurityLevel securityLevel;
|
||||
rv = LookupPolicy(subjectPrincipal, classInfoData, aProperty, aAction,
|
||||
rv = LookupPolicy(cx, subjectPrincipal, classInfoData, property, aAction,
|
||||
(ClassPolicy**)aCachedClassPolicy, &securityLevel);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (securityLevel.level == SCRIPT_SECURITY_UNDEFINED_ACCESS)
|
||||
{
|
||||
{
|
||||
// No policy found for this property so use the default of last resort.
|
||||
// If we were called from somewhere other than XPConnect
|
||||
// (no XPC call context), assume this is a DOM class. Otherwise,
|
||||
@ -659,9 +662,9 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
case SCRIPT_SECURITY_SAME_ORIGIN_ACCESS:
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> principalHolder;
|
||||
if(aJSObject)
|
||||
if (jsObject)
|
||||
{
|
||||
objectPrincipal = doGetObjectPrincipal(aJSObject);
|
||||
objectPrincipal = doGetObjectPrincipal(jsObject);
|
||||
if (!objectPrincipal)
|
||||
rv = NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
@ -703,7 +706,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
const nsIID* objIID = nullptr;
|
||||
rv = aCallContext->GetCalleeWrapper(getter_AddRefs(wrapper));
|
||||
if (NS_SUCCEEDED(rv) && wrapper)
|
||||
rv = wrapper->FindInterfaceWithMember(aProperty, getter_AddRefs(interfaceInfo));
|
||||
rv = wrapper->FindInterfaceWithMember(property, getter_AddRefs(interfaceInfo));
|
||||
if (NS_SUCCEEDED(rv) && interfaceInfo)
|
||||
rv = interfaceInfo->GetIIDShared(&objIID);
|
||||
if (NS_SUCCEEDED(rv) && objIID)
|
||||
@ -712,22 +715,22 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
{
|
||||
case nsIXPCSecurityManager::ACCESS_GET_PROPERTY:
|
||||
checkedComponent->CanGetProperty(objIID,
|
||||
IDToString(cx, aProperty),
|
||||
IDToString(cx, property),
|
||||
getter_Copies(objectSecurityLevel));
|
||||
break;
|
||||
case nsIXPCSecurityManager::ACCESS_SET_PROPERTY:
|
||||
checkedComponent->CanSetProperty(objIID,
|
||||
IDToString(cx, aProperty),
|
||||
IDToString(cx, property),
|
||||
getter_Copies(objectSecurityLevel));
|
||||
break;
|
||||
case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
|
||||
checkedComponent->CanCallMethod(objIID,
|
||||
IDToString(cx, aProperty),
|
||||
IDToString(cx, property),
|
||||
getter_Copies(objectSecurityLevel));
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = CheckXPCPermissions(cx, aObj, aJSObject, subjectPrincipal,
|
||||
rv = CheckXPCPermissions(cx, aObj, jsObject, subjectPrincipal,
|
||||
objectSecurityLevel);
|
||||
|
||||
if (NS_FAILED(rv)) //-- Security tests failed, access is denied, report error
|
||||
@ -791,7 +794,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
{
|
||||
subjectOriginUnicode.get(),
|
||||
className.get(),
|
||||
IDToString(cx, aProperty),
|
||||
IDToString(cx, property),
|
||||
objectOriginUnicode.get(),
|
||||
subjectDomainUnicode.get(),
|
||||
objectDomainUnicode.get()
|
||||
@ -969,7 +972,8 @@ nsScriptSecurityManager::CheckSameOriginDOMProp(nsIPrincipal* aSubject,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
|
||||
nsScriptSecurityManager::LookupPolicy(JSContext* cx,
|
||||
nsIPrincipal* aPrincipal,
|
||||
ClassInfoData& aClassData,
|
||||
jsid aProperty,
|
||||
uint32_t aAction,
|
||||
@ -977,6 +981,7 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
|
||||
SecurityLevel* result)
|
||||
{
|
||||
nsresult rv;
|
||||
JS::RootedId property(cx, aProperty);
|
||||
result->level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
|
||||
|
||||
DomainPolicy* dpolicy = nullptr;
|
||||
@ -1083,14 +1088,14 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
|
||||
*aCachedClassPolicy = cpolicy;
|
||||
}
|
||||
|
||||
NS_ASSERTION(JSID_IS_INT(aProperty) || JSID_IS_OBJECT(aProperty) ||
|
||||
JSID_IS_STRING(aProperty), "Property must be a valid id");
|
||||
NS_ASSERTION(JSID_IS_INT(property) || JSID_IS_OBJECT(property) ||
|
||||
JSID_IS_STRING(property), "Property must be a valid id");
|
||||
|
||||
// Only atomized strings are stored in the policies' hash tables.
|
||||
if (!JSID_IS_STRING(aProperty))
|
||||
if (!JSID_IS_STRING(property))
|
||||
return NS_OK;
|
||||
|
||||
JSString *propertyKey = JSID_TO_STRING(aProperty);
|
||||
JS::RootedString propertyKey(cx, JSID_TO_STRING(property));
|
||||
|
||||
// We look for a PropertyPolicy in the following places:
|
||||
// 1) The ClassPolicy for our class we got from our DomainPolicy
|
||||
@ -1443,8 +1448,9 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
ClassInfoData nameData(nullptr, loadURIPrefGroup);
|
||||
|
||||
SecurityLevel secLevel;
|
||||
rv = LookupPolicy(aPrincipal, nameData, sEnabledID,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
rv = LookupPolicy(GetCurrentJSContext(),
|
||||
aPrincipal, nameData, sEnabledID,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
nullptr, &secLevel);
|
||||
if (NS_SUCCEEDED(rv) && secLevel.level == SCRIPT_SECURITY_ALL_ACCESS)
|
||||
{
|
||||
@ -1748,8 +1754,8 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
|
||||
ClassInfoData nameData(nullptr, jsPrefGroupName);
|
||||
|
||||
SecurityLevel secLevel;
|
||||
rv = LookupPolicy(aPrincipal, nameData, sEnabledID,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
rv = LookupPolicy(cx, aPrincipal, nameData, sEnabledID,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
nullptr, &secLevel);
|
||||
if (NS_FAILED(rv) || secLevel.level == SCRIPT_SECURITY_NO_ACCESS)
|
||||
{
|
||||
@ -2052,31 +2058,32 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
|
||||
NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
|
||||
nsIPrincipal* result = nullptr;
|
||||
|
||||
JSObject* origObj = aObj;
|
||||
js::Class *jsClass = js::GetObjectClass(aObj);
|
||||
JS::RootedObject obj(sXPConnect->GetCurrentJSContext(), aObj);
|
||||
JSObject* origObj = obj;
|
||||
js::Class *jsClass = js::GetObjectClass(obj);
|
||||
|
||||
// A common case seen in this code is that we enter this function
|
||||
// with aObj being a Function object, whose parent is a Call
|
||||
// with obj being a Function object, whose parent is a Call
|
||||
// object. Neither of those have object principals, so we can skip
|
||||
// those objects here before we enter the below loop. That way we
|
||||
// avoid wasting time checking properties of their classes etc in
|
||||
// the loop.
|
||||
|
||||
if (jsClass == &js::FunctionClass) {
|
||||
aObj = js::GetObjectParent(aObj);
|
||||
obj = js::GetObjectParent(obj);
|
||||
|
||||
if (!aObj)
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
jsClass = js::GetObjectClass(aObj);
|
||||
jsClass = js::GetObjectClass(obj);
|
||||
|
||||
if (jsClass == &js::CallClass) {
|
||||
aObj = js::GetObjectParentMaybeScope(aObj);
|
||||
obj = js::GetObjectParentMaybeScope(obj);
|
||||
|
||||
if (!aObj)
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
jsClass = js::GetObjectClass(aObj);
|
||||
jsClass = js::GetObjectClass(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2085,7 +2092,7 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
|
||||
// *end* of this loop.
|
||||
|
||||
if (IS_WRAPPER_CLASS(jsClass)) {
|
||||
result = sXPConnect->GetPrincipal(aObj,
|
||||
result = sXPConnect->GetPrincipal(obj,
|
||||
aAllowShortCircuit);
|
||||
if (result) {
|
||||
break;
|
||||
@ -2094,8 +2101,8 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
|
||||
nsISupports *priv;
|
||||
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
|
||||
priv = (nsISupports *) js::GetObjectPrivate(aObj);
|
||||
} else if (!UnwrapDOMObjectToISupports(aObj, priv)) {
|
||||
priv = (nsISupports *) js::GetObjectPrivate(obj);
|
||||
} else if (!UnwrapDOMObjectToISupports(obj, priv)) {
|
||||
priv = nullptr;
|
||||
}
|
||||
|
||||
@ -2121,12 +2128,12 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
|
||||
}
|
||||
}
|
||||
|
||||
aObj = js::GetObjectParentMaybeScope(aObj);
|
||||
obj = js::GetObjectParentMaybeScope(obj);
|
||||
|
||||
if (!aObj)
|
||||
if (!obj)
|
||||
break;
|
||||
|
||||
jsClass = js::GetObjectClass(aObj);
|
||||
jsClass = js::GetObjectClass(obj);
|
||||
} while (1);
|
||||
|
||||
if (aAllowShortCircuit) {
|
||||
@ -2266,6 +2273,7 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext* cx,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
const char* aObjectSecurityLevel)
|
||||
{
|
||||
JS::RootedObject jsObject(cx, aJSObject);
|
||||
// Check if the subject is privileged.
|
||||
if (SubjectIsPrivileged())
|
||||
return NS_OK;
|
||||
@ -2278,13 +2286,13 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext* cx,
|
||||
if (cx && PL_strcasecmp(aObjectSecurityLevel, "sameOrigin") == 0)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!aJSObject)
|
||||
if (!jsObject)
|
||||
{
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> xpcwrappedjs =
|
||||
do_QueryInterface(aObj);
|
||||
if (xpcwrappedjs)
|
||||
{
|
||||
rv = xpcwrappedjs->GetJSObject(&aJSObject);
|
||||
rv = xpcwrappedjs->GetJSObject(jsObject.address());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
@ -2295,9 +2303,9 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext* cx,
|
||||
aSubjectPrincipal = GetSubjectPrincipal(cx, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (aSubjectPrincipal && aJSObject)
|
||||
if (aSubjectPrincipal && jsObject)
|
||||
{
|
||||
nsIPrincipal* objectPrincipal = doGetObjectPrincipal(aJSObject);
|
||||
nsIPrincipal* objectPrincipal = doGetObjectPrincipal(jsObject);
|
||||
|
||||
// Only do anything if we have both a subject and object
|
||||
// principal.
|
||||
|
Loading…
Reference in New Issue
Block a user