Fix bug 657267. r=bz
authorBlake Kaplan <mrbkap@gmail.com>
Thu, 19 May 2011 13:31:54 +0200
changeset 69948 80771239f43051eb37945b3c6121accdeca8b2c0
parent 69947 fc1369652e847a1b094479c852b127f5ef202b0e
child 69949 3b1ffc6d282f2bedf00fd54e6613d36fd93034f6
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs657267
milestone6.0a1
Fix bug 657267. r=bz
caps/idl/nsIPrincipal.idl
caps/include/nsPrincipal.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsSystemPrincipal.cpp
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/xpcinlines.h
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/tests/mochitest/Makefile.in
js/src/xpconnect/tests/mochitest/bug657267.jar
js/src/xpconnect/tests/mochitest/test_bug657267.html
js/src/xpconnect/wrappers/AccessCheck.cpp
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -47,17 +47,17 @@ struct JSPrincipals;
 %}
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 
-[scriptable, uuid(799ab95c-0038-4e0f-b705-74c21f185bb5)]
+[scriptable, uuid(B406A2DB-E547-4C95-B8E2-AD09ECB54CE0)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Values of capabilities for each principal. Order is
      * significant: if an operation is performed on a set
      * of capabilities, the minimum is computed.
      */
     const short ENABLE_DENIED                = 1;
@@ -82,16 +82,21 @@ interface nsIPrincipal : nsISerializable
     /**
      * Returns whether the other principal is equivalent to this principal.
      * Principals are considered equal if they are the same principal,
      * they have the same origin, or have the same certificate fingerprint ID
      */
     boolean equals(in nsIPrincipal other);
 
     /**
+     * Like equals, but doesn't take document.domain changes into account.
+     */
+    boolean equalsIgnoringDomain(in nsIPrincipal other);
+
+    /**
      * Returns a hash value for the principal.
      */
     [noscript] readonly attribute unsigned long hashValue;
 
     /**
      * Returns the JS equivalent of the principal.
      * @see JSPrincipals.h
      */
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -126,16 +126,19 @@ protected:
     nsCOMPtr<nsISupports> cert;
   };
 
   nsresult SetCertificate(const nsACString& aFingerprint,
                           const nsACString& aSubjectName,
                           const nsACString& aPrettyName,
                           nsISupports* aCert);
 
