Bug 1010434 - NeckoParent matches a wrong app for the request of a new RemoteOpenFile. r=bent
authorJason Duell <jduell.mcbugs@gmail.com>
Fri, 30 May 2014 12:50:51 -0700
changeset 198435 ed3a1590134957c7fe576bd97644f463a34f5d25
parent 198434 9d19364fe875a7b8f3961e0f0e6b790770f1e05b
child 198436 dc79f34a19f10a21bee9a1dff85bbc9d5615af88
push idunknown
push userunknown
push dateunknown
reviewersbent
bugs1010434
milestone32.0a1
Bug 1010434 - NeckoParent matches a wrong app for the request of a new RemoteOpenFile. r=bent
modules/libjar/nsJARChannel.cpp
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/ipc/RemoteOpenFileChild.cpp
netwerk/ipc/RemoteOpenFileChild.h
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -370,18 +370,21 @@ nsJARChannel::LookupFile()
                 // JarHandler will trigger OnRemoteFileOpen() after the first
                 // request for this file completes and we'll get a JAR cache
                 // hit.
                 return NS_OK;
             }
 
             // Open file on parent: OnRemoteFileOpenComplete called when done
             nsCOMPtr<nsITabChild> tabChild;
-            NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, tabChild);
-            rv = remoteFile->AsyncRemoteFileOpen(PR_RDONLY, this, tabChild.get());
+            NS_QueryNotificationCallbacks(this, tabChild);
+            nsCOMPtr<nsILoadContext> loadContext;
+            NS_QueryNotificationCallbacks(this, loadContext);
+            rv = remoteFile->AsyncRemoteFileOpen(PR_RDONLY, this, tabChild,
+                                                 loadContext);
             NS_ENSURE_SUCCESS(rv, rv);
         }
     }
     // try to handle a nested jar
     if (!mJarFile) {
         nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(mJarBaseURI);
         if (jarURI) {
             nsCOMPtr<nsIFileURL> fileURL;
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -264,17 +264,19 @@ bool
 NeckoChild::DeallocPDNSRequestChild(PDNSRequestChild* aChild)
 {
   DNSRequestChild *p = static_cast<DNSRequestChild*>(aChild);
   p->ReleaseIPDLReference();
   return true;
 }
 
 PRemoteOpenFileChild*
-NeckoChild::AllocPRemoteOpenFileChild(const URIParams&, const OptionalURIParams&)
+NeckoChild::AllocPRemoteOpenFileChild(const SerializedLoadContext& aSerialized,
+                                      const URIParams&,
+                                      const OptionalURIParams&)
 {
   // We don't allocate here: instead we always use IPDL constructor that takes
   // an existing RemoteOpenFileChild
   NS_NOTREACHED("AllocPRemoteOpenFileChild should not be called on child");
   return nullptr;
 }
 
 bool
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -52,17 +52,18 @@ protected:
   virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aHost,
                                                 const uint16_t& aPort,
                                                 const nsCString& aFilter) MOZ_OVERRIDE;
   virtual bool DeallocPUDPSocketChild(PUDPSocketChild*) MOZ_OVERRIDE;
   virtual PDNSRequestChild* AllocPDNSRequestChild(const nsCString& aHost,
                                                   const uint32_t& aFlags) MOZ_OVERRIDE;
   virtual bool DeallocPDNSRequestChild(PDNSRequestChild*) MOZ_OVERRIDE;
   virtual PRemoteOpenFileChild*
-    AllocPRemoteOpenFileChild(const URIParams&,
+    AllocPRemoteOpenFileChild(const SerializedLoadContext& aSerialized,
+                              const URIParams&,
                               const OptionalURIParams&) MOZ_OVERRIDE;
   virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) MOZ_OVERRIDE;
   virtual PRtspControllerChild* AllocPRtspControllerChild() MOZ_OVERRIDE;
   virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) MOZ_OVERRIDE;
   virtual PRtspChannelChild*
     AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
                            MOZ_OVERRIDE;
   virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) MOZ_OVERRIDE;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -495,17 +495,18 @@ bool
 NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent)
 {
   DNSRequestParent *p = static_cast<DNSRequestParent*>(aParent);
   p->Release();
   return true;
 }
 
 PRemoteOpenFileParent*
