Bug 1038756: Callsites creating a channel in /dom/xbl/ (r=bz)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Sun, 21 Sep 2014 09:38:38 -0700
changeset 206506 b968440b6204d0664cfe025c3fc6d2c31deddb38
parent 206505 a12b926cff35925c4a037114aa2e05fa43edac60
child 206507 5609cb03aaccbf31e24c13cbd0f7d2dd1ce9aeb4
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs1038756
milestone35.0a1
Bug 1038756: Callsites creating a channel in /dom/xbl/ (r=bz)
dom/xbl/nsXBLService.cpp
dom/xbl/nsXBLService.h
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -989,17 +989,18 @@ nsXBLService::LoadBindingDocumentInfo(ns
 
       // Always load chrome synchronously
       bool chrome;
       if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome)
         aForceSyncLoad = true;
 
       nsCOMPtr<nsIDocument> document;
       FetchBindingDocument(aBoundElement, aBoundDocument, documentURI,
-                           aBindingURI, aForceSyncLoad, getter_AddRefs(document));
+                           aBindingURI, aOriginPrincipal, aForceSyncLoad,
+                           getter_AddRefs(document));
 
       if (document) {
         nsBindingManager *xblDocBindingManager = document->BindingManager();
         info = xblDocBindingManager->GetXBLDocumentInfo(documentURI);
         if (!info) {
           NS_ERROR("An XBL file is malformed.  Did you forget the XBL namespace on the bindings tag?");
           return NS_ERROR_FAILURE;
         }
@@ -1026,17 +1027,18 @@ nsXBLService::LoadBindingDocumentInfo(ns
   info.forget(aResult);
 
   return NS_OK;
 }
 
 nsresult
 nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
                                    nsIURI* aDocumentURI, nsIURI* aBindingURI,
-                                   bool aForceSyncLoad, nsIDocument** aResult)
+                                   nsIPrincipal* aOriginPrincipal, bool aForceSyncLoad,
+                                   nsIDocument** aResult)
 {
   nsresult rv = NS_OK;
   // Initialize our out pointer to nullptr
   *aResult = nullptr;
 
   // Now we have to synchronously load the binding file.
   // Create an XML content sink and a parser.
   nsCOMPtr<nsILoadGroup> loadGroup;
@@ -1053,18 +1055,35 @@ nsXBLService::FetchBindingDocument(nsICo
   rv = NS_NewXMLDocument(getter_AddRefs(doc));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIXMLContentSink> xblSink;
   rv = NS_NewXBLContentSink(getter_AddRefs(xblSink), doc, aDocumentURI, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Open channel
+  // Note: There are some cases where aOriginPrincipal and aBoundDocument are purposely
+  // set to null (to bypass security checks) when calling LoadBindingDocumentInfo() which calls
+  // FetchBindingDocument().  LoadInfo will end up with no principal or node in those cases,
+  // so we use systemPrincipal.  This achieves the same result of bypassing security checks,
+  // but it gives the wrong information to potential future consumers of loadInfo.
+  nsCOMPtr<nsIPrincipal> requestingPrincipal = aOriginPrincipal ? aOriginPrincipal
+                                                                : nsContentUtils::GetSystemPrincipal();
   nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewChannel(getter_AddRefs(channel), aDocumentURI, nullptr, loadGroup);
+  // Note that we are calling NS_NewChannelInternal here with both a node and a principal.
+  // This is because the principal and node could be different.
+  rv = NS_NewChannelInternal(getter_AddRefs(channel),
+                             aDocumentURI,
+                             aBoundDocument,
+                             requestingPrincipal,
+                             nsILoadInfo::SEC_NORMAL,
+                             nsIContentPolicy::TYPE_OTHER,
+                             nullptr,   // aChannelPolicy
+                             loadGroup);
+
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIInterfaceRequestor> sameOriginChecker = nsContentUtils::GetSameOriginChecker();
   NS_ENSURE_TRUE(sameOriginChecker, NS_ERROR_OUT_OF_MEMORY);
 
   channel->SetNotificationCallbacks(sameOriginChecker);
 
   if (!aForceSyncLoad) {
--- a/dom/xbl/nsXBLService.h
+++ b/dom/xbl/nsXBLService.h
@@ -73,17 +73,18 @@ private:
 
 protected:
   // This function clears out the bindings on a given content node.
   nsresult FlushStyleBindings(nsIContent* aContent);
 
   // This method synchronously loads and parses an XBL file.
   nsresult FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
                                 nsIURI* aDocumentURI, nsIURI* aBindingURI,
-                                bool aForceSyncLoad, nsIDocument** aResult);
+                                nsIPrincipal* aOriginPrincipal, bool aForceSyncLoad,
+                                nsIDocument** aResult);
 
   /**
    * This method calls the one below with an empty |aDontExtendURIs| array.
    */
   nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
                       bool aPeekFlag, nsIPrincipal* aOriginPrincipal,
                       bool* aIsReady, nsXBLBinding** aResult);