From b9438341f0a219552c767cc8202a32822a88b400 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Sun, 1 Mar 2020 04:16:22 +0000 Subject: [PATCH] Bug 1617789 - Set content process Document pointer without relying on LoadInfo. r=nika We currently extract Document pointers from the old LoadInfo, and attach them to the new one, such that they aren't lost during serialization. This moves us to setting them more directly from their original source, since the old LoadInfo is no longer reliable (and was only configured fully in the parent process). Differential Revision: https://phabricator.services.mozilla.com/D64249 --HG-- extra : moz-landing-system : lando --- ipc/glue/BackgroundUtils.cpp | 30 ++++++++++++++++++---------- ipc/glue/BackgroundUtils.h | 6 ++---- netwerk/base/LoadInfo.h | 6 ++---- netwerk/ipc/DocumentChannelChild.cpp | 28 +++++++++++++------------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 717d244f94fc..d7b443030629 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -27,11 +27,13 @@ #include "URIUtils.h" #include "mozilla/dom/nsCSPUtils.h" #include "mozilla/dom/nsCSPContext.h" +#include "mozilla/dom/BrowsingContext.h" namespace mozilla { using mozilla::BasePrincipal; using mozilla::Maybe; +using mozilla::dom::BrowsingContext; using mozilla::dom::ServiceWorkerDescriptor; using namespace mozilla::net; @@ -587,16 +589,15 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, nsresult LoadInfoArgsToLoadInfo( const Maybe& aOptionalLoadInfoArgs, nsILoadInfo** outLoadInfo) { - return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, nullptr, - outLoadInfo); + return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo); } nsresult LoadInfoArgsToLoadInfo( - const Maybe& aOptionalLoadInfoArgs, nsINode* aLoadingContext, + const Maybe& aOptionalLoadInfoArgs, nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo) { RefPtr loadInfo; - nsresult rv = LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aLoadingContext, - aCspToInheritLoadingContext, - getter_AddRefs(loadInfo)); + nsresult rv = + LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aCspToInheritLoadingContext, + getter_AddRefs(loadInfo)); NS_ENSURE_SUCCESS(rv, rv); loadInfo.forget(outLoadInfo); @@ -605,11 +606,10 @@ nsresult LoadInfoArgsToLoadInfo( nsresult LoadInfoArgsToLoadInfo( const Maybe& aOptionalLoadInfoArgs, LoadInfo** outLoadInfo) { - return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, nullptr, - outLoadInfo); + return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo); } nsresult LoadInfoArgsToLoadInfo( - const Maybe& aOptionalLoadInfoArgs, nsINode* aLoadingContext, + const Maybe& aOptionalLoadInfoArgs, nsINode* aCspToInheritLoadingContext, LoadInfo** outLoadInfo) { if (aOptionalLoadInfoArgs.isNothing()) { *outLoadInfo = nullptr; @@ -735,6 +735,16 @@ nsresult LoadInfoArgsToLoadInfo( cspToInherit = CSPInfoToCSP(cspToInheritInfo.ref(), doc); } + // Restore the loadingContext for frames using the BrowsingContext's + // embedder element. Note that this only works if the embedder is + // same-process, so won't be fission compatible. + nsCOMPtr loadingContext; + RefPtr frameBrowsingContext = + BrowsingContext::Get(loadInfoArgs.frameBrowsingContextID()); + if (frameBrowsingContext) { + loadingContext = frameBrowsingContext->GetEmbedderElement(); + } + RefPtr loadInfo = new mozilla::LoadInfo( loadingPrincipal, triggeringPrincipal, principalToInherit, sandboxedLoadingPrincipal, topLevelPrincipal, @@ -767,7 +777,7 @@ nsresult LoadInfoArgsToLoadInfo( loadInfoArgs.documentHasLoaded(), loadInfoArgs.allowListFutureDocumentsCreatedFromThisRedirectChain(), loadInfoArgs.cspNonce(), loadInfoArgs.skipContentSniffing(), - loadInfoArgs.requestBlockingReason(), aLoadingContext); + loadInfoArgs.requestBlockingReason(), loadingContext); if (loadInfoArgs.isFromProcessingFrameAttributes()) { loadInfo->SetIsFromProcessingFrameAttributes(); diff --git a/ipc/glue/BackgroundUtils.h b/ipc/glue/BackgroundUtils.h index d45d27585bba..283b116073c1 100644 --- a/ipc/glue/BackgroundUtils.h +++ b/ipc/glue/BackgroundUtils.h @@ -136,15 +136,13 @@ nsresult LoadInfoArgsToLoadInfo( nsILoadInfo** outLoadInfo); nsresult LoadInfoArgsToLoadInfo( const Maybe& aOptionalLoadInfoArgs, - nsINode* aLoadingContext, nsINode* aCspToInheritLoadingContext, - nsILoadInfo** outLoadInfo); + nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo); nsresult LoadInfoArgsToLoadInfo( const Maybe& aOptionalLoadInfoArgs, mozilla::net::LoadInfo** outLoadInfo); nsresult LoadInfoArgsToLoadInfo( const Maybe& aOptionalLoadInfoArgs, - nsINode* aLoadingContext, nsINode* aCspToInheritLoadingContext, - mozilla::net::LoadInfo** outLoadInfo); + nsINode* aCspToInheritLoadingContext, mozilla::net::LoadInfo** outLoadInfo); /** * Fills ParentLoadInfoForwarderArgs with properties we want to carry to child diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 73e1798b2bae..fcac8c4e2986 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -40,8 +40,7 @@ namespace ipc { // we have to forward declare that function so we can use it as a friend. nsresult LoadInfoArgsToLoadInfo( const Maybe& aLoadInfoArgs, - nsINode* aLoadingContext, nsINode* aCspToInheritLoadingContext, - net::LoadInfo** outLoadInfo); + nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo); } // namespace ipc namespace net { @@ -167,8 +166,7 @@ class LoadInfo final : public nsILoadInfo { friend nsresult mozilla::ipc::LoadInfoArgsToLoadInfo( const Maybe& aLoadInfoArgs, - nsINode* aLoadingContext, nsINode* aCspToInheritLoadingContext, - net::LoadInfo** outLoadInfo); + nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo); ~LoadInfo() = default; diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index cb45d381cf46..2eb89e9f0585 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -220,20 +220,22 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( LOG(("DocumentChannelChild RecvRedirectToRealChannel [this=%p, uri=%s]", this, aArgs.uri()->GetSpecOrDefault().get())); - RefPtr loadingDocument; - mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument)); - + // The document that created the cspToInherit. + // This is used when deserializing LoadInfo from the parent + // process, since we can't serialize Documents directly. + // TODO: For a fission OOP iframe this will be unavailable, + // as will the loadingContext computed in LoadInfoArgsToLoadInfo. + // Figure out if we need these for cross-origin subdocs. RefPtr cspToInheritLoadingDocument; - nsCOMPtr policy = mLoadInfo->GetCspToInherit(); + nsCOMPtr policy = mLoadState->Csp(); if (policy) { nsWeakPtr ctx = static_cast(policy.get())->GetLoadingContext(); cspToInheritLoadingDocument = do_QueryReferent(ctx); } nsCOMPtr loadInfo; - MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(aArgs.loadInfo(), loadingDocument, - cspToInheritLoadingDocument, - getter_AddRefs(loadInfo))); + MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo( + aArgs.loadInfo(), cspToInheritLoadingDocument, getter_AddRefs(loadInfo))); mLastVisitInfo = std::move(aArgs.lastVisitInfo()); mRedirects = std::move(aArgs.redirects()); @@ -397,25 +399,23 @@ IPCResult DocumentChannelChild::RecvConfirmRedirect( // not propagating the redirect into this process, we don't have an nsIChannel // for the redirection and we have to do the checks manually. // This just checks CSP thus far, hopefully there's not much else needed. - RefPtr loadingDocument; - mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument)); RefPtr cspToInheritLoadingDocument; - nsCOMPtr policy = mLoadInfo->GetCspToInherit(); + nsCOMPtr policy = mLoadState->Csp(); if (policy) { nsWeakPtr ctx = static_cast(policy.get())->GetLoadingContext(); cspToInheritLoadingDocument = do_QueryReferent(ctx); } nsCOMPtr loadInfo; - MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo( - Some(std::move(aLoadInfo)), loadingDocument, cspToInheritLoadingDocument, - getter_AddRefs(loadInfo))); + MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(Some(std::move(aLoadInfo)), + cspToInheritLoadingDocument, + getter_AddRefs(loadInfo))); nsCOMPtr originalUri; GetOriginalURI(getter_AddRefs(originalUri)); Maybe cancelCode; nsresult rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, - mLoadInfo, cancelCode); + loadInfo, cancelCode); aResolve(Tuple&>(rv, cancelCode)); return IPC_OK(); }