Bug 417617 - [p=Olli.Pettay@gmail.com (Smaug) r+sr=jst a=blocking1.9+]

This commit is contained in:
reed%reedloden.com 2008-02-27 02:03:28 +00:00
Родитель 9cfcb8e7fa
Коммит 8bb739557f
3 изменённых файлов: 103 добавлений и 38 удалений

Просмотреть файл

@ -96,6 +96,7 @@ class nsVoidArray;
struct JSRuntime; struct JSRuntime;
class nsICaseConversion; class nsICaseConversion;
class nsIWidget; class nsIWidget;
class nsPIDOMWindow;
#ifdef MOZ_XTF #ifdef MOZ_XTF
class nsIXTFService; class nsIXTFService;
#endif #endif
@ -371,6 +372,10 @@ public:
// Check if the (JS) caller can access aNode. // Check if the (JS) caller can access aNode.
static PRBool CanCallerAccess(nsIDOMNode *aNode); static PRBool CanCallerAccess(nsIDOMNode *aNode);
// Check if the (JS) caller can access aWindow.
// aWindow can be either outer or inner window.
static PRBool CanCallerAccess(nsPIDOMWindow* aWindow);
/** /**
* Get the docshell through the JS context that's currently on the stack. * Get the docshell through the JS context that's currently on the stack.
* If there's no JS context currently on the stack aDocShell will be null. * If there's no JS context currently on the stack aDocShell will be null.
@ -1188,6 +1193,9 @@ private:
PR_STATIC_CALLBACK(void) DropScriptObject(PRUint32 aLangID, void *aObject, PR_STATIC_CALLBACK(void) DropScriptObject(PRUint32 aLangID, void *aObject,
void *aClosure); void *aClosure);
static PRBool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
nsIPrincipal* aPrincipal);
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory; static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
static nsIXPConnect *sXPConnect; static nsIXPConnect *sXPConnect;

Просмотреть файл

@ -148,6 +148,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIPrivateDOMEvent.h" #include "nsIPrivateDOMEvent.h"
#include "nsXULPopupManager.h" #include "nsXULPopupManager.h"
#include "nsIPermissionManager.h" #include "nsIPermissionManager.h"
#include "nsIScriptObjectPrincipal.h"
#ifdef IBMBIDI #ifdef IBMBIDI
#include "nsIBidiKeyboard.h" #include "nsIBidiKeyboard.h"
@ -890,6 +891,31 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
return NS_OK; return NS_OK;
} }
// static
PRBool
nsContentUtils::CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
nsIPrincipal* aPrincipal)
{
PRBool subsumes;
nsresult rv = aSubjectPrincipal->Subsumes(aPrincipal, &subsumes);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
if (subsumes) {
return PR_TRUE;
}
// The subject doesn't subsume aPrincipal. Allow access only if the subject
// has either "UniversalXPConnect" (if aPrincipal is system principal) or
// "UniversalBrowserRead" (in all other cases).
PRBool isSystem;
rv = sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
isSystem = NS_FAILED(rv) || isSystem;
const char* capability =
NS_FAILED(rv) || isSystem ? "UniversalXPConnect" : "UniversalBrowserRead";
return IsCallerTrustedForCapability(capability);
}
// static // static
PRBool PRBool
nsContentUtils::CanCallerAccess(nsIDOMNode *aNode) nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
@ -909,26 +935,31 @@ nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
nsCOMPtr<nsINode> node = do_QueryInterface(aNode); nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, PR_FALSE); NS_ENSURE_TRUE(node, PR_FALSE);
nsIPrincipal* nodePrincipal = node->NodePrincipal(); return CanCallerAccess(subjectPrincipal, node->NodePrincipal());
}
PRBool subsumes; // static
nsresult rv = subjectPrincipal->Subsumes(nodePrincipal, &subsumes); PRBool
NS_ENSURE_SUCCESS(rv, PR_FALSE); nsContentUtils::CanCallerAccess(nsPIDOMWindow* aWindow)
{
// XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
// with the system principal games? But really, there should be a simpler
// API here, dammit.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
if (!subjectPrincipal) {
// we're running as system, grant access to the node.
if (subsumes) {
return PR_TRUE; return PR_TRUE;
} }
// The subject doesn't subsume the node. Allow access only if the subject nsCOMPtr<nsIScriptObjectPrincipal> scriptObject =
// has either "UniversalXPConnect" (if the node has the system principal) or do_QueryInterface(aWindow->IsOuterWindow() ?
// "UniversalBrowserRead" (in all other cases). aWindow->GetCurrentInnerWindow() : aWindow);
PRBool isSystem; NS_ENSURE_TRUE(scriptObject, PR_FALSE);
rv = sSecurityManager->IsSystemPrincipal(nodePrincipal, &isSystem);
isSystem = NS_FAILED(rv) || isSystem;
const char* capability =
NS_FAILED(rv) || isSystem ? "UniversalXPConnect" : "UniversalBrowserRead";
return IsCallerTrustedForCapability(capability); return CanCallerAccess(subjectPrincipal, scriptObject->GetPrincipal());
} }
//static //static

Просмотреть файл

@ -4782,8 +4782,9 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
nsCOMPtr<nsIJSNativeInitializer> initializer(do_QueryInterface(native)); nsCOMPtr<nsIJSNativeInitializer> initializer(do_QueryInterface(native));
if (initializer) { if (initializer) {
nsCOMPtr<nsISupports> owner = do_QueryReferent(aWeakOwner); nsCOMPtr<nsPIDOMWindow> owner = do_QueryReferent(aWeakOwner);
NS_ENSURE_STATE(owner); NS_ENSURE_STATE(owner && owner->GetOuterWindow() &&
owner->GetOuterWindow()->GetCurrentInnerWindow() == owner);
rv = initializer->Initialize(owner, cx, obj, argc, argv); rv = initializer->Initialize(owner, cx, obj, argc, argv);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
@ -4890,16 +4891,23 @@ DefineInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
class nsDOMConstructor : public nsIDOMDOMConstructor class nsDOMConstructor : public nsIDOMDOMConstructor
{ {
public: protected:
nsDOMConstructor(const PRUnichar *aName, nsDOMConstructor(const PRUnichar *aName,
const nsGlobalNameStruct *aNameStruct, const nsGlobalNameStruct *aNameStruct,
nsISupports* aOwner) nsPIDOMWindow* aOwner)
: mClassName(aName), : mClassName(aName),
mConstructable(IsConstructable(aNameStruct)), mConstructable(IsConstructable(aNameStruct)),
mWeakOwner(do_GetWeakReference(aOwner)) mWeakOwner(do_GetWeakReference(aOwner))
{ {
} }
public:
static nsresult Create(const PRUnichar* aName,
const nsGlobalNameStruct* aNameStruct,
nsPIDOMWindow* aOwner,
nsDOMConstructor** aResult);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIDOMDOMCONSTRUCTOR NS_DECL_NSIDOMDOMCONSTRUCTOR
@ -4980,6 +4988,27 @@ private:
nsWeakPtr mWeakOwner; nsWeakPtr mWeakOwner;
}; };
//static
nsresult
nsDOMConstructor::Create(const PRUnichar* aName,
const nsGlobalNameStruct* aNameStruct,
nsPIDOMWindow* aOwner,
nsDOMConstructor** aResult)
{
*aResult = nsnull;
if (!aOwner->IsOuterWindow()) {
*aResult = new nsDOMConstructor(aName, aNameStruct, aOwner);
} else if (!nsContentUtils::CanCallerAccess(aOwner)) {
return NS_ERROR_DOM_SECURITY_ERR;
} else {
*aResult =
new nsDOMConstructor(aName, aNameStruct, aOwner->GetCurrentInnerWindow());
}
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMPL_ADDREF(nsDOMConstructor) NS_IMPL_ADDREF(nsDOMConstructor)
NS_IMPL_RELEASE(nsDOMConstructor) NS_IMPL_RELEASE(nsDOMConstructor)
NS_INTERFACE_MAP_BEGIN(nsDOMConstructor) NS_INTERFACE_MAP_BEGIN(nsDOMConstructor)
@ -5227,14 +5256,13 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// We're resolving a name of a DOM interface for which there is no // We're resolving a name of a DOM interface for which there is no
// direct DOM class, create a constructor object... // direct DOM class, create a constructor object...
nsRefPtr<nsDOMConstructor> constructor = nsRefPtr<nsDOMConstructor> constructor;
new nsDOMConstructor(reinterpret_cast<PRUnichar *> rv = nsDOMConstructor::Create(reinterpret_cast<PRUnichar *>
(::JS_GetStringChars(str)), (::JS_GetStringChars(str)),
name_struct, name_struct,
static_cast<nsPIDOMWindow*>(aWin)); static_cast<nsPIDOMWindow*>(aWin),
if (!constructor) { getter_AddRefs(constructor));
return NS_ERROR_OUT_OF_MEMORY; NS_ENSURE_SUCCESS(rv, rv);
}
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE; sDoSecurityCheckInAddProperty = PR_FALSE;
@ -5292,12 +5320,11 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
const PRUnichar *name = reinterpret_cast<PRUnichar *> const PRUnichar *name = reinterpret_cast<PRUnichar *>
(::JS_GetStringChars(str)); (::JS_GetStringChars(str));
nsRefPtr<nsDOMConstructor> constructor = nsRefPtr<nsDOMConstructor> constructor;
new nsDOMConstructor(name, name_struct, rv = nsDOMConstructor::Create(name, name_struct,
static_cast<nsPIDOMWindow*>(aWin)); static_cast<nsPIDOMWindow*>(aWin),
if (!constructor) { getter_AddRefs(constructor));
return NS_ERROR_OUT_OF_MEMORY; NS_ENSURE_SUCCESS(rv, rv);
}
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE; sDoSecurityCheckInAddProperty = PR_FALSE;
@ -5512,12 +5539,11 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
} }
if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructor) { if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructor) {
nsRefPtr<nsDOMConstructor> constructor = nsRefPtr<nsDOMConstructor> constructor;
new nsDOMConstructor(class_name, name_struct, rv = nsDOMConstructor::Create(class_name, name_struct,
static_cast<nsPIDOMWindow*>(aWin)); static_cast<nsPIDOMWindow*>(aWin),
if (!constructor) { getter_AddRefs(constructor));
return NS_ERROR_OUT_OF_MEMORY; NS_ENSURE_SUCCESS(rv, rv);
}
jsval val; jsval val;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder; nsCOMPtr<nsIXPConnectJSObjectHolder> holder;