Bug 1538028 - Part 2: Track TriggeringRemoteType through nsDocShellLoadState and LoadInfo, r=smaug,ckerschb,necko-reviewers,valentin

This is done using slightly different mechanisms for each of LoadInfo and
nsDocShellLoadState, and will be used in the next part to validate document
loads based on the RemoteType responsible for the load.

For subresource loads, the TriggeringRemoteType is fairly straightforward - it
is the process which created the channel. We can handle this by getting the
current remote type when creating the channel, and then using the remote type
of the sending process when receiving the LoadInfo over IPC to either replace
the triggering remote type, or validate it.

For document loads, the situation is a bit more complex, as there are at least
3 (potentially-)different processes responsible for different parts of the
navigation:

 1. The "Triggering Process" is the process which provided the URI to load.
    This is also the process which provides the Triggering Principal. This is
    the process being tracked in this patch.

 2. The "Loading Process" is the process which actually creates the channel and
    starts the load. This may be the same as the triggering process, or may be
    a different process starting the navigation on behalf of the triggering
    process. In general this is the process hosting the current docshell,
    though it may be the parent process in the case of parent-initiated loads.

 3. The "Final Process" is the process which receives the response and renders
    the final document. This isn't known at channel creation time, and is
    determined by the result principal and process isolation policy.

This change uses a serializer and special field on nsDocShellLoadState to track
the "Triggering Process" for the load, even as the load state is serialized
between processes by tracking which loads were sent into which content
processes, and matching them up when the parent process sees them again. The
information is then copied into the LoadInfo before configuring the real
channel, so it can be used for security checks.

The "Triggering Process" is overridden to be the parent process for history
loads, as history loads are often started in processes which wouldn't normally
be able to navigate to those pages. This is OK thanks to the changes in part 1
which validate history loads against the real session history when SHIP is
enabled.

Differential Revision: https://phabricator.services.mozilla.com/D161198
This commit is contained in:
Nika Layzell 2022-11-29 20:41:45 +00:00
Родитель 03335b6d32
Коммит 34e62a0d9c
28 изменённых файлов: 452 добавлений и 97 удалений

Просмотреть файл

@ -9852,6 +9852,9 @@ nsIPrincipal* nsDocShell::GetInheritedPrincipal(
srcdoc = aLoadState->SrcdocData();
}
aLoadInfo->SetTriggeringRemoteType(
aLoadState->GetEffectiveTriggeringRemoteType());
if (aLoadState->PrincipalToInherit()) {
aLoadInfo->SetPrincipalToInherit(aLoadState->PrincipalToInherit());
}

Просмотреть файл

