Bug 1125961 - Allow sending null PBrowser actors when there's a triggering principal which can be used for security checks. r=bkelly,ddamjano
☠☠ backed out by 57273aac7996 ☠ ☠
authorJosh Matthews <josh@joshmatthews.net>
Wed, 03 Jun 2015 15:07:42 -0400
changeset 255459 2bdaed564656451cc9de7f47f1120548b4cfe228
parent 255458 3e78fb4512a68ea7eedfe0102b56c63ada8b9235
child 255460 1fe5e8dc9bab72edfbbcba4b879bee78582578e2
push id63049
push userjosh@joshmatthews.net
push dateThu, 30 Jul 2015 18:28:14 +0000
treeherdermozilla-inbound@2bdaed564656 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly, ddamjano
bugs1125961
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1125961 - Allow sending null PBrowser actors when there's a triggering principal which can be used for security checks. r=bkelly,ddamjano
dom/workers/test/serviceworkers/mochitest.ini
netwerk/base/nsBaseChannel.h
netwerk/ipc/NeckoChannelParams.ipdlh
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoCommon.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/ipc/RemoteOpenFileChild.cpp
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/websocket/WebSocketChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
netwerk/test/unit/test_cache_jar.js
netwerk/test/unit/test_cookiejars.js
netwerk/test/unit_ipc/child_app_offline.js
uriloader/prefetch/OfflineCacheUpdateChild.cpp
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -1,10 +1,9 @@
 [DEFAULT]
-skip-if = buildapp == 'b2g'
 support-files =
   worker.js
   worker2.js
   worker3.js
   fetch_event_worker.js
   parse_error_worker.js
   activate_event_error_worker.js
   install_event_worker.js
@@ -153,56 +152,67 @@ support-files =
   test_eval_not_allowed.html^headers^
   opaque_intercept_worker.js
   notify_loaded.js
   test_request_context.js
   fetch_event_client.js
   sw_clients/dummy.html
 
 [test_app_protocol.html]
-skip-if = release_build
+skip-if = release_build || buildapp == 'b2g' # bug 1184427
 [test_bug1151916.html]
 [test_claim.html]
 [test_claim_fetch.html]
 [test_claim_oninstall.html]
 [test_client_focus.html]
 [test_close.html]
 [test_controller.html]
 [test_cross_origin_url_after_redirect.html]
 [test_empty_serviceworker.html]
 [test_eval_allowed.html]
 [test_eval_not_allowed.html]
 [test_fetch_event.html]
 [test_force_refresh.html]
 [test_gzip_redirect.html]
 [test_https_fetch.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_https_fetch_cloned_response.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_https_origin_after_redirect.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_https_origin_after_redirect_cached.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_https_synth_fetch_from_cached_sw.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_importscript.html]
 [test_install_event.html]
 [test_installation_simple.html]
 [test_interception_featuredetect.html]
 [test_match_all.html]
 [test_match_all_advanced.html]
 [test_match_all_client_id.html]
 [test_match_all_client_properties.html]
 [test_navigator.html]
 [test_origin_after_redirect.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_origin_after_redirect_cached.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_origin_after_redirect_to_https.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_origin_after_redirect_to_https_cached.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_periodic_https_update.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_periodic_update.html]
 [test_post_message.html]
 [test_post_message_advanced.html]
 [test_post_message_source.html]
 [test_register_base.html]
 [test_register_https_in_http.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_request_context_audio.html]
 [test_request_context_beacon.html]
 [test_request_context_cache.html]
 [test_request_context_cspreport.html]
 [test_request_context_embed.html]
 [test_request_context_fetch.html]
 [test_request_context_font.html]
 [test_request_context_frame.html]
@@ -232,14 +242,15 @@ skip-if = release_build
 [test_sanitize.html]
 [test_sanitize_domain.html]
 [test_service_worker_allowed.html]
 [test_serviceworker_interfaces.html]
 [test_serviceworker_not_sharedworker.html]
 [test_skip_waiting.html]
 [test_strict_mode_error.html]
 [test_third_party_iframes.html]
