From 5d30ec3616f286aedf2a82b425cdc7c435f29c26 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 25 Sep 2019 08:25:29 +0000 Subject: [PATCH] Bug 1583076 - Pass LoadInfo back for the current channel when confirming redirects. r=ckerschb We previously used the initial LoadInfo from when the DocumentChannel was created, but need the one from the most recent channel in the parent. Differential Revision: https://phabricator.services.mozilla.com/D46741 --HG-- extra : moz-landing-system : lando --- netwerk/ipc/DocumentChannelChild.cpp | 17 +++++++++------ netwerk/ipc/DocumentChannelChild.h | 3 ++- netwerk/ipc/DocumentChannelParent.cpp | 31 ++++++++++++++++----------- netwerk/ipc/PDocumentChannel.ipdl | 2 +- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index eaea8faa73be..fd59458a448b 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -255,12 +255,8 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( const uint32_t& aRedirectFlags, const Maybe& aContentDisposition, const Maybe& aContentDispositionFilename, RedirectToRealChannelResolver&& aResolve) { - nsCOMPtr originalLoadInfo; RefPtr loadingDocument; - GetLoadInfo(getter_AddRefs(originalLoadInfo)); - if (originalLoadInfo) { - originalLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument)); - } + mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument)); nsCOMPtr loadInfo; nsresult rv = LoadInfoArgsToLoadInfo(aLoadInfo, loadingDocument, @@ -404,11 +400,18 @@ DocumentChannelChild::OnRedirectVerifyCallback(nsresult aStatusCode) { } IPCResult DocumentChannelChild::RecvConfirmRedirect( - nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve) { + const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri, + ConfirmRedirectResolver&& aResolve) { // This is effectively the same as AsyncOnChannelRedirect, except since we're // 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)); + nsCOMPtr loadInfo; + MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(Some(aLoadInfo), loadingDocument, + getter_AddRefs(loadInfo))); + nsCOMPtr originalUri; nsresult rv = GetOriginalURI(getter_AddRefs(originalUri)); if (NS_FAILED(rv)) { @@ -418,7 +421,7 @@ IPCResult DocumentChannelChild::RecvConfirmRedirect( } Maybe cancelCode; - rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, mLoadInfo, + rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, loadInfo, cancelCode); aResolve(Tuple&>(rv, cancelCode)); return IPC_OK(); diff --git a/netwerk/ipc/DocumentChannelChild.h b/netwerk/ipc/DocumentChannelChild.h index d553cae243a4..ebf1ac1eff8b 100644 --- a/netwerk/ipc/DocumentChannelChild.h +++ b/netwerk/ipc/DocumentChannelChild.h @@ -82,7 +82,8 @@ class DocumentChannelChild final : public PDocumentChannelChild, const nsCString& aLists, const nsCString& aFullHash); mozilla::ipc::IPCResult RecvConfirmRedirect( - nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve); + const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri, + ConfirmRedirectResolver&& aResolve); void DoFailedAsyncOpen(const nsresult& aStatusCode); diff --git a/netwerk/ipc/DocumentChannelParent.cpp b/netwerk/ipc/DocumentChannelParent.cpp index 720450d2ef2c..9bce6c0ed9a3 100644 --- a/netwerk/ipc/DocumentChannelParent.cpp +++ b/netwerk/ipc/DocumentChannelParent.cpp @@ -801,24 +801,31 @@ DocumentChannelParent::AsyncOnChannelRedirect( // process so that it can send events. Send a message to // our content process to ask CSP if we should allow this // redirect, and wait for confirmation. + nsCOMPtr loadInfo = aOldChannel->LoadInfo(); + Maybe loadInfoArgs; + MOZ_ALWAYS_SUCCEEDS(ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs)); + MOZ_ASSERT(loadInfoArgs.isSome()); + nsCOMPtr newUri; nsresult rv = aNewChannel->GetURI(getter_AddRefs(newUri)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr callback(aCallback); nsCOMPtr oldChannel(aOldChannel); - SendConfirmRedirect(newUri)->Then( - GetCurrentThreadSerialEventTarget(), __func__, - [callback, oldChannel](const Tuple>& aResult) { - if (Get<1>(aResult)) { - oldChannel->Cancel(*Get<1>(aResult)); - } - callback->OnRedirectVerifyCallback(Get<0>(aResult)); - }, - [callback, oldChannel](const mozilla::ipc::ResponseRejectReason) { - oldChannel->Cancel(NS_ERROR_DOM_BAD_URI); - callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED); - }); + SendConfirmRedirect(*loadInfoArgs, newUri) + ->Then( + GetCurrentThreadSerialEventTarget(), __func__, + [callback, + oldChannel](const Tuple>& aResult) { + if (Get<1>(aResult)) { + oldChannel->Cancel(*Get<1>(aResult)); + } + callback->OnRedirectVerifyCallback(Get<0>(aResult)); + }, + [callback, oldChannel](const mozilla::ipc::ResponseRejectReason) { + oldChannel->Cancel(NS_ERROR_DOM_BAD_URI); + callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED); + }); // Clear out our nsIParentChannel functions, since a normal parent // channel would actually redirect and not have those values on the new one. diff --git a/netwerk/ipc/PDocumentChannel.ipdl b/netwerk/ipc/PDocumentChannel.ipdl index 86a725b96fb0..7bf93e90bd52 100644 --- a/netwerk/ipc/PDocumentChannel.ipdl +++ b/netwerk/ipc/PDocumentChannel.ipdl @@ -75,7 +75,7 @@ child: uint32_t? aContentDisposition, nsString? aContentDispositionFilename) returns(nsresult rv); - async ConfirmRedirect(nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode); + async ConfirmRedirect(LoadInfoArgs aLoadInfo, nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode); // Tell child to delete channel (all IPDL deletes must be done from child to // avoid races: see bug 591708).