@ -18,6 +18,8 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Components.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_fission.h"
@ -40,10 +42,17 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
: nsDocShellLoadState(aURI, nsContentUtils::GenerateLoadIdentifier()) {}
nsDocShellLoadState::nsDocShellLoadState(
const DocShellLoadStateInit& aLoadState)
const DocShellLoadStateInit& aLoadState, mozilla::ipc::IProtocol* aActor,
bool* aReadSuccess)
: mNotifiedBeforeUnloadListeners(false),
mLoadIdentifier(aLoadState.LoadIdentifier()) {
MOZ_ASSERT(aLoadState.URI(), "Cannot create a LoadState with a null URI!");
// If we return early, we failed to read in the data.
*aReadSuccess = false;
if (!aLoadState.URI()) {
MOZ_ASSERT_UNREACHABLE("Cannot create a LoadState with a null URI!");
return;
}
mResultPrincipalURI = aLoadState.ResultPrincipalURI();
mResultPrincipalURIIsSome = aLoadState.ResultPrincipalURIIsSome();
mKeepResultPrincipalURIIfSet = aLoadState.KeepResultPrincipalURIIfSet();
@ -75,6 +84,7 @@ nsDocShellLoadState::nsDocShellLoadState(
mPrincipalToInherit = aLoadState.PrincipalToInherit();
mPartitionedPrincipalToInherit = aLoadState.PartitionedPrincipalToInherit();
mTriggeringSandboxFlags = aLoadState.TriggeringSandboxFlags();
mTriggeringRemoteType = aLoadState.TriggeringRemoteType();
mCsp = aLoadState.Csp();
mOriginalURIString = aLoadState.OriginalURIString();
mCancelContentJSEpoch = aLoadState.CancelContentJSEpoch();
@ -89,6 +99,45 @@ nsDocShellLoadState::nsDocShellLoadState(
}
mUnstrippedURI = aLoadState.UnstrippedURI();
mRemoteTypeOverride = aLoadState.RemoteTypeOverride();
// We know this was created remotely, as we just received it over IPC.
mWasCreatedRemotely = true;
// If we're in the parent process, potentially validate against a LoadState
// which we sent to the source content process.
if (XRE_IsParentProcess()) {
mozilla::ipc::IToplevelProtocol* top = aActor->ToplevelProtocol();
if (!top ||
top->GetProtocolId() != mozilla::ipc::ProtocolId::PContentMsgStart ||
top->GetSide() != mozilla::ipc::ParentSide) {
aActor->FatalError("nsDocShellLoadState must be received over PContent");
return;
}
ContentParent* cp = static_cast<ContentParent*>(top);
// If this load was sent down to the content process as a navigation
// request, ensure it still matches the one we sent down.
if (RefPtr<nsDocShellLoadState> originalState =
cp->TakePendingLoadStateForId(mLoadIdentifier)) {
if (const char* mismatch = ValidateWithOriginalState(originalState)) {
aActor->FatalError(
nsPrintfCString(
"nsDocShellLoadState %s changed while in content process",
mismatch)
.get());
return;
}
} else if (mTriggeringRemoteType != cp->GetRemoteType()) {
// If we don't have a previous load to compare to, the content process
// must be the triggering process.
aActor->FatalError(
"nsDocShellLoadState with invalid triggering remote type");
return;
}
}
// We successfully read in the data - return a success value.
*aReadSuccess = true;
}
nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther)
@ -134,8 +183,15 @@ nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther)
mLoadIdentifier(aOther.mLoadIdentifier),
mChannelInitialized(aOther.mChannelInitialized),
mIsMetaRefresh(aOther.mIsMetaRefresh),
mWasCreatedRemotely(aOther.mWasCreatedRemotely),
mUnstrippedURI(aOther.mUnstrippedURI),
mRemoteTypeOverride(aOther.mRemoteTypeOverride) {
mRemoteTypeOverride(aOther.mRemoteTypeOverride),
mTriggeringRemoteType(aOther.mTriggeringRemoteType) {
MOZ_DIAGNOSTIC_ASSERT(
XRE_IsParentProcess(),
"Cloning a nsDocShellLoadState with the same load identifier is only "
"allowed in the parent process, as it could break triggering remote type "
"tracking in content.");
if (aOther.mLoadingSessionHistoryInfo) {
mLoadingSessionHistoryInfo = MakeUnique<LoadingSessionHistoryInfo>(
*aOther.mLoadingSessionHistoryInfo);
@ -168,11 +224,19 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier)
mIsFromProcessingFrameAttributes(false),
mLoadIdentifier(aLoadIdentifier),
mChannelInitialized(false),
mIsMetaRefresh(false) {
mIsMetaRefresh(false),
mWasCreatedRemotely(false),
mTriggeringRemoteType(XRE_IsContentProcess()
? ContentChild::GetSingleton()->GetRemoteType()
: NOT_REMOTE_TYPE) {
MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!");
}
nsDocShellLoadState::~nsDocShellLoadState() {}
nsDocShellLoadState::~nsDocShellLoadState() {
if (mWasCreatedRemotely && XRE_IsContentProcess()) {
ContentChild::GetSingleton()->SendCleanupPendingLoadState(mLoadIdentifier);
}
}
nsresult nsDocShellLoadState::CreateFromPendingChannel(
nsIChannel* aPendingChannel, uint64_t aLoadIdentifier,
@ -769,6 +833,24 @@ void nsDocShellLoadState::SetFileName(const nsAString& aFileName) {
mFileName = aFileName;
}
const nsCString& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const {
// Consider non-errorpage loads from session history as being triggred by the
// parent process, as we'll validate them against the history entry.
//
// NOTE: Keep this check in-sync with the session-history validation check in
// `DocumentLoadListener::Open`!
if (LoadIsFromSessionHistory() && LoadType() != LOAD_ERROR_PAGE) {
return NOT_REMOTE_TYPE;
}
return mTriggeringRemoteType;
}
void nsDocShellLoadState::SetTriggeringRemoteType(
const nsACString& aTriggeringRemoteType) {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent");
mTriggeringRemoteType = aTriggeringRemoteType;
}
nsresult nsDocShellLoadState::SetupInheritingPrincipal(
BrowsingContext::Type aType,
const mozilla::OriginAttributes& aOriginAttributes) {
@ -1021,7 +1103,63 @@ nsLoadFlags nsDocShellLoadState::CalculateChannelLoadFlags(
return loadFlags;
}
DocShellLoadStateInit nsDocShellLoadState::Serialize() {
const char* nsDocShellLoadState::ValidateWithOriginalState(
nsDocShellLoadState* aOriginalState) {
MOZ_ASSERT(mLoadIdentifier == aOriginalState->mLoadIdentifier);
// Check that `aOriginalState` is sufficiently similar to this state that
// they're performing the same load.
auto uriEq = [](nsIURI* a, nsIURI* b) -> bool {
bool eq = false;
return a == b || (a && b && NS_SUCCEEDED(a->Equals(b, &eq)) && eq);
};
if (!uriEq(mURI, aOriginalState->mURI)) {
return "URI";
}
if (!uriEq(mUnstrippedURI, aOriginalState->mUnstrippedURI)) {
return "UnstrippedURI";
}
if (!uriEq(mOriginalURI, aOriginalState->mOriginalURI)) {
return "OriginalURI";
}
if (!uriEq(mBaseURI, aOriginalState->mBaseURI)) {
return "BaseURI";
}
if (!mTriggeringPrincipal->Equals(aOriginalState->mTriggeringPrincipal)) {
return "TriggeringPrincipal";
}
if (mTriggeringSandboxFlags != aOriginalState->mTriggeringSandboxFlags) {
return "TriggeringSandboxFlags";
}
if (mTriggeringRemoteType != aOriginalState->mTriggeringRemoteType) {
return "TriggeringRemoteType";
}
if (mOriginalURIString != aOriginalState->mOriginalURIString) {
return "OriginalURIString";
}
if (mRemoteTypeOverride != aOriginalState->mRemoteTypeOverride) {
return "RemoteTypeOverride";
}
if (mSourceBrowsingContext.ContextId() !=
aOriginalState->mSourceBrowsingContext.ContextId()) {
return "SourceBrowsingContext";
}
// FIXME: Consider calculating less information in the target process so that
// we can validate more properties more easily.
// FIXME: Identify what other flags will not change when sent through a
// content process.
return nullptr;
}
DocShellLoadStateInit nsDocShellLoadState::Serialize(
mozilla::ipc::IProtocol* aActor) {
MOZ_ASSERT(aActor);
DocShellLoadStateInit loadState;
loadState.ResultPrincipalURI() = mResultPrincipalURI;
loadState.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome;
@ -1053,6 +1191,7 @@ DocShellLoadStateInit nsDocShellLoadState::Serialize() {
loadState.PrincipalToInherit() = mPrincipalToInherit;
loadState.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit;
loadState.TriggeringSandboxFlags() = mTriggeringSandboxFlags;
loadState.TriggeringRemoteType() = mTriggeringRemoteType;
loadState.Csp() = mCsp;
loadState.OriginalURIString() = mOriginalURIString;
loadState.CancelContentJSEpoch() = mCancelContentJSEpoch;
@ -1069,6 +1208,18 @@ DocShellLoadStateInit nsDocShellLoadState::Serialize() {
}
loadState.UnstrippedURI() = mUnstrippedURI;
loadState.RemoteTypeOverride() = mRemoteTypeOverride;
if (XRE_IsParentProcess()) {
mozilla::ipc::IToplevelProtocol* top = aActor->ToplevelProtocol();
MOZ_RELEASE_ASSERT(top &&
top->GetProtocolId() ==
mozilla::ipc::ProtocolId::PContentMsgStart &&
top->GetSide() == mozilla::ipc::ParentSide,
"nsDocShellLoadState must be sent over PContent");
ContentParent* cp = static_cast<ContentParent*>(top);
cp->StorePendingLoadState(this);
}
return loadState;
}

Просмотреть файл

@ -47,7 +47,8 @@ class nsDocShellLoadState final {
explicit nsDocShellLoadState(nsIURI* aURI);
explicit nsDocShellLoadState(
const mozilla::dom::DocShellLoadStateInit& aLoadState);
const mozilla::dom::DocShellLoadStateInit& aLoadState,
mozilla::ipc::IProtocol* aActor, bool* aReadSuccess);
explicit nsDocShellLoadState(const nsDocShellLoadState& aOther);
nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier);
@ -314,6 +315,17 @@ class nsDocShellLoadState final {
mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride);
}
// Determine the remote type of the process which should be considered
// responsible for this load for the purposes of security checks.
//
// This will generally be the process which created the nsDocShellLoadState
// originally, however non-errorpage history loads are always considered to be
// triggered by the parent process, as we can validate them against the
// history entry.
const nsCString& GetEffectiveTriggeringRemoteType() const;
void SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType);
// When loading a document through nsDocShell::LoadURI(), a special set of
// flags needs to be set based on other values in nsDocShellLoadState. This
// function calculates those flags, before the LoadState is passed to
@ -326,7 +338,8 @@ class nsDocShellLoadState final {
mozilla::dom::BrowsingContext* aBrowsingContext,
mozilla::Maybe<bool> aUriModified, mozilla::Maybe<bool> aIsXFOError);
mozilla::dom::DocShellLoadStateInit Serialize();
mozilla::dom::DocShellLoadStateInit Serialize(
mozilla::ipc::IProtocol* aActor);
void SetLoadIsFromSessionHistory(int32_t aOffset, bool aLoadingCurrentEntry);
void ClearLoadIsFromSessionHistory();
@ -338,6 +351,12 @@ class nsDocShellLoadState final {
// includes it needs to do so.
~nsDocShellLoadState();
// Given the original `nsDocShellLoadState` which was sent to a content
// process, validate that they corespond to the same load.
// Returns a static (telemetry-safe) string naming what did not match, or
// nullptr if it succeeds.
const char* ValidateWithOriginalState(nsDocShellLoadState* aOriginalState);
protected:
// This is the referrer for the load.
nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
@ -528,12 +547,18 @@ class nsDocShellLoadState final {
// True if the load was triggered by a meta refresh.
bool mIsMetaRefresh;
// True if the nsDocShellLoadState was received over IPC.
bool mWasCreatedRemotely = false;
// The original URI before query stripping happened. If it's present, it shows
// the query stripping happened. Otherwise, it will be a nullptr.
nsCOMPtr<nsIURI> mUnstrippedURI;
// If set, the remote type which the load should be completed within.
mozilla::Maybe<nsCString> mRemoteTypeOverride;
// Remote type of the process which originally requested the load.
nsCString mTriggeringRemoteType;
};
#endif /* nsDocShellLoadState_h__ */

Просмотреть файл

@ -3535,8 +3535,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
nsTArray<Endpoint<extensions::PStreamFilterParent>>&& aEndpoints,
CrossProcessRedirectResolver&& aResolve) {
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aArgs.loadInfo(),
getter_AddRefs(loadInfo));
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(
aArgs.loadInfo(), NOT_REMOTE_TYPE, getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed");
return IPC_OK();
@ -4301,8 +4301,8 @@ mozilla::ipc::IPCResult ContentChild::RecvReportFrameTimingData(
}
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(loadInfoArgs,
getter_AddRefs(loadInfo));
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(
loadInfoArgs, NOT_REMOTE_TYPE, getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed");
return IPC_OK();

Просмотреть файл

@ -2210,6 +2210,8 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
group->Unsubscribe(this);
}
MOZ_DIAGNOSTIC_ASSERT(mGroups.IsEmpty());
mPendingLoadStates.Clear();
}
void ContentParent::ActorDealloc() { mSelfRef = nullptr; }
@ -3642,6 +3644,26 @@ mozilla::ipc::IPCResult ContentParent::RecvFirstIdle() {
return IPC_OK();
}
already_AddRefed<nsDocShellLoadState> ContentParent::TakePendingLoadStateForId(
uint64_t aLoadIdentifier) {
return mPendingLoadStates.Extract(aLoadIdentifier).valueOr(nullptr).forget();
}
void ContentParent::StorePendingLoadState(nsDocShellLoadState* aLoadState) {
MOZ_DIAGNOSTIC_ASSERT(
!mPendingLoadStates.Contains(aLoadState->GetLoadIdentifier()),
"The same nsDocShellLoadState was sent to the same content process "
"twice? This will mess with cross-process tracking of loads");
mPendingLoadStates.InsertOrUpdate(aLoadState->GetLoadIdentifier(),
aLoadState);
}
mozilla::ipc::IPCResult ContentParent::RecvCleanupPendingLoadState(
uint64_t aLoadIdentifier) {
mPendingLoadStates.Remove(aLoadIdentifier);
return IPC_OK();
}
// We want ContentParent to show up in CC logs for debugging purposes, but we
// don't actually cycle collect it.
NS_IMPL_CYCLE_COLLECTION_0(ContentParent)

Просмотреть файл

@ -143,6 +143,10 @@ class ContentParent final : public PContentParent,
static LogModule* GetLog();
static ContentParent* Cast(PContentParent* aActor) {
return static_cast<ContentParent*>(aActor);
}
/**
* Create a ContentParent suitable for use later as a content process.
*/
@ -409,6 +413,12 @@ class ContentParent final : public PContentParent,
bool NeedsPermissionsUpdate(const nsACString& aPermissionKey) const;
// Manage pending load states which have been sent to this process, and are
// expected to be used to start a load imminently.
already_AddRefed<nsDocShellLoadState> TakePendingLoadStateForId(
uint64_t aLoadIdentifier);
void StorePendingLoadState(nsDocShellLoadState* aLoadState);
/**
* Kill our subprocess and make sure it dies. Should only be used
* in emergency situations since it bypasses the normal shutdown
@ -1400,6 +1410,8 @@ class ContentParent final : public PContentParent,
const MaybeDiscarded<BrowsingContext>& aContext,
const uint32_t aReloadFlags);
mozilla::ipc::IPCResult RecvCleanupPendingLoadState(uint64_t aLoadIdentifier);
// Notify the ContentChild to enable the input event prioritization when
// initializing.
void MaybeEnableRemoteInputEventQueue();
@ -1637,6 +1649,12 @@ class ContentParent final : public PContentParent,
nsTHashSet<RefPtr<BrowsingContextGroup>> mGroups;
// When we request a content process to load a document on our behalf, we'll
// record the nsDocShellLoadState we sent to the content process mapped by the
// load ID. If the load is then requested from the content process, we can
// compare the load state and ensure it matches.
nsTHashMap<uint64_t, RefPtr<nsDocShellLoadState>> mPendingLoadStates;
// See `BrowsingContext::mEpochs` for an explanation of this field.
uint64_t mBrowsingContextFieldEpoch = 0;

Просмотреть файл

@ -315,6 +315,10 @@ struct DocShellLoadStateInit
// responsible for causing the load to occur.
uint32_t TriggeringSandboxFlags;
// The provided remote type of the process responsible for causing the load to
// occur. Validated in the parent process.
nsCString TriggeringRemoteType;
nsCString? OriginalURIString;
int32_t? CancelContentJSEpoch;

Просмотреть файл

@ -9,20 +9,18 @@
#include "mozilla/ipc/IPDLParamTraits.h"
#include "nsSerializationHelper.h"
namespace mozilla::ipc {
namespace IPC {
void IPDLParamTraits<nsDocShellLoadState*>::Write(IPC::MessageWriter* aWriter,
IProtocol* aActor,
nsDocShellLoadState* aParam) {
void ParamTraits<nsDocShellLoadState*>::Write(IPC::MessageWriter* aWriter,
nsDocShellLoadState* aParam) {
MOZ_RELEASE_ASSERT(aParam);
WriteIPDLParam(aWriter, aActor, aParam->Serialize());
WriteParam(aWriter, aParam->Serialize(aWriter->GetActor()));
}
bool IPDLParamTraits<nsDocShellLoadState*>::Read(
IPC::MessageReader* aReader, IProtocol* aActor,
RefPtr<nsDocShellLoadState>* aResult) {
dom::DocShellLoadStateInit loadState;
if (!ReadIPDLParam(aReader, aActor, &loadState)) {
bool ParamTraits<nsDocShellLoadState*>::Read(
IPC::MessageReader* aReader, RefPtr<nsDocShellLoadState>* aResult) {
mozilla::dom::DocShellLoadStateInit loadState;
if (!ReadParam(aReader, &loadState)) {
return false;
}
@ -31,10 +29,18 @@ bool IPDLParamTraits<nsDocShellLoadState*>::Read(
// for nsDocShellLoadState, but makes it clearer that the
// DocShellLoadStateInit IPC object can't be clearly converted into a
// nsDocShellLoadState.
MOZ_ASSERT(loadState.URI());
if (!loadState.URI()) {
MOZ_ASSERT_UNREACHABLE("no URI in load state from IPC");
return false;
}
*aResult = new nsDocShellLoadState(loadState);
return true;
bool readSuccess = false;
RefPtr result =
new nsDocShellLoadState(loadState, aReader->GetActor(), &readSuccess);
if (readSuccess) {
*aResult = result.forget();
}
return readSuccess;
}
} // namespace mozilla::ipc
} // namespace IPC

Просмотреть файл

@ -14,20 +14,15 @@
#include "mozilla/ScrollbarPreferences.h"
#include "mozilla/ipc/IPDLParamTraits.h"
namespace mozilla::ipc {
namespace IPC {
template <>
struct IPDLParamTraits<nsDocShellLoadState*> {
static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
nsDocShellLoadState* aParam);
static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
struct ParamTraits<nsDocShellLoadState*> {
static void Write(IPC::MessageWriter* aWriter, nsDocShellLoadState* aParam);
static bool Read(IPC::MessageReader* aReader,
RefPtr<nsDocShellLoadState>* aResult);
};
} // namespace mozilla::ipc
namespace IPC {
template <>
struct ParamTraits<mozilla::ScrollbarPreference>
: public ContiguousEnumSerializerInclusive<

Просмотреть файл

@ -102,7 +102,6 @@ using struct CollectedInputDataValue from "mozilla/dom/SessionStoreMessageUtils.
using mozilla::ContentBlockingNotifier::StorageAccessPermissionGrantedReason from "mozilla/ContentBlockingNotifier.h";
using CallerType from "mozilla/dom/BindingDeclarations.h";
using mozilla::dom::EmbedderElementEventType from "mozilla/dom/TabMessageTypes.h";
[RefCounted] using class nsDocShellLoadState from "nsDocShellLoadState.h";
using mozilla::IntrinsicSize from "nsIFrame.h";
using mozilla::AspectRatio from "mozilla/AspectRatio.h";
using mozilla::NativeKeyBindingsType from "mozilla/NativeKeyBindingsType.h";

Просмотреть файл

@ -136,7 +136,6 @@ using mozilla::dom::MediaMetadataBase from "mozilla/dom/MediaMetadata.h";
using mozilla::dom::MediaSessionAction from "mozilla/dom/MediaSessionBinding.h";
using mozilla::dom::MediaSessionPlaybackState from "mozilla/dom/MediaSessionBinding.h";
using mozilla::dom::PositionState from "mozilla/dom/MediaSession.h";
[RefCounted] using class nsDocShellLoadState from "nsDocShellLoadState.h";
using mozilla::dom::ServiceWorkerShutdownState::Progress from "mozilla/dom/ServiceWorkerShutdownState.h";
using mozilla::ContentBlockingNotifier::StorageAccessPermissionGrantedReason from "mozilla/ContentBlockingNotifier.h";
using mozilla::ContentBlockingNotifier::BlockingDecision from "mozilla/ContentBlockingNotifier.h";
@ -1832,6 +1831,11 @@ parent:
async RemoveFromSessionHistory(
MaybeDiscardedBrowsingContext aContext, nsID changeID);
// Called when a nsDocShellLoadState which was received over IPC is
// destroyed in the content process to clean up pending state left behind
// tracking the load state in the parent process.
async CleanupPendingLoadState(uint64_t aLoadIdentifier);
both:
async ScriptError(nsString message, nsString sourceName, nsString sourceLine,
uint32_t lineNumber, uint32_t colNumber, uint32_t flags,

Просмотреть файл

@ -28,7 +28,6 @@ using JSActorMessageKind from "mozilla/dom/JSActor.h";
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
[MoveOnly] using mozilla::gfx::PaintFragment from "mozilla/gfx/CrossProcessPaint.h";
using nscolor from "nsColor.h";
[RefCounted] using class nsDocShellLoadState from "nsDocShellLoadState.h";
using mozilla::dom::XPCOMPermitUnloadAction from "nsIContentViewer.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";

Просмотреть файл

@ -400,7 +400,15 @@ nsresult WebrtcTCPSocket::OpenWithHttpProxy() {
nsCOMPtr<nsILoadInfo> loadInfo;
Maybe<net::LoadInfoArgs> loadInfoArgs = Some(mProxyConfig->loadInfoArgs());
rv = ipc::LoadInfoArgsToLoadInfo(loadInfoArgs, getter_AddRefs(loadInfo));
// FIXME: We don't know the remote type of the process which provided these
// LoadInfoArgs. Pass in `NOT_REMOTE_TYPE` as the origin process to blindly
// accept whatever value was passed by the other side for now, as we aren't
// using it for security checks here.
// If this code ever starts checking the triggering remote type, this needs to
// be changed.
rv = ipc::LoadInfoArgsToLoadInfo(loadInfoArgs, NOT_REMOTE_TYPE,
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
LOG(("WebrtcTCPSocket %p: could not init load info\n", this));
return rv;

Просмотреть файл

@ -447,6 +447,10 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
SerializeURI(resultPrincipalURI, optionalResultPrincipalURI);
}
nsCString triggeringRemoteType;
rv = aLoadInfo->GetTriggeringRemoteType(triggeringRemoteType);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<RedirectHistoryEntryInfo> redirectChainIncludingInternalRedirects;
for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
aLoadInfo->RedirectChainIncludingInternalRedirects()) {
@ -546,7 +550,7 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
*aOptionalLoadInfoArgs = Some(LoadInfoArgs(
loadingPrincipalInfo, triggeringPrincipalInfo, principalToInheritInfo,
topLevelPrincipalInfo, optionalResultPrincipalURI,
topLevelPrincipalInfo, optionalResultPrincipalURI, triggeringRemoteType,
aLoadInfo->GetSandboxedNullPrincipalID(), aLoadInfo->GetSecurityFlags(),
aLoadInfo->GetSandboxFlags(), aLoadInfo->GetTriggeringSandboxFlags(),
aLoadInfo->InternalContentPolicyType(),
@ -593,16 +597,18 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
nsresult LoadInfoArgsToLoadInfo(
const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
nsILoadInfo** outLoadInfo) {
return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo);
const nsACString& aOriginRemoteType, nsILoadInfo** outLoadInfo) {
return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aOriginRemoteType,
nullptr, outLoadInfo);
}
nsresult LoadInfoArgsToLoadInfo(
const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo) {
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
nsILoadInfo** outLoadInfo) {
RefPtr<LoadInfo> loadInfo;
nsresult rv =
LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aCspToInheritLoadingContext,
getter_AddRefs(loadInfo));
nsresult rv = LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aOriginRemoteType,
aCspToInheritLoadingContext,
getter_AddRefs(loadInfo));
NS_ENSURE_SUCCESS(rv, rv);
loadInfo.forget(outLoadInfo);
@ -610,12 +616,15 @@ nsresult LoadInfoArgsToLoadInfo(
}
nsresult LoadInfoArgsToLoadInfo(
const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs, LoadInfo** outLoadInfo) {
return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo);
const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
const nsACString& aOriginRemoteType, LoadInfo** outLoadInfo) {
return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aOriginRemoteType,
nullptr, outLoadInfo);
}
nsresult LoadInfoArgsToLoadInfo(
const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, LoadInfo** outLoadInfo) {
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
LoadInfo** outLoadInfo) {
if (aOptionalLoadInfoArgs.isNothing()) {
*outLoadInfo = nullptr;
return NS_OK;
@ -695,6 +704,20 @@ nsresult LoadInfoArgsToLoadInfo(
NS_ENSURE_TRUE(resultPrincipalURI, NS_ERROR_UNEXPECTED);
}
// If we received this message from a content process, reset
// triggeringRemoteType to the process which sent us the message. If the
// parent sent us the message, we trust it to provide the correct triggering
// remote type.
//
// This means that the triggering remote type will be reset if a LoadInfo is
// bounced through a content process, as the LoadInfo can no longer be
// validated to be coming from the originally specified remote type.
nsCString triggeringRemoteType = loadInfoArgs.triggeringRemoteType();
if (aOriginRemoteType != NOT_REMOTE_TYPE &&
aOriginRemoteType != triggeringRemoteType) {
triggeringRemoteType = aOriginRemoteType;
}
RedirectHistoryArray redirectChainIncludingInternalRedirects;
for (const RedirectHistoryEntryInfo& entryInfo :
loadInfoArgs.redirectChainIncludingInternalRedirects()) {
@ -818,10 +841,10 @@ nsresult LoadInfoArgsToLoadInfo(
RefPtr<mozilla::net::LoadInfo> loadInfo = new mozilla::net::LoadInfo(
loadingPrincipal, triggeringPrincipal, principalToInherit,
topLevelPrincipal, resultPrincipalURI, cookieJarSettings, cspToInherit,
loadInfoArgs.sandboxedNullPrincipalID(), clientInfo, reservedClientInfo,
initialClientInfo, controller, loadInfoArgs.securityFlags(),
loadInfoArgs.sandboxFlags(), loadInfoArgs.triggeringSandboxFlags(),
loadInfoArgs.contentPolicyType(),
triggeringRemoteType, loadInfoArgs.sandboxedNullPrincipalID(), clientInfo,
reservedClientInfo, initialClientInfo, controller,
loadInfoArgs.securityFlags(), loadInfoArgs.sandboxFlags(),
loadInfoArgs.triggeringSandboxFlags(), loadInfoArgs.contentPolicyType(),
static_cast<LoadTainting>(loadInfoArgs.tainting()),
loadInfoArgs.blockAllMixedContent(),
loadInfoArgs.upgradeInsecureRequests(),

Просмотреть файл

@ -144,16 +144,18 @@ nsresult LoadInfoToLoadInfoArgs(
*/
nsresult LoadInfoArgsToLoadInfo(
const Maybe<mozilla::net::LoadInfoArgs>& aOptionalLoadInfoArgs,
nsILoadInfo** outLoadInfo);
const nsACString& aOriginRemoteType, nsILoadInfo** outLoadInfo);
nsresult LoadInfoArgsToLoadInfo(
const Maybe<mozilla::net::LoadInfoArgs>& aOptionalLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo);
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
nsILoadInfo** outLoadInfo);
nsresult LoadInfoArgsToLoadInfo(
const Maybe<net::LoadInfoArgs>& aOptionalLoadInfoArgs,
const nsACString& aOriginRemoteType, mozilla::net::LoadInfo** outLoadInfo);
nsresult LoadInfoArgsToLoadInfo(
const Maybe<net::LoadInfoArgs>& aOptionalLoadInfoArgs,
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
mozilla::net::LoadInfo** outLoadInfo);
nsresult LoadInfoArgsToLoadInfo(
const Maybe<net::LoadInfoArgs>& aOptionalLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, mozilla::net::LoadInfo** outLoadInfo);
/**
* Fills ParentLoadInfoForwarderArgs with properties we want to carry to child

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ClientIPCTypes.h"
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceStorage.h"
#include "mozilla/dom/BrowserChild.h"
@ -49,6 +50,14 @@ using namespace mozilla::dom;
namespace mozilla::net {
static nsCString CurrentRemoteType() {
MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsContentProcess());
if (ContentChild* cc = ContentChild::GetSingleton()) {
return nsCString(cc->GetRemoteType());
}
return NOT_REMOTE_TYPE;
}
static nsContentPolicyType InternalContentPolicyTypeForFrame(
CanonicalBrowsingContext* aBrowsingContext) {
const auto& maybeEmbedderElementType =
@ -65,29 +74,30 @@ static nsContentPolicyType InternalContentPolicyTypeForFrame(
/* static */ already_AddRefed<LoadInfo> LoadInfo::CreateForDocument(
dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aTriggeringPrincipal, const nsACString& aTriggeringRemoteType,
const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags) {
return MakeAndAddRef<LoadInfo>(aBrowsingContext, aURI, aTriggeringPrincipal,
aOriginAttributes, aSecurityFlags,
aSandboxFlags);
aTriggeringRemoteType, aOriginAttributes,
aSecurityFlags, aSandboxFlags);
}
/* static */ already_AddRefed<LoadInfo> LoadInfo::CreateForFrame(
dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags) {
nsIPrincipal* aTriggeringPrincipal, const nsACString& aTriggeringRemoteType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) {
return MakeAndAddRef<LoadInfo>(aBrowsingContext, aTriggeringPrincipal,
aSecurityFlags, aSandboxFlags);
aTriggeringRemoteType, aSecurityFlags,
aSandboxFlags);
}
/* static */ already_AddRefed<LoadInfo> LoadInfo::CreateForNonDocument(
dom::WindowGlobalParent* aParentWGP, nsIPrincipal* aTriggeringPrincipal,
nsContentPolicyType aContentPolicyType, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags) {
return MakeAndAddRef<LoadInfo>(aParentWGP, aTriggeringPrincipal,
aContentPolicyType, aSecurityFlags,
aSandboxFlags);
return MakeAndAddRef<LoadInfo>(
aParentWGP, aTriggeringPrincipal, aParentWGP->GetRemoteType(),
aContentPolicyType, aSecurityFlags, aSandboxFlags);
}
LoadInfo::LoadInfo(
@ -101,13 +111,13 @@ LoadInfo::LoadInfo(
: aLoadingPrincipal),
mTriggeringPrincipal(aTriggeringPrincipal ? aTriggeringPrincipal
: mLoadingPrincipal.get()),
mTriggeringRemoteType(CurrentRemoteType()),
mSandboxedNullPrincipalID(nsID::GenerateUUID()),
mClientInfo(aLoadingClientInfo),
mController(aController),
mLoadingContext(do_GetWeakReference(aLoadingContext)),
mSecurityFlags(aSecurityFlags),
mSandboxFlags(aSandboxFlags),
mInternalContentPolicyType(aContentPolicyType),
mSkipCheckForBrokenURLOrZeroSized(aSkipCheckForBrokenURLOrZeroSized) {
MOZ_ASSERT(mLoadingPrincipal);
@ -315,11 +325,11 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIURI* aURI,
nsISupports* aContextForTopLevelLoad,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
: mTriggeringPrincipal(aTriggeringPrincipal),
mTriggeringRemoteType(CurrentRemoteType()),
mSandboxedNullPrincipalID(nsID::GenerateUUID()),
mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad)),
mSecurityFlags(aSecurityFlags),
mSandboxFlags(aSandboxFlags),
mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT) {
// Top-level loads are never third-party
// Grab the information we can out of the window.
@ -376,13 +386,14 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIURI* aURI,
LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
const OriginAttributes& aOriginAttributes,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
: mTriggeringPrincipal(aTriggeringPrincipal),
mTriggeringRemoteType(aTriggeringRemoteType),
mSandboxedNullPrincipalID(nsID::GenerateUUID()),
mSecurityFlags(aSecurityFlags),
mSandboxFlags(aSandboxFlags),
mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT) {
// Top-level loads are never third-party
// Grab the information we can out of the window.
@ -423,9 +434,11 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
nsContentPolicyType aContentPolicyType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
: mTriggeringPrincipal(aTriggeringPrincipal),
mTriggeringRemoteType(aTriggeringRemoteType),
mSandboxedNullPrincipalID(nsID::GenerateUUID()),
mSecurityFlags(aSecurityFlags),
mSandboxFlags(aSandboxFlags),
@ -524,8 +537,10 @@ LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP,
// Used for TYPE_FRAME or TYPE_IFRAME load.
LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
: LoadInfo(aBrowsingContext->GetParentWindowContext(), aTriggeringPrincipal,
aTriggeringRemoteType,
InternalContentPolicyTypeForFrame(aBrowsingContext),
aSecurityFlags, aSandboxFlags) {
mFrameBrowsingContextID = aBrowsingContext->Id();
@ -540,6 +555,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mChannelCreationOriginalURI(rhs.mChannelCreationOriginalURI),
mCookieJarSettings(rhs.mCookieJarSettings),
mCspToInherit(rhs.mCspToInherit),
mTriggeringRemoteType(rhs.mTriggeringRemoteType),
mSandboxedNullPrincipalID(rhs.mSandboxedNullPrincipalID),
mClientInfo(rhs.mClientInfo),
// mReservedClientSource must be handled specially during redirect
@ -615,6 +631,7 @@ LoadInfo::LoadInfo(
nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aTopLevelPrincipal,
nsIURI* aResultPrincipalURI, nsICookieJarSettings* aCookieJarSettings,
nsIContentSecurityPolicy* aCspToInherit,
const nsACString& aTriggeringRemoteType,
const nsID& aSandboxedNullPrincipalID, const Maybe<ClientInfo>& aClientInfo,
const Maybe<ClientInfo>& aReservedClientInfo,
const Maybe<ClientInfo>& aInitialClientInfo,
@ -656,6 +673,7 @@ LoadInfo::LoadInfo(
mResultPrincipalURI(aResultPrincipalURI),
mCookieJarSettings(aCookieJarSettings),
mCspToInherit(aCspToInherit),
mTriggeringRemoteType(aTriggeringRemoteType),
mSandboxedNullPrincipalID(aSandboxedNullPrincipalID),
mClientInfo(aClientInfo),
mReservedClientInfo(aReservedClientInfo),
@ -861,6 +879,18 @@ void LoadInfo::ResetSandboxedNullPrincipalID() {
nsIPrincipal* LoadInfo::GetTopLevelPrincipal() { return mTopLevelPrincipal; }
NS_IMETHODIMP
LoadInfo::GetTriggeringRemoteType(nsACString& aTriggeringRemoteType) {
aTriggeringRemoteType = mTriggeringRemoteType;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType) {
mTriggeringRemoteType = aTriggeringRemoteType;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetLoadingDocument(Document** aResult) {
if (nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext)) {

Просмотреть файл

@ -44,7 +44,8 @@ namespace ipc {
// we have to forward declare that function so we can use it as a friend.
nsresult LoadInfoArgsToLoadInfo(
const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo);
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
net::LoadInfo** outLoadInfo);
} // namespace ipc
namespace net {
@ -66,13 +67,15 @@ class LoadInfo final : public nsILoadInfo {
static already_AddRefed<LoadInfo> CreateForDocument(
dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags);
// Used for TYPE_FRAME or TYPE_IFRAME load.
static already_AddRefed<LoadInfo> CreateForFrame(
dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags);
// Use for non-{TYPE_DOCUMENT|TYPE_FRAME|TYPE_IFRAME} load.
@ -105,19 +108,22 @@ class LoadInfo final : public nsILoadInfo {
// Used for TYPE_DOCUMENT load.
LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
const OriginAttributes& aOriginAttributes,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags);
// Use factory function CreateForFrame
// Used for TYPE_FRAME or TYPE_IFRAME load.
LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags);
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags);
// Used for loads initiated by DocumentLoadListener that are not TYPE_DOCUMENT
// | TYPE_FRAME | TYPE_FRAME.
LoadInfo(dom::WindowGlobalParent* aParentWGP,
nsIPrincipal* aTriggeringPrincipal,
const nsACString& aTriggeringRemoteType,
nsContentPolicyType aContentPolicyType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags);
@ -198,6 +204,7 @@ class LoadInfo final : public nsILoadInfo {
nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aTopLevelPrincipal,
nsIURI* aResultPrincipalURI, nsICookieJarSettings* aCookieJarSettings,
nsIContentSecurityPolicy* aCspToInherit,
const nsACString& aTriggeringRemoteType,
const nsID& aSandboxedNullPrincipalID,
const Maybe<mozilla::dom::ClientInfo>& aClientInfo,
const Maybe<mozilla::dom::ClientInfo>& aReservedClientInfo,
@ -243,7 +250,8 @@ class LoadInfo final : public nsILoadInfo {
friend nsresult mozilla::ipc::LoadInfoArgsToLoadInfo(
const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo);
const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext,
net::LoadInfo** outLoadInfo);
~LoadInfo();
@ -279,6 +287,7 @@ class LoadInfo final : public nsILoadInfo {
nsCOMPtr<nsICSPEventListener> mCSPEventListener;
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
nsCOMPtr<nsIContentSecurityPolicy> mCspToInherit;
nsCString mTriggeringRemoteType;
nsID mSandboxedNullPrincipalID;
Maybe<mozilla::dom::ClientInfo> mClientInfo;

Просмотреть файл

@ -66,6 +66,16 @@ void TRRLoadInfo::ResetSandboxedNullPrincipalID() {}
nsIPrincipal* TRRLoadInfo::GetTopLevelPrincipal() { return nullptr; }
NS_IMETHODIMP
TRRLoadInfo::GetTriggeringRemoteType(nsACString& aTriggeringRemoteType) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::GetLoadingDocument(Document** aResult) {
return NS_ERROR_NOT_IMPLEMENTED;

Просмотреть файл

@ -309,6 +309,21 @@ interface nsILoadInfo : nsISupports
[noscript, notxpcom, nostdcall, binaryname(TriggeringPrincipal)]
nsIPrincipal binaryTriggeringPrincipal();
/**
* The remote type of the process which caused the network load to start. I.e.
* this is the remote type of the process which provided the URL to be loaded.
*
* For subresource loads, this should be the same as the process which will
* handle the response, however for document loads this may both be different
* than the final process, as well as different from the process which starts
* the navigation.
*
* This field is intentionally not perfectly preserved over IPC, and will be
* reset to the remote type of the sending process when sent from a content
* process to the parent process.
*/
attribute AUTF8String triggeringRemoteType;
/**
* For non-document loads the principalToInherit is always null. For
* loads of type TYPE_DOCUMENT or TYPE_SUBDOCUMENT the principalToInherit

Просмотреть файл

@ -8,6 +8,7 @@
#include "DocumentChannelChild.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/RemoteType.h"
#include "mozilla/extensions/StreamFilterParent.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/net/HttpBaseChannel.h"
@ -109,7 +110,7 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) {
DocumentChannelCreationArgs args;
args.loadState() = mLoadState->Serialize();
args.loadState() = mLoadState;
args.cacheKey() = mCacheKey;
args.channelId() = mChannelId;
args.asyncOpenTime() = TimeStamp::Now();
@ -249,8 +250,9 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel(
cspToInheritLoadingDocument = do_QueryReferent(ctx);
}
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(
aArgs.loadInfo(), cspToInheritLoadingDocument, getter_AddRefs(loadInfo)));
MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(aArgs.loadInfo(), NOT_REMOTE_TYPE,
cspToInheritLoadingDocument,
getter_AddRefs(loadInfo)));
mRedirectResolver = std::move(aResolve);

Просмотреть файл

@ -31,8 +31,7 @@ DocumentChannelParent::~DocumentChannelParent() {
bool DocumentChannelParent::Init(dom::CanonicalBrowsingContext* aContext,
const DocumentChannelCreationArgs& aArgs) {
RefPtr<nsDocShellLoadState> loadState =
new nsDocShellLoadState(aArgs.loadState());
RefPtr<nsDocShellLoadState> loadState = aArgs.loadState();
LOG(("DocumentChannelParent Init [this=%p, uri=%s]", this,
loadState->URI()->GetSpecOrDefault().get()));
if (aArgs.parentInitiatedNavigationEpoch() <

Просмотреть файл

@ -138,15 +138,17 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext,
auto securityFlags = SecurityFlagsForLoadInfo(aLoadState);
if (aBrowsingContext->GetParent()) {
loadInfo = LoadInfo::CreateForFrame(aBrowsingContext,
aLoadState->TriggeringPrincipal(),
securityFlags, sandboxFlags);
loadInfo = LoadInfo::CreateForFrame(
aBrowsingContext, aLoadState->TriggeringPrincipal(),
aLoadState->GetEffectiveTriggeringRemoteType(), securityFlags,
sandboxFlags);
} else {
OriginAttributes attrs;
aBrowsingContext->GetOriginAttributes(attrs);
loadInfo = LoadInfo::CreateForDocument(aBrowsingContext, aLoadState->URI(),
aLoadState->TriggeringPrincipal(),
attrs, securityFlags, sandboxFlags);
loadInfo = LoadInfo::CreateForDocument(
aBrowsingContext, aLoadState->URI(), aLoadState->TriggeringPrincipal(),
aLoadState->GetEffectiveTriggeringRemoteType(), attrs, securityFlags,
sandboxFlags);
}
if (aLoadState->IsExemptFromHTTPSOnlyMode()) {
@ -621,6 +623,9 @@ auto DocumentLoadListener::Open(nsDocShellLoadState* aLoadState,
// If we are using SHIP and this load is from session history, validate that
// the load matches our local copy of the loading history entry.
//
// NOTE: Keep this check in-sync with the check in
// `nsDocShellLoadState::GetEffectiveTriggeringRemoteType()`!
if (SessionHistoryInParent() && aLoadState->LoadIsFromSessionHistory() &&
aLoadState->LoadType() != LOAD_ERROR_PAGE) {
if (const char* mismatch =

Просмотреть файл

@ -29,6 +29,7 @@ using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
[RefCounted] using class nsIPropertyBag2 from "nsIPropertyBag2.h";
[RefCounted] using class nsDOMNavigationTiming from "nsDOMNavigationTiming.h";
[RefCounted] using class nsDocShellLoadState from "nsDocShellLoadState.h";
using nsContentPolicyType from "nsIContentPolicy.h";
using mozilla::net::PreferredAlternativeDataDeliveryTypeIPC from "nsICacheInfoChannel.h";
using nsILoadInfo::CrossOriginEmbedderPolicy from "nsILoadInfo.h";
@ -98,6 +99,7 @@ struct LoadInfoArgs
PrincipalInfo? principalToInheritInfo;
PrincipalInfo? topLevelPrincipalInfo;
URIParams? resultPrincipalURI;
nsCString triggeringRemoteType;
nsID sandboxedNullPrincipalID;
uint32_t securityFlags;
uint32_t sandboxFlags;
@ -446,7 +448,7 @@ union DocumentChannelElementCreationArgs {
};
struct DocumentChannelCreationArgs {
DocShellLoadStateInit loadState;
nsDocShellLoadState loadState;
TimeStamp asyncOpenTime;
uint64_t channelId;
uint32_t cacheKey;

Просмотреть файл

@ -741,7 +741,9 @@ mozilla::ipc::IPCResult NeckoParent::RecvPClassifierDummyChannelConstructor(
}
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo));
nsresult rv = LoadInfoArgsToLoadInfo(
aLoadInfo, ContentParent::Cast(Manager())->GetRemoteType(),
getter_AddRefs(loadInfo));
if (NS_WARN_IF(NS_FAILED(rv)) || !loadInfo) {
return IPC_FAIL_NO_REASON(this);
}
@ -874,14 +876,16 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
nsIURI* aURI, const Maybe<LoadInfoArgs>& aLoadInfoArgs,
GetPageIconStreamResolver&& aResolver) {
#ifdef MOZ_PLACES
const nsACString& remoteType =
ContentParent::Cast(Manager())->GetRemoteType();
// Only the privileged about content process is allowed to access
// things over the page-icon protocol. Any other content process
// that tries to send this should have been blocked via the
// ScriptSecurityManager, but if somehow the process has been tricked into
// sending this message, we send IPC_FAIL in order to crash that
// likely-compromised content process.
if (static_cast<ContentParent*>(Manager())->GetRemoteType() !=
PRIVILEGEDABOUT_REMOTE_TYPE) {
if (remoteType != PRIVILEGEDABOUT_REMOTE_TYPE) {
return IPC_FAIL(this, "Wrong process type");
}
@ -890,7 +894,7 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
}
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
return IPC_FAIL(this, "Page-icon request must include loadInfo");

Просмотреть файл

@ -95,8 +95,14 @@ bool GIOChannelParent::DoAsyncOpen(const URIParams& aURI,
return SendFailedAsyncOpen(rv);
}
nsAutoCString remoteType;
rv = GetRemoteType(remoteType);
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);
}
nsCOMPtr<nsILoadInfo> loadInfo;
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);

Просмотреть файл

@ -398,10 +398,18 @@ bool HttpChannelParent::DoAsyncOpen(
nsresult rv;
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);
}
nsAutoCString remoteType;
rv = GetRemoteType(remoteType);
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);
}
nsCOMPtr<nsILoadInfo> loadInfo;
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
return SendFailedAsyncOpen(rv);

Просмотреть файл

@ -7,6 +7,7 @@
#include "WebSocketLog.h"
#include "WebSocketChannelParent.h"
#include "nsIAuthPromptProvider.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -64,7 +65,10 @@ mozilla::ipc::IPCResult WebSocketChannelParent::RecvAsyncOpen(
nsCOMPtr<nsILoadInfo> loadInfo;
nsCOMPtr<nsIURI> uri;
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(loadInfo));
rv = LoadInfoArgsToLoadInfo(
aLoadInfoArgs,
mozilla::dom::ContentParent::Cast(Manager()->Manager())->GetRemoteType(),
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
goto fail;
}

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/DebugOnly.h"
#include "ExternalHelperAppParent.h"
#include "nsExternalHelperAppService.h"
#include "nsIContent.h"
#include "nsCExternalHandlerService.h"
#include "nsIExternalHelperAppService.h"
@ -63,8 +64,9 @@ bool ExternalHelperAppParent::Init(
const nsACString& aMimeContentType, const bool& aForceSave,
nsIURI* aReferrer, BrowsingContext* aContext,
const bool& aShouldCloseWindow) {
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
getter_AddRefs(mLoadInfo));
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(
aLoadInfoArgs, ContentParent::Cast(Manager())->GetRemoteType(),
getter_AddRefs(mLoadInfo));
if (NS_FAILED(rv)) {
return false;
}