Bug 1617789 - Move loadInfo configuration into CreateAndConfigureRealChannelForLoadState so that it runs in the parent process with DocumentChannel. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D63997

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2020-03-01 04:15:44 +00:00
parent d912d2f8d9
commit 1103c09263
3 changed files with 127 additions and 112 deletions

View File

@ -9358,17 +9358,64 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) {
/* static */ bool nsDocShell::CreateAndConfigureRealChannelForLoadState(
nsDocShellLoadState* aLoadState, LoadInfo* aLoadInfo,
nsIInterfaceRequestor* aCallbacks, nsDocShell* aDocShell,
nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey,
bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags,
nsresult& aRv, nsIChannel** aChannel) {
MOZ_ASSERT(aLoadInfo);
const OriginAttributes& aOriginAttributes, nsLoadFlags aLoadFlags,
uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc,
bool aHasNonEmptySandboxingFlags, nsresult& aRv, nsIChannel** aChannel) {
nsString srcdoc = VoidString();
bool isSrcdoc = aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC);
if (isSrcdoc) {
srcdoc = aLoadState->SrcdocData();
}
if (aLoadState->PrincipalToInherit()) {
aLoadInfo->SetPrincipalToInherit(aLoadState->PrincipalToInherit());
}
aLoadInfo->SetLoadTriggeredFromExternal(aLoadState->LoadType() ==
LOAD_NORMAL_EXTERNAL);
aLoadInfo->SetForceAllowDataURI(
aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI));
aLoadInfo->SetOriginalFrameSrcLoad(
aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC));
bool inheritAttrs = false;
if (aLoadState->PrincipalToInherit()) {
inheritAttrs = nsContentUtils::ChannelShouldInheritPrincipal(
aLoadState->PrincipalToInherit(), aLoadState->URI(),
true, // aInheritForAboutBlank
isSrcdoc);
}
OriginAttributes attrs;
// Inherit origin attributes from PrincipalToInherit if inheritAttrs is
// true. Otherwise we just use the origin attributes from docshell.
if (inheritAttrs) {
MOZ_ASSERT(aLoadState->PrincipalToInherit(),
"We should have PrincipalToInherit here.");
attrs = aLoadState->PrincipalToInherit()->OriginAttributesRef();
// If firstPartyIsolation is not enabled, then PrincipalToInherit should
// have the same origin attributes with docshell.
MOZ_ASSERT_IF(!OriginAttributes::IsFirstPartyEnabled(),
attrs == aOriginAttributes);
} else {
attrs = aOriginAttributes;
attrs.SetFirstPartyDomain(aIsTopLevelDoc, aLoadState->URI());
}
aRv = aLoadInfo->SetOriginAttributes(attrs);
if (NS_WARN_IF(NS_FAILED(aRv))) {
return false;
}
if (aLoadState->GetIsFromProcessingFrameAttributes()) {
aLoadInfo->SetIsFromProcessingFrameAttributes();
}
// Propagate the IsFormSubmission flag to the loadInfo.
if (aLoadState->IsFormSubmission()) {
aLoadInfo->SetIsFormSubmission(true);
}
nsCOMPtr<nsIChannel> channel;
aRv = CreateRealChannelForDocument(getter_AddRefs(channel), aLoadState->URI(),
aLoadInfo, aCallbacks, aDocShell,
@ -9567,6 +9614,60 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) {
}
}
nsCOMPtr<nsIURI> rpURI;
aLoadInfo->GetResultPrincipalURI(getter_AddRefs(rpURI));
Maybe<nsCOMPtr<nsIURI>> originalResultPrincipalURI;
aLoadState->GetMaybeResultPrincipalURI(originalResultPrincipalURI);
if (originalResultPrincipalURI &&
(!aLoadState->KeepResultPrincipalURIIfSet() || !rpURI)) {
// Unconditionally override, we want the replay to be equal to what has
// been captured.
aLoadInfo->SetResultPrincipalURI(originalResultPrincipalURI.ref());
}
if (aLoadState->OriginalURI() && aLoadState->LoadReplace()) {
// The LOAD_REPLACE flag and its handling here will be removed as part
// of bug 1319110. For now preserve its restoration here to not break
// any code expecting it being set specially on redirected channels.
// If the flag has originally been set to change result of
// NS_GetFinalChannelURI it won't have any effect and also won't cause
// any harm.
uint32_t loadFlags;
aRv = channel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(aRv, false);
channel->SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
}
nsCOMPtr<nsIContentSecurityPolicy> csp = aLoadState->Csp();
if (csp) {
// Navigational requests that are same origin need to be upgraded in case
// upgrade-insecure-requests is present.
bool upgradeInsecureRequests = false;
csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
if (upgradeInsecureRequests) {
// only upgrade if the navigation is same origin
nsCOMPtr<nsIPrincipal> resultPrincipal;
aRv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
channel, getter_AddRefs(resultPrincipal));
NS_ENSURE_SUCCESS(aRv, false);
if (IsConsideredSameOriginForUIR(aLoadState->TriggeringPrincipal(),
resultPrincipal)) {
aLoadInfo->SetUpgradeInsecureRequests();
}
}
// For document loads we store the CSP that potentially needs to
// be inherited by the new document, e.g. in case we are loading
// an opaque origin like a data: URI. The actual inheritance
// check happens within Document::InitCSP().
// Please create an actual copy of the CSP (do not share the same
// reference) otherwise a Meta CSP of an opaque origin will
// incorrectly be propagated to the embedding document.
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(csp.get()));
aLoadInfo->SetCSPToInherit(cspToInherit);
}
channel.forget(aChannel);
return true;
}
@ -9746,11 +9847,11 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
// 1. ChannelShouldInheritPrincipal returns true.
// 2. aLoadState->URI() is not data: URI, or data: URI is not
// configured as unique opaque origin.
bool inheritAttrs = false, inheritPrincipal = false;
bool inheritPrincipal = false;
if (aLoadState->PrincipalToInherit()) {
bool isSrcdoc = aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC);
inheritAttrs = nsContentUtils::ChannelShouldInheritPrincipal(
bool inheritAttrs = nsContentUtils::ChannelShouldInheritPrincipal(
aLoadState->PrincipalToInherit(), aLoadState->URI(),
true, // aInheritForAboutBlank
isSrcdoc);
@ -9800,16 +9901,6 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
Maybe<mozilla::dom::ServiceWorkerDescriptor>(),
sandboxFlags);
if (aLoadState->PrincipalToInherit()) {
loadInfo->SetPrincipalToInherit(aLoadState->PrincipalToInherit());
}
loadInfo->SetLoadTriggeredFromExternal(aLoadState->LoadType() ==
LOAD_NORMAL_EXTERNAL);
loadInfo->SetForceAllowDataURI(
aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI));
loadInfo->SetOriginalFrameSrcLoad(
aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC));
// We have to do this in case our OriginAttributes are different from the
// OriginAttributes of the parent document. Or in case there isn't a
// parent document.
@ -9817,37 +9908,6 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
(contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
GetIsMozBrowser());
OriginAttributes attrs;
// Inherit origin attributes from PrincipalToInherit if inheritAttrs is
// true. Otherwise we just use the origin attributes from docshell.
if (inheritAttrs) {
MOZ_ASSERT(aLoadState->PrincipalToInherit(),
"We should have PrincipalToInherit here.");
attrs = aLoadState->PrincipalToInherit()->OriginAttributesRef();
// If firstPartyIsolation is not enabled, then PrincipalToInherit should
// have the same origin attributes with docshell.
MOZ_ASSERT_IF(!OriginAttributes::IsFirstPartyEnabled(),
attrs == GetOriginAttributes());
} else {
attrs = GetOriginAttributes();
attrs.SetFirstPartyDomain(isTopLevelDoc, aLoadState->URI());
}
rv = loadInfo->SetOriginAttributes(attrs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (aLoadState->GetIsFromProcessingFrameAttributes()) {
loadInfo->SetIsFromProcessingFrameAttributes();
}
// Propagate the IsFormSubmission flag to the loadInfo.
if (aLoadState->IsFormSubmission()) {
loadInfo->SetIsFormSubmission(true);
}
/* Get the cache Key from SH */
uint32_t cacheKey = 0;
if (mLSHE) {
@ -9875,8 +9935,8 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
isTopLevelDoc, sandboxFlags);
channel->SetNotificationCallbacks(this);
} else if (!CreateAndConfigureRealChannelForLoadState(
aLoadState, loadInfo, this, this, loadFlags, mLoadType,
cacheKey, isActive, isTopLevelDoc,
aLoadState, loadInfo, this, this, GetOriginAttributes(),
loadFlags, mLoadType, cacheKey, isActive, isTopLevelDoc,
mBrowsingContext->GetSandboxFlags(), rv,
getter_AddRefs(channel))) {
return rv;
@ -9888,59 +9948,8 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
NS_ADDREF(*aRequest = channel);
}
nsCOMPtr<nsIURI> rpURI;
loadInfo->GetResultPrincipalURI(getter_AddRefs(rpURI));
Maybe<nsCOMPtr<nsIURI>> originalResultPrincipalURI;
aLoadState->GetMaybeResultPrincipalURI(originalResultPrincipalURI);
if (originalResultPrincipalURI &&
(!aLoadState->KeepResultPrincipalURIIfSet() || !rpURI)) {
// Unconditionally override, we want the replay to be equal to what has
// been captured.
loadInfo->SetResultPrincipalURI(originalResultPrincipalURI.ref());
}
if (aLoadState->OriginalURI() && aLoadState->LoadReplace()) {
// The LOAD_REPLACE flag and its handling here will be removed as part
// of bug 1319110. For now preserve its restoration here to not break
// any code expecting it being set specially on redirected channels.
// If the flag has originally been set to change result of
// NS_GetFinalChannelURI it won't have any effect and also won't cause
// any harm.
uint32_t loadFlags;
rv = channel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
}
nsCOMPtr<nsIContentSecurityPolicy> csp = aLoadState->Csp();
if (csp) {
// Navigational requests that are same origin need to be upgraded in case
// upgrade-insecure-requests is present.
bool upgradeInsecureRequests = false;
csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
if (upgradeInsecureRequests) {
// only upgrade if the navigation is same origin
nsCOMPtr<nsIPrincipal> resultPrincipal;
rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
channel, getter_AddRefs(resultPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
if (IsConsideredSameOriginForUIR(aLoadState->TriggeringPrincipal(),
resultPrincipal)) {
static_cast<LoadInfo*>(loadInfo.get())->SetUpgradeInsecureRequests();
}
}
// For document loads we store the CSP that potentially needs to
// be inherited by the new document, e.g. in case we are loading
// an opaque origin like a data: URI. The actual inheritance
// check happens within Document::InitCSP().
// Please create an actual copy of the CSP (do not share the same
// reference) otherwise a Meta CSP of an opaque origin will
// incorrectly be propagated to the embedding document.
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(csp.get()));
static_cast<LoadInfo*>(loadInfo.get())->SetCSPToInherit(cspToInherit);
// Check CSP navigate-to
bool allowsNavigateTo = false;
rv = csp->GetAllowsNavigateTo(aLoadState->URI(),
@ -10190,16 +10199,18 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
MaybeCreateInitialClientSource();
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
if (aOpenFlags & nsIURILoader::REDIRECTED_CHANNEL) {
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
LoadInfo* li = static_cast<LoadInfo*>(loadInfo.get());
if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_DOCUMENT) {
li->UpdateBrowsingContextID(mBrowsingContext->Id());
} else if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT) {
li->UpdateFrameBrowsingContextID(mBrowsingContext->Id());
LoadInfo* li = static_cast<LoadInfo*>(loadInfo.get());
if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_DOCUMENT) {
li->UpdateBrowsingContextID(mBrowsingContext->Id());
} else if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT) {
li->UpdateFrameBrowsingContextID(mBrowsingContext->Id());
}
}
// TODO: more attributes need to be updated on the LoadInfo (bug 1561706)

View File

@ -501,6 +501,7 @@ class nsDocShell final : public nsDocLoader,
static bool CreateAndConfigureRealChannelForLoadState(
nsDocShellLoadState* aLoadState, mozilla::net::LoadInfo* aLoadInfo,
nsIInterfaceRequestor* aCallbacks, nsDocShell* aDocShell,
const mozilla::OriginAttributes& aOriginAttributes,
nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey,
bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags,
nsresult& rv, nsIChannel** aChannel);

View File

@ -261,9 +261,12 @@ bool DocumentLoadListener::Open(
LOG(("DocumentLoadListener Open [this=%p, uri=%s]", this,
aLoadState->URI()->GetSpecOrDefault().get()));
OriginAttributes attrs;
mLoadContext->GetOriginAttributes(attrs);
if (!nsDocShell::CreateAndConfigureRealChannelForLoadState(
aLoadState, aLoadInfo, mParentChannelListener, nullptr, aLoadFlags,
aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc,
aLoadState, aLoadInfo, mParentChannelListener, nullptr, attrs,
aLoadFlags, aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc,
aHasNonEmptySandboxingFlags, *aRv, getter_AddRefs(mChannel))) {
mParentChannelListener = nullptr;
return false;