-NeckoParent::AllocPRemoteOpenFileParent(const URIParams& aURI,
+NeckoParent::AllocPRemoteOpenFileParent(const SerializedLoadContext& aSerialized,
+                                        const URIParams& aURI,
                                         const OptionalURIParams& aAppURI)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
   if (!fileURL) {
     return nullptr;
   }
 
@@ -518,27 +519,31 @@ NeckoParent::AllocPRemoteOpenFileParent(
     }
     bool haveValidBrowser = false;
     bool hasManage = false;
     nsCOMPtr<mozIApplication> mozApp;
     for (uint32_t i = 0; i < Manager()->ManagedPBrowserParent().Length(); i++) {
       nsRefPtr<TabParent> tabParent =
         static_cast<TabParent*>(Manager()->ManagedPBrowserParent()[i]);
       uint32_t appId = tabParent->OwnOrContainingAppId();
-      nsresult rv = appsService->GetAppByLocalId(appId, getter_AddRefs(mozApp));
-      if (NS_FAILED(rv) || !mozApp) {
-        continue;
+      // Note: this enforces that SerializedLoadContext.appID is one of the apps
+      // in the child process, but there's currently no way to verify the
+      // request is not from a different app in that process.
+      if (appId == aSerialized.mAppId) {
+        nsresult rv = appsService->GetAppByLocalId(appId, getter_AddRefs(mozApp));
+        if (NS_FAILED(rv) || !mozApp) {
+          break;
+        }
+        rv = mozApp->HasPermission("webapps-manage", &hasManage);
+        if (NS_FAILED(rv)) {
+          break;
+        }
+        haveValidBrowser = true;
+        break;
       }
-      hasManage = false;
-      rv = mozApp->HasPermission("webapps-manage", &hasManage);
-      if (NS_FAILED(rv)) {
-        continue;
-      }
-      haveValidBrowser = true;
-      break;
     }
 
     if (!haveValidBrowser) {
       return nullptr;
     }
 
     nsAutoCString requestedPath;
     fileURL->GetPath(requestedPath);
@@ -616,19 +621,21 @@ NeckoParent::AllocPRemoteOpenFileParent(
     }
   }
 
   RemoteOpenFileParent* parent = new RemoteOpenFileParent(fileURL);
   return parent;
 }
 
 bool
-NeckoParent::RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
-                                            const URIParams& aFileURI,
-                                            const OptionalURIParams& aAppURI)
+NeckoParent::RecvPRemoteOpenFileConstructor(
+                PRemoteOpenFileParent* aActor,
+                const SerializedLoadContext& aSerialized,
+                const URIParams& aFileURI,
+                const OptionalURIParams& aAppURI)
 {
   return static_cast<RemoteOpenFileParent*>(aActor)->OpenSendCloseDelete();
 }
 
 bool
 NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor)
 {
   delete actor;
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -95,23 +95,26 @@ protected:
                       const FTPChannelCreationArgs& aOpenArgs) MOZ_OVERRIDE;
   virtual bool DeallocPFTPChannelParent(PFTPChannelParent*) MOZ_OVERRIDE;
   virtual PWebSocketParent*
     AllocPWebSocketParent(PBrowserParent* browser,
                           const SerializedLoadContext& aSerialized) MOZ_OVERRIDE;
   virtual bool DeallocPWebSocketParent(PWebSocketParent*) MOZ_OVERRIDE;
   virtual PTCPSocketParent* AllocPTCPSocketParent() MOZ_OVERRIDE;
 
