Bug 1305237 LoadInfo changes to include all ancestors principals and window IDs draft
authorevilpies@gmail.com
Fri, 11 Aug 2017 14:53:38 -0700
changeset 646068 d191899e1691c31a4b2a68a6c4c76f05a02506c8
parent 645074 80ff3f300e05f38f96c385b03d1973a966a2bd35
child 646069 9e74d5b8f6dcce55a18a45dd8d625dc4671ef972
push id73988
push usermixedpuppy@gmail.com
push dateMon, 14 Aug 2017 19:55:05 +0000
bugs1305237
milestone57.0a1
Bug 1305237 LoadInfo changes to include all ancestors principals and window IDs MozReview-Commit-ID: 9ZLBfQno3ik
ipc/glue/BackgroundUtils.cpp
netwerk/base/LoadInfo.cpp
netwerk/base/LoadInfo.h
netwerk/base/nsILoadInfo.idl
netwerk/ipc/NeckoChannelParams.ipdlh
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -365,16 +365,22 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
   nsTArray<RedirectHistoryEntryInfo> redirectChain;
   for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
        aLoadInfo->RedirectChain()) {
     RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
     rv = RHEntryToRHEntryInfo(redirectEntry, entry);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  nsTArray<PrincipalInfo> ancestors;
+  for (const nsCOMPtr<nsIPrincipal>& principal : aLoadInfo->Ancestors()) {
+    rv = PrincipalToPrincipalInfo(principal, ancestors.AppendElement());
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   *aOptionalLoadInfoArgs =
     LoadInfoArgs(
       loadingPrincipalInfo,
       triggeringPrincipalInfo,
       principalToInheritInfo,
       sandboxedLoadingPrincipalInfo,
       optionalResultPrincipalURI,
       aLoadInfo->GetSecurityFlags(),
@@ -389,16 +395,18 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
       aLoadInfo->GetParentOuterWindowID(),
       aLoadInfo->GetFrameOuterWindowID(),
       aLoadInfo->GetEnforceSecurity(),
       aLoadInfo->GetInitialSecurityCheckDone(),
       aLoadInfo->GetIsInThirdPartyContext(),
       aLoadInfo->GetOriginAttributes(),
       redirectChainIncludingInternalRedirects,
       redirectChain,
+      ancestors,
+      aLoadInfo->AncestorsOuterWindowIDs(),
       aLoadInfo->CorsUnsafeHeaders(),
       aLoadInfo->GetForcePreflight(),
       aLoadInfo->GetIsPreflight(),
       aLoadInfo->GetForceHSTSPriming(),
       aLoadInfo->GetMixedContentWouldBlock(),
       aLoadInfo->GetIsHSTSPriming(),
       aLoadInfo->GetIsHSTSPrimingUpgrade()
       );
@@ -461,16 +469,24 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
   RedirectHistoryArray redirectChain;
   for (const RedirectHistoryEntryInfo& entryInfo : loadInfoArgs.redirectChain()) {
     nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
       RHEntryInfoToRHEntry(entryInfo);
     NS_ENSURE_SUCCESS(rv, rv);
     redirectChain.AppendElement(redirectHistoryEntry.forget());
   }
 
+  nsTArray<nsCOMPtr<nsIPrincipal>> ancestors;
+  for (const PrincipalInfo& principalInfo : loadInfoArgs.ancestors()) {
+    nsCOMPtr<nsIPrincipal> ancestorPrincipal =
+      PrincipalInfoToPrincipal(principalInfo, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    ancestors.AppendElement(ancestorPrincipal.forget());
+  }
+
   nsCOMPtr<nsILoadInfo> loadInfo =
     new mozilla::LoadInfo(loadingPrincipal,
                           triggeringPrincipal,
                           principalToInherit,
                           sandboxedLoadingPrincipal,
                           resultPrincipalURI,
                           loadInfoArgs.securityFlags(),
                           loadInfoArgs.contentPolicyType(),
@@ -484,16 +500,18 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
                           loadInfoArgs.parentOuterWindowID(),
                           loadInfoArgs.frameOuterWindowID(),
                           loadInfoArgs.enforceSecurity(),
                           loadInfoArgs.initialSecurityCheckDone(),
                           loadInfoArgs.isInThirdPartyContext(),
                           loadInfoArgs.originAttributes(),
                           redirectChainIncludingInternalRedirects,
                           redirectChain,
+                          ancestors,
+                          loadInfoArgs.ancestorsOuterWindowIDs(),
                           loadInfoArgs.corsUnsafeHeaders(),
                           loadInfoArgs.forcePreflight(),
                           loadInfoArgs.isPreflight(),
                           loadInfoArgs.forceHSTSPriming(),
                           loadInfoArgs.mixedContentWouldBlock(),
                           loadInfoArgs.isHSTSPriming(),
                           loadInfoArgs.isHSTSPrimingUpgrade()
                           );
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -97,16 +97,34 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
 
   if (aLoadingContext) {
     nsCOMPtr<nsPIDOMWindowOuter> contextOuter = aLoadingContext->OwnerDoc()->GetWindow();
     if (contextOuter) {
       ComputeIsThirdPartyContext(contextOuter);
       mOuterWindowID = contextOuter->WindowID();
       nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
       mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
+
+      nsCOMPtr<nsPIDOMWindowOuter> prevParent = contextOuter;
+      do {
+        if (!parent || prevParent == parent) {
+          break;
+        }
+
+        nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(parent);
+        if (!scriptObjPrin) {
+          break;
+        }
+
+        mAncestors.AppendElement(scriptObjPrin->GetPrincipal());
+        mAncestorsOuterWindowIDs.AppendElement(parent->WindowID());
+
+        prevParent = parent;
+        parent = parent->GetScriptableParent();
+      } while (true);
     }
 
     mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
 
     // When the element being loaded is a frame, we choose the frame's window
     // for the window ID and the frame element's window as the parent
     // window. This is the behavior that Chrome exposes to add-ons.
     // NB: If the frameLoaderOwner doesn't have a frame loader, then the load
@@ -289,16 +307,18 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
   , mFrameOuterWindowID(rhs.mFrameOuterWindowID)
   , mEnforceSecurity(rhs.mEnforceSecurity)
   , mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
   , mIsThirdPartyContext(rhs.mIsThirdPartyContext)
   , mOriginAttributes(rhs.mOriginAttributes)
   , mRedirectChainIncludingInternalRedirects(
       rhs.mRedirectChainIncludingInternalRedirects)
   , mRedirectChain(rhs.mRedirectChain)
+  , mAncestors(rhs.mAncestors)
+  , mAncestorsOuterWindowIDs(rhs.mAncestorsOuterWindowIDs)
   , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
   , mForcePreflight(rhs.mForcePreflight)
   , mIsPreflight(rhs.mIsPreflight)
   , mForceHSTSPriming(rhs.mForceHSTSPriming)
   , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock)
   , mIsHSTSPriming(rhs.mIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(rhs.mIsHSTSPrimingUpgrade)
 {
@@ -321,16 +341,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
                    uint64_t aParentOuterWindowID,
                    uint64_t aFrameOuterWindowID,
                    bool aEnforceSecurity,
                    bool aInitialSecurityCheckDone,
                    bool aIsThirdPartyContext,
                    const OriginAttributes& aOriginAttributes,
                    RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
                    RedirectHistoryArray& aRedirectChain,
+                   nsTArray<nsCOMPtr<nsIPrincipal>>& aAncestors,
+                   const nsTArray<uint64_t>& aAncestorsOuterWindowIDs,
                    const nsTArray<nsCString>& aCorsUnsafeHeaders,
                    bool aForcePreflight,
                    bool aIsPreflight,
                    bool aForceHSTSPriming,
                    bool aMixedContentWouldBlock,
                    bool aIsHSTSPriming,
                    bool aIsHSTSPrimingUpgrade)
   : mLoadingPrincipal(aLoadingPrincipal)
@@ -347,32 +369,34 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mInnerWindowID(aInnerWindowID)
   , mOuterWindowID(aOuterWindowID)
   , mParentOuterWindowID(aParentOuterWindowID)
   , mFrameOuterWindowID(aFrameOuterWindowID)
   , mEnforceSecurity(aEnforceSecurity)
   , mInitialSecurityCheckDone(aInitialSecurityCheckDone)
   , mIsThirdPartyContext(aIsThirdPartyContext)
   , mOriginAttributes(aOriginAttributes)
+  , mAncestorsOuterWindowIDs(aAncestorsOuterWindowIDs)
   , mCorsUnsafeHeaders(aCorsUnsafeHeaders)
   , mForcePreflight(aForcePreflight)
   , mIsPreflight(aIsPreflight)
   , mForceHSTSPriming (aForceHSTSPriming)
   , mMixedContentWouldBlock(aMixedContentWouldBlock)
   , mIsHSTSPriming(aIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(aIsHSTSPrimingUpgrade)
 {
   // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
   MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
   MOZ_ASSERT(mTriggeringPrincipal);
 
   mRedirectChainIncludingInternalRedirects.SwapElements(
     aRedirectChainIncludingInternalRedirects);
 
   mRedirectChain.SwapElements(aRedirectChain);
+  mAncestors.SwapElements(aAncestors);
 }
 
 LoadInfo::~LoadInfo()
 {
 }
 
 void
 LoadInfo::ComputeIsThirdPartyContext(nsPIDOMWindowOuter* aOuterWindow)
@@ -870,16 +894,46 @@ LoadInfo::GetRedirectChain(JSContext* aC
 }
 
 const RedirectHistoryArray&
 LoadInfo::RedirectChain()
 {
   return mRedirectChain;
 }
 
+NS_IMETHODIMP
+LoadInfo::GetAncestors(JSContext* aCx, JS::MutableHandle<JS::Value> aChain)
+{
+  if (NS_WARN_IF(!ToJSValue(aCx, mAncestors, aChain))) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  return NS_OK;
+}
+
+const nsTArray<nsCOMPtr<nsIPrincipal>>&
+LoadInfo::Ancestors()
+{
+  return mAncestors;
+}
+
+NS_IMETHODIMP
+LoadInfo::GetAncestorsOuterWindowIDs(JSContext* aCx, JS::MutableHandle<JS::Value> aChain)
+{
+  if (NS_WARN_IF(!ToJSValue(aCx, mAncestorsOuterWindowIDs, aChain))) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  return NS_OK;
+}
+
+const nsTArray<uint64_t>&
+LoadInfo::AncestorsOuterWindowIDs()
+{
+  return mAncestorsOuterWindowIDs;
+}
+
 void
 LoadInfo::SetCorsPreflightInfo(const nsTArray<nsCString>& aHeaders,
                                bool aForcePreflight)
 {
   MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
   MOZ_ASSERT(!mInitialSecurityCheckDone);
   mCorsUnsafeHeaders = aHeaders;
   mForcePreflight = aForcePreflight;
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -107,16 +107,18 @@ private:
            uint64_t aParentOuterWindowID,
            uint64_t aFrameOuterWindowID,
            bool aEnforceSecurity,
            bool aInitialSecurityCheckDone,
            bool aIsThirdPartyRequest,
            const OriginAttributes& aOriginAttributes,
            RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
            RedirectHistoryArray& aRedirectChain,
+           nsTArray<nsCOMPtr<nsIPrincipal>>& aAncestors,
+           const nsTArray<uint64_t>& aAncestorsOuterWindowIDs,
            const nsTArray<nsCString>& aUnsafeHeaders,
            bool aForcePreflight,
            bool aIsPreflight,
            bool aForceHSTSPriming,
            bool aMixedContentWouldBlock,
            bool aIsHSTSPriming,
            bool aIsHSTSPrimingUpgrade);
   LoadInfo(const LoadInfo& rhs);
@@ -158,16 +160,18 @@ private:
   uint64_t                         mParentOuterWindowID;
   uint64_t                         mFrameOuterWindowID;
   bool                             mEnforceSecurity;
   bool                             mInitialSecurityCheckDone;
   bool                             mIsThirdPartyContext;
   OriginAttributes                 mOriginAttributes;
   RedirectHistoryArray             mRedirectChainIncludingInternalRedirects;
   RedirectHistoryArray             mRedirectChain;
+  nsTArray<nsCOMPtr<nsIPrincipal>> mAncestors;
+  nsTArray<uint64_t>               mAncestorsOuterWindowIDs;
   nsTArray<nsCString>              mCorsUnsafeHeaders;
   bool                             mForcePreflight;
   bool                             mIsPreflight;
 
   bool                             mForceHSTSPriming : 1;
   bool                             mMixedContentWouldBlock : 1;
   bool                             mIsHSTSPriming: 1;
   bool                             mIsHSTSPrimingUpgrade: 1;
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -19,16 +19,18 @@ interface nsIURI;
 
 class nsCString;
 %}
 
 [ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
 native OriginAttributes(mozilla::OriginAttributes);
 [ref] native const_OriginAttributesRef(const mozilla::OriginAttributes);
 [ref] native StringArrayRef(const nsTArray<nsCString>);
+[ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
+[ref] native const_nsIPrincipalArray(const nsTArray<nsCOMPtr<nsIPrincipal>>);
 
 typedef unsigned long nsSecurityFlags;
 
 /**
  * The LoadInfo object contains information about a network load, why it
  * was started, and how we plan on using the resulting response.
  * If a network request is redirected, the new channel will receive a new
  * LoadInfo object. The new object will contain mostly the same
@@ -627,16 +629,51 @@ interface nsILoadInfo : nsISupports
    * A C++-friendly version of redirectChain.
    * Please note that this array has the same lifetime as the
    * loadInfo object - use with caution!
    */
   [noscript, notxpcom, nostdcall, binaryname(RedirectChain)]
   nsIRedirectHistoryEntryArray binaryRedirectChain();
 
   /**
+   * An array of nsIPrincipals which stores the all the parent frames not
+   * including the frame loading this request.  Closest ancestor is at index
+   * zero, top level ancestor is last index.
+   *
+   * The ancestors[0] entry for an iframe will be the iframes parent frame.
+   * The ancestors[0] entry for an image loaded in an iframe will be the
+   * iframe's parent frame.
+   */
+  [implicit_jscontext] jsval getAncestors();
+
+  /**
+   * A C++-friendly version of ancestors.
+   * Please note that this array has the same lifetime as the
+   * loadInfo object - use with caution!
+   */
+  [noscript, notxpcom, nostdcall, binaryname(Ancestors)]
+  const_nsIPrincipalArray binaryAncestors();
+
+
+  /**
+   * An array of outer window IDs, which stores IDs for all the parent frames not
+   * including the frame loading this request.  These IDs match the
+   * corresponding index in ancestors above.
+   */
+  [implicit_jscontext] jsval getAncestorsOuterWindowIDs();
+
+  /**
+   * A C++-friendly version of ancestorsOuterWindowIDs.
+   * Please note that this array has the same lifetime as the
+   * loadInfo object - use with caution!
+   */
+  [noscript, notxpcom, nostdcall, binaryname(AncestorsOuterWindowIDs)]
+  Uint64ArrayRef binaryAncestorsOuterWindowIDs();
+
+  /**
    * Sets the list of unsafe headers according to CORS spec, as well as
    * potentially forces a preflight.
    * Note that you do not need to set the Content-Type header. That will be
    * automatically detected as needed.
    *
    * Only call this function when using the SEC_REQUIRE_CORS_DATA_INHERITS mode.
    */
   [noscript, notxpcom, nostdcall]
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -54,16 +54,18 @@ struct LoadInfoArgs
   uint64_t                    parentOuterWindowID;
   uint64_t                    frameOuterWindowID;
   bool                        enforceSecurity;
   bool                        initialSecurityCheckDone;
   bool                        isInThirdPartyContext;
   OriginAttributes            originAttributes;
   RedirectHistoryEntryInfo[]  redirectChainIncludingInternalRedirects;
   RedirectHistoryEntryInfo[]  redirectChain;
+  PrincipalInfo[]             ancestors;
+  uint64_t[]                  ancestorsOuterWindowIDs;
   nsCString[]                 corsUnsafeHeaders;
   bool                        forcePreflight;
   bool                        isPreflight;
   bool                        forceHSTSPriming;
   bool                        mixedContentWouldBlock;
   bool                        isHSTSPriming;
   bool                        isHSTSPrimingUpgrade;
 };