+  // Checks whether this principal's certificate equals aOther's.
+  PRBool CertificateEquals(nsIPrincipal *aOther);
+
   // Keep this is a pointer, even though it may slightly increase the
   // cost of keeping a certificate, this is a good tradeoff though since
   // it is very rare that we actually have a certificate.
   nsAutoPtr<Certificate> mCert;
 
   DomainPolicy* mSecurityPolicy;
 
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -158,16 +158,22 @@ nsNullPrincipal::Equals(nsIPrincipal *aO
 {
   // Just equal to ourselves.  Note that nsPrincipal::Equals will return false
   // for us since we have a unique domain/origin/etc.
   *aResult = (aOther == this);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsNullPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, PRBool *aResult)
+{
+  return Equals(aOther, aResult);
+}
+
+NS_IMETHODIMP
 nsNullPrincipal::GetHashValue(PRUint32 *aResult)
 {
   *aResult = (NS_PTR_TO_INT32(this) >> 2);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNullPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **aJsprin)
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -304,63 +304,74 @@ nsPrincipal::SetSecurityPolicy(void* aSe
  
   if (mSecurityPolicy)
     mSecurityPolicy->Drop();
   
   mSecurityPolicy = newPolicy;
   return NS_OK;
 }
 
+PRBool
+nsPrincipal::CertificateEquals(nsIPrincipal *aOther)
+{
+  PRBool otherHasCert;
+  aOther->GetHasCertificate(&otherHasCert);
+  if (otherHasCert != (mCert != nsnull)) {
+    // One has a cert while the other doesn't.  Not equal.
+    return PR_FALSE;
+  }
+
+  if (!mCert)
+    return PR_TRUE;
+
+  nsCAutoString str;
+  aOther->GetFingerprint(str);
+  if (!str.Equals(mCert->fingerprint))
+    return PR_FALSE;
+
+  // If either subject name is empty, just let the result stand (so that
+  // nsScriptSecurityManager::SetCanEnableCapability works), but if they're
+  // both non-empty, only claim equality if they're equal.
+  if (!mCert->subjectName.IsEmpty()) {
+    // Check the other principal's subject name
+    aOther->GetSubjectName(str);
+    return str.Equals(mCert->subjectName) || str.IsEmpty();
+  }
+
+  return PR_TRUE;
+}
+
 NS_IMETHODIMP
 nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
 {
-  *aResult = PR_FALSE;
-
   if (!aOther) {
     NS_WARNING("Need a principal to compare this to!");
+    *aResult = PR_FALSE;
     return NS_OK;
   }
 
   if (this != aOther) {
-    PRBool otherHasCert;
-    aOther->GetHasCertificate(&otherHasCert);
-    if (otherHasCert != (mCert != nsnull)) {
-      // One has a cert while the other doesn't.  Not equal.
+    if (!CertificateEquals(aOther)) {
+      *aResult = PR_FALSE;
       return NS_OK;
     }
 
     if (mCert) {
-      nsCAutoString str;
-      aOther->GetFingerprint(str);
-      *aResult = str.Equals(mCert->fingerprint);
-
-      // If either subject name is empty, just let the result stand (so that
-      // nsScriptSecurityManager::SetCanEnableCapability works), but if they're
-      // both non-empty, only claim equality if they're equal.
-      if (*aResult && !mCert->subjectName.IsEmpty()) {
-        // Check the other principal's subject name
-        aOther->GetSubjectName(str);
-        *aResult = str.Equals(mCert->subjectName) || str.IsEmpty();
-      }
-
-      if (!*aResult) {
-        return NS_OK;
-      }
-
       // If either principal has no URI, it's the saved principal from
       // preferences; in that case, test true.  Do NOT test true if the two
       // principals have URIs with different codebases.
       nsCOMPtr<nsIURI> otherURI;
       nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
       if (NS_FAILED(rv)) {
         *aResult = PR_FALSE;
         return rv;
       }
 
       if (!otherURI || !mCodebase) {
+        *aResult = PR_TRUE;
         return NS_OK;
       }
 
       // Fall through to the codebase comparison.
     }
 
     // Codebases are equal if they have the same origin.
     *aResult =
@@ -369,16 +380,44 @@ nsPrincipal::Equals(nsIPrincipal *aOther
     return NS_OK;
   }
 
   *aResult = PR_TRUE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, PRBool *aResult)
+{
+  if (this == aOther) {
+    *aResult = PR_TRUE;
+    return NS_OK;
+  }
+
+  *aResult = PR_FALSE;
+  if (!CertificateEquals(aOther)) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIURI> otherURI;
+  nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  NS_ASSERTION(mCodebase,
+               "shouldn't be calling this on principals from preferences");
+
+  // Compare codebases.
+  *aResult = nsScriptSecurityManager::SecurityCompareURIs(mCodebase,
+                                                          otherURI);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsPrincipal::Subsumes(nsIPrincipal *aOther, PRBool *aResult)
 {
   return Equals(aOther, aResult);
 }
 
 static PRBool
 URIIsLocalFile(nsIURI *aURI)
 {
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -106,16 +106,22 @@ nsSystemPrincipal::GetPreferences(char**
 NS_IMETHODIMP
 nsSystemPrincipal::Equals(nsIPrincipal *other, PRBool *result)
 {
     *result = (other == this);
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsSystemPrincipal::EqualsIgnoringDomain(nsIPrincipal *other, PRBool *result)
+{
+    return Equals(other, result);
+}
+
+NS_IMETHODIMP
 nsSystemPrincipal::Subsumes(nsIPrincipal *other, PRBool *result)
 {
     *result = PR_TRUE;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSystemPrincipal::CheckMayLoad(nsIURI* uri, PRBool aReport)
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -1034,27 +1034,22 @@ nsresult
 xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
                        nsIPrincipal *principal, nsISupports *ptr,
                        bool wantXrays, JSObject **global,
                        JSCompartment **compartment)
 {
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "using a principal off the main thread?");
     NS_ABORT_IF_FALSE(principal, "bad key");
 
-    nsCOMPtr<nsIURI> uri;
-    nsresult rv = principal->GetURI(getter_AddRefs(uri));
-    if(NS_FAILED(rv))
-        return UnexpectedFailure(rv);
-
     XPCCompartmentMap& map = nsXPConnect::GetRuntimeInstance()->GetCompartmentMap();
-    xpc::PtrAndPrincipalHashKey key(ptr, uri);
+    xpc::PtrAndPrincipalHashKey key(ptr, principal);
     if(!map.Get(&key, compartment))
     {
         xpc::PtrAndPrincipalHashKey *priv_key =
-            new xpc::PtrAndPrincipalHashKey(ptr, uri);
+            new xpc::PtrAndPrincipalHashKey(ptr, principal);
         xpc::CompartmentPrivate *priv =
             new xpc::CompartmentPrivate(priv_key, wantXrays, NS_IsMainThread());
         if(!CreateNewCompartment(cx, clasp, principal, priv,
                                  global, compartment))
         {
             return UnexpectedFailure(NS_ERROR_FAILURE);
         }
 
--- a/js/src/xpconnect/src/xpcinlines.h
+++ b/js/src/xpconnect/src/xpcinlines.h
@@ -1,9 +1,10 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=79:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -42,24 +43,29 @@
 
 #ifndef xpcinlines_h___
 #define xpcinlines_h___
 
 /***************************************************************************/
 PRBool
 xpc::PtrAndPrincipalHashKey::KeyEquals(const PtrAndPrincipalHashKey* aKey) const
 {
-  if(aKey->mPtr != mPtr)
-    return PR_FALSE;
+    if(aKey->mPtr != mPtr)
+        return PR_FALSE;
+    if(aKey->mPrincipal == mPrincipal)
+        return PR_TRUE;
 
-  if(!mURI || !aKey->mURI)
-      return mURI == aKey->mURI;
+    PRBool equals;
+    if(NS_FAILED(mPrincipal->EqualsIgnoringDomain(aKey->mPrincipal, &equals)))
+    {
+        NS_ERROR("we failed, guessing!");
+        return PR_FALSE;
+    }
 
-  nsIScriptSecurityManager *ssm = nsXPConnect::gScriptSecurityManager;
-  return !ssm || NS_SUCCEEDED(ssm->CheckSameOriginURI(mURI, aKey->mURI, PR_FALSE));
+    return equals;
 }
 
 inline void
 XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
 {
     variant->AddToRootSet(GetMapLock(), &mVariantRoots);
 }
 
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -242,27 +242,30 @@ namespace xpc {
 
 class PtrAndPrincipalHashKey : public PLDHashEntryHdr
 {
   public:
     typedef PtrAndPrincipalHashKey *KeyType;
     typedef const PtrAndPrincipalHashKey *KeyTypePointer;
 
     PtrAndPrincipalHashKey(const PtrAndPrincipalHashKey *aKey)
-      : mPtr(aKey->mPtr), mURI(aKey->mURI), mSavedHash(aKey->mSavedHash)
+      : mPtr(aKey->mPtr), mPrincipal(aKey->mPrincipal),
+        mSavedHash(aKey->mSavedHash)
     {
         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
     }
 
-    PtrAndPrincipalHashKey(nsISupports *aPtr, nsIURI *aURI)
-      : mPtr(aPtr), mURI(aURI)
+    PtrAndPrincipalHashKey(nsISupports *aPtr, nsIPrincipal *aPrincipal)
+      : mPtr(aPtr), mPrincipal(aPrincipal)
     {
         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
-        mSavedHash = mURI
-                     ? NS_SecurityHashURI(mURI)
+        nsCOMPtr<nsIURI> uri;
+        aPrincipal->GetURI(getter_AddRefs(uri));
+        mSavedHash = uri
+                     ? NS_SecurityHashURI(uri)
                      : (NS_PTR_TO_UINT32(mPtr.get()) >> 2);
     }
 
     ~PtrAndPrincipalHashKey()
     {
         MOZ_COUNT_DTOR(PtrAndPrincipalHashKey);
     }
 
@@ -280,17 +283,17 @@ class PtrAndPrincipalHashKey : public PL
     {
         return aKey->mSavedHash;
     }
 
     enum { ALLOW_MEMMOVE = PR_TRUE };
 
   protected:
     nsCOMPtr<nsISupports> mPtr;
-    nsCOMPtr<nsIURI> mURI;
+    nsCOMPtr<nsIPrincipal> mPrincipal;
 
     // During shutdown, when we GC, we need to remove these keys from the hash
     // table. However, computing the saved hash, NS_SecurityHashURI calls back
     // into XPCOM (which is illegal during shutdown). In order to avoid this,
     // we compute the hash up front, so when we're in GC during shutdown, we
     // don't have to call into XPCOM.
     PLDHashNumber mSavedHash;
 };
--- a/js/src/xpconnect/tests/mochitest/Makefile.in
+++ b/js/src/xpconnect/tests/mochitest/Makefile.in
@@ -86,14 +86,16 @@ include $(topsrcdir)/config/rules.mk
 		file2_bug629227.html \
 		test_bug629331.html \
 		test1_bug629331.html \
 		test2_bug629331.html \
 		test_bug618017.html \
 		test_bug636097.html \
 		test_bug650273.html \
 		file_bug650273.html \
+		test_bug657267.html \
+		bug657267.jar \
 		$(NULL)
 
 		#test_bug484107.html \
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
index 0000000000000000000000000000000000000000..a4d72515fe6371fbe9b9070eabe96a6902007bc1
GIT binary patch
literal 2251
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
ZyqFbB*cRh4n3WBrnH31Pf=pls@c_vpcLe|d
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/mochitest/test_bug657267.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=657267
+-->
+<head>
+  <title>Test for Bug 657267</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank"
+href="https://bugzilla.mozilla.org/show_bug.cgi?id=657267">Mozilla Bug 657267</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 657267 **/
+function go() {
+    var win = $('ifr').contentWindow;
+    try {
+        win.a();
+        var thrown = false;
+    } catch (e) {
+        thrown = /Permission denied/i.test(e);
+    }
+    ok(thrown, "Should have thrown");
+}
+
+</script>
+</pre>
+
+<iframe src="jar:http://mochi.test:8888/tests/js/src/xpconnect/tests/mochitest/bug657267.jar!/file_bug657267.html"
+        id="ifr"
+        onload="go()">
+</iframe>
+</body>
+</html>
--- a/js/src/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/src/xpconnect/wrappers/AccessCheck.cpp
@@ -67,27 +67,24 @@ AccessCheck::isSameOrigin(JSCompartment 
     nsIPrincipal *bprin = GetCompartmentPrincipal(b);
 
     // If either a or b doesn't have principals, we don't have enough
     // information to tell. Seeing as how this is Gecko, we are default-unsafe
     // in this case.
     if (!aprin || !bprin)
         return true;
 
-    nsCOMPtr<nsIURI> auri;
-    aprin->GetURI(getter_AddRefs(auri));
-
-    nsCOMPtr<nsIURI> buri;
-    bprin->GetURI(getter_AddRefs(buri));
+    PRBool equals;
+    nsresult rv = aprin->EqualsIgnoringDomain(bprin, &equals);
+    if (NS_FAILED(rv)) {
+        NS_ERROR("unable to ask about equality");
+        return false;
+    }
 
-    if (!auri || !buri)
-        return aprin == bprin;
-
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    return !ssm || NS_SUCCEEDED(ssm->CheckSameOriginURI(auri, buri, PR_FALSE));
+    return equals;
 }
 
 bool
 AccessCheck::isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper)
 {
     JSObject *obj = wrapper->unwrap()->getParent();
     if (!obj->getClass()->ext.innerObject) {
         obj = obj->unwrap();