+skip-if = buildapp == 'b2g' # bug 1184427
 [test_unregister.html]
 [test_workerUnregister.html]
 [test_workerUpdate.html]
 [test_workerupdatefoundevent.html]
 [test_opaque_intercept.html]
 [test_fetch_event_client_postmessage.html]
--- a/netwerk/base/nsBaseChannel.h
+++ b/netwerk/base/nsBaseChannel.h
@@ -264,17 +264,16 @@ private:
     nsCOMPtr<nsIChannel> mNewChannel;
   };
   friend class RedirectRunnable;
 
   nsRefPtr<nsInputStreamPump>         mPump;
   nsCOMPtr<nsIProgressEventSink>      mProgressSink;
   nsCOMPtr<nsIURI>                    mOriginalURI;
   nsCOMPtr<nsISupports>               mOwner;
-  nsCOMPtr<nsILoadInfo>               mLoadInfo;
   nsCOMPtr<nsISupports>               mSecurityInfo;
   nsCOMPtr<nsIChannel>                mRedirectChannel;
   nsCString                           mContentType;
   nsCString                           mContentCharset;
   uint32_t                            mLoadFlags;
   bool                                mQueriedProgressSink;
   bool                                mSynthProgressEvents;
   bool                                mAllowThreadRetargeting;
@@ -283,16 +282,17 @@ private:
   uint32_t                            mRedirectFlags;
 
 protected:
   nsCOMPtr<nsIURI>                    mURI;
   nsCOMPtr<nsILoadGroup>              mLoadGroup;
   nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
   nsCOMPtr<nsIStreamListener>         mListener;
   nsCOMPtr<nsISupports>               mListenerContext;
+  nsCOMPtr<nsILoadInfo>               mLoadInfo;
   nsresult                            mStatus;
   uint32_t                            mContentDispositionHint;
   nsAutoPtr<nsString>                 mContentDispositionFilename;
   int64_t                             mContentLength;
   bool                                mWasOpened;
 
   friend class mozilla::net::PrivateBrowsingChannel<nsBaseChannel>;
 };
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -93,16 +93,17 @@ struct HttpChannelOpenArgs
   OptionalHttpResponseHead    synthesizedResponseHead;
   uint32_t                    cacheKey;
 };
 
 struct HttpChannelConnectArgs
 {
   uint32_t channelId;
   bool shouldIntercept;
+  OptionalLoadInfoArgs loadInfo;
 };
 
 union HttpChannelCreationArgs
 {
   HttpChannelOpenArgs;      // For AsyncOpen: the common case.
   HttpChannelConnectArgs;   // Used for redirected-to channels
 };
 
