diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 36e486df35e4..8868444b377d 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -291,7 +291,8 @@ BrowsingContext::BrowsingContext(BrowsingContext* aParent, mIsDiscarded(false), mWindowless(false), mDanglingRemoteOuterProxies(false), - mPendingInitialization(false) { + mPendingInitialization(false), + mEmbeddedByThisProcess(false) { MOZ_RELEASE_ASSERT(!mParent || mParent->Group() == mGroup); MOZ_RELEASE_ASSERT(mBrowsingContextId != 0); MOZ_RELEASE_ASSERT(mGroup); @@ -352,12 +353,16 @@ void BrowsingContext::CleanUpDanglingRemoteOuterWindowProxies( } void BrowsingContext::SetEmbedderElement(Element* aEmbedder) { + mEmbeddedByThisProcess = true; // Notify the parent process of the embedding status. We don't need to do // this when clearing our embedder, as we're being destroyed either way. if (aEmbedder) { if (nsCOMPtr inner = do_QueryInterface(aEmbedder->GetOwnerGlobal())) { - SetEmbedderInnerWindowId(inner->WindowID()); + Transaction txn; + txn.SetEmbedderInnerWindowId(inner->WindowID()); + txn.SetEmbedderElementType(Some(aEmbedder->LocalName())); + txn.Commit(this); } } @@ -1395,6 +1400,17 @@ bool BrowsingContext::CanSet(FieldIndex, return true; } +bool BrowsingContext::CheckOnlyEmbedderCanSet(ContentParent* aSource) { + if (aSource) { + // Set by a content process, verify that it's this BC's embedder. + MOZ_ASSERT(XRE_IsParentProcess()); + return Canonical()->IsEmbeddedInProcess(aSource->ChildID()); + } + + // In-process case, verify that we've been embedded in this process. + return mEmbeddedByThisProcess; +} + bool BrowsingContext::CanSet(FieldIndex, const uint64_t& aValue, ContentParent* aSource) { // Generally allow clearing this. We may want to be more precise about this @@ -1449,6 +1465,11 @@ bool BrowsingContext::CanSet(FieldIndex, return true; } +bool BrowsingContext::CanSet(FieldIndex, + const Maybe&, ContentParent* aSource) { + return CheckOnlyEmbedderCanSet(aSource); +} + bool BrowsingContext::CanSet(FieldIndex, const uint64_t& aValue, ContentParent* aSource) { // Generally allow clearing this. We may want to be more precise about this diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index f86a4fb51151..9eb0551eb3ad 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -32,6 +32,7 @@ class nsDocShellLoadState; class nsGlobalWindowOuter; +class nsILoadInfo; class nsIPrincipal; class nsOuterWindowProxy; class PickleIterator; @@ -108,7 +109,8 @@ class WindowProxyHolder; /* ScreenOrientation-related APIs */ \ FIELD(CurrentOrientationAngle, float) \ FIELD(CurrentOrientationType, mozilla::dom::OrientationType) \ - FIELD(UserAgentOverride, nsString) + FIELD(UserAgentOverride, nsString) \ + FIELD(EmbedderElementType, Maybe) // BrowsingContext, in this context, is the cross process replicated // environment in which information about documents is stored. In @@ -637,6 +639,9 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { bool CanSet(FieldIndex, const nsString& aUserAgent, ContentParent* aSource); + bool CanSet(FieldIndex, + const Maybe& aInitiatorType, ContentParent* aSource); + template bool CanSet(FieldIndex, const T&, ContentParent*) { return true; @@ -645,6 +650,10 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { template void DidSet(FieldIndex) {} + // True if the process attempting to set field is the same as the embedder's + // process. + bool CheckOnlyEmbedderCanSet(ContentParent* aSource); + // Type of BrowsingContent const Type mType; @@ -694,6 +703,10 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { // as the target of a load. bool mPendingInitialization : 1; + // True if this BrowsingContext has been embedded in a element in this + // process. + bool mEmbeddedByThisProcess : 1; + // The start time of user gesture, this is only available if the browsing // context is in process. TimeStamp mUserGestureStart; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index f8435a722b37..9f7408efbfd8 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9361,9 +9361,11 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) { /* static */ bool nsDocShell::CreateAndConfigureRealChannelForLoadState( nsDocShellLoadState* aLoadState, LoadInfo* aLoadInfo, nsIInterfaceRequestor* aCallbacks, nsDocShell* aDocShell, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, uint32_t aLoadType, - uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, - bool aHasNonEmptySandboxingFlags, nsresult& aRv, nsIChannel** aChannel) { + nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, + bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, + nsresult& aRv, nsIChannel** aChannel) { + MOZ_ASSERT(aLoadInfo); + nsString srcdoc = VoidString(); bool isSrcdoc = aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC); if (isSrcdoc) { @@ -9555,8 +9557,10 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) { if (nsCOMPtr timedChannel = do_QueryInterface(channel)) { timedChannel->SetTimingEnabled(true); - if (aInitiatorType) { - timedChannel->SetInitiatorType(*aInitiatorType); + RefPtr bc; + MOZ_ALWAYS_SUCCEEDS(aLoadInfo->GetFrameBrowsingContext(getter_AddRefs(bc))); + if (bc && bc->GetEmbedderElementType()) { + timedChannel->SetInitiatorType(*bc->GetEmbedderElementType()); } } @@ -9855,15 +9859,6 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, cacheKey = mOSHE->GetCacheKey(); } - const nsString* initiatorType = nullptr; - nsCOMPtr win = GetWindow(); - if (IsFrame() && win) { - nsCOMPtr frameElement = win->GetFrameElementInternal(); - if (frameElement) { - initiatorType = &frameElement->LocalName(); - } - } - bool isActive = mBrowsingContext->GetIsActive() || (mLoadType & (LOAD_CMD_NORMAL | LOAD_CMD_HISTORY)); @@ -9878,13 +9873,13 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, if (StaticPrefs::browser_tabs_documentchannel() && XRE_IsContentProcess() && canUseDocumentChannel) { - channel = new DocumentChannelChild(aLoadState, loadInfo, initiatorType, - loadFlags, mLoadType, cacheKey, isActive, + channel = new DocumentChannelChild(aLoadState, loadInfo, loadFlags, + mLoadType, cacheKey, isActive, isTopLevelDoc, sandboxFlags); channel->SetNotificationCallbacks(this); } else if (!CreateAndConfigureRealChannelForLoadState( - aLoadState, loadInfo, this, this, initiatorType, loadFlags, - mLoadType, cacheKey, isActive, isTopLevelDoc, + aLoadState, loadInfo, this, this, loadFlags, mLoadType, + cacheKey, isActive, isTopLevelDoc, mBrowsingContext->GetSandboxFlags(), rv, getter_AddRefs(channel))) { return rv; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 9c0b072c4965..7e9b7dc36085 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -501,10 +501,9 @@ class nsDocShell final : public nsDocLoader, static bool CreateAndConfigureRealChannelForLoadState( nsDocShellLoadState* aLoadState, mozilla::net::LoadInfo* aLoadInfo, nsIInterfaceRequestor* aCallbacks, nsDocShell* aDocShell, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, - uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, - bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, nsresult& rv, - nsIChannel** aChannel); + nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, + bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, + nsresult& rv, nsIChannel** aChannel); // Notify consumers of a search being loaded through the observer service: static void MaybeNotifyKeywordSearchLoading(const nsString& aProvider, diff --git a/netwerk/ipc/DocumentChannel.cpp b/netwerk/ipc/DocumentChannel.cpp index 36d186649dd9..7e75a8790181 100644 --- a/netwerk/ipc/DocumentChannel.cpp +++ b/netwerk/ipc/DocumentChannel.cpp @@ -85,14 +85,12 @@ NS_INTERFACE_MAP_END DocumentChannel::DocumentChannel(nsDocShellLoadState* aLoadState, net::LoadInfo* aLoadInfo, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags) : mAsyncOpenTime(TimeStamp::Now()), mLoadState(aLoadState), - mInitiatorType(aInitiatorType ? Some(*aInitiatorType) : Nothing()), mLoadType(aLoadType), mCacheKey(aCacheKey), mIsActive(aIsActive), diff --git a/netwerk/ipc/DocumentChannel.h b/netwerk/ipc/DocumentChannel.h index f20da014f1b3..f9b520722d43 100644 --- a/netwerk/ipc/DocumentChannel.h +++ b/netwerk/ipc/DocumentChannel.h @@ -45,9 +45,9 @@ class DocumentChannel : public nsIIdentChannel, public nsITraceableChannel { NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_IID) DocumentChannel(nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, - uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, - bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags); + nsLoadFlags aLoadFlags, uint32_t aLoadType, + uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, + bool aHasNonEmptySandboxingFlags); const nsTArray& GetRedirectChain() const { return mRedirects; @@ -77,7 +77,6 @@ class DocumentChannel : public nsIIdentChannel, public nsITraceableChannel { const TimeStamp mAsyncOpenTime; const RefPtr mLoadState; - const Maybe mInitiatorType; const uint32_t mLoadType; const uint32_t mCacheKey; const bool mIsActive; diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index d733412b3dd6..13260f1680ac 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -28,12 +28,10 @@ NS_IMPL_RELEASE_INHERITED(DocumentChannelChild, DocumentChannel) DocumentChannelChild::DocumentChannelChild( nsDocShellLoadState* aLoadState, net::LoadInfo* aLoadInfo, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, uint32_t aLoadType, - uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, - bool aHasNonEmptySandboxingFlags) - : DocumentChannel(aLoadState, aLoadInfo, aInitiatorType, aLoadFlags, - aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc, - aHasNonEmptySandboxingFlags) { + nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, + bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags) + : DocumentChannel(aLoadState, aLoadInfo, aLoadFlags, aLoadType, aCacheKey, + aIsActive, aIsTopLevelDoc, aHasNonEmptySandboxingFlags) { LOG(("DocumentChannelChild ctor [this=%p, uri=%s]", this, aLoadState->URI()->GetSpecOrDefault().get())); } @@ -116,7 +114,6 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) { args.loadInfo() = *maybeArgs; args.loadFlags() = mLoadFlags; - args.initiatorType() = mInitiatorType; args.loadType() = mLoadType; args.cacheKey() = mCacheKey; args.isActive() = mIsActive; diff --git a/netwerk/ipc/DocumentChannelChild.h b/netwerk/ipc/DocumentChannelChild.h index 5fb7c1438af4..8234f5d17285 100644 --- a/netwerk/ipc/DocumentChannelChild.h +++ b/netwerk/ipc/DocumentChannelChild.h @@ -25,8 +25,7 @@ class DocumentChannelChild final : public DocumentChannel, public PDocumentChannelChild { public: DocumentChannelChild(nsDocShellLoadState* aLoadState, - class LoadInfo* aLoadInfo, - const nsString* aInitiatorType, nsLoadFlags aLoadFlags, + class LoadInfo* aLoadInfo, nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags); diff --git a/netwerk/ipc/DocumentChannelParent.cpp b/netwerk/ipc/DocumentChannelParent.cpp index 9c89a8cd8643..15d82a17beef 100644 --- a/netwerk/ipc/DocumentChannelParent.cpp +++ b/netwerk/ipc/DocumentChannelParent.cpp @@ -39,9 +39,8 @@ bool DocumentChannelParent::Init(BrowserParent* aBrowser, rv = NS_ERROR_UNEXPECTED; if (!mParent->Open( - aBrowser, loadState, loadInfo, aArgs.initiatorType().ptrOr(nullptr), - aArgs.loadFlags(), aArgs.loadType(), aArgs.cacheKey(), - aArgs.isActive(), aArgs.isTopLevelDoc(), + aBrowser, loadState, loadInfo, aArgs.loadFlags(), aArgs.loadType(), + aArgs.cacheKey(), aArgs.isActive(), aArgs.isTopLevelDoc(), aArgs.hasNonEmptySandboxingFlags(), aArgs.topWindowURI(), aArgs.contentBlockingAllowListPrincipal(), aArgs.channelId(), aArgs.asyncOpenTime(), aArgs.documentOpenFlags(), diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 2734c5318ae9..adebce27d771 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -250,10 +250,9 @@ DocumentLoadListener::~DocumentLoadListener() { bool DocumentLoadListener::Open( BrowserParent* aBrowser, nsDocShellLoadState* aLoadState, - class LoadInfo* aLoadInfo, const nsString* aInitiatorType, - nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, - bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, - const Maybe& aTopWindowURI, + LoadInfo* aLoadInfo, nsLoadFlags aLoadFlags, uint32_t aLoadType, + uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, + bool aHasNonEmptySandboxingFlags, const Maybe& aTopWindowURI, const Maybe& aContentBlockingAllowListPrincipal, const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime, const Maybe& aDocumentOpenFlags, bool aPluginsAllowed, @@ -262,10 +261,9 @@ bool DocumentLoadListener::Open( aLoadState->URI()->GetSpecOrDefault().get())); if (!nsDocShell::CreateAndConfigureRealChannelForLoadState( - aLoadState, aLoadInfo, mParentChannelListener, nullptr, - aInitiatorType, aLoadFlags, aLoadType, aCacheKey, aIsActive, - aIsTopLevelDoc, aHasNonEmptySandboxingFlags, *aRv, - getter_AddRefs(mChannel))) { + aLoadState, aLoadInfo, mParentChannelListener, nullptr, aLoadFlags, + aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc, + aHasNonEmptySandboxingFlags, *aRv, getter_AddRefs(mChannel))) { mParentChannelListener = nullptr; return false; } diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index 81d768143893..a763bc4311ee 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -34,6 +34,8 @@ namespace mozilla { namespace net { +class LoadInfo; + /** * DocumentLoadListener represents a connecting document load for a * CanonicalBrowsingContext (in the parent process). @@ -71,9 +73,8 @@ class DocumentLoadListener : public nsIInterfaceRequestor, // expect Necko to pass it again so that we don't need a member var for // it. bool Open(dom::BrowserParent* aBrowser, nsDocShellLoadState* aLoadState, - class LoadInfo* aLoadInfo, const nsString* aInitiatorType, - nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, - bool aIsActive, bool aIsTopLevelDoc, + LoadInfo* aLoadInfo, nsLoadFlags aLoadFlags, uint32_t aLoadType, + uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, const Maybe& aTopWindowURI, const Maybe& aContentBlockingAllowListPrincipal, diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 8f7ab20beafe..3259793afd1f 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -402,7 +402,6 @@ struct DocumentChannelCreationArgs { LoadInfoArgs loadInfo; PrincipalInfo? contentBlockingAllowListPrincipal; TimeStamp asyncOpenTime; - nsString? initiatorType; uint64_t channelId; uint32_t loadFlags; uint32_t loadType;