Bug 716754 - 'Crash when accessing navigator.mozTelephony from chrome page'. r=sicking.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 11 Jan 2012 18:19:53 -0800
changeset 85550 4abbedf5b4ca3e532f84c7c020fa2629f6e542e1
parent 85549 ebb34e2325778e6be9d312c7619e25585bc7561f
child 85551 a9eb2cfdebd81907d14f0a4f35c3cfd2679a1bad
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs716754
milestone12.0a1
Bug 716754 - 'Crash when accessing navigator.mozTelephony from chrome page'. r=sicking.
dom/telephony/Telephony.cpp
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -429,41 +429,56 @@ NS_NewTelephony(nsPIDOMWindow* aWindow, 
   NS_ASSERTION(aWindow, "Null pointer!");
 
   // Make sure we're dealing with an inner window.
   nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
                                aWindow :
                                aWindow->GetCurrentInnerWindow();
   NS_ENSURE_TRUE(innerWindow, NS_ERROR_FAILURE);
 
+  // Make sure we're being called from a window that we have permission to
+  // access.
   if (!nsContentUtils::CanCallerAccess(innerWindow)) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
+  // Need the document in order to make security decisions.
   nsCOMPtr<nsIDocument> document =
     do_QueryInterface(innerWindow->GetExtantDocument());
   NS_ENSURE_TRUE(document, NS_NOINTERFACE);
 
-  nsCOMPtr<nsIURI> documentURI;
-  nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(documentURI));
-  NS_ENSURE_SUCCESS(rv, rv);
+  // Do security checks. We assume that chrome is always allowed and we also
+  // allow a single page specified by preferences.
+  if (!nsContentUtils::IsSystemPrincipal(document->NodePrincipal())) {
+    nsCOMPtr<nsIURI> documentURI;
+    nsresult rv =
+      document->NodePrincipal()->GetURI(getter_AddRefs(documentURI));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCString documentURL;
-  rv = documentURI->GetSpec(documentURL);
-  NS_ENSURE_SUCCESS(rv, rv);
+    nsCString documentURL;
+    rv = documentURI->GetSpec(documentURL);
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCString phoneAppURL;
-  rv = Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF, &phoneAppURL);
-  NS_ENSURE_SUCCESS(rv, rv);
+    // The pref may not exist but in that case we deny access just as we do if
+    // the url doesn't match.
+    nsCString phoneAppURL;
+    if (NS_FAILED(Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF,
+                                          &phoneAppURL)) ||
+        !phoneAppURL.Equals(documentURL,
+                            nsCaseInsensitiveCStringComparator())) {
+      *aTelephony = nsnull;
+      return NS_OK;
+    }
+  }
 
-  nsRefPtr<Telephony> telephony;
-  if (phoneAppURL.Equals(documentURL, nsCaseInsensitiveCStringComparator())) {
-    nsIInterfaceRequestor* ireq = SystemWorkerManager::GetInterfaceRequestor();
-    NS_ENSURE_TRUE(ireq, NS_ERROR_UNEXPECTED);
+  // Security checks passed, make a telephony object.
+  nsIInterfaceRequestor* ireq = SystemWorkerManager::GetInterfaceRequestor();
+  NS_ENSURE_TRUE(ireq, NS_ERROR_UNEXPECTED);
 
-    nsCOMPtr<nsITelephone> telephone = do_GetInterface(ireq);
-    NS_ENSURE_TRUE(telephone, NS_ERROR_UNEXPECTED);
+  nsCOMPtr<nsITelephone> telephone = do_GetInterface(ireq);
+  NS_ENSURE_TRUE(telephone, NS_ERROR_UNEXPECTED);
 
-    telephony = Telephony::Create(innerWindow, telephone);
-  }
+  nsRefPtr<Telephony> telephony = Telephony::Create(innerWindow, telephone);
+  NS_ENSURE_TRUE(telephony, NS_ERROR_UNEXPECTED);
+
   telephony.forget(aTelephony);
   return NS_OK;
 }