@@ -117,16 +118,17 @@ struct FTPChannelOpenArgs
   nsCString                 entityID;
   OptionalInputStreamParams uploadStream;
   OptionalLoadInfoArgs      loadInfo;
 };
 
 struct FTPChannelConnectArgs
 {
   uint32_t channelId;
+  OptionalLoadInfoArgs loadInfo;
 };
 
 union FTPChannelCreationArgs
 {
   FTPChannelOpenArgs;      // For AsyncOpen: the common case.
   FTPChannelConnectArgs;   // Used for redirected-to channels
 };
 
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -152,17 +152,18 @@ NeckoChild::DeallocPWyciwygChannelChild(
 
   WyciwygChannelChild *p = static_cast<WyciwygChannelChild*>(channel);
   p->ReleaseIPDLReference();
   return true;
 }
 
 PWebSocketChild*
 NeckoChild::AllocPWebSocketChild(const PBrowserOrId& browser,
-                                 const SerializedLoadContext& aSerialized)
+                                 const SerializedLoadContext& aSerialized,
+                                 const PrincipalInfo& requestingPrincipal)
 {
   NS_NOTREACHED("AllocPWebSocketChild should not be called");
   return nullptr;
 }
 
 bool
 NeckoChild::DeallocPWebSocketChild(PWebSocketChild* child)
 {
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -36,17 +36,18 @@ protected:
   virtual bool DeallocPWyciwygChannelChild(PWyciwygChannelChild*) override;
   virtual PFTPChannelChild*
     AllocPFTPChannelChild(const PBrowserOrId& aBrowser,
                           const SerializedLoadContext& aSerialized,
                           const FTPChannelCreationArgs& aOpenArgs) override;
   virtual bool DeallocPFTPChannelChild(PFTPChannelChild*) override;
   virtual PWebSocketChild*
     AllocPWebSocketChild(const PBrowserOrId&,
-                         const SerializedLoadContext&) override;
+                         const SerializedLoadContext&,
+                         const PrincipalInfo&) override;
   virtual bool DeallocPWebSocketChild(PWebSocketChild*) override;
   virtual PTCPSocketChild* AllocPTCPSocketChild(const nsString& host,
                                                 const uint16_t& port) override;
   virtual bool DeallocPTCPSocketChild(PTCPSocketChild*) override;
   virtual PTCPServerSocketChild*
     AllocPTCPServerSocketChild(const uint16_t& aLocalPort,
                                const uint16_t& aBacklog,
                                const nsString& aBinaryType) override;
--- a/netwerk/ipc/NeckoCommon.h
+++ b/netwerk/ipc/NeckoCommon.h
@@ -7,16 +7,17 @@
 
 #ifndef mozilla_net_NeckoCommon_h
 #define mozilla_net_NeckoCommon_h
 
 #include "nsXULAppAPI.h"
 #include "prenv.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
+#include "nsILoadInfo.h"
 
 namespace mozilla { namespace dom {
 class TabChild;
 } // namespace dom
 } // namespace mozilla
 
 #if defined(DEBUG)
 # define NECKO_ERRORS_ARE_FATAL_DEFAULT true