-  virtual PRemoteOpenFileParent* AllocPRemoteOpenFileParent(const URIParams& aFileURI,
-                                                            const OptionalURIParams& aAppURI)
-                                                            MOZ_OVERRIDE;
-  virtual bool RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
-                                              const URIParams& aFileURI,
-                                              const OptionalURIParams& aAppURI)
-                                              MOZ_OVERRIDE;
+  virtual PRemoteOpenFileParent*
+    AllocPRemoteOpenFileParent(const SerializedLoadContext& aSerialized,
+                               const URIParams& aFileURI,
+                               const OptionalURIParams& aAppURI) MOZ_OVERRIDE;
+  virtual bool
+    RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
+                                   const SerializedLoadContext& aSerialized,
+                                   const URIParams& aFileURI,
+                                   const OptionalURIParams& aAppURI)
+                                   MOZ_OVERRIDE;
   virtual bool DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* aActor)
                                             MOZ_OVERRIDE;
 
   virtual bool DeallocPTCPSocketParent(PTCPSocketParent*) MOZ_OVERRIDE;
   virtual PTCPServerSocketParent*
     AllocPTCPServerSocketParent(const uint16_t& aLocalPort,
                                 const uint16_t& aBacklog,
                                 const nsString& aBinaryType) MOZ_OVERRIDE;
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -63,17 +63,19 @@ parent:
               FTPChannelCreationArgs args);
 
   PWebSocket(PBrowser browser, SerializedLoadContext loadContext);
   PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
   PUDPSocket(nsCString host, uint16_t port, nsCString filter);
 
   PDNSRequest(nsCString hostName, uint32_t flags);
 
-  PRemoteOpenFile(URIParams fileuri, OptionalURIParams appuri);
+  PRemoteOpenFile(SerializedLoadContext loadContext,
+                  URIParams fileuri,
+                  OptionalURIParams appuri);
 
   HTMLDNSPrefetch(nsString hostname, uint16_t flags);
   CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
   PRtspController();
   PRtspChannel(RtspChannelConnectArgs args);
   PChannelDiverter(ChannelDiverterArgs channel);
 
 both:
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/net/NeckoChild.h"
 #include "nsThreadUtils.h"
 #include "nsJARProtocolHandler.h"
 #include "nsIRemoteOpenFileListener.h"
 #include "nsProxyRelease.h"
+#include "SerializedLoadContext.h"
 
 // needed to alloc/free NSPR file descriptors
 #include "private/pprio.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
@@ -170,17 +171,18 @@ RemoteOpenFileChild::Init(nsIURI* aRemot
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
 RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags,
                                          nsIRemoteOpenFileListener* aListener,
-                                         nsITabChild* aTabChild)
+                                         nsITabChild* aTabChild,
+                                         nsILoadContext *aLoadContext)
 {
   if (!mFile) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   if (!aListener) {
     return NS_ERROR_INVALID_ARG;
   }
@@ -222,17 +224,18 @@ RemoteOpenFileChild::AsyncRemoteFileOpen
     }
   }
 
   URIParams uri;
   SerializeURI(mURI, uri);
   OptionalURIParams appUri;
   SerializeURI(mAppURI, appUri);
 
-  gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, appUri);
+  IPC::SerializedLoadContext loadContext(aLoadContext);
+  gNeckoChild->SendPRemoteOpenFileConstructor(this, loadContext, uri, appUri);
 
   // The chrome process now has a logical ref to us until it calls Send__delete.
   AddIPDLReference();
 
   mListener = aListener;
   mAsyncOpenCalled = true;
   return NS_OK;
 #endif
--- a/netwerk/ipc/RemoteOpenFileChild.h
+++ b/netwerk/ipc/RemoteOpenFileChild.h
@@ -9,16 +9,18 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/net/PRemoteOpenFileChild.h"
 #include "nsICachedFileDescriptorListener.h"
 #include "nsILocalFile.h"
 #include "nsIRemoteOpenFileListener.h"
 
+class nsILoadContext;
+
 namespace mozilla {
 
 namespace ipc {
 class FileDescriptor;
 }
 
 namespace net {
 
@@ -67,17 +69,18 @@ public:
   // a file:// uri.
   nsresult Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri);
 
   // Send message to parent to tell it to open file handle for file.
   // TabChild is required, for IPC security.
   // Note: currently only PR_RDONLY is supported for 'flags'
   nsresult AsyncRemoteFileOpen(int32_t aFlags,
                                nsIRemoteOpenFileListener* aListener,
-                               nsITabChild* aTabChild);
+                               nsITabChild* aTabChild,
+                               nsILoadContext *aLoadContext);
 
   void ReleaseIPDLReference()
   {
     Release();
   }
 
 private:
   RemoteOpenFileChild(const RemoteOpenFileChild& other);