@@ -116,20 +117,21 @@ UsingNeckoIPCSecurity()
                                  "network.disable.ipc.security");
     NeckoCommonInternal::gRegisteredBool = true;
   }
   return !NeckoCommonInternal::gSecurityDisabled;
 }
 
 inline bool
 MissingRequiredTabChild(mozilla::dom::TabChild* tabChild,
+                        nsILoadInfo* loadInfo,
                         const char* context)
 {
   if (UsingNeckoIPCSecurity()) {
-    if (!tabChild) {
+    if (!tabChild && (!loadInfo || !loadInfo->LoadingPrincipal())) {
       printf_stderr("WARNING: child tried to open %s IPDL channel w/o "
                     "security info\n", context);
       return true;
     }
   }
   return false;
 }
 
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -22,16 +22,17 @@
 #include "mozilla/net/RemoteOpenFileParent.h"
 #include "mozilla/net/ChannelDiverterParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/TabContext.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/network/TCPSocketParent.h"
 #include "mozilla/dom/network/TCPServerSocketParent.h"
 #include "mozilla/dom/network/UDPSocketParent.h"
+#include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/AppProcessChecker.h"
 #include "nsPrintfCString.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsIAppsService.h"
 #include "nsEscape.h"
 #include "RemoteOpenFileParent.h"
@@ -165,16 +166,17 @@ NeckoParent::GetValidatedAppInfo(const S
     return nullptr;
   }
 
   return "ContentParent does not have any PBrowsers";
 }
 
 const char *
 NeckoParent::CreateChannelLoadContext(const PBrowserOrId& aBrowser,
+                                      nsIPrincipal* aRequestingPrincipal,
                                       PContentParent* aContent,
                                       const SerializedLoadContext& aSerialized,
                                       nsCOMPtr<nsILoadContext> &aResult)
 {
   uint32_t appId = NECKO_UNKNOWN_APP_ID;
   bool inBrowser = false;
   const char* error = GetValidatedAppInfo(aSerialized, aContent, &appId, &inBrowser);
   if (error) {
@@ -187,16 +189,33 @@ NeckoParent::CreateChannelLoadContext(co
     switch (aBrowser.type()) {
       case PBrowserOrId::TPBrowserParent:
       {
         nsRefPtr<TabParent> tabParent =
           TabParent::GetFrom(aBrowser.get_PBrowserParent());
         dom::Element* topFrameElement = nullptr;
         if (tabParent) {
           topFrameElement = tabParent->GetOwnerElement();
+        } else {
+          if (!aRequestingPrincipal) {
+            return "missing associated browser and requesting principal";
+          }
+
+          // If a null tab parent is provided, we rely on comparing the requesting principal's
+          // reported data against the provided load context's data.
+          uint32_t reportedAppId = NECKO_UNKNOWN_APP_ID;
+          aRequestingPrincipal->GetAppId(&reportedAppId);
+          if (appId != reportedAppId) {
+            return "app id mismatch for request without associated browser";
+          }
+          bool reportedInBrowser = false;
+          aRequestingPrincipal->GetIsInBrowserElement(&reportedInBrowser);
+          if (reportedInBrowser != inBrowser) {
+            return "browser element mismatch for request without associated browser";
+          }
         }
         aResult = new LoadContext(aSerialized, topFrameElement,
                                   appId, inBrowser);
         break;
       }
       case PBrowserOrId::TTabId:
       {
         aResult = new LoadContext(aSerialized, aBrowser.get_TabId(),
@@ -217,18 +236,36 @@ NeckoParent::ActorDestroy(ActorDestroyRe
   // Implement me! Bug 1005184
 }
 
 PHttpChannelParent*
 NeckoParent::AllocPHttpChannelParent(const PBrowserOrId& aBrowser,
                                      const SerializedLoadContext& aSerialized,
                                      const HttpChannelCreationArgs& aOpenArgs)
 {
+  const OptionalLoadInfoArgs& infoArgs =
+    aOpenArgs.type() == HttpChannelCreationArgs::THttpChannelOpenArgs ?
+    aOpenArgs.get_HttpChannelOpenArgs().loadInfo() :
+    aOpenArgs.get_HttpChannelConnectArgs().loadInfo();
+
+  nsCOMPtr<nsILoadInfo> loadInfo;
+  nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(infoArgs, getter_AddRefs(loadInfo));
+  if (NS_FAILED(rv)) {
+    printf_stderr("NeckoParent::AllocPHttpChannelParent: "
+                  "FATAL error: couldn't deserialize load info: KILLING CHILD PROCESS\n");
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIPrincipal> requestingPrincipal;
+  if (loadInfo) {
+    requestingPrincipal = loadInfo->LoadingPrincipal();
+  }
+
   nsCOMPtr<nsILoadContext> loadContext;
-  const char *error = CreateChannelLoadContext(aBrowser, Manager(),
+  const char *error = CreateChannelLoadContext(aBrowser, requestingPrincipal, Manager(),
                                                aSerialized, loadContext);
   if (error) {
     printf_stderr("NeckoParent::AllocPHttpChannelParent: "
                   "FATAL error: %s: KILLING CHILD PROCESS\n",
                   error);
     return nullptr;
   }
   PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
@@ -256,18 +293,36 @@ NeckoParent::RecvPHttpChannelConstructor
   return p->Init(aOpenArgs);
 }
 
 PFTPChannelParent*
 NeckoParent::AllocPFTPChannelParent(const PBrowserOrId& aBrowser,
                                     const SerializedLoadContext& aSerialized,
                                     const FTPChannelCreationArgs& aOpenArgs)
 {
+  const OptionalLoadInfoArgs& infoArgs =
+    aOpenArgs.type() == FTPChannelCreationArgs::TFTPChannelOpenArgs ?
+    aOpenArgs.get_FTPChannelOpenArgs().loadInfo() :
+    aOpenArgs.get_FTPChannelConnectArgs().loadInfo();
+
+  nsCOMPtr<nsILoadInfo> loadInfo;
+  nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(infoArgs, getter_AddRefs(loadInfo));
+  if (NS_FAILED(rv)) {
+    printf_stderr("NeckoParent::AllocPFTPChannelParent: "
+                  "FATAL error: couldn't deserialize load info: KILLING CHILD PROCESS\n");
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIPrincipal> requestingPrincipal;
+  if (loadInfo) {
+    requestingPrincipal = loadInfo->LoadingPrincipal();
+  }
+  
   nsCOMPtr<nsILoadContext> loadContext;
-  const char *error = CreateChannelLoadContext(aBrowser, Manager(),
+  const char *error = CreateChannelLoadContext(aBrowser, requestingPrincipal, Manager(),
                                                aSerialized, loadContext);
   if (error) {
     printf_stderr("NeckoParent::AllocPFTPChannelParent: "
                   "FATAL error: %s: KILLING CHILD PROCESS\n",
                   error);
     return nullptr;
   }
   PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
@@ -321,20 +376,30 @@ NeckoParent::DeallocPWyciwygChannelParen
 {
   WyciwygChannelParent *p = static_cast<WyciwygChannelParent *>(channel);
   p->Release();
   return true;
 }
 
 PWebSocketParent*
 NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser,
-                                   const SerializedLoadContext& serialized)
+                                   const SerializedLoadContext& serialized,
+                                   const PrincipalInfo& requestingPrincipalInfo)
 {
+  nsresult rv;
+  nsCOMPtr<nsIPrincipal> requestingPrincipal =
+    mozilla::ipc::PrincipalInfoToPrincipal(requestingPrincipalInfo, &rv);
+  if (NS_FAILED(rv)) {
+    printf_stderr("NeckoParent::AllocPWebSocketParent: "
+                  "FATAL error: couldn't deserialize principal: KILLING CHILD PROCESS\n");
+    return nullptr;
+  }
+
   nsCOMPtr<nsILoadContext> loadContext;
-  const char *error = CreateChannelLoadContext(browser, Manager(),
+  const char *error = CreateChannelLoadContext(browser, requestingPrincipal, Manager(),
                                                serialized, loadContext);
   if (error) {
     printf_stderr("NeckoParent::AllocPWebSocketParent: "
                   "FATAL error: %s: KILLING CHILD PROCESS\n",
                   error);
     return nullptr;
   }
 
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -46,16 +46,17 @@ public:
    *
    * PContentParent corresponds to the process that is requesting the load.
    *
    * Returns null if successful, or an error string if failed.
    */
   MOZ_WARN_UNUSED_RESULT
   static const char*
   CreateChannelLoadContext(const PBrowserOrId& aBrowser,
+                           nsIPrincipal* aRequestingPrincipal,
                            PContentParent* aContent,
                            const SerializedLoadContext& aSerialized,
                            nsCOMPtr<nsILoadContext> &aResult);
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
   virtual nsresult OfflineNotification(nsISupports *) override;
   virtual uint32_t GetAppId() override { return NECKO_UNKNOWN_APP_ID; }
   virtual void
@@ -119,17 +120,18 @@ protected:
     RecvPFTPChannelConstructor(
                       PFTPChannelParent* aActor,
                       const PBrowserOrId& aBrowser,
                       const SerializedLoadContext& aSerialized,
                       const FTPChannelCreationArgs& aOpenArgs) override;
   virtual bool DeallocPFTPChannelParent(PFTPChannelParent*) override;
   virtual PWebSocketParent*
     AllocPWebSocketParent(const PBrowserOrId& browser,
-                          const SerializedLoadContext& aSerialized) override;
+                          const SerializedLoadContext& aSerialized,
+                          const PrincipalInfo& requestingPrincipal) override;
   virtual bool DeallocPWebSocketParent(PWebSocketParent*) override;
   virtual PTCPSocketParent* AllocPTCPSocketParent(const nsString& host,
                                                   const uint16_t& port) override;
 
   virtual PRemoteOpenFileParent*
     AllocPRemoteOpenFileParent(const SerializedLoadContext& aSerialized,
                                const URIParams& aFileURI,
                                const OptionalURIParams& aAppURI) override;
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -23,16 +23,17 @@ include protocol PFileDescriptorSet;
 include protocol PDataChannel;
 
 include protocol PRtspController;
 include protocol PRtspChannel;
 include URIParams;
 include InputStreamParams;
 include NeckoChannelParams;
 include PBrowserOrId;
+include PBackgroundSharedTypes;
 
 using class IPC::SerializedLoadContext from "SerializedLoadContext.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 
 namespace mozilla {
 namespace net {
 
@@ -61,17 +62,18 @@ parent:
   prio(urgent) async PCookieService();
   PHttpChannel(PBrowserOrId browser,
                SerializedLoadContext loadContext,
                HttpChannelCreationArgs args);
   PWyciwygChannel();
   PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
               FTPChannelCreationArgs args);
 
-  PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext);
+  PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext,
+             PrincipalInfo requestingPrincipalInfo);
   PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
   PUDPSocket(Principal principal, nsCString filter);
 
   PDNSRequest(nsCString hostName, uint32_t flags, nsCString networkInterface);
 
 
   /* Predictor Methods */
   PredPredict(OptionalURIParams targetURI, OptionalURIParams sourceURI,
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -205,17 +205,17 @@ RemoteOpenFileChild::AsyncRemoteFileOpen
   }
 
   if (aFlags != PR_RDONLY) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   mTabChild = static_cast<TabChild*>(aTabChild);
 
-  if (MissingRequiredTabChild(mTabChild, "remoteopenfile")) {
+  if (MissingRequiredTabChild(mTabChild, nullptr, "remoteopenfile")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
   // Windows/OSX desktop builds skip remoting, and just open file in child
   // process when asked for NSPR handle
   nsRefPtr<CallsListenerInNewEvent> runnable =
     new CallsListenerInNewEvent(aListener, NS_OK);
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -164,17 +164,17 @@ FTPChannelChild::AsyncOpen(::nsIStreamLi
   nsCOMPtr<nsITabChild> iTabChild;
   NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                 NS_GET_IID(nsITabChild),
                                 getter_AddRefs(iTabChild));
   GetCallback(iTabChild);
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
-  if (MissingRequiredTabChild(tabChild, "ftp")) {
+  if (MissingRequiredTabChild(tabChild, mLoadInfo, "ftp")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   mListener = listener;
   mListenerContext = aContext;
 
   // add ourselves to the load group. 
   if (mLoadGroup)
@@ -713,17 +713,20 @@ FTPChannelChild::ConnectParent(uint32_t 
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
-  FTPChannelConnectArgs connectArgs(id);
+  FTPChannelConnectArgs connectArgs;
+  connectArgs.channelId() = id;
+  nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &connectArgs.loadInfo());
+  NS_ENSURE_SUCCESS(rv, rv);
 
   if (!gNeckoChild->SendPFTPChannelConstructor(this, tabChild,
                                                IPC::SerializedLoadContext(this),
                                                connectArgs)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1266,25 +1266,30 @@ HttpChannelChild::ConnectParent(uint32_t
 {
   LOG(("HttpChannelChild::ConnectParent [this=%p]\n", this));
   mozilla::dom::TabChild* tabChild = nullptr;
   nsCOMPtr<nsITabChild> iTabChild;
   GetCallback(iTabChild);
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
-  if (MissingRequiredTabChild(tabChild, "http")) {
+  if (MissingRequiredTabChild(tabChild, mLoadInfo, "http")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
-  HttpChannelConnectArgs connectArgs(id, mShouldParentIntercept);
+  HttpChannelConnectArgs connectArgs;
+  connectArgs.channelId() = id;
+  connectArgs.shouldIntercept() = mShouldParentIntercept;
+  nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &connectArgs.loadInfo());
+  NS_ENSURE_SUCCESS(rv, rv);
+
   PBrowserOrId browser = static_cast<ContentChild*>(gNeckoChild->Manager())
                          ->GetBrowserOrId(tabChild);
   if (!gNeckoChild->
         SendPHttpChannelConstructor(this, browser,
                                     IPC::SerializedLoadContext(this),
                                     connectArgs)) {
     return NS_ERROR_FAILURE;
   }
@@ -1590,17 +1595,17 @@ HttpChannelChild::ContinueAsyncOpen()
   //
 
   mozilla::dom::TabChild* tabChild = nullptr;
   nsCOMPtr<nsITabChild> iTabChild;
   GetCallback(iTabChild);
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
-  if (MissingRequiredTabChild(tabChild, "http")) {
+  if (MissingRequiredTabChild(tabChild, mLoadInfo, "http")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   HttpChannelOpenArgs openArgs;
   // No access to HttpChannelOpenArgs members, but they each have a
   // function with the struct name that returns a ref.
   SerializeURI(mURI, openArgs.uri());
   SerializeURI(mOriginalURI, openArgs.original());
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -468,32 +468,38 @@ WebSocketChannelChild::AsyncOpen(nsIURI 
   mozilla::dom::TabChild* tabChild = nullptr;
   nsCOMPtr<nsITabChild> iTabChild;
   NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                 NS_GET_IID(nsITabChild),
                                 getter_AddRefs(iTabChild));
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
-  if (MissingRequiredTabChild(tabChild, "websocket")) {
+  if (MissingRequiredTabChild(tabChild, mLoadInfo, "websocket")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   URIParams uri;
   SerializeURI(aURI, uri);
 
   // Corresponding release in DeallocPWebSocket
   AddIPDLReference();
 
   OptionalLoadInfoArgs loadInfoArgs;
   nsresult rv = LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  mozilla::ipc::PrincipalInfo requestingPrincipalInfo;
+  mozilla::ipc::PrincipalToPrincipalInfo(mLoadInfo->LoadingPrincipal(),
+                                         &requestingPrincipalInfo);
+
   gNeckoChild->SendPWebSocketConstructor(this, tabChild,
-                                         IPC::SerializedLoadContext(this));
+                                         IPC::SerializedLoadContext(this),
+                                         requestingPrincipalInfo);
+
   if (!SendAsyncOpen(uri, nsCString(aOrigin), mProtocol, mEncrypted,
                      mPingInterval, mClientSetPingInterval,
                      mPingResponseTimeout, mClientSetPingTimeout, loadInfoArgs)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   mOriginalURI = aURI;
   mURI = mOriginalURI;
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -662,17 +662,17 @@ WyciwygChannelChild::AsyncOpen(nsIStream
   if (mLoadGroup) {
     mLoadGroup->AddRequest(this, nullptr);
   }
 
   URIParams originalURI;
   SerializeURI(mOriginalURI, originalURI);
 
   mozilla::dom::TabChild* tabChild = GetTabChild(this);
-  if (MissingRequiredTabChild(tabChild, "wyciwyg")) {
+  if (MissingRequiredTabChild(tabChild, nullptr, "wyciwyg")) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   PBrowserOrId browser = static_cast<ContentChild*>(Manager()->Manager())
                          ->GetBrowserOrId(tabChild);
 
   SendAsyncOpen(originalURI, mLoadFlags, IPC::SerializedLoadContext(this), browser);
 
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
@@ -129,16 +129,17 @@ WyciwygChannelParent::RecvAppData(const 
 bool
 WyciwygChannelParent::SetupAppData(const IPC::SerializedLoadContext& loadContext,
                                    const PBrowserOrId &aParent)
 {
   if (!mChannel)
     return true;
 
   const char* error = NeckoParent::CreateChannelLoadContext(aParent,
+                                                            nullptr,
                                                             Manager()->Manager(),
                                                             loadContext,
                                                             mLoadContext);
   if (error) {
     printf_stderr("WyciwygChannelParent::SetupAppData: FATAL ERROR: %s\n",
                   error);
     return false;
   }
--- a/netwerk/test/unit/test_cache_jar.js
+++ b/netwerk/test/unit/test_cache_jar.js
@@ -15,21 +15,24 @@ function cached_handler(metadata, respon
   response.setStatusLine(metadata.httpVersion, 200, "OK");
   var body = "0123456789";
   response.bodyOutputStream.write(body, body.length);
   handlers_called++;
 }
 
 function makeChan(url, appId, inBrowser) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+  var uri = ios.newURI(url, null, null);
   var chan = ios.newChannel2(url,
                              null,
                              null,
                              null,      // aLoadingNode
-                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             Services.scriptSecurityManager.getAppCodebasePrincipal(uri,
+                                                                                    appId,
+                                                                                    inBrowser),
                              null,      // aTriggeringPrincipal
                              Ci.nsILoadInfo.SEC_NORMAL,
                              Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   chan.notificationCallbacks = {
     appId: appId,
     isInBrowserElement: inBrowser,
     QueryInterface: function(iid) {
       if (iid.equals(Ci.nsILoadContext))
--- a/netwerk/test/unit/test_cookiejars.js
+++ b/netwerk/test/unit/test_cookiejars.js
@@ -44,21 +44,26 @@ var tests = [
 ];
 
 // test number: index into 'tests' array
 var i = 0;
 
 function setupChannel(path)
 {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+  var uri = ios.newURI(URL + path, null, null);
+  var appId = tests[i].loadContext.appId;
+  var inBrowser = tests[i].loadContext.isInBrowserElement;
   var chan = ios.newChannel2(URL + path,
                              "",
                              null,
                              null,      // aLoadingNode
-                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             Services.scriptSecurityManager.getAppCodebasePrincipal(uri,
+                                                                                    appId,
+                                                                                    inBrowser),
                              null,      // aTriggeringPrincipal
                              Ci.nsILoadInfo.SEC_NORMAL,
                              Ci.nsIContentPolicy.TYPE_OTHER);
   chan.notificationCallbacks = tests[i].loadContext;
   chan.QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
--- a/netwerk/test/unit_ipc/child_app_offline.js
+++ b/netwerk/test/unit_ipc/child_app_offline.js
@@ -3,21 +3,24 @@ Cu.import("resource://gre/modules/Servic
 function inChildProcess() {
   return Cc["@mozilla.org/xre/app-info;1"]
            .getService(Ci.nsIXULRuntime)
            .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 }
 
 function makeChan(url, appId, inBrowser) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+  var uri = ios.newURI(url, null, null);
   var chan = ios.newChannel2(url,
                              null,
                              null,
                              null,      // aLoadingNode
-                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             Services.scriptSecurityManager.getAppCodebasePrincipal(uri,
+                                                                                    appId,
+                                                                                    inBrowser),
                              null,      // aTriggeringPrincipal
                              Ci.nsILoadInfo.SEC_NORMAL,
                              Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   chan.notificationCallbacks = {
     appId: appId,
     isInBrowserElement: inBrowser,
     QueryInterface: function(iid) {
       if (iid.equals(Ci.nsILoadContext))
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -396,17 +396,17 @@ OfflineCacheUpdateChild::Schedule()
     nsCOMPtr<nsIDocShellTreeOwner> owner;
     item->GetTreeOwner(getter_AddRefs(owner));
 
     nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
     // because owner implements nsITabChild, we can assume that it is
     // the one and only TabChild.
     TabChild* child = tabchild ? static_cast<TabChild*>(tabchild.get()) : nullptr;
 
-    if (MissingRequiredTabChild(child, "offlinecacheupdate")) {
+    if (MissingRequiredTabChild(child, nullptr, "offlinecacheupdate")) {
       return NS_ERROR_FAILURE;
     }
 
     URIParams manifestURI, documentURI;
     SerializeURI(mManifestURI, manifestURI);
     SerializeURI(mDocumentURI, documentURI);
 
     nsCOMPtr<nsIObserverService> observerService =