diff --git a/browser/modules/test/unit/test_E10SUtils_nested_URIs.js b/browser/modules/test/unit/test_E10SUtils_nested_URIs.js index 4d2205c8519b..8fe4528fad55 100644 --- a/browser/modules/test/unit/test_E10SUtils_nested_URIs.js +++ b/browser/modules/test/unit/test_E10SUtils_nested_URIs.js @@ -5,7 +5,6 @@ const { E10SUtils } = ChromeUtils.importESModule( var TEST_PREFERRED_REMOTE_TYPES = [ E10SUtils.WEB_REMOTE_TYPE, E10SUtils.NOT_REMOTE, - "fakeRemoteType", ]; var TEST_USE_REMOTE_SUBFRAMES = [true, false]; diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index aaca13e98a07..ddeb7ec7d138 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -1073,7 +1073,7 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags( } auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType(); - if (remoteType == PRIVILEGEDABOUT_REMOTE_TYPE) { + if (remoteType.IsPrivilegedAbout()) { return NS_OK; } } diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 783bbea83fca..a77e8cc62c0a 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -1655,8 +1655,7 @@ bool BrowsingContext::CrossOriginIsolated() { nsILoadInfo:: OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP && XRE_IsContentProcess() && - StringBeginsWith(ContentChild::GetSingleton()->GetRemoteType(), - WITH_COOP_COEP_REMOTE_TYPE_PREFIX); + ContentChild::GetSingleton()->GetRemoteType().IsWebCoopCoep(); } void BrowsingContext::SetTriggeringAndInheritPrincipals( diff --git a/docshell/base/BrowsingContextGroup.cpp b/docshell/base/BrowsingContextGroup.cpp index 30f153be7ceb..ca68cdc7e9e7 100644 --- a/docshell/base/BrowsingContextGroup.cpp +++ b/docshell/base/BrowsingContextGroup.cpp @@ -131,10 +131,12 @@ void BrowsingContextGroup::EnsureHostProcess(ContentParent* aProcess) { MOZ_DIAGNOSTIC_ASSERT(!mDestroyed); MOZ_DIAGNOSTIC_ASSERT(this != sChromeGroup, "cannot have content host for chrome group"); - MOZ_DIAGNOSTIC_ASSERT(aProcess->GetRemoteType() != PREALLOC_REMOTE_TYPE, - "cannot use preallocated process as host"); - MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsEmpty(), + MOZ_DIAGNOSTIC_ASSERT(aProcess->GetRemoteType().IsKnown(), "host process must have remote type"); + MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsPrealloc(), + "cannot use preallocated process as host"); + MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsNotRemote(), + "host process must be remote"); // XXX: The diagnostic crashes in bug 1816025 seemed to come through caller // ContentParent::GetNewOrUsedLaunchingBrowserProcess where we already @@ -168,7 +170,7 @@ void BrowsingContextGroup::EnsureHostProcess(ContentParent* aProcess) { void BrowsingContextGroup::RemoveHostProcess(ContentParent* aProcess) { MOZ_DIAGNOSTIC_ASSERT(aProcess); - MOZ_DIAGNOSTIC_ASSERT(aProcess->GetRemoteType() != PREALLOC_REMOTE_TYPE); + MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsPrealloc()); auto entry = mHosts.Lookup(aProcess->GetRemoteType()); if (entry && entry.Data() == aProcess) { entry.Remove(); @@ -193,7 +195,7 @@ static void CollectContextInitializers( void BrowsingContextGroup::Subscribe(ContentParent* aProcess) { MOZ_DIAGNOSTIC_ASSERT(!mDestroyed); MOZ_DIAGNOSTIC_ASSERT(aProcess && !aProcess->IsLaunching()); - MOZ_DIAGNOSTIC_ASSERT(aProcess->GetRemoteType() != PREALLOC_REMOTE_TYPE); + MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsPrealloc()); // Check if we're already subscribed to this process. if (!mSubscribers.EnsureInserted(aProcess)) { @@ -235,7 +237,7 @@ void BrowsingContextGroup::Subscribe(ContentParent* aProcess) { void BrowsingContextGroup::Unsubscribe(ContentParent* aProcess) { MOZ_DIAGNOSTIC_ASSERT(aProcess); - MOZ_DIAGNOSTIC_ASSERT(aProcess->GetRemoteType() != PREALLOC_REMOTE_TYPE); + MOZ_DIAGNOSTIC_ASSERT(!aProcess->GetRemoteType().IsPrealloc()); mSubscribers.Remove(aProcess); aProcess->RemoveBrowsingContextGroup(this); @@ -247,7 +249,7 @@ void BrowsingContextGroup::Unsubscribe(ContentParent* aProcess) { } ContentParent* BrowsingContextGroup::GetHostProcess( - const nsACString& aRemoteType) { + const RemoteType& aRemoteType) { return mHosts.GetWeak(aRemoteType); } diff --git a/docshell/base/BrowsingContextGroup.h b/docshell/base/BrowsingContextGroup.h index 34027c390db8..f3e15959deb6 100644 --- a/docshell/base/BrowsingContextGroup.h +++ b/docshell/base/BrowsingContextGroup.h @@ -7,6 +7,7 @@ #include "mozilla/PrincipalHashKey.h" #include "mozilla/dom/BrowsingContext.h" +#include "mozilla/dom/RemoteType.h" #include "nsRefPtrHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" @@ -82,7 +83,7 @@ class BrowsingContextGroup final : public nsWrapperCache { // Look up the process which should be used to host documents with this // RemoteType. This will be a non-dead process associated with this // BrowsingContextGroup, if possible. - ContentParent* GetHostProcess(const nsACString& aRemoteType); + ContentParent* GetHostProcess(const RemoteType& aRemoteType); // Check if the process which sent the message being read from aReader is // aware of this BrowsingContextGroup's existence. @@ -297,7 +298,7 @@ class BrowsingContextGroup final : public nsWrapperCache { // A non-launching host process must also be a subscriber, though a launching // host process may not yet be subscribed, and a subscriber need not be a host // process. - nsRefPtrHashtable mHosts; + nsRefPtrHashtable, ContentParent> mHosts; // Whether or not a given http(s) origin uses origin or siteOrigin-keyed // DocGroups/AgentClusters. Only contains entries for http(s) origins. diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 1fa976de8af7..bfe3f437bf83 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -247,7 +247,7 @@ void CanonicalBrowsingContext::GetCurrentRemoteType(nsACString& aRemoteType, ErrorResult& aRv) const { // If we're in the parent process, dump out the void string. if (mProcessId == 0) { - aRemoteType = NOT_REMOTE_TYPE; + aRemoteType = RemoteType::NotRemote().Stringify(); return; } @@ -257,7 +257,7 @@ void CanonicalBrowsingContext::GetCurrentRemoteType(nsACString& aRemoteType, return; } - aRemoteType = cp->GetRemoteType(); + aRemoteType = cp->GetRemoteType().Stringify(); } void CanonicalBrowsingContext::SetOwnerProcessId(uint64_t aProcessId) { @@ -2546,7 +2546,8 @@ CanonicalBrowsingContext::ChangeRemoteness( return RemotenessPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__); } - if (aOptions.mRemoteType.IsEmpty() && (!IsTop() || !GetEmbedderElement())) { + if (aOptions.mRemoteType.IsNotRemote() && + (!IsTop() || !GetEmbedderElement())) { NS_WARNING("Cannot load non-remote subframes"); return RemotenessPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); } @@ -2615,7 +2616,8 @@ CanonicalBrowsingContext::ChangeRemoteness( "which will never perform a process-switch to being in-process with " "their embedder"); MOZ_DIAGNOSTIC_ASSERT(!aOptions.mReplaceBrowsingContext); - MOZ_DIAGNOSTIC_ASSERT(!aOptions.mRemoteType.IsEmpty()); + MOZ_DIAGNOSTIC_ASSERT(aOptions.mRemoteType.IsKnown()); + MOZ_DIAGNOSTIC_ASSERT(!aOptions.mRemoteType.IsNotRemote()); MOZ_DIAGNOSTIC_ASSERT(!change->mWaitingForPrepareToChange); MOZ_DIAGNOSTIC_ASSERT(!change->mSpecificGroup); @@ -2628,7 +2630,7 @@ CanonicalBrowsingContext::ChangeRemoteness( } // Switching to the parent process. - if (aOptions.mRemoteType.IsEmpty()) { + if (aOptions.mRemoteType.IsNotRemote()) { change->ProcessLaunched(); return promise.forget(); } @@ -3631,7 +3633,7 @@ void CanonicalBrowsingContext::RemovePageAwakeRequest() { } void CanonicalBrowsingContext::CloneDocumentTreeInto( - CanonicalBrowsingContext* aSource, const nsACString& aRemoteType, + CanonicalBrowsingContext* aSource, const RemoteType& aRemoteType, embedding::PrintData&& aPrintData) { NavigationIsolationOptions options; options.mRemoteType = aRemoteType; diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 7a5b8c85d14a..484dadb86f39 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -269,8 +269,9 @@ class CanonicalBrowsingContext final : public BrowsingContext { // The returned CanonicalBrowsingContext may be different than |this| if a BCG // switch was performed. // - // A NOT_REMOTE_TYPE aRemoteType argument will perform a process switch into - // the parent process, and the method will resolve with a null BrowserParent. + // A RemoteType::NotRemote() aRemoteType argument will perform a process + // switch into the parent process, and the method will resolve with a null + // BrowserParent. using RemotenessPromise = MozPromise< std::pair, RefPtr>, nsresult, false>; @@ -445,7 +446,7 @@ class CanonicalBrowsingContext final : public BrowsingContext { MOZ_CAN_RUN_SCRIPT void CloneDocumentTreeInto(CanonicalBrowsingContext* aSource, - const nsACString& aRemoteType, + const RemoteType& aRemoteType, embedding::PrintData&& aPrintData); // Returns a Promise which resolves when cloning documents for printing diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index 239b0600b6da..1ec396c84c3e 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -60,7 +60,7 @@ class CrashChannel final : public nsBaseChannel { using ContentParent = mozilla::dom::ContentParent; nsTArray> toKill; for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { - if (cp->GetRemoteType() == EXTENSION_REMOTE_TYPE) { + if (cp->GetRemoteType().IsExtension()) { toKill.AppendElement(cp); } } diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 81bd3323e022..6587442daf58 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -51,8 +51,8 @@ using namespace mozilla::dom; static mozilla::StaticRefPtr sURIFixup; static bool ContentTriggeredURILoadIsAllowed( - nsIURI* aURI, const nsACString& aEffectiveRemoteType) { - MOZ_ASSERT(aEffectiveRemoteType != NOT_REMOTE_TYPE); + nsIURI* aURI, const RemoteType& aEffectiveRemoteType) { + MOZ_ASSERT(!aEffectiveRemoteType.IsNotRemote()); MOZ_ASSERT(!aURI->SchemeIs("javascript"), "Should have been blocked already"); // view-source: URIs are not linkable from web content, but the "View Page @@ -232,7 +232,7 @@ nsDocShellLoadState::nsDocShellLoadState( } } - if (mTriggeringRemoteType != NOT_REMOTE_TYPE) { + if (!mTriggeringRemoteType.IsNotRemote()) { if (mURI->SchemeIs("javascript")) { aActor->FatalError("Illegal cross-process javascript: load attempt"); return; @@ -244,8 +244,8 @@ nsDocShellLoadState::nsDocShellLoadState( } } - const nsCString& effectiveRemoteType = GetEffectiveTriggeringRemoteType(); - if (effectiveRemoteType != NOT_REMOTE_TYPE && + const RemoteType& effectiveRemoteType = GetEffectiveTriggeringRemoteType(); + if (!effectiveRemoteType.IsNotRemote() && !ContentTriggeredURILoadIsAllowed(mURI, effectiveRemoteType)) { nsAutoCString aboutModuleOrScheme; if (mURI->SchemeIs("about")) { @@ -255,10 +255,10 @@ nsDocShellLoadState::nsDocShellLoadState( mURI->GetScheme(aboutModuleOrScheme); aboutModuleOrScheme.AppendLiteral(":"); } - nsCString remotePrefix(RemoteTypePrefix(effectiveRemoteType)); aActor->FatalError( nsPrintfCString("Illegal load attempt of %s URL from %s", - aboutModuleOrScheme.get(), remotePrefix.get()) + aboutModuleOrScheme.get(), + effectiveRemoteType.StringifyKind().get()) .get()); return; } @@ -401,7 +401,7 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier) mWasCreatedRemotely(false), mTriggeringRemoteType(XRE_IsContentProcess() ? ContentChild::GetSingleton()->GetRemoteType() - : NOT_REMOTE_TYPE), + : RemoteType::NotRemote()), mSchemelessInput(nsILoadInfo::SchemelessInputTypeUnset), mIsInitialAboutBlankHandlingProhibited(false) { MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!"); @@ -650,19 +650,31 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions( } if (aLoadURIOptions.mTriggeringRemoteType.WasPassed()) { + RemoteType triggeringRemoteType = + RemoteType::Parse(aLoadURIOptions.mTriggeringRemoteType.Value()); + if (!triggeringRemoteType) { + NS_WARNING("Invalid TriggeringRemoteType from LoadURIOptions"); + return NS_ERROR_INVALID_ARG; + } + if (XRE_IsParentProcess()) { - loadState->SetTriggeringRemoteType( - aLoadURIOptions.mTriggeringRemoteType.Value()); + loadState->SetTriggeringRemoteType(triggeringRemoteType); } else if (ContentChild::GetSingleton()->GetRemoteType() != - aLoadURIOptions.mTriggeringRemoteType.Value()) { + triggeringRemoteType) { NS_WARNING("Invalid TriggeringRemoteType from LoadURIOptions in content"); return NS_ERROR_INVALID_ARG; } } if (aLoadURIOptions.mRemoteTypeOverride.WasPassed()) { - loadState->SetRemoteTypeOverride( - aLoadURIOptions.mRemoteTypeOverride.Value()); + RemoteType remoteTypeOverride = + RemoteType::Parse(aLoadURIOptions.mRemoteTypeOverride.Value()); + if (!remoteTypeOverride) { + NS_WARNING("Invalid RemoteTypeOverride from LoadURIOptions"); + return NS_ERROR_INVALID_ARG; + } + + loadState->SetRemoteTypeOverride(remoteTypeOverride); } loadState->SetSchemelessInput(static_cast( @@ -1203,27 +1215,28 @@ nsDocShellLoadState::TakeSpeculativeListener() { } void nsDocShellLoadState::SetRemoteTypeOverride( - const nsCString& aRemoteTypeOverride) { + const RemoteType& aRemoteTypeOverride) { MOZ_DIAGNOSTIC_ASSERT( NS_IsAboutBlank(mURI), "Should only have aRemoteTypeOverride for about:blank URIs"); mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride); } -const nsCString& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const { +const RemoteType& 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 RemoteType::NotRemote(); } return mTriggeringRemoteType; } void nsDocShellLoadState::SetTriggeringRemoteType( - const nsACString& aTriggeringRemoteType) { + const RemoteType& aTriggeringRemoteType) { MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent"); mTriggeringRemoteType = aTriggeringRemoteType; } @@ -1236,7 +1249,7 @@ void nsDocShellLoadState::AssertProcessCouldTriggerLoadIfSystem() { // nsContentSecurityManager checks, however this assertion should happen // closer to whichever caller is triggering the system-principal load. if (TriggeringPrincipal()->IsSystemPrincipal() && - mozilla::dom::IsWebRemoteType(GetEffectiveTriggeringRemoteType())) { + GetEffectiveTriggeringRemoteType().IsWeb()) { bool localFile = false; if (NS_SUCCEEDED(NS_URIChainHasFlags( URI(), nsIProtocolHandler::URI_IS_LOCAL_FILE, &localFile)) && diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index 8dd38a5c14d7..21ac1f05f338 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -7,6 +7,7 @@ #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/NavigationBinding.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/dom/SessionHistoryEntry.h" #include "mozilla/dom/UserNavigationInvolvement.h" #include "mozilla/dom/LoadURIOptionsBinding.h" @@ -363,11 +364,13 @@ class nsDocShellLoadState final { bool IsMetaRefresh() const { return mIsMetaRefresh; } - const mozilla::Maybe& GetRemoteTypeOverride() const { + const mozilla::Maybe& GetRemoteTypeOverride() + const { return mRemoteTypeOverride; } - void SetRemoteTypeOverride(const nsCString& aRemoteTypeOverride); + void SetRemoteTypeOverride( + const mozilla::dom::RemoteType& aRemoteTypeOverride); void SetSchemelessInput(nsILoadInfo::SchemelessInputType aSchemelessInput) { mSchemelessInput = aSchemelessInput; @@ -402,9 +405,10 @@ class nsDocShellLoadState final { // 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; + const mozilla::dom::RemoteType& GetEffectiveTriggeringRemoteType() const; - void SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType); + void SetTriggeringRemoteType( + const mozilla::dom::RemoteType& aTriggeringRemoteType); // Diagnostic assert if this is a system-principal triggered load, and it is // trivial to determine that the effective triggering remote type would not be @@ -758,10 +762,10 @@ class nsDocShellLoadState final { nsCOMPtr mUnstrippedURI; // If set, the remote type which the load should be completed within. - mozilla::Maybe mRemoteTypeOverride; + mozilla::Maybe mRemoteTypeOverride; // Remote type of the process which originally requested the load. - nsCString mTriggeringRemoteType; + mozilla::dom::RemoteType mTriggeringRemoteType; // if the address had an intentional protocol nsILoadInfo::SchemelessInputType mSchemelessInput = diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp index dac837e73302..038c43a873c5 100644 --- a/dom/base/ChromeUtils.cpp +++ b/dom/base/ChromeUtils.cpp @@ -2062,44 +2062,44 @@ already_AddRefed ChromeUtils::RequestProcInfo(GlobalObject& aGlobal, // Convert the remoteType into a ProcType. // Ideally, the remoteType should be strongly typed // upstream, this would make the conversion less brittle. - const nsAutoCString remoteType(contentParent->GetRemoteType()); - if (StringBeginsWith(remoteType, FISSION_WEB_REMOTE_TYPE)) { - // WARNING: Do not change the order, as - // `DEFAULT_REMOTE_TYPE` is a prefix of - // `FISSION_WEB_REMOTE_TYPE`. - type = mozilla::ProcType::WebIsolated; - } else if (StringBeginsWith(remoteType, SERVICEWORKER_REMOTE_TYPE)) { - type = mozilla::ProcType::WebServiceWorker; - } else if (StringBeginsWith(remoteType, - WITH_COOP_COEP_REMOTE_TYPE_PREFIX)) { - type = mozilla::ProcType::WebCOOPCOEP; - } else if (remoteType == FILE_REMOTE_TYPE) { - type = mozilla::ProcType::File; - } else if (remoteType == EXTENSION_REMOTE_TYPE) { - type = mozilla::ProcType::Extension; - } else if (remoteType == PRIVILEGEDABOUT_REMOTE_TYPE) { - type = mozilla::ProcType::PrivilegedAbout; - } else if (remoteType == PRIVILEGEDMOZILLA_REMOTE_TYPE) { - type = mozilla::ProcType::PrivilegedMozilla; - } else if (remoteType == PREALLOC_REMOTE_TYPE) { - type = mozilla::ProcType::Preallocated; - } else if (remoteType == INFERENCE_REMOTE_TYPE) { - type = mozilla::ProcType::Inference; - } else if (StringBeginsWith(remoteType, DEFAULT_REMOTE_TYPE)) { - type = mozilla::ProcType::Web; - } else { - MOZ_CRASH_UNSAFE_PRINTF("Unknown remoteType '%s'", remoteType.get()); + const RemoteType& remoteType = contentParent->GetRemoteType(); + switch (remoteType.GetKind()) { + case RemoteType::Kind::WebContent: + type = remoteType.HasOrigin() ? mozilla::ProcType::WebIsolated + : mozilla::ProcType::Web; + break; + case RemoteType::Kind::WebServiceWorker: + type = mozilla::ProcType::WebServiceWorker; + break; + case RemoteType::Kind::WebCoopCoep: + type = mozilla::ProcType::WebCOOPCOEP; + break; + case RemoteType::Kind::File: + type = mozilla::ProcType::File; + break; + case RemoteType::Kind::Extension: + type = mozilla::ProcType::Extension; + break; + case RemoteType::Kind::PrivilegedAbout: + type = mozilla::ProcType::PrivilegedAbout; + break; + case RemoteType::Kind::PrivilegedMozilla: + type = mozilla::ProcType::PrivilegedMozilla; + break; + case RemoteType::Kind::Prealloc: + type = mozilla::ProcType::Preallocated; + break; + case RemoteType::Kind::Inference: + type = mozilla::ProcType::Inference; + break; + default: { + MOZ_CRASH_UNSAFE_PRINTF("Unknown remoteType '%s'", + remoteType.StringifyKind().get()); + } } - // By convention, everything after '=' is the origin. - nsAutoCString origin; - nsACString::const_iterator cursor; - nsACString::const_iterator end; - remoteType.BeginReading(cursor); - remoteType.EndReading(end); - if (FindCharInReadable('=', cursor, end)) { - origin = Substring(++cursor, end); - } + // FIXME: We should pass out a parsed remote type to the caller + nsAutoCString origin = remoteType.StringifyMeta(); // Attach DOM window information to the process. nsTArray windows; @@ -2608,7 +2608,13 @@ already_AddRefed ChromeUtils::EnsureHeadlessContentProcess( return nullptr; } - ContentParent::GetNewOrUsedBrowserProcessAsync(aRemoteType) + RemoteType parsedRemoteType = RemoteType::Parse(aRemoteType); + if (!parsedRemoteType) { + promise->MaybeReject(NS_ERROR_INVALID_ARG); + return promise.forget(); + } + + ContentParent::GetNewOrUsedBrowserProcessAsync(parsedRemoteType) ->Then( GetCurrentSerialEventTarget(), __func__, [promise](UniqueContentParentKeepAlive&& aKeepAlive) { @@ -3012,8 +3018,8 @@ void ChromeUtils::PredictRemoteTypeForURI( GlobalObject& aGlobal, nsIURI* aURI, const PredictRemoteTypeOptions& aOptions, nsACString& aRemoteType, ErrorResult& aRv) { - // If 'useRemoteTabs' is disabled, immediately return with NOT_REMOTE_TYPE, - // as we won't perform any process isolation. + // If 'useRemoteTabs' is disabled, immediately return with NotRemote as we + // won't perform any process isolation. bool useRemoteTabs = true; if (aOptions.mUseRemoteTabs.WasPassed()) { useRemoteTabs = aOptions.mUseRemoteTabs.Value(); @@ -3021,7 +3027,7 @@ void ChromeUtils::PredictRemoteTypeForURI( useRemoteTabs = aOptions.mWindow->GetBrowsingContext()->UseRemoteTabs(); } if (!useRemoteTabs) { - aRemoteType = NOT_REMOTE_TYPE; + aRemoteType = RemoteType::NotRemote().Stringify(); return; } @@ -3042,14 +3048,22 @@ void ChromeUtils::PredictRemoteTypeForURI( attrs.mPrivateBrowsingId = aOptions.mWindow->IsPrivateBrowsing() ? 1 : 0; } - nsCString preferredRemoteType = aOptions.mPreferredRemoteType.WasPassed() - ? aOptions.mPreferredRemoteType.Value() - : SharedWebRemoteType(attrs); + RemoteType preferredRemoteType; + if (aOptions.mPreferredRemoteType.WasPassed()) { + preferredRemoteType = + RemoteType::Parse(aOptions.mPreferredRemoteType.Value()); + if (!preferredRemoteType) { + aRv.ThrowTypeError("Invalid preferredRemoteType value"); + return; + } + } else { + preferredRemoteType = RemoteType::SharedWeb(attrs); + } // If we got nullptr as our argument URI argument, treat it like an // about:blank document, and load it into our preferred remote type. if (!aURI) { - aRemoteType = preferredRemoteType; + aRemoteType = preferredRemoteType.Stringify(); return; } @@ -3060,7 +3074,7 @@ void ChromeUtils::PredictRemoteTypeForURI( return; } - aRemoteType = result.unwrap(); + aRemoteType = result.unwrap().Stringify(); } void ChromeUtils::PredictRemoteTypeForURI( diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index d956fdc0cb08..cbe296f25108 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -168,7 +168,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext, mOwnerContent(aOwner), mPendingSwitchID(0), mChildID(0), - mRemoteType(NOT_REMOTE_TYPE), + mRemoteType(RemoteType::NotRemote()), mInitialized(false), mDepthTooGreat(false), mIsTopLevelContent(false), @@ -418,24 +418,30 @@ already_AddRefed nsFrameLoader::Create( } bool isRemoteFrame = InitialLoadIsRemote(aOwner); - RefPtr fl = - new nsFrameLoader(aOwner, context, isRemoteFrame, aNetworkCreated); - fl->mOpenWindowInfo = aOpenWindowInfo; // If this is a toplevel initial remote frame, we're looking at a browser // loaded in the parent process. Pull the remote type attribute off of the // element to determine which remote type it should be loaded in, or // use a shared web remote type if we can't tell. + RemoteType remoteType; if (isRemoteFrame) { MOZ_ASSERT(XRE_IsParentProcess()); - nsAutoString remoteType; - if (aOwner->GetAttr(nsGkAtoms::RemoteType, remoteType) && - !remoteType.IsEmpty()) { - CopyUTF16toUTF8(remoteType, fl->mRemoteType); + nsAutoString remoteTypeAttr; + if (aOwner->GetAttr(nsGkAtoms::RemoteType, remoteTypeAttr) && + !remoteTypeAttr.IsEmpty()) { + remoteType = RemoteType::Parse(NS_ConvertUTF16toUTF8(remoteTypeAttr)); + NS_ENSURE_TRUE(remoteType, nullptr); } else { - fl->mRemoteType = SharedWebRemoteType(context->OriginAttributesRef()); + remoteType = RemoteType::SharedWeb(context->OriginAttributesRef()); } + } else { + remoteType = RemoteType::NotRemote(); } + + RefPtr fl = + new nsFrameLoader(aOwner, context, isRemoteFrame, aNetworkCreated); + fl->mOpenWindowInfo = aOpenWindowInfo; + fl->mRemoteType = remoteType; return fl.forget(); } @@ -541,7 +547,7 @@ void nsFrameLoader::LoadFrame(bool aOriginalSrc, } } -void nsFrameLoader::ConfigRemoteProcess(const nsACString& aRemoteType, +void nsFrameLoader::ConfigRemoteProcess(const RemoteType& aRemoteType, ContentParent* aContentParent) { MOZ_DIAGNOSTIC_ASSERT(IsRemoteFrame(), "Must be a remote frame"); MOZ_DIAGNOSTIC_ASSERT(!mRemoteBrowser, "Must not have a browser yet"); diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index 2db22ec9631e..7a6b7da2b866 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -25,6 +25,7 @@ #include "mozilla/dom/Nullable.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/ReferrerPolicyBinding.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/dom/WindowProxyHolder.h" #include "mozilla/dom/ipc/IdType.h" #include "mozilla/layers/LayersTypes.h" @@ -406,7 +407,7 @@ class nsFrameLoader final : public nsStubMutationObserver, // `TryRemoteBrowser`, and a script blocker must be on the stack. // // |aContentParent|, if set, must have the remote type |aRemoteType|. - void ConfigRemoteProcess(const nsACString& aRemoteType, + void ConfigRemoteProcess(const mozilla::dom::RemoteType& aRemoteType, mozilla::dom::ContentParent* aContentParent); // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) @@ -526,7 +527,7 @@ class nsFrameLoader final : public nsStubMutationObserver, // refcounted cycles early. RefPtr mSessionStoreChild; - nsCString mRemoteType; + mozilla::dom::RemoteType mRemoteType; bool mInitialized : 1; bool mDepthTooGreat : 1; diff --git a/dom/base/nsFrameLoaderOwner.cpp b/dom/base/nsFrameLoaderOwner.cpp index a9653876477a..8708f93a5057 100644 --- a/dom/base/nsFrameLoaderOwner.cpp +++ b/dom/base/nsFrameLoaderOwner.cpp @@ -250,14 +250,18 @@ void nsFrameLoaderOwner::UpdateFocusAndMouseEnterStateAfterFrameLoaderChange( void nsFrameLoaderOwner::ChangeRemoteness( const mozilla::dom::RemotenessOptions& aOptions, mozilla::ErrorResult& rv) { - bool isRemote = !aOptions.mRemoteType.IsEmpty(); + RemoteType remoteType = RemoteType::Parse(aOptions.mRemoteType); + if (!remoteType) { + rv.ThrowTypeError("Invalid RemoteType"); + return; + } MOZ_RELEASE_ASSERT(mFrameLoader, "Expecting to have mFrameLoader here."); std::function frameLoaderInit = [&] { MOZ_RELEASE_ASSERT(mFrameLoader, "Expecting still to have mFrameLoader here."); - if (isRemote) { - mFrameLoader->ConfigRemoteProcess(aOptions.mRemoteType, nullptr); + if (!remoteType.IsNotRemote()) { + mFrameLoader->ConfigRemoteProcess(remoteType, nullptr); } if (aOptions.mPendingSwitchID.WasPassed()) { @@ -269,10 +273,11 @@ void nsFrameLoaderOwner::ChangeRemoteness( }; auto shouldPreserve = ShouldPreserveBrowsingContext( - isRemote, /* replaceBrowsingContext */ false); + !remoteType.IsNotRemote(), /* replaceBrowsingContext */ false); NavigationIsolationOptions options; ChangeRemotenessCommon(shouldPreserve, options, - aOptions.mSwitchingInProgressLoad, isRemote, + aOptions.mSwitchingInProgressLoad, + !remoteType.IsNotRemote(), /* group */ nullptr, frameLoaderInit, rv); } diff --git a/dom/clients/manager/ClientOpenWindowUtils.cpp b/dom/clients/manager/ClientOpenWindowUtils.cpp index 0645a413447b..4f52b8b10644 100644 --- a/dom/clients/manager/ClientOpenWindowUtils.cpp +++ b/dom/clients/manager/ClientOpenWindowUtils.cpp @@ -366,7 +366,7 @@ void WaitForLoad(const ClientOpenWindowArgsParsed& aArgsValidated, loadState->SetTriggeringRemoteType( aArgsValidated.originContent ? aArgsValidated.originContent->GetRemoteType() - : NOT_REMOTE_TYPE); + : RemoteType::NotRemote()); rv = aBrowsingContext->LoadURI(loadState, true); if (NS_FAILED(rv)) { diff --git a/dom/clients/manager/ClientValidation.cpp b/dom/clients/manager/ClientValidation.cpp index b8cd7167c07f..2e8fd8006a13 100644 --- a/dom/clients/manager/ClientValidation.cpp +++ b/dom/clients/manager/ClientValidation.cpp @@ -8,6 +8,7 @@ #include "mozilla/dom/ClientIPCTypes.h" #include "mozilla/dom/LoadedOriginSet.h" #include "mozilla/dom/ProcessIsolation.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" #include "mozilla/net/MozURL.h" diff --git a/dom/fetch/FetchParent.cpp b/dom/fetch/FetchParent.cpp index e720acc51f1a..a36b784e2780 100644 --- a/dom/fetch/FetchParent.cpp +++ b/dom/fetch/FetchParent.cpp @@ -114,7 +114,7 @@ IPCResult FetchParent::RecvFetchOp(FetchOpArgs&& aArgs) { // The inference process uses ChromeWorkers which have a system principal, // so system principals must be allowed there. EnumSet options; - if (contentHandle->GetRemoteType() == INFERENCE_REMOTE_TYPE) { + if (contentHandle->GetRemoteType().IsInference()) { options += ValidatePrincipalOptions::AllowSystemIfLoaded; } if (!contentHandle->ValidatePrincipal(principal, options)) { diff --git a/dom/fs/child/FileSystemBackgroundRequestHandler.cpp b/dom/fs/child/FileSystemBackgroundRequestHandler.cpp index 2104859172fb..55bfba000a20 100644 --- a/dom/fs/child/FileSystemBackgroundRequestHandler.cpp +++ b/dom/fs/child/FileSystemBackgroundRequestHandler.cpp @@ -79,7 +79,7 @@ FileSystemBackgroundRequestHandler::CreateFileSystemManagerChild( // Throw if this process wouldn't be allowed to access storage. EnumSet options; - if (CurrentRemoteType() == INFERENCE_REMOTE_TYPE) { + if (CurrentRemoteType().IsInference()) { options += ValidatePrincipalOptions::AllowSystemIfLoaded; } if (!BackgroundChild::ValidatePrincipalInfo(aPrincipalInfo, options)) { diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 36ec79dc9e3f..22df402700c5 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -2212,7 +2212,7 @@ already_AddRefed BrowserChild::ConvertToDataTransfer( // the principal permits it (and dom.events.datatransfer.protected.enabled is // false). Otherwise, protected DataTransfer access should only be given to // the system. - if (!aPrincipal || Manager()->GetRemoteType() != EXTENSION_REMOTE_TYPE) { + if (!aPrincipal || !Manager()->GetRemoteType().IsExtension()) { aPrincipal = nsContentUtils::GetSystemPrincipal(); } diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index bcda6d006242..8f1559c0a45a 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -646,7 +646,8 @@ ContentChild::ContentChild() { StaticMutexAutoLock lock(sLoadedOriginsMutex); MOZ_ASSERT(!sLoadedOrigins); - sLoadedOrigins = MakeRefPtr(PREALLOC_REMOTE_TYPE); + sLoadedOrigins = + MakeRefPtr(RemoteType(RemoteType::Kind::Prealloc)); RunOnShutdown([] { StaticMutexAutoLock lock(sLoadedOriginsMutex); sLoadedOrigins = nullptr; @@ -822,12 +823,8 @@ void ContentChild::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint, } void ContentChild::AddProfileToProcessName(const nsACString& aProfile) { - nsCOMPtr isolationPrincipal = - ContentParent::CreateRemoteTypeIsolationPrincipal(mRemoteType); - if (isolationPrincipal) { - if (isolationPrincipal->OriginAttributesRef().IsPrivateBrowsing()) { - return; - } + if (mRemoteType.IsPrivateBrowsing()) { + return; } mProcessName = aProfile + ":"_ns + mProcessName; //:example.com @@ -861,35 +858,26 @@ void ContentChild::SetProcessName(const nsACString& aName, // Requires pref flip if (aSite && StaticPrefs::fission_processSiteNames()) { - nsCOMPtr isolationPrincipal = - ContentParent::CreateRemoteTypeIsolationPrincipal(mRemoteType); - if (isolationPrincipal) { - // DEFAULT_PRIVATE_BROWSING_ID is the value when it's not private - MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, - ("private = %d, pref = %d", - isolationPrincipal->OriginAttributesRef().IsPrivateBrowsing(), - StaticPrefs::fission_processPrivateWindowSiteNames())); - if (!isolationPrincipal->OriginAttributesRef().IsPrivateBrowsing() + // DEFAULT_PRIVATE_BROWSING_ID is the value when it's not private + MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, + ("private = %d, pref = %d", mRemoteType.IsPrivateBrowsing(), + StaticPrefs::fission_processPrivateWindowSiteNames())); + if (!mRemoteType.IsPrivateBrowsing() #ifdef NIGHTLY_BUILD - // Nightly can show site names for private windows, with a second pref - || StaticPrefs::fission_processPrivateWindowSiteNames() + // Nightly can show site names for private windows, with a second pref + || StaticPrefs::fission_processPrivateWindowSiteNames() #endif - ) { + ) { #if !defined(XP_MACOSX) - // Mac doesn't have the 15-character limit Linux does - // Sets profiler process name - if (isolationPrincipal->SchemeIs("https")) { - nsAutoCString schemeless; - isolationPrincipal->GetHostPort(schemeless); - nsAutoCString originSuffix; - isolationPrincipal->GetOriginSuffix(originSuffix); - schemeless.Append(originSuffix); - mProcessName = std::move(schemeless); - } else + // Mac doesn't have the 15-character limit Linux does + // Sets profiler process name + constexpr nsLiteralCString prefix = "https://"_ns; + if (StringBeginsWith(*aSite, prefix)) { + mProcessName = Substring(*aSite, prefix.Length()); + } else #endif - { - mProcessName = *aSite; - } + { + mProcessName = *aSite; } } } @@ -1288,11 +1276,11 @@ void ContentChild::MaybeBecomeUntrusted() { } ContentChild* cc = ContentChild::GetSingleton(); - MOZ_DIAGNOSTIC_ASSERT(cc->GetRemoteType() != PREALLOC_REMOTE_TYPE, + MOZ_DIAGNOSTIC_ASSERT(!cc->GetRemoteType().IsPrealloc(), "Prealloc process cannot become untrusted"); // Never mark the privilegedabout process as untrusted. - if (cc->GetRemoteType() == PRIVILEGEDABOUT_REMOTE_TYPE) { + if (cc->GetRemoteType().IsPrivilegedAbout()) { return; } @@ -1358,7 +1346,7 @@ void ContentChild::InitXPCOM( ClientManager::Startup(); - // RemoteWorkerService will be initialized in RecvRemoteType, to avoid to + // RemoteWorkerService will be initialized in RecvSetRemoteType, to avoid to // register it to the RemoteWorkerManager while it is still a prealloc // remoteType and defer it to the point the child process is assigned a. // actual remoteType. @@ -1454,10 +1442,10 @@ mozilla::ipc::IPCResult ContentChild::RecvRequestMemoryReport( const Maybe& aDMDFile, const RequestMemoryReportResolver& aResolver) { nsCString process; - if (aAnonymize || mRemoteType.IsEmpty()) { + if (aAnonymize || !mRemoteType.IsKnown()) { GetProcessName(process); } else { - process = mRemoteType; + process = mRemoteType.Stringify(); } AppendProcessId(process); MOZ_ASSERT(!process.IsEmpty()); @@ -2705,15 +2693,15 @@ mozilla::ipc::IPCResult ContentChild::RecvAppInfo( return IPC_OK(); } -nsCString CurrentRemoteType() { +RemoteType CurrentRemoteType() { if (XRE_IsContentProcess()) { if (RefPtr loadedOrigins = CurrentLoadedOriginSet()) { return loadedOrigins->GetRemoteType(); } - return PREALLOC_REMOTE_TYPE; + return RemoteType(RemoteType::Kind::Prealloc); } - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } already_AddRefed CurrentLoadedOriginSet() { @@ -2721,40 +2709,37 @@ already_AddRefed CurrentLoadedOriginSet() { return do_AddRef(sLoadedOrigins); } -mozilla::ipc::IPCResult ContentChild::RecvRemoteType( - const nsCString& aRemoteType, const nsCString& aProfile) { +mozilla::ipc::IPCResult ContentChild::RecvSetRemoteType( + const RemoteType& aRemoteType, const nsCString& aProfile) { if (aRemoteType == mRemoteType) { // Allocation of preallocated processes that are still launching can // cause this return IPC_OK(); } - if (!mRemoteType.IsVoid()) { - // Preallocated processes are type PREALLOC_REMOTE_TYPE; they may not - // become a File: process, or Privileged About Content Process + if (mRemoteType.IsKnown()) { MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, ("Changing remoteType of process %d from %s to %s", getpid(), - mRemoteType.get(), aRemoteType.get())); - // prealloc->anything (but file) or web->web allowed, and no-change - MOZ_RELEASE_ASSERT(mRemoteType == PREALLOC_REMOTE_TYPE && - aRemoteType != FILE_REMOTE_TYPE && - aRemoteType != PRIVILEGEDABOUT_REMOTE_TYPE); + mRemoteType.Stringify().get(), aRemoteType.Stringify().get())); + MOZ_RELEASE_ASSERT( + mRemoteType.IsPrealloc(), + "Cannot change remote type unless we're a prealloc process"); + MOZ_RELEASE_ASSERT(aRemoteType.SupportsPrealloc(), + "Cannot use prealloc process for this remote type"); } else { // Initial setting of remote type. Either to 'prealloc' or the actual // final type (if we didn't use a preallocated process) MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, ("Setting remoteType of process %d to %s", getpid(), - aRemoteType.get())); + aRemoteType.Stringify().get())); - if (aRemoteType == PREALLOC_REMOTE_TYPE) { + if (aRemoteType.IsPrealloc()) { PreallocInit(); } } - auto remoteTypePrefix = RemoteTypePrefix(aRemoteType); - // Must do before SetProcessName - mRemoteType.Assign(aRemoteType); + mRemoteType = aRemoteType; RefPtr loadedOrigins = CurrentLoadedOriginSet(); if (!loadedOrigins) { @@ -2763,36 +2748,32 @@ mozilla::ipc::IPCResult ContentChild::RecvRemoteType( loadedOrigins->SetRemoteType(mRemoteType); // Update the process name so about:memory's process names are more obvious. - if (aRemoteType == FILE_REMOTE_TYPE) { + if (aRemoteType.IsFile()) { SetProcessName("file:// Content"_ns, nullptr, &aProfile); - } else if (aRemoteType == EXTENSION_REMOTE_TYPE) { + } else if (aRemoteType.IsExtension()) { SetProcessName("WebExtensions"_ns, nullptr, &aProfile); - } else if (aRemoteType == PRIVILEGEDABOUT_REMOTE_TYPE) { + } else if (aRemoteType.IsPrivilegedAbout()) { SetProcessName("Privileged Content"_ns, nullptr, &aProfile); - } else if (aRemoteType == PRIVILEGEDMOZILLA_REMOTE_TYPE) { + } else if (aRemoteType.IsPrivilegedMozilla()) { SetProcessName("Privileged Mozilla"_ns, nullptr, &aProfile); - } else if (aRemoteType == INFERENCE_REMOTE_TYPE) { + } else if (aRemoteType.IsInference()) { SetProcessName("Inference"_ns, nullptr, &aProfile); - } else if (remoteTypePrefix == WITH_COOP_COEP_REMOTE_TYPE) { - // The profiler can sanitize out the eTLD+1 - nsDependentCSubstring etld = - Substring(aRemoteType, WITH_COOP_COEP_REMOTE_TYPE.Length() + 1); + } else if (aRemoteType.IsIsolatedWeb()) { + nsAutoCString site = mRemoteType.StringifyMeta(); + + if (aRemoteType.IsWebServiceWorker()) { + SetProcessName("Isolated Service Worker"_ns, &site, &aProfile); + } #ifdef NIGHTLY_BUILD - SetProcessName("WebCOOP+COEP Content"_ns, &etld, &aProfile); -#else - SetProcessName("Isolated Web Content"_ns, &etld, - &aProfile); // to avoid confusing people + else if (aRemoteType.IsWebCoopCoep()) { + // NOTE: We only distinguish between isolated web sub-types on Nightly + // builds to avoid confusing users. + SetProcessName("WebCOOP+COEP Content"_ns, &site, &aProfile); + } #endif - } else if (remoteTypePrefix == FISSION_WEB_REMOTE_TYPE) { - // The profiler can sanitize out the eTLD+1 - nsDependentCSubstring etld = - Substring(aRemoteType, FISSION_WEB_REMOTE_TYPE.Length() + 1); - SetProcessName("Isolated Web Content"_ns, &etld, &aProfile); - } else if (remoteTypePrefix == SERVICEWORKER_REMOTE_TYPE) { - // The profiler can sanitize out the eTLD+1 - nsDependentCSubstring etld = - Substring(aRemoteType, SERVICEWORKER_REMOTE_TYPE.Length() + 1); - SetProcessName("Isolated Service Worker"_ns, &etld, &aProfile); + else { + SetProcessName("Isolated Web Content"_ns, &site, &aProfile); + } } else { // else "prealloc" or "web" type -> "Web Content" SetProcessName("Web Content"_ns, nullptr, &aProfile); @@ -2801,17 +2782,15 @@ mozilla::ipc::IPCResult ContentChild::RecvRemoteType( // Turn off Spectre mitigations in isolated web content processes. if (StaticPrefs::javascript_options_spectre_disable_for_isolated_content() && StaticPrefs::browser_opaqueResponseBlocking() && - (remoteTypePrefix == FISSION_WEB_REMOTE_TYPE || - remoteTypePrefix == SERVICEWORKER_REMOTE_TYPE || - remoteTypePrefix == WITH_COOP_COEP_REMOTE_TYPE || - aRemoteType == PRIVILEGEDABOUT_REMOTE_TYPE || - aRemoteType == PRIVILEGEDMOZILLA_REMOTE_TYPE)) { + (aRemoteType.IsIsolatedWeb() || aRemoteType.IsPrivilegedAbout() || + aRemoteType.IsPrivilegedMozilla())) { JS::DisableSpectreMitigationsAfterInit(); } - // Use the prefix to avoid URIs from Fission isolated processes. + // Only include the kind, as we don't want to include URIs from + // Fission-isolated processes. CrashReporter::RecordAnnotationNSCString( - CrashReporter::Annotation::RemoteType, remoteTypePrefix); + CrashReporter::Annotation::RemoteType, mRemoteType.StringifyKind()); return IPC_OK(); } @@ -2845,9 +2824,9 @@ void ContentChild::PreallocInit() { nsHttpHandler::PresetAcceptLanguages(); } -// Call RemoteTypePrefix() on the result to remove URIs if you want to use this +// Call .StringifyKind() on the result to remove URIs if you want to use this // for telemetry. -const nsACString& ContentChild::GetRemoteType() const { return mRemoteType; } +const RemoteType& ContentChild::GetRemoteType() const { return mRemoteType; } mozilla::ipc::IPCResult ContentChild::RecvInitRemoteWorkerService( Endpoint&& aEndpoint, @@ -3541,7 +3520,7 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( nsCOMPtr loadInfo; nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo( - aArgs.loadInfo(), NOT_REMOTE_TYPE, getter_AddRefs(loadInfo)); + aArgs.loadInfo(), RemoteType::NotRemote(), getter_AddRefs(loadInfo)); if (NS_FAILED(rv)) { MOZ_DIAGNOSTIC_CRASH("LoadInfoArgsToLoadInfo failed"); return IPC_OK(); @@ -4350,7 +4329,7 @@ mozilla::ipc::IPCResult ContentChild::RecvReportFrameTimingData( nsCOMPtr loadInfo; nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo( - loadInfoArgs, NOT_REMOTE_TYPE, getter_AddRefs(loadInfo)); + loadInfoArgs, RemoteType::NotRemote(), getter_AddRefs(loadInfo)); if (NS_FAILED(rv)) { MOZ_DIAGNOSTIC_CRASH("LoadInfoArgsToLoadInfo failed"); return IPC_OK(); diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index f458695782e1..0b347d487450 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -69,6 +69,7 @@ class SharedMap; class ConsoleListener; class BrowserChild; +class IPCTabContext; class TabContext; enum class CallerType : uint32_t; @@ -393,14 +394,12 @@ class ContentChild final : public PContentChild, const nsCString& UAName, const nsCString& ID, const nsCString& vendor, const nsCString& sourceURL, const nsCString& updateURL); - mozilla::ipc::IPCResult RecvRemoteType(const nsCString& aRemoteType, - const nsCString& aProfile); + mozilla::ipc::IPCResult RecvSetRemoteType(const RemoteType& aRemoteType, + const nsCString& aProfile); void PreallocInit(); - // Call RemoteTypePrefix() on the result to remove URIs if you want to use - // this for telemetry. - const nsACString& GetRemoteType() const override; + const RemoteType& GetRemoteType() const override; mozilla::ipc::IPCResult RecvAddLoadedOrigin(nsIPrincipal* aPrincipal); @@ -906,7 +905,7 @@ class ContentChild final : public PContentChild, AppInfo mAppInfo; bool mIsForBrowser; - nsCString mRemoteType = NOT_REMOTE_TYPE; + RemoteType mRemoteType; bool mIsAlive; nsCString mProcessName; @@ -960,7 +959,7 @@ inline nsISupports* ToSupports(mozilla::dom::ContentChild* aContentChild) { } // Threadsafe getter for the current process's RemoteType. -nsCString CurrentRemoteType(); +RemoteType CurrentRemoteType(); // Threadsafe getter for the current process's loaded origins. already_AddRefed CurrentLoadedOriginSet(); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 9fa589c251da..54567ebeff9f 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -580,18 +580,17 @@ ContentParentsMemoryReporter::CollectReports( // processes that are in the Preallocator cache (which would be type // 'prealloc'), and recycled processes ('web' and in the future // eTLD+1-locked) processes). -nsClassHashtable>* +nsClassHashtable, nsTArray>* ContentParent::sBrowserContentParents; namespace { -ProcessID GetTelemetryProcessID(const nsACString& remoteType) { +ProcessID GetTelemetryProcessID(const RemoteType& remoteType) { // OOP WebExtensions run in a content process. // For Telemetry though we want to break out collected data from the // WebExtensions process into a separate bucket, to make sure we can analyze // it separately and avoid skewing normal content process metrics. - return remoteType == EXTENSION_REMOTE_TYPE ? ProcessID::Extension - : ProcessID::Content; + return remoteType.IsExtension() ? ProcessID::Extension : ProcessID::Content; } } // anonymous namespace @@ -649,7 +648,8 @@ void ContentParent_NotifyUpdatedDictionaries() { // PreallocateProcess is called by the PreallocatedProcessManager. // ContentParent then takes this process back within GetNewOrUsedBrowserProcess. /*static*/ UniqueContentParentKeepAlive ContentParent::MakePreallocProcess() { - RefPtr process = new ContentParent(PREALLOC_REMOTE_TYPE); + RefPtr process = + new ContentParent(RemoteType(RemoteType::Kind::Prealloc)); if (NS_WARN_IF(!process->BeginSubprocessLaunch(PROCESS_PRIORITY_PREALLOC))) { process->LaunchSubprocessReject(); return nullptr; @@ -704,7 +704,7 @@ void ContentParent::ShutDown() { } /*static*/ -uint32_t ContentParent::GetPoolSize(const nsACString& aContentProcessType) { +uint32_t ContentParent::GetPoolSize(const RemoteType& aContentProcessType) { if (!sBrowserContentParents) { return 0; } @@ -716,74 +716,20 @@ uint32_t ContentParent::GetPoolSize(const nsACString& aContentProcessType) { } /*static*/ nsTArray& ContentParent::GetOrCreatePool( - const nsACString& aContentProcessType) { + const RemoteType& aContentProcessType) { if (!sBrowserContentParents) { - sBrowserContentParents = - new nsClassHashtable>; + sBrowserContentParents = new nsClassHashtable, + nsTArray>; } return *sBrowserContentParents->GetOrInsertNew(aContentProcessType); } -nsDependentCSubstring RemoteTypePrefix(const nsACString& aContentProcessType) { - // The suffix after a `=` in a remoteType is dynamic, and used to control the - // process pool to use. - int32_t equalIdx = aContentProcessType.FindChar(L'='); - if (equalIdx == kNotFound) { - equalIdx = aContentProcessType.Length(); - } - return StringHead(aContentProcessType, equalIdx); -} - -static bool IsRemoteTypeJitDisabled(const nsACString& aContentProcessType) { - if (!StringEndsWith(aContentProcessType, DISABLE_JIT_REMOTE_TYPE_SUFFIX)) { - return false; - } - - auto remoteTypePrefix = RemoteTypePrefix(aContentProcessType); - if (remoteTypePrefix != FISSION_WEB_REMOTE_TYPE && - remoteTypePrefix != SERVICEWORKER_REMOTE_TYPE && - remoteTypePrefix != WITH_COOP_COEP_REMOTE_TYPE) { - return false; - } - - auto suffixStart = - aContentProcessType.Length() - DISABLE_JIT_REMOTE_TYPE_SUFFIX.Length(); - if (suffixStart > 0) { - char priorChar = aContentProcessType[suffixStart - 1]; - if (priorChar != '&' && priorChar != '^') { - return false; - } - } else { - return false; - } - - return true; -} - -bool IsWebRemoteType(const nsACString& aContentProcessType) { - // Note: matches webIsolated, web, and webCOOP+COEP types. - return StringBeginsWith(aContentProcessType, DEFAULT_REMOTE_TYPE); -} - -bool IsWebCoopCoepRemoteType(const nsACString& aContentProcessType) { - return StringBeginsWith(aContentProcessType, - WITH_COOP_COEP_REMOTE_TYPE_PREFIX); -} - -bool IsExtensionRemoteType(const nsACString& aContentProcessType) { - return aContentProcessType == EXTENSION_REMOTE_TYPE; -} - /*static*/ uint32_t ContentParent::GetMaxProcessCount( - const nsACString& aContentProcessType) { - // Max process count is based only on the prefix. - const nsDependentCSubstring processTypePrefix = - RemoteTypePrefix(aContentProcessType); - - // Check for the default remote type of "web", as it uses different prefs. - if (processTypePrefix == DEFAULT_REMOTE_TYPE) { + const RemoteType& aContentProcessType) { + // Check for the shared web remote type, as it uses different prefs. + if (aContentProcessType.IsSharedWeb()) { return GetMaxWebProcessCount(); } @@ -791,7 +737,7 @@ uint32_t ContentParent::GetMaxProcessCount( // used as a fallback, as it is intended to control the number of "web" // content processes, checked in `mozilla::GetMaxWebProcessCount()`. nsAutoCString processCountPref("dom.ipc.processCount."); - processCountPref.Append(processTypePrefix); + processCountPref.Append(aContentProcessType.StringifyKind()); int32_t maxContentParents = Preferences::GetInt(processCountPref.get(), 1); if (maxContentParents < 1) { @@ -803,7 +749,7 @@ uint32_t ContentParent::GetMaxProcessCount( /*static*/ bool ContentParent::IsMaxProcessCountReached( - const nsACString& aContentProcessType) { + const RemoteType& aContentProcessType) { return GetPoolSize(aContentProcessType) >= GetMaxProcessCount(aContentProcessType); } @@ -820,7 +766,7 @@ void ContentParent::ReleaseCachedProcesses() { #ifdef DEBUG for (const auto& cps : *sBrowserContentParents) { MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, - ("%s: %zu processes", PromiseFlatCString(cps.GetKey()).get(), + ("%s: %zu processes", cps.GetKey().Stringify().get(), cps.GetData()->Length())); } #endif @@ -892,29 +838,9 @@ already_AddRefed ContentParent::MinTabSelect( return candidate.forget(); } -/* static */ -already_AddRefed -ContentParent::CreateRemoteTypeIsolationPrincipal( - const nsACString& aRemoteType) { - if ((RemoteTypePrefix(aRemoteType) != FISSION_WEB_REMOTE_TYPE) && - !StringBeginsWith(aRemoteType, WITH_COOP_COEP_REMOTE_TYPE_PREFIX)) { - return nullptr; - } - - int32_t offset = aRemoteType.FindChar('=') + 1; - MOZ_ASSERT(offset > 1, "can not extract origin from that remote type"); - nsAutoCString origin( - Substring(aRemoteType, offset, aRemoteType.Length() - offset)); - - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); - nsCOMPtr principal; - ssm->CreateContentPrincipalFromOrigin(origin, getter_AddRefs(principal)); - return principal.forget(); -} - /*static*/ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( - const nsACString& aRemoteType, nsTArray& aContentParents, + const RemoteType& aRemoteType, nsTArray& aContentParents, uint32_t aMaxContentParents, bool aPreferUsed, ProcessPriority aPriority, uint64_t aBrowserId) { #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED @@ -944,7 +870,7 @@ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, ("GetUsedProcess: Reused process id=%p childID=%" PRIu64 " for %s", selected.get(), (uint64_t)selected->ChildID(), - PromiseFlatCString(aRemoteType).get())); + aRemoteType.Stringify().get())); selected->AssertAlive(); return selected->AddKeepAlive(aBrowserId); } @@ -952,13 +878,9 @@ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( // Try to take a preallocated process except for certain remote types. // Note: this process may not have finished launching yet UniqueContentParentKeepAlive preallocated; - if (aRemoteType != FILE_REMOTE_TYPE && - aRemoteType != PRIVILEGEDABOUT_REMOTE_TYPE && - aRemoteType != EXTENSION_REMOTE_TYPE && // Bug 1638119 - !IsRemoteTypeJitDisabled(aRemoteType) && + if (aRemoteType.SupportsPrealloc() && (preallocated = PreallocatedProcessManager::Take(aRemoteType))) { - MOZ_DIAGNOSTIC_ASSERT(preallocated->GetRemoteType() == - PREALLOC_REMOTE_TYPE); + MOZ_DIAGNOSTIC_ASSERT(preallocated->GetRemoteType().IsPrealloc()); preallocated->AssertAlive(); if (profiler_thread_is_being_profiled_for_markers()) { @@ -972,20 +894,18 @@ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( ContentParent::GetLog(), LogLevel::Debug, ("Adopted preallocated process id=%p childID=%" PRIu64 " for type %s%s", preallocated.get(), (uint64_t)preallocated->ChildID(), - PromiseFlatCString(aRemoteType).get(), + aRemoteType.Stringify().get(), preallocated->IsLaunching() ? " (still launching)" : "")); - MOZ_LOG(mozilla::ipc::gChildProcessLifecycleLog, LogLevel::Info, - ("REMOTETYPE [childID = %" PRIi32 "] [remoteType = %s]", - preallocated->Process()->GetChildID(), - PromiseFlatCString(aRemoteType).get())); + MOZ_LOG( + mozilla::ipc::gChildProcessLifecycleLog, LogLevel::Info, + ("REMOTETYPE [childID = %" PRIi32 "] [remoteType = %s]", + preallocated->Process()->GetChildID(), aRemoteType.Stringify().get())); // This ensures that the preallocator won't shut down the process once // it finishes starting - preallocated->mRemoteType.Assign(aRemoteType); + preallocated->mRemoteType = aRemoteType; preallocated->LoadedOrigins()->SetRemoteType(preallocated->mRemoteType); - preallocated->mRemoteTypeIsolationPrincipal = - CreateRemoteTypeIsolationPrincipal(aRemoteType); preallocated->AddToPool(aContentParents); // rare, but will happen @@ -993,8 +913,8 @@ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( // Specialize this process for the appropriate remote type, and activate // it. - (void)preallocated->SendRemoteType(preallocated->mRemoteType, - preallocated->mProfile); + (void)preallocated->SendSetRemoteType(preallocated->mRemoteType, + preallocated->mProfile); preallocated->StartRemoteWorkerService(); @@ -1019,11 +939,10 @@ UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess( /*static*/ UniqueContentParentKeepAlive ContentParent::GetNewOrUsedLaunchingBrowserProcess( - const nsACString& aRemoteType, BrowsingContextGroup* aGroup, + const RemoteType& aRemoteType, BrowsingContextGroup* aGroup, ProcessPriority aPriority, bool aPreferUsed, uint64_t aBrowserId) { MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, - ("GetNewOrUsedProcess for type %s", - PromiseFlatCString(aRemoteType).get())); + ("GetNewOrUsedProcess for type %s", aRemoteType.Stringify().get())); if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) { return nullptr; @@ -1063,7 +982,7 @@ UniqueContentParentKeepAlive ContentParent::GetNewOrUsedLaunchingBrowserProcess( // The life cycle will be set to `LifecycleState::LAUNCHING`. MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, ("Launching new process immediately for type %s", - PromiseFlatCString(aRemoteType).get())); + aRemoteType.Stringify().get())); RefPtr newCp = new ContentParent(aRemoteType); if (NS_WARN_IF(!newCp->BeginSubprocessLaunch(aPriority))) { @@ -1099,7 +1018,7 @@ UniqueContentParentKeepAlive ContentParent::GetNewOrUsedLaunchingBrowserProcess( /*static*/ RefPtr -ContentParent::GetNewOrUsedBrowserProcessAsync(const nsACString& aRemoteType, +ContentParent::GetNewOrUsedBrowserProcessAsync(const RemoteType& aRemoteType, BrowsingContextGroup* aGroup, ProcessPriority aPriority, bool aPreferUsed, @@ -1118,7 +1037,7 @@ ContentParent::GetNewOrUsedBrowserProcessAsync(const nsACString& aRemoteType, /*static*/ UniqueContentParentKeepAlive ContentParent::GetNewOrUsedBrowserProcess( - const nsACString& aRemoteType, BrowsingContextGroup* aGroup, + const RemoteType& aRemoteType, BrowsingContextGroup* aGroup, ProcessPriority aPriority, bool aPreferUsed, uint64_t aBrowserId) { UniqueContentParentKeepAlive contentParent = GetNewOrUsedLaunchingBrowserProcess(aRemoteType, aGroup, aPriority, @@ -1372,7 +1291,7 @@ NS_IMETHODIMP ContentParent::ValidatePrincipalXPCOM(nsIPrincipal* aPrincipal, /*static*/ already_AddRefed ContentParent::CreateBrowser( const TabContext& aContext, Element* aFrameElement, - const nsACString& aRemoteType, BrowsingContext* aBrowsingContext, + const RemoteType& aRemoteType, BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent) { AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER); @@ -1389,9 +1308,9 @@ already_AddRefed ContentParent::CreateBrowser( return nullptr; } - nsAutoCString remoteType(aRemoteType); - if (remoteType.IsEmpty()) { - remoteType = SharedWebRemoteType(aBrowsingContext->OriginAttributesRef()); + RemoteType remoteType(aRemoteType); + if (!remoteType.IsKnown() || remoteType.IsNotRemote()) { + remoteType = RemoteType::SharedWeb(aBrowsingContext->OriginAttributesRef()); } TabId tabId(nsContentUtils::GenerateTabId()); @@ -1599,7 +1518,7 @@ void ContentParent::BroadcastMediaCodecsSupportedUpdate( } } -const nsACString& ContentParent::GetRemoteType() const { return mRemoteType; } +const RemoteType& ContentParent::GetRemoteType() const { return mRemoteType; } static StaticRefPtr sXPCOMShutdownClient; static StaticRefPtr sProfileBeforeChangeClient; @@ -2182,7 +2101,7 @@ void ContentParent::MaybeBeginShutDown(bool aImmediate, aImmediate || IsDead() || AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed) || StaticPrefs::dom_ipc_processReuse_unusedGraceMs() == 0 || - IsRemoteTypeJitDisabled(mRemoteType); + mRemoteType.IsJitDisabled(); // Clean up any scheduled idle task unless we schedule a new one. auto cancelIdleTask = MakeScopeExit([&] { @@ -2205,7 +2124,7 @@ void ContentParent::MaybeBeginShutDown(bool aImmediate, // processes alive for performance reasons (e.g. test runs and privileged // content process for some about: pages). We don't want to alter behavior // if the pref is not set, so default to 0. - if (!aIgnoreKeepAlivePref && mIsInPool && !mRemoteType.Contains('=') && + if (!aIgnoreKeepAlivePref && mIsInPool && !mRemoteType.HasMeta() && !AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) { auto* contentParents = sBrowserContentParents->Get(mRemoteType); MOZ_RELEASE_ASSERT( @@ -2213,7 +2132,7 @@ void ContentParent::MaybeBeginShutDown(bool aImmediate, "mIsInPool, yet no entry for mRemoteType in sBrowserContentParents?"); nsAutoCString keepAlivePref("dom.ipc.keepProcessesAlive."); - keepAlivePref.Append(mRemoteType); + keepAlivePref.Append(mRemoteType.StringifyKind()); int32_t processesToKeepAlive = 0; if (NS_SUCCEEDED(Preferences::GetInt(keepAlivePref.get(), @@ -2335,7 +2254,7 @@ already_AddRefed ContentParent::GetTestShellSingleton() { void ContentParent::AppendDynamicSandboxParams( std::vector& aArgs) { // For file content processes - if (GetRemoteType() == FILE_REMOTE_TYPE) { + if (GetRemoteType().IsFile()) { MacSandboxInfo::AppendFileAccessParam(aArgs, true); } } @@ -2499,7 +2418,7 @@ bool ContentParent::BeginSubprocessLaunch(ProcessPriority aPriority) { Preferences::AddStrongObserver(this, ""); geckoargs::sSafeMode.Put(gSafeMode, extraArgs); - geckoargs::sDisableJit.Put(IsRemoteTypeJitDisabled(mRemoteType), extraArgs); + geckoargs::sDisableJit.Put(mRemoteType.IsJitDisabled(), extraArgs); #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) if (IsContentSandboxEnabled()) { @@ -2520,7 +2439,7 @@ bool ContentParent::BeginSubprocessLaunch(ProcessPriority aPriority) { MOZ_LOG(mozilla::ipc::gChildProcessLifecycleLog, LogLevel::Info, ("REMOTETYPE [childID = %" PRIi32 "] [remoteType = %s]", - mSubprocess->GetChildID(), mRemoteType.get())); + mSubprocess->GetChildID(), mRemoteType.Stringify().get())); mLaunchYieldTS = TimeStamp::Now(); return mSubprocess->AsyncLaunch(std::move(extraArgs)); @@ -2641,13 +2560,9 @@ bool ContentParent::LaunchSubprocessResolve(bool aIsSync, return true; } -static bool IsFileContent(const nsACString& aRemoteType) { - return aRemoteType == FILE_REMOTE_TYPE; -} - -ContentParent::ContentParent(const nsACString& aRemoteType) +ContentParent::ContentParent(const RemoteType& aRemoteType) : mSubprocess(new GeckoChildProcessHost(GeckoProcessType_Content, - IsFileContent(aRemoteType))), + aRemoteType.IsFile())), mLaunchTS(TimeStamp::Now()), mLaunchYieldTS(mLaunchTS), mIsAPreallocBlocker(false), @@ -2657,7 +2572,7 @@ ContentParent::ContentParent(const nsACString& aRemoteType) mThreadsafeHandle( new ThreadsafeContentParentHandle(this, mChildID, mRemoteType)), mLifecycleState(LifecycleState::LAUNCHING), - mIsForBrowser(!mRemoteType.IsEmpty()), + mIsForBrowser(!mRemoteType.IsNotRemote()), mCalledClose(false), mCalledKillHard(false), mCreatedPairedMinidumps(false), @@ -2676,9 +2591,6 @@ ContentParent::ContentParent(const nsACString& aRemoteType) mHangMonitorActor(nullptr) { MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); - mRemoteTypeIsolationPrincipal = - CreateRemoteTypeIsolationPrincipal(aRemoteType); - // Insert ourselves into the global linked list of ContentParent objects. if (!sContentParents) { sContentParents = new LinkedList(); @@ -2996,9 +2908,9 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) { // to the message we send to enable the Sandbox (SendStartProcessSandbox) // because different remote types require different sandbox privileges. - (void)SendRemoteType(mRemoteType, mProfile); + (void)SendSetRemoteType(mRemoteType, mProfile); - if (mRemoteType != PREALLOC_REMOTE_TYPE) { + if (!mRemoteType.IsPrealloc()) { StartRemoteWorkerService(); } @@ -3108,7 +3020,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) { # ifdef XP_LINUX if (shouldSandbox) { MOZ_ASSERT(!mSandboxBroker); - bool isFileProcess = mRemoteType == FILE_REMOTE_TYPE; + bool isFileProcess = mRemoteType.IsFile(); UniquePtr policy = sSandboxBrokerPolicyFactory->GetContentPolicy(Pid(), isFileProcess); if (policy) { @@ -3637,7 +3549,7 @@ mozilla::ipc::IPCResult ContentParent::RecvFirstIdle() { if (mIsAPreallocBlocker) { MOZ_LOG(ContentParent::GetLog(), LogLevel::Verbose, ("RecvFirstIdle id=%p childID=%" PRIu64 ": Removing Blocker for %s", - this, (uint64_t)this->ChildID(), mRemoteType.get())); + this, (uint64_t)this->ChildID(), mRemoteType.Stringify().get())); PreallocatedProcessManager::RemoveBlocker(mRemoteType, this); mIsAPreallocBlocker = false; } @@ -3835,7 +3747,7 @@ NS_IMETHODIMP ContentParent::GetState(nsIPropertyBag** aResult) { auto props = MakeRefPtr(); props->SetPropertyAsACString(u"remoteTypePrefix"_ns, - RemoteTypePrefix(mRemoteType)); + mRemoteType.StringifyKind()); *aResult = props.forget().downcast().take(); return NS_OK; } @@ -4736,7 +4648,7 @@ mozilla::ipc::IPCResult ContentParent::RecvPExternalHelperAppConstructor( // file:// URI coming from any other process. if (uri && uri->SchemeIs("file") && StaticPrefs::browser_tabs_remote_separateFileUriProcess() && - GetRemoteType() != FILE_REMOTE_TYPE) { + !GetRemoteType().IsFile()) { return IPC_FAIL(this, "Non-file process sent a file:// URI."); } @@ -6464,17 +6376,14 @@ mozilla::ipc::IPCResult ContentParent::RecvRecordPageLoadEvent( } // Set the process isolation category based on the remote type for Android. - const nsDependentCSubstring remoteTypePrefix = - RemoteTypePrefix(GetRemoteType()); - using namespace mozilla::performance::pageload_event; AndroidIsolationCategory isolationCategory; - if (remoteTypePrefix == WEB_REMOTE_TYPE) { + if (mRemoteType.IsSharedWeb()) { isolationCategory = AndroidIsolationCategory::SHARED_WEB; - } else if (remoteTypePrefix == FISSION_WEB_REMOTE_TYPE) { - isolationCategory = AndroidIsolationCategory::SITE_ISOLATED; - } else if (remoteTypePrefix == WITH_COOP_COEP_REMOTE_TYPE) { + } else if (mRemoteType.IsWebCoopCoep()) { isolationCategory = AndroidIsolationCategory::COOP_ISOLATED; + } else if (mRemoteType.IsIsolatedWeb()) { + isolationCategory = AndroidIsolationCategory::SITE_ISOLATED; } else { isolationCategory = AndroidIsolationCategory::OTHER; } @@ -8004,13 +7913,13 @@ NS_IMETHODIMP ContentParent::GetOsPid(int32_t* aOut) { } NS_IMETHODIMP ContentParent::GetRemoteType(nsACString& aRemoteType) { - aRemoteType = GetRemoteType(); + aRemoteType = GetRemoteType().Stringify(); return NS_OK; } void ContentParent::StartRemoteWorkerService() { MOZ_ASSERT(!mRemoteWorkerServiceActor); - MOZ_ASSERT(mRemoteType != PREALLOC_REMOTE_TYPE); + MOZ_ASSERT(!mRemoteType.IsPrealloc()); Endpoint childEp; mRemoteWorkerServiceActor = @@ -8234,7 +8143,7 @@ IPCResult ContentParent::RecvKillGPUProcess() { } #endif -nsCString ThreadsafeContentParentHandle::GetRemoteType() { +RemoteType ThreadsafeContentParentHandle::GetRemoteType() { return mLoadedOrigins->GetRemoteType(); } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 1f7b097d0022..9b3645e5dd52 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -104,6 +104,7 @@ namespace dom { class BrowsingContextGroup; class Element; class BrowserParent; +class IPCTabContext; class MemoryReport; class TabContext; class GetFilesHelper; @@ -168,11 +169,11 @@ class ContentParent final : public PContentParent, /** Shut down the content-process machinery. */ static void ShutDown(); - static uint32_t GetPoolSize(const nsACString& aContentProcessType); + static uint32_t GetPoolSize(const RemoteType& aContentProcessType); - static uint32_t GetMaxProcessCount(const nsACString& aContentProcessType); + static uint32_t GetMaxProcessCount(const RemoteType& aContentProcessType); - static bool IsMaxProcessCountReached(const nsACString& aContentProcessType); + static bool IsMaxProcessCountReached(const RemoteType& aContentProcessType); static void ReleaseCachedProcesses(); @@ -218,7 +219,7 @@ class ContentParent final : public PContentParent, * The returned KeepAlive will be for this BrowserId. */ static UniqueContentParentKeepAlive GetNewOrUsedLaunchingBrowserProcess( - const nsACString& aRemoteType, BrowsingContextGroup* aGroup = nullptr, + const RemoteType& aRemoteType, BrowsingContextGroup* aGroup = nullptr, hal::ProcessPriority aPriority = hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND, bool aPreferUsed = false, uint64_t aBrowserId = 0); @@ -228,7 +229,7 @@ class ContentParent final : public PContentParent, * resolves when the process is finished launching. */ static RefPtr GetNewOrUsedBrowserProcessAsync( - const nsACString& aRemoteType, BrowsingContextGroup* aGroup = nullptr, + const RemoteType& aRemoteType, BrowsingContextGroup* aGroup = nullptr, hal::ProcessPriority aPriority = hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND, bool aPreferUsed = false, uint64_t aBrowserId = 0); @@ -238,7 +239,7 @@ class ContentParent final : public PContentParent, * until the process process is finished launching before returning. */ static UniqueContentParentKeepAlive GetNewOrUsedBrowserProcess( - const nsACString& aRemoteType, BrowsingContextGroup* aGroup = nullptr, + const RemoteType& aRemoteType, BrowsingContextGroup* aGroup = nullptr, hal::ProcessPriority aPriority = hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND, bool aPreferUsed = false, uint64_t aBrowserId = 0); @@ -276,7 +277,7 @@ class ContentParent final : public PContentParent, */ static already_AddRefed CreateBrowser( const TabContext& aContext, Element* aFrameElement, - const nsACString& aRemoteType, BrowsingContext* aBrowsingContext, + const RemoteType& aRemoteType, BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent); /** @@ -302,11 +303,11 @@ class ContentParent final : public PContentParent, static void BroadcastMediaCodecsSupportedUpdate( RemoteMediaIn aLocation, const media::MediaCodecsSupported& aSupported); - const nsACString& GetRemoteType() const override; + const RemoteType& GetRemoteType() const override; virtual void DoGetRemoteType(nsACString& aRemoteType, ErrorResult& aError) const override { - aRemoteType = GetRemoteType(); + aRemoteType = GetRemoteType().Stringify(); } enum CPIteratorPolicy { eLive, eAll }; @@ -752,8 +753,8 @@ class ContentParent final : public PContentParent, * removed from this list, but will still be in the sContentParents list for * the GetAll/GetAllEvenIfDead APIs. */ - static nsClassHashtable>* - sBrowserContentParents; + static nsClassHashtable, + nsTArray>* sBrowserContentParents; static mozilla::StaticAutoPtr> sContentParents; void AddShutdownBlockers(); @@ -779,7 +780,7 @@ class ContentParent final : public PContentParent, const OriginAttributes& aOriginAttributes, bool aUserActivation, bool aTextDirectiveUserActivation); - explicit ContentParent(const nsACString& aRemoteType); + explicit ContentParent(const RemoteType& aRemoteType); // Common implementation of LaunchSubprocess{Sync,Async}. // Return `true` in case of success, `false` if launch was @@ -871,7 +872,7 @@ class ContentParent final : public PContentParent, * |aContentProcessType|. */ static nsTArray& GetOrCreatePool( - const nsACString& aContentProcessType); + const RemoteType& aContentProcessType); mozilla::ipc::IPCResult RecvInitBackground( Endpoint&& aEndpoint); @@ -1447,9 +1448,6 @@ class ContentParent final : public PContentParent, ErrorResult& aRv) override; mozilla::ipc::IProtocol* AsNativeActor() override { return this; } - static already_AddRefed CreateRemoteTypeIsolationPrincipal( - const nsACString& aRemoteType); - #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED bool IsBlockingShutdown() { return mBlockShutdownCalled; } #endif @@ -1467,7 +1465,7 @@ class ContentParent final : public PContentParent, private: // Return an existing ContentParent if possible. Otherwise, `nullptr`. static UniqueContentParentKeepAlive GetUsedBrowserProcess( - const nsACString& aRemoteType, nsTArray& aContentParents, + const RemoteType& aRemoteType, nsTArray& aContentParents, uint32_t aMaxContentParents, bool aPreferUsed, ProcessPriority aPriority, uint64_t aBrowserId); @@ -1498,9 +1496,8 @@ class ContentParent final : public PContentParent, bool mIsAPreallocBlocker; // We called AddBlocker for this ContentParent - nsCString mRemoteType; + RemoteType mRemoteType; nsCString mProfile; - nsCOMPtr mRemoteTypeIsolationPrincipal; ContentParentId mChildID; int32_t mGeolocationWatchID; @@ -1679,9 +1676,9 @@ class ThreadsafeContentParentHandle final { ContentParentId ChildID() const { return mChildID; } // Get the current RemoteType of this ContentParent. Safe to call from any - // thread. If the returned RemoteType is PREALLOC_REMOTE_TYPE, it may change - // again in the future. - nsCString GetRemoteType() MOZ_EXCLUDES(mMutex); + // thread. If the returned RemoteType is Prealloc, it may change again in the + // future. + RemoteType GetRemoteType() MOZ_EXCLUDES(mMutex); // Try to get a reference to the real `ContentParent` object from this weak // reference. This may only be called on the main thread. @@ -1710,7 +1707,7 @@ class ThreadsafeContentParentHandle final { private: ThreadsafeContentParentHandle(ContentParent* aActor, ContentParentId aChildID, - const nsACString& aRemoteType) + const RemoteType& aRemoteType) : mChildID(aChildID), mLoadedOrigins(MakeRefPtr(aRemoteType)), mWeakActor(aActor) {} @@ -1739,16 +1736,6 @@ class ThreadsafeContentParentHandle final { ContentParent* mWeakActor MOZ_GUARDED_BY(sMainThreadCapability); }; -// This is the C++ version of remoteTypePrefix in E10SUtils.sys.mjs. -nsDependentCSubstring RemoteTypePrefix(const nsACString& aContentProcessType); - -// This is based on isWebRemoteType in E10SUtils.sys.mjs. -bool IsWebRemoteType(const nsACString& aContentProcessType); - -bool IsWebCoopCoepRemoteType(const nsACString& aContentProcessType); - -bool IsExtensionRemoteType(const nsACString& aContentProcessType); - inline nsISupports* ToSupports(mozilla::dom::ContentParent* aContentParent) { return static_cast(aContentParent); } diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh index 08618e2dfb4e..fd6337909915 100644 --- a/dom/ipc/DOMTypes.ipdlh +++ b/dom/ipc/DOMTypes.ipdlh @@ -62,6 +62,7 @@ using mozilla::dom::ForceMediaDocument from "mozilla/dom/LoadURIOptionsBinding.h using mozilla::dom::NavigationHistoryBehavior from "mozilla/dom/NavigationBinding.h"; [RefCounted] using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h"; [RefCounted] using class nsStructuredCloneContainer from "nsStructuredCloneContainer.h"; +using struct mozilla::dom::RemoteType from "mozilla/dom/RemoteType.h"; namespace mozilla { namespace dom { @@ -156,13 +157,13 @@ struct DocShellLoadStateInit // The provided remote type of the process responsible for causing the load to // occur. Validated in the parent process. - nsCString TriggeringRemoteType; + RemoteType TriggeringRemoteType; nsString SrcdocData; // useless without sourcedocshell nsCString? OriginalURIString; - nsCString? RemoteTypeOverride; + RemoteType? RemoteTypeOverride; LoadingSessionHistoryInfo? loadingSessionHistoryInfo; diff --git a/dom/ipc/InProcessChild.h b/dom/ipc/InProcessChild.h index 1bb476a16aeb..393f935d22d4 100644 --- a/dom/ipc/InProcessChild.h +++ b/dom/ipc/InProcessChild.h @@ -43,7 +43,9 @@ class InProcessChild final : public nsIDOMProcessChild, // |nullptr|. static IProtocol* ParentActorFor(IProtocol* aActor); - const nsACString& GetRemoteType() const override { return NOT_REMOTE_TYPE; } + const RemoteType& GetRemoteType() const override { + return RemoteType::NotRemote(); + } protected: already_AddRefed InitJSActor(JS::Handle aMaybeActor, diff --git a/dom/ipc/InProcessImpl.cpp b/dom/ipc/InProcessImpl.cpp index 1517ea0dbb40..c0909b31d493 100644 --- a/dom/ipc/InProcessImpl.cpp +++ b/dom/ipc/InProcessImpl.cpp @@ -136,7 +136,7 @@ InProcessParent::GetOsPid(int32_t* aOsPid) { } NS_IMETHODIMP InProcessParent::GetRemoteType(nsACString& aRemoteType) { - aRemoteType = NOT_REMOTE_TYPE; + aRemoteType = dom::RemoteType::NotRemote().Stringify(); return NS_OK; } diff --git a/dom/ipc/InProcessParent.h b/dom/ipc/InProcessParent.h index 044f53ee9335..3992cb00140e 100644 --- a/dom/ipc/InProcessParent.h +++ b/dom/ipc/InProcessParent.h @@ -45,7 +45,9 @@ class InProcessParent final : public nsIDOMProcessParent, // |nullptr|. static IProtocol* ChildActorFor(IProtocol* aActor); - const nsACString& GetRemoteType() const override { return NOT_REMOTE_TYPE; }; + const RemoteType& GetRemoteType() const override { + return RemoteType::NotRemote(); + }; protected: already_AddRefed InitJSActor(JS::Handle aMaybeActor, diff --git a/dom/ipc/LoadedOriginSet.cpp b/dom/ipc/LoadedOriginSet.cpp index 3508cdf47cbe..077a487b44db 100644 --- a/dom/ipc/LoadedOriginSet.cpp +++ b/dom/ipc/LoadedOriginSet.cpp @@ -9,17 +9,17 @@ namespace mozilla::dom { -LoadedOriginSet::LoadedOriginSet(const nsACString& aRemoteType) +LoadedOriginSet::LoadedOriginSet(const RemoteType& aRemoteType) : mRemoteType(aRemoteType) {} -nsCString LoadedOriginSet::GetRemoteType() { +RemoteType LoadedOriginSet::GetRemoteType() { MutexAutoLock lock(mMutex); return mRemoteType; } -void LoadedOriginSet::SetRemoteType(const nsACString& aRemoteType) { +void LoadedOriginSet::SetRemoteType(const RemoteType& aRemoteType) { MutexAutoLock lock(mMutex); - MOZ_ASSERT(mRemoteType == PREALLOC_REMOTE_TYPE); + MOZ_ASSERT(mRemoteType.IsPrealloc()); mRemoteType = aRemoteType; } @@ -90,7 +90,7 @@ LoadedOriginSet::Level LoadedOriginSet::AddInternal(nsIPrincipal* aPrincipal, bool LoadedOriginSet::ValidatePrincipal( nsIPrincipal* aPrincipal, const EnumSet& aOptions) { - nsCString remoteType = GetRemoteType(); + RemoteType remoteType = GetRemoteType(); auto isPrincipalLoaded = [&](nsIPrincipal* prin) { // FIXME: Currently we only match site, and ignore OAs. This is consistent // with ValidatePrincipal behaviour prior to bug 2055554. In the future, we diff --git a/dom/ipc/LoadedOriginSet.h b/dom/ipc/LoadedOriginSet.h index ee2763d80d08..526bc02ed900 100644 --- a/dom/ipc/LoadedOriginSet.h +++ b/dom/ipc/LoadedOriginSet.h @@ -32,7 +32,7 @@ class LoadedOriginSet { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LoadedOriginSet) - explicit LoadedOriginSet(const nsACString& aRemoteType); + explicit LoadedOriginSet(const RemoteType& aRemoteType); enum class Level : uint8_t { Unloaded, @@ -47,10 +47,10 @@ class LoadedOriginSet { Full, }; - nsCString GetRemoteType(); + RemoteType GetRemoteType(); // Should only be called by ContentParent or ContentChild. - void SetRemoteType(const nsACString& aRemoteType); + void SetRemoteType(const RemoteType& aRemoteType); // Check if this LoadedOriginSet has the given principal. bool Has(nsIPrincipal* aPrincipal, Level aThreshold, @@ -89,7 +89,7 @@ class LoadedOriginSet { }; Mutex mMutex{"LoadedOriginSet"}; - nsCString mRemoteType MOZ_GUARDED_BY(mMutex); + RemoteType mRemoteType MOZ_GUARDED_BY(mMutex); nsTArray mLoadedOrigins MOZ_GUARDED_BY(mMutex); }; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index fa2c4d1e15bf..7f4644bc8fa2 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -186,6 +186,7 @@ using mozilla::dom::UserActivation::Modifiers from "mozilla/dom/UserActivation.h using nsIClipboard::ClipboardType from "nsIClipboard.h"; using nsIUrlClassifierFeature::listType from "nsIUrlClassifierFeature.h"; using mozilla::dom::ReferrerPolicy from "mozilla/dom/ReferrerPolicyBinding.h"; +using struct mozilla::dom::RemoteType from "mozilla/dom/RemoteType.h"; #ifdef MOZ_WMF_CDM using nsIOriginStatusEntry from "nsIWindowsMediaFoundationCDMOriginsListService.h"; @@ -830,7 +831,7 @@ child: /** * Send the remote type associated with the content process. */ - async RemoteType(nsCString aRemoteType, nsCString aProfile); + async SetRemoteType(RemoteType aRemoteType, nsCString aProfile); /** * Record an origin which is being loaded in this content process. diff --git a/dom/ipc/PreallocatedProcessManager.cpp b/dom/ipc/PreallocatedProcessManager.cpp index e896a1d80f01..e2351d788531 100644 --- a/dom/ipc/PreallocatedProcessManager.cpp +++ b/dom/ipc/PreallocatedProcessManager.cpp @@ -38,7 +38,7 @@ class PreallocatedProcessManagerImpl final : public nsIObserver { // See comments on PreallocatedProcessManager for these methods. void AddBlocker(ContentParent* aParent); void RemoveBlocker(ContentParent* aParent); - UniqueContentParentKeepAlive Take(const nsACString& aRemoteType); + UniqueContentParentKeepAlive Take(const RemoteType& aRemoteType); void Erase(ContentParent* aParent); PreallocatedProcessManagerImpl(const PreallocatedProcessManagerImpl&) = @@ -189,7 +189,7 @@ void PreallocatedProcessManagerImpl::RereadPrefs() { } UniqueContentParentKeepAlive PreallocatedProcessManagerImpl::Take( - const nsACString& aRemoteType) { + const RemoteType& aRemoteType) { if (!IsEnabled()) { return nullptr; } @@ -269,8 +269,8 @@ void PreallocatedProcessManagerImpl::RemoveBlocker(ContentParent* aParent) { bool PreallocatedProcessManagerImpl::CanAllocate() { return IsEnabled() && sNumBlockers == 0 && mPreallocatedProcesses.Length() < mNumberPreallocs && !IsShutdown() && - (FissionAutostart() || - !ContentParent::IsMaxProcessCountReached(DEFAULT_REMOTE_TYPE)); + (FissionAutostart() || !ContentParent::IsMaxProcessCountReached( + RemoteType(RemoteType::Kind::WebContent))); } void PreallocatedProcessManagerImpl::AllocateAfterDelay() { @@ -383,24 +383,23 @@ bool PreallocatedProcessManager::Enabled() { } /* static */ -void PreallocatedProcessManager::AddBlocker(const nsACString& aRemoteType, +void PreallocatedProcessManager::AddBlocker(const RemoteType& aRemoteType, ContentParent* aParent) { MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, - ("AddBlocker: %s %p (sNumBlockers=%d)", - PromiseFlatCString(aRemoteType).get(), aParent, - PreallocatedProcessManagerImpl::sNumBlockers)); + ("AddBlocker: %s %p (sNumBlockers=%d)", aRemoteType.Stringify().get(), + aParent, PreallocatedProcessManagerImpl::sNumBlockers)); if (auto impl = GetPPMImpl()) { impl->AddBlocker(aParent); } } /* static */ -void PreallocatedProcessManager::RemoveBlocker(const nsACString& aRemoteType, +void PreallocatedProcessManager::RemoveBlocker(const RemoteType& aRemoteType, ContentParent* aParent) { - MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug, - ("RemoveBlocker: %s %p (sNumBlockers=%d)", - PromiseFlatCString(aRemoteType).get(), aParent, - PreallocatedProcessManagerImpl::sNumBlockers)); + MOZ_LOG( + ContentParent::GetLog(), LogLevel::Debug, + ("RemoveBlocker: %s %p (sNumBlockers=%d)", aRemoteType.Stringify().get(), + aParent, PreallocatedProcessManagerImpl::sNumBlockers)); if (auto impl = GetPPMImpl()) { impl->RemoveBlocker(aParent); } @@ -408,7 +407,7 @@ void PreallocatedProcessManager::RemoveBlocker(const nsACString& aRemoteType, /* static */ UniqueContentParentKeepAlive PreallocatedProcessManager::Take( - const nsACString& aRemoteType) { + const RemoteType& aRemoteType) { if (auto impl = GetPPMImpl()) { return impl->Take(aRemoteType); } diff --git a/dom/ipc/PreallocatedProcessManager.h b/dom/ipc/PreallocatedProcessManager.h index 438aab5946a3..ffd7fe242ac6 100644 --- a/dom/ipc/PreallocatedProcessManager.h +++ b/dom/ipc/PreallocatedProcessManager.h @@ -6,6 +6,7 @@ #define mozilla_PreallocatedProcessManager_h #include "base/basictypes.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/dom/UniqueContentParentKeepAlive.h" #include "nsStringFwd.h" @@ -28,6 +29,7 @@ class PreallocatedProcessManagerImpl; class PreallocatedProcessManager final { using ContentParent = mozilla::dom::ContentParent; + using RemoteType = mozilla::dom::RemoteType; using UniqueContentParentKeepAlive = mozilla::dom::UniqueContentParentKeepAlive; @@ -41,8 +43,8 @@ class PreallocatedProcessManager final { * background. To avoid that, the PreallocatedProcessManager won't start up * any processes while there is a blocker active. */ - static void AddBlocker(const nsACString& aRemoteType, ContentParent* aParent); - static void RemoveBlocker(const nsACString& aRemoteType, + static void AddBlocker(const RemoteType& aRemoteType, ContentParent* aParent); + static void RemoveBlocker(const RemoteType& aRemoteType, ContentParent* aParent); /** @@ -52,7 +54,7 @@ class PreallocatedProcessManager final { * If we use a preallocated process, it will schedule the start of * another on Idle (AllocateOnIdle()). */ - static UniqueContentParentKeepAlive Take(const nsACString& aRemoteType); + static UniqueContentParentKeepAlive Take(const RemoteType& aRemoteType); /** * Note that a process was shut down, and should no longer be tracked as a diff --git a/dom/ipc/ProcessIsolation.cpp b/dom/ipc/ProcessIsolation.cpp index 465e57ae4bb7..02e397c75ddf 100644 --- a/dom/ipc/ProcessIsolation.cpp +++ b/dom/ipc/ProcessIsolation.cpp @@ -121,7 +121,7 @@ struct CommaSeparatedPref { CommaSeparatedPref sSeparatedMozillaDomains{ "browser.tabs.remote.separatedMozillaDomains"_ns}; -bool AllowJITForSiteOrigin(const nsACString& aSiteOriginNoSuffix, +bool AllowJITForSiteOrigin(nsIURI* aSiteOriginURI, WindowGlobalParent* aParentWindow) { nsresult rv; @@ -131,32 +131,30 @@ bool AllowJITForSiteOrigin(const nsACString& aSiteOriginNoSuffix, return true; } - nsAutoCString topSiteOriginNoSuffix(aSiteOriginNoSuffix); + nsCOMPtr topSiteOriginURI = aSiteOriginURI; // If this is a subframe then use the principal of the top window. if (aParentWindow) { + nsAutoCString topSiteOriginNoSuffix; rv = aParentWindow->TopWindowContext() ->DocumentPrincipal() ->GetSiteOriginNoSuffix(topSiteOriginNoSuffix); - if (NS_FAILED(rv)) { - topSiteOriginNoSuffix = aSiteOriginNoSuffix; - } + NS_ENSURE_SUCCESS(rv, true); + + rv = NS_NewURI(getter_AddRefs(topSiteOriginURI), topSiteOriginNoSuffix); + NS_ENSURE_SUCCESS(rv, true); } - nsCOMPtr topSite; - rv = NS_NewURI(getter_AddRefs(topSite), topSiteOriginNoSuffix); - NS_ENSURE_SUCCESS(rv, true); - bool isJitAllowed = true; - if (NS_FAILED( - policyService->IsAllowedForURI("jit"_ns, topSite, &isJitAllowed))) { + if (NS_FAILED(policyService->IsAllowedForURI("jit"_ns, topSiteOriginURI, + &isJitAllowed))) { return true; } if (!isJitAllowed) { MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("JIT is disabled for site %s by enterprise policy", - topSiteOriginNoSuffix.get())); + topSiteOriginURI->GetSpecOrDefault().get())); } return isJitAllowed; @@ -426,24 +424,11 @@ static nsAutoCString OriginString(nsIPrincipal* aPrincipal) { } /** - * Trim the OriginAttributes, and use it to create a OriginSuffix string - * appropriate to use within a remoteType string. + * Helper method for logging origin attributes as a string. */ -static nsAutoCString OriginSuffixForRemoteType(OriginAttributes aAttrs, - bool aDisableJit) { +static nsAutoCString OriginAttributesString(const OriginAttributes& aAttrs) { nsAutoCString originSuffix; - aAttrs.StripAttributes(OriginAttributes::STRIP_FIRST_PARTY_DOMAIN | - OriginAttributes::STRIP_PARTITION_KEY); aAttrs.CreateSuffix(originSuffix); - - if (aDisableJit) { - if (originSuffix.IsEmpty()) { - originSuffix = "^"_ns + DISABLE_JIT_REMOTE_TYPE_SUFFIX; - } else { - originSuffix += "&"_ns + DISABLE_JIT_REMOTE_TYPE_SUFFIX; - } - } - return originSuffix; } @@ -574,35 +559,35 @@ static bool ShouldIsolateSite(nsIPrincipal* aPrincipal, } } -static Result SpecialBehaviorRemoteType( - IsolationBehavior aBehavior, const nsACString& aCurrentRemoteType, +static Result SpecialBehaviorRemoteType( + IsolationBehavior aBehavior, const RemoteType& aCurrentRemoteType, WindowGlobalParent* aParentWindow, const OriginAttributes& aAttrs) { switch (aBehavior) { case IsolationBehavior::ForceWebRemoteType: - return {SharedWebRemoteType(aAttrs)}; + return {RemoteType::SharedWeb(aAttrs)}; case IsolationBehavior::PrivilegedAbout: // The privileged about: content process cannot be disabled, as it // causes various actors to break. - return {PRIVILEGEDABOUT_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::PrivilegedAbout)}; case IsolationBehavior::Extension: if (ExtensionPolicyService::GetSingleton().UseRemoteExtensions()) { - return {EXTENSION_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::Extension)}; } - return {NOT_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::NotRemote)}; case IsolationBehavior::File: if (StaticPrefs::browser_tabs_remote_separateFileUriProcess()) { - return {FILE_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::File)}; } - return {SharedWebRemoteType(aAttrs)}; + return {RemoteType::SharedWeb(aAttrs)}; case IsolationBehavior::PrivilegedMozilla: - return {PRIVILEGEDMOZILLA_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::PrivilegedMozilla)}; case IsolationBehavior::Parent: - return {NOT_REMOTE_TYPE}; + return {RemoteType(RemoteType::Kind::NotRemote)}; case IsolationBehavior::Anywhere: - return {nsCString(aCurrentRemoteType)}; + return {aCurrentRemoteType}; case IsolationBehavior::Inherit: MOZ_DIAGNOSTIC_ASSERT(aParentWindow); - return {nsCString(aParentWindow->GetRemoteType())}; + return {aParentWindow->GetRemoteType()}; case IsolationBehavior::Error: return Err(NS_ERROR_UNEXPECTED); @@ -613,30 +598,15 @@ static Result SpecialBehaviorRemoteType( } } -enum class WebProcessType { - Web, - WebIsolated, - WebCoopCoep, -}; - } // namespace -nsCString SharedWebRemoteType(const OriginAttributes& aAttrs, - bool aDisableJit) { - nsAutoCString suffix = OriginSuffixForRemoteType(aAttrs, aDisableJit); - if (suffix.IsEmpty()) { - return WEB_REMOTE_TYPE; - } - return WEB_REMOTE_TYPE "="_ns + suffix; -} - Result IsolationOptionsForNavigation( CanonicalBrowsingContext* aTopBC, WindowGlobalParent* aParentWindow, nsIURI* aChannelCreationURI, nsIChannel* aChannel, - const nsACString& aCurrentRemoteType, bool aHasCOOPMismatch, + const RemoteType& aCurrentRemoteType, bool aHasCOOPMismatch, bool aForNewTab, uint32_t aLoadStateLoadType, const Maybe& aChannelId, - const Maybe& aRemoteTypeOverride) { + const Maybe& aRemoteTypeOverride) { // Get the final principal, used to select which process to load into. nsCOMPtr resultPrincipal; nsresult rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal( @@ -688,7 +658,7 @@ Result IsolationOptionsForNavigation( MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, ("using remote type override (%s) for load", - aRemoteTypeOverride->get())); + aRemoteTypeOverride->Stringify().get())); options.mRemoteType = *aRemoteTypeOverride; return options; } @@ -781,7 +751,7 @@ Result IsolationOptionsForNavigation( // and it's safe for it to end in the parent process, we should finish the // load there. bool isUIResource = false; - if (aCurrentRemoteType.IsEmpty() && + if (aCurrentRemoteType.IsNotRemote() && (aChannelCreationURI->SchemeIs("about") || (NS_SUCCEEDED(NS_URIChainHasFlags( aChannelCreationURI, nsIProtocolHandler::URI_IS_UI_RESOURCE, @@ -806,7 +776,7 @@ Result IsolationOptionsForNavigation( // to some other remote type, make sure we leave the extension's BCG which we // may have entered earlier to separate extension and non-extension BCGs from // each-other. - if (!aParentWindow && aCurrentRemoteType == EXTENSION_REMOTE_TYPE && + if (!aParentWindow && aCurrentRemoteType.IsExtension() && behavior != IsolationBehavior::Extension && behavior != IsolationBehavior::Anywhere) { MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, @@ -848,7 +818,7 @@ Result IsolationOptionsForNavigation( behavior != IsolationBehavior::Parent && (ExtensionPolicyService::GetSingleton().UseRemoteExtensions() || behavior != IsolationBehavior::Extension) && - !aCurrentRemoteType.IsEmpty() && + !aCurrentRemoteType.IsNotRemote() && aTopBC->GetHasLoadedNonInitialDocument() && (aLoadStateLoadType == LOAD_NORMAL || aLoadStateLoadType == LOAD_HISTORY || aLoadStateLoadType == LOAD_LINK || @@ -875,7 +845,8 @@ Result IsolationOptionsForNavigation( behavior, aCurrentRemoteType, aParentWindow, originAttributes)); if (options.mRemoteType != aCurrentRemoteType && - (options.mRemoteType.IsEmpty() || aCurrentRemoteType.IsEmpty())) { + (options.mRemoteType.IsNotRemote() || + aCurrentRemoteType.IsNotRemote())) { options.mReplaceBrowsingContext = true; } @@ -883,14 +854,15 @@ Result IsolationOptionsForNavigation( gProcessIsolationLog, LogLevel::Debug, ("Selecting specific remote type (%s) due to a special case isolation " "behavior %s", - options.mRemoteType.get(), IsolationBehaviorName(behavior))); + options.mRemoteType.Stringify().get(), + IsolationBehaviorName(behavior))); return options; } // At this point we're definitely not going to be loading in the parent // process anymore, so we're definitely going to be replacing BrowsingContext // if we're in the parent process. - if (aCurrentRemoteType.IsEmpty()) { + if (aCurrentRemoteType.IsNotRemote()) { MOZ_ASSERT(!aParentWindow); options.mReplaceBrowsingContext = true; } @@ -909,6 +881,9 @@ Result IsolationOptionsForNavigation( nsAutoCString siteOriginNoSuffix; MOZ_TRY(resultOrPrecursor->GetSiteOriginNoSuffix(siteOriginNoSuffix)); + nsCOMPtr siteOriginURI; + MOZ_TRY(NS_NewURI(getter_AddRefs(siteOriginURI), siteOriginNoSuffix)); + // Check if we've already loaded a document with the given principal in some // content process. We want to finish the load in the same process in that // case. @@ -957,12 +932,12 @@ Result IsolationOptionsForNavigation( // Check if this WindowGlobalParent has the given resultPrincipal, and // if it does, we need to load in that process. - if (!wgp->GetRemoteType().IsEmpty() && + if (!wgp->GetRemoteType().IsNotRemote() && principalIsSameSite(wgp->DocumentPrincipal())) { MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("Found existing frame with matching principal " "(remoteType:(%s), origin:%s)", - PromiseFlatCString(wgp->GetRemoteType()).get(), + wgp->GetRemoteType().Stringify().get(), OriginString(wgp->DocumentPrincipal()).get())); options.mRemoteType = wgp->GetRemoteType(); return options; @@ -974,40 +949,26 @@ Result IsolationOptionsForNavigation( } } - bool isJitAllowed = AllowJITForSiteOrigin(siteOriginNoSuffix, aParentWindow); - nsAutoCString originSuffix = OriginSuffixForRemoteType( - resultOrPrecursor->OriginAttributesRef(), !isJitAllowed); + options.mRemoteType = RemoteType::SharedWeb(originAttributes); - WebProcessType webProcessType = WebProcessType::Web; - if (ShouldIsolateSite(resultOrPrecursor, aTopBC->UseRemoteSubframes())) { - webProcessType = WebProcessType::WebIsolated; + if (!AllowJITForSiteOrigin(siteOriginURI, aParentWindow)) { + options.mRemoteType = options.mRemoteType.WithDisableJit(true); } - // Check if we should be cross-origin isolated. - if (options.mShouldCrossOriginIsolate) { - webProcessType = WebProcessType::WebCoopCoep; + if (options.mShouldCrossOriginIsolate || + ShouldIsolateSite(resultOrPrecursor, aTopBC->UseRemoteSubframes())) { + options.mRemoteType = options.mRemoteType.WithSiteOrigin( + siteOriginNoSuffix, options.mShouldCrossOriginIsolate + ? RemoteType::Kind::WebCoopCoep + : RemoteType::Kind::WebContent); } - switch (webProcessType) { - case WebProcessType::Web: - options.mRemoteType = - SharedWebRemoteType(originAttributes, !isJitAllowed); - break; - case WebProcessType::WebIsolated: - options.mRemoteType = - FISSION_WEB_REMOTE_TYPE "="_ns + siteOriginNoSuffix + originSuffix; - break; - case WebProcessType::WebCoopCoep: - options.mRemoteType = - WITH_COOP_COEP_REMOTE_TYPE "="_ns + siteOriginNoSuffix + originSuffix; - break; - } return options; } static bool ValidateBehaviorForWorker(IsolationBehavior aBehavior, - const nsACString& aCurrentRemoteType) { - if (aCurrentRemoteType == NOT_REMOTE_TYPE) { + const RemoteType& aCurrentRemoteType) { + if (aCurrentRemoteType.IsNotRemote()) { return true; } @@ -1031,14 +992,14 @@ static bool ValidateBehaviorForWorker(IsolationBehavior aBehavior, return true; case IsolationBehavior::PrivilegedAbout: - return aCurrentRemoteType == PRIVILEGEDABOUT_REMOTE_TYPE; + return aCurrentRemoteType.IsPrivilegedAbout(); case IsolationBehavior::File: return !StaticPrefs::browser_tabs_remote_separateFileUriProcess() || - aCurrentRemoteType == FILE_REMOTE_TYPE; + aCurrentRemoteType.IsFile(); case IsolationBehavior::PrivilegedMozilla: - return aCurrentRemoteType == PRIVILEGEDMOZILLA_REMOTE_TYPE; + return aCurrentRemoteType.IsPrivilegedMozilla(); case IsolationBehavior::Error: break; @@ -1049,11 +1010,11 @@ static bool ValidateBehaviorForWorker(IsolationBehavior aBehavior, Result IsolationOptionsForWorker( nsIPrincipal* aPrincipal, WorkerKind aWorkerKind, - const nsACString& aCurrentRemoteType, bool aUseRemoteSubframes) { + const RemoteType& aCurrentRemoteType, bool aUseRemoteSubframes) { MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, ("IsolationOptionsForWorker principal:%s, kind:%s, current:%s", OriginString(aPrincipal).get(), WorkerKindName(aWorkerKind), - PromiseFlatCString(aCurrentRemoteType).get())); + aCurrentRemoteType.Stringify().get())); MOZ_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT( @@ -1083,11 +1044,10 @@ Result IsolationOptionsForWorker( // processes. Currently process selection for workers occurs before response // headers are available, so we will never select to load a shared worker in a // COOP+COEP content process. - nsCString preferredRemoteType = - SharedWebRemoteType(aPrincipal->OriginAttributesRef()); + RemoteType preferredRemoteType = + RemoteType::SharedWeb(aPrincipal->OriginAttributesRef()); if (aWorkerKind == WorkerKind::WorkerKindShared && - !StringBeginsWith(aCurrentRemoteType, - WITH_COOP_COEP_REMOTE_TYPE_PREFIX)) { + !aCurrentRemoteType.IsWebCoopCoep()) { preferredRemoteType = aCurrentRemoteType; } @@ -1118,7 +1078,7 @@ Result IsolationOptionsForWorker( // Only allow system principal shared workers to load within the parent // process, and only if that process is responsible for the load. - if (preferredRemoteType == NOT_REMOTE_TYPE) { + if (preferredRemoteType.IsNotRemote()) { MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("Loading system principal shared worker in parent process")); behavior = IsolationBehavior::Parent; @@ -1132,7 +1092,7 @@ Result IsolationOptionsForWorker( MOZ_ASSERT(resultOrPrecursor->GetIsNullPrincipal()); MOZ_ASSERT(aWorkerKind == WorkerKindShared); - if (preferredRemoteType == NOT_REMOTE_TYPE) { + if (preferredRemoteType.IsNotRemote()) { MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("Ensuring precursorless null principal shared worker loads in a " "content process")); @@ -1141,7 +1101,7 @@ Result IsolationOptionsForWorker( MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("Loading precursorless null principal shared worker within " "current remotetype: (%s)", - preferredRemoteType.get())); + preferredRemoteType.Stringify().get())); behavior = IsolationBehavior::Anywhere; } } @@ -1158,7 +1118,7 @@ Result IsolationOptionsForWorker( gProcessIsolationLog, LogLevel::Warning, ("Rejecting invalid worker isolation behavior %s for remote type %s", IsolationBehaviorName(behavior), - PromiseFlatCString(aCurrentRemoteType).get())); + aCurrentRemoteType.Stringify().get())); return Err(NS_ERROR_FAILURE); } @@ -1171,7 +1131,7 @@ Result IsolationOptionsForWorker( gProcessIsolationLog, LogLevel::Debug, ("Selecting specific %s worker remote type (%s) due to a special case " "isolation behavior %s", - WorkerKindName(aWorkerKind), options.mRemoteType.get(), + WorkerKindName(aWorkerKind), options.mRemoteType.Stringify().get(), IsolationBehaviorName(behavior))); return options; } @@ -1179,30 +1139,29 @@ Result IsolationOptionsForWorker( nsAutoCString siteOriginNoSuffix; MOZ_TRY(resultOrPrecursor->GetSiteOriginNoSuffix(siteOriginNoSuffix)); - bool isJitAllowed = AllowJITForSiteOrigin(siteOriginNoSuffix, nullptr); + nsCOMPtr siteOriginURI; + MOZ_TRY(NS_NewURI(getter_AddRefs(siteOriginURI), siteOriginNoSuffix)); + + options.mRemoteType = + RemoteType::SharedWeb(resultOrPrecursor->OriginAttributesRef()); + + if (!AllowJITForSiteOrigin(siteOriginURI, nullptr)) { + options.mRemoteType = options.mRemoteType.WithDisableJit(true); + } // If we should be isolating this site, we can determine the correct fission // remote type from the principal's site-origin. if (ShouldIsolateSite(resultOrPrecursor, aUseRemoteSubframes)) { - nsAutoCString originSuffix = OriginSuffixForRemoteType( - resultOrPrecursor->OriginAttributesRef(), !isJitAllowed); - - nsCString prefix = aWorkerKind == WorkerKindService - ? SERVICEWORKER_REMOTE_TYPE - : FISSION_WEB_REMOTE_TYPE; - options.mRemoteType = prefix + "="_ns + siteOriginNoSuffix + originSuffix; - - MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, - ("Isolating web content %s worker in remote type (%s)", - WorkerKindName(aWorkerKind), options.mRemoteType.get())); - } else { - options.mRemoteType = SharedWebRemoteType( - resultOrPrecursor->OriginAttributesRef(), !isJitAllowed); - - MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, - ("Loading web content %s worker in shared web remote type", - WorkerKindName(aWorkerKind))); + options.mRemoteType = options.mRemoteType.WithSiteOrigin( + siteOriginNoSuffix, aWorkerKind == WorkerKindService + ? RemoteType::Kind::WebServiceWorker + : RemoteType::Kind::WebContent); } + + MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, + ("Loading web content %s worker in remote type (%s)", + WorkerKindName(aWorkerKind), options.mRemoteType.Stringify().get())); + return options; } @@ -1297,16 +1256,15 @@ static already_AddRefed MaybeResolveWebAppHandler(nsIURI* aURI) { return newURI.forget(); } -Result PredictRemoteTypeForURI( +Result PredictRemoteTypeForURI( nsIURI* aURI, const OriginAttributes& aOriginAttributes, - const nsACString& aPreferredRemoteType, bool aUseRemoteSubframes) { - MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, - ("PredictRemoteTypeForURI uri:%s, preferred:%s, oa:%s, " - "useRemoteSubframes:%d", - aURI->GetSpecOrDefault().get(), - PromiseFlatCString(aPreferredRemoteType).get(), - OriginSuffixForRemoteType(aOriginAttributes, false).get(), - aUseRemoteSubframes)); + const RemoteType& aPreferredRemoteType, bool aUseRemoteSubframes) { + MOZ_LOG( + gProcessIsolationLog, LogLevel::Verbose, + ("PredictRemoteTypeForURI uri:%s, preferred:%s, oa:%s, " + "useRemoteSubframes:%d", + aURI->GetSpecOrDefault().get(), aPreferredRemoteType.Stringify().get(), + OriginAttributesString(aOriginAttributes).get(), aUseRemoteSubframes)); IsolationBehavior behavior = IsolationBehaviorForURI( aURI, /* aIsSubframe */ false, /* aForChannelCreationURI */ true, @@ -1372,13 +1330,13 @@ Result PredictRemoteTypeForURI( // If we have a special behaviour RemoteType, return it. if (behavior != IsolationBehavior::WebContent) { - nsCString remoteType = MOZ_TRY(SpecialBehaviorRemoteType( + RemoteType remoteType = MOZ_TRY(SpecialBehaviorRemoteType( behavior, aPreferredRemoteType, nullptr, aOriginAttributes)); MOZ_LOG(gProcessIsolationLog, LogLevel::Debug, ("Predicting specific remote type (%s) due to a special case " "isolation behavior %s", - remoteType.get(), IsolationBehaviorName(behavior))); + remoteType.Stringify().get(), IsolationBehaviorName(behavior))); return remoteType; } @@ -1387,35 +1345,36 @@ Result PredictRemoteTypeForURI( nsAutoCString siteOriginNoSuffix; MOZ_TRY(principal->GetSiteOriginNoSuffix(siteOriginNoSuffix)); - bool isJitAllowed = AllowJITForSiteOrigin(siteOriginNoSuffix, nullptr); - nsAutoCString originSuffix = OriginSuffixForRemoteType( - principal->OriginAttributesRef(), !isJitAllowed); + nsCOMPtr siteOriginURI; + MOZ_TRY(NS_NewURI(getter_AddRefs(siteOriginURI), siteOriginNoSuffix)); + + RemoteType remoteType = RemoteType::SharedWeb(aOriginAttributes); + + if (!AllowJITForSiteOrigin(siteOriginURI, nullptr)) { + remoteType = remoteType.WithDisableJit(true); + } // The only situation we'll return a coop+coep remote type is if the preferred // remote type would perfectly match. Check if that is the case. - if (StringBeginsWith(aPreferredRemoteType, - WITH_COOP_COEP_REMOTE_TYPE_PREFIX)) { - nsCString coopCoepRemoteType = - WITH_COOP_COEP_REMOTE_TYPE "="_ns + siteOriginNoSuffix + originSuffix; + if (aPreferredRemoteType.IsWebCoopCoep()) { + RemoteType coopCoepRemoteType = remoteType.WithSiteOrigin( + siteOriginNoSuffix, RemoteType::Kind::WebCoopCoep); if (coopCoepRemoteType == aPreferredRemoteType) { MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, ("Predicting preferred COOP+COEP remote type (%s) due to " "compatible site-origin %s", - coopCoepRemoteType.get(), OriginString(principal).get())); + coopCoepRemoteType.Stringify().get(), + OriginString(principal).get())); return coopCoepRemoteType; } } - nsCString remoteType; if (ShouldIsolateSite(principal, aUseRemoteSubframes)) { - remoteType = - FISSION_WEB_REMOTE_TYPE "="_ns + siteOriginNoSuffix + originSuffix; - } else { - remoteType = SharedWebRemoteType(aOriginAttributes, !isJitAllowed); + remoteType = remoteType.WithSiteOrigin(siteOriginNoSuffix); } MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, - ("Predicting web remote type (%s)", remoteType.get())); + ("Predicting web remote type (%s)", remoteType.Stringify().get())); return remoteType; } @@ -1497,7 +1456,7 @@ bool IsIsolateHighValueSiteEnabled() { } bool ValidatePrincipalCouldPotentiallyBeLoadedBy( - nsIPrincipal* aPrincipal, const nsACString& aRemoteType, + nsIPrincipal* aPrincipal, const RemoteType& aRemoteType, const EnumSet& aOptions, FunctionRef aIsPrincipalLoaded) { #ifdef DEBUG @@ -1514,7 +1473,7 @@ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( #endif // Don't bother validating principals from the parent process. - if (aRemoteType == NOT_REMOTE_TYPE) { + if (aRemoteType.IsNotRemote()) { return true; } @@ -1610,7 +1569,7 @@ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( if (!StaticPrefs::browser_tabs_remote_separateFileUriProcess()) { return true; } - return aRemoteType == FILE_REMOTE_TYPE; + return aRemoteType.IsFile(); } if (originScheme == "about"_ns) { @@ -1642,11 +1601,11 @@ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( // unfortunately not part of the principal. return true; case IsolationBehavior::Extension: - return aRemoteType == EXTENSION_REMOTE_TYPE; + return aRemoteType.IsExtension(); case IsolationBehavior::PrivilegedAbout: - return aRemoteType == PRIVILEGEDABOUT_REMOTE_TYPE; + return aRemoteType.IsPrivilegedAbout(); case IsolationBehavior::ForceWebRemoteType: - return RemoteTypePrefix(aRemoteType) == WEB_REMOTE_TYPE; + return aRemoteType.IsSharedWeb(); case IsolationBehavior::WebContent: case IsolationBehavior::Error: // NOTE: We can encounter races around about: pages being unregistered. @@ -1658,22 +1617,9 @@ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( } } - // If the remote type doesn't have an origin suffix, we can do no further - // principal validation with it. - int32_t equalIdx = aRemoteType.FindChar('='); - if (equalIdx == kNotFound) { - return true; - } - - // Split out the remote type prefix and the origin suffix. - nsDependentCSubstring typePrefix(aRemoteType, 0, equalIdx); - nsDependentCSubstring typeOrigin(aRemoteType, equalIdx + 1); - - // Only validate webIsolated, webCOOP+COEP and webServiceWorker remote types - // for now. This should be expanded in the future. - if (typePrefix != FISSION_WEB_REMOTE_TYPE && - typePrefix != WITH_COOP_COEP_REMOTE_TYPE && - typePrefix != SERVICEWORKER_REMOTE_TYPE) { + // Only validate webIsolated and webServiceWorker remote types for now. This + // should be expanded in the future. + if (!aRemoteType.IsIsolatedWeb()) { return true; } @@ -1682,29 +1628,21 @@ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( // HACK: Unfortunately, we can't easily check useRemoteSubframes here, but we // shouldn't be loading any webCOOP+COEP windows without useRemoteSubframes if // Fission is enabled. - if (typePrefix == WITH_COOP_COEP_REMOTE_TYPE && - !mozilla::FissionAutostart()) { - return true; - } - - // Trim any OriginAttributes from the origin, as those will not be validated. - int32_t suffixIdx = typeOrigin.RFindChar('^'); - nsDependentCSubstring typeOriginNoSuffix(typeOrigin, 0, suffixIdx); - - // If the origin perfectly matches, we can skip computing the site origin. - if (typeOriginNoSuffix == originNoSuffix) { + if (aRemoteType.IsWebCoopCoep() && !mozilla::FissionAutostart()) { return true; } // NOTE: Currently every webIsolated remote type is site-origin keyed, meaning - // we can unconditionally compare site origins. If this changes in the future, - // this logic will need to be updated to reflect that. + // we can unconditionally compare site origin to the origin from the + // remoteType. If this changes in the future, this logic will need to be + // updated to reflect that. nsAutoCString siteOriginNoSuffix; if (NS_FAILED(aPrincipal->GetSiteOriginNoSuffix(siteOriginNoSuffix))) { MOZ_ASSERT_UNREACHABLE("Failed when not late in shutdown?"); return false; } - return siteOriginNoSuffix == typeOriginNoSuffix; + + return aRemoteType.OriginNoSuffix() == siteOriginNoSuffix; } } // namespace mozilla::dom diff --git a/dom/ipc/ProcessIsolation.h b/dom/ipc/ProcessIsolation.h index c35800918142..f6117615c6ac 100644 --- a/dom/ipc/ProcessIsolation.h +++ b/dom/ipc/ProcessIsolation.h @@ -28,17 +28,10 @@ constexpr nsLiteralCString kHighValueHasSavedLoginPermission = constexpr nsLiteralCString kHighValueIsLoggedInPermission = "highValueIsLoggedIn"_ns; -/** - * Given a specific set of BrowsingContext origin attributes, get a shared "web" - * process which should be used for loading shared content. - */ -nsCString SharedWebRemoteType(const OriginAttributes& aAttrs, - bool aDisableJit = false); - // NavigationIsolationOptions is passed through the methods to store the state // of the possible process and/or browsing context change. struct NavigationIsolationOptions { - nsCString mRemoteType; + RemoteType mRemoteType; bool mReplaceBrowsingContext = false; uint64_t mSpecificGroupId = 0; bool mShouldCrossOriginIsolate = false; @@ -61,15 +54,15 @@ struct NavigationIsolationOptions { Result IsolationOptionsForNavigation( CanonicalBrowsingContext* aTopBC, WindowGlobalParent* aParentWindow, nsIURI* aChannelCreationURI, nsIChannel* aChannel, - const nsACString& aCurrentRemoteType, bool aHasCOOPMismatch, + const RemoteType& aCurrentRemoteType, bool aHasCOOPMismatch, bool aForNewTab, uint32_t aLoadStateLoadType, const Maybe& aChannelId, - const Maybe& aRemoteTypeOverride); + const Maybe& aRemoteTypeOverride); // WorkerIsolationOptions is passed back to the RemoteWorkerManager to store the // destination process information for remote worker loads. struct WorkerIsolationOptions { - nsCString mRemoteType; + RemoteType mRemoteType; }; /** @@ -80,7 +73,7 @@ struct WorkerIsolationOptions { */ Result IsolationOptionsForWorker( nsIPrincipal* aPrincipal, WorkerKind aWorkerKind, - const nsACString& aCurrentRemoteType, bool aUseRemoteSubframes); + const RemoteType& aCurrentRemoteType, bool aUseRemoteSubframes); /** * Given a URI being loaded, and some relevant context, predict what remote type @@ -92,9 +85,9 @@ Result IsolationOptionsForWorker( * frontend JS, and should not be used as part of navigation. The remote types * selected by this method are not used to enforce security invariants. */ -Result PredictRemoteTypeForURI( +Result PredictRemoteTypeForURI( nsIURI* aURI, const OriginAttributes& aOriginAttributes, - const nsACString& aPreferredRemoteType, bool aUseRemoteSubframes); + const RemoteType& aPreferredRemoteType, bool aUseRemoteSubframes); /** * Adds a `highValue` permission to the permissions database, and make loads of @@ -169,7 +162,7 @@ enum class ValidatePrincipalOptions { * assertions, and should NOT be used for process isolation decisions. */ bool ValidatePrincipalCouldPotentiallyBeLoadedBy( - nsIPrincipal* aPrincipal, const nsACString& aRemoteType, + nsIPrincipal* aPrincipal, const RemoteType& aRemoteType, const EnumSet& aOptions, FunctionRef aIsPrincipalLoaded = nullptr); diff --git a/dom/ipc/ProcessPriorityManager.cpp b/dom/ipc/ProcessPriorityManager.cpp index 5c2705dd7f8a..022186720d8a 100644 --- a/dom/ipc/ProcessPriorityManager.cpp +++ b/dom/ipc/ProcessPriorityManager.cpp @@ -748,7 +748,7 @@ ProcessPriority ParticularProcessPriorityManager::CurrentPriority() { ProcessPriority ParticularProcessPriorityManager::ComputePriority() { if (!mHighPriorityBrowserParents.IsEmpty() || - mContentParent->GetRemoteType() == EXTENSION_REMOTE_TYPE || + mContentParent->GetRemoteType().IsExtension() || mHoldsPlayingAudioWakeLock) { return PROCESS_PRIORITY_FOREGROUND; } diff --git a/dom/ipc/RemoteType.cpp b/dom/ipc/RemoteType.cpp new file mode 100644 index 000000000000..08fe26206506 --- /dev/null +++ b/dom/ipc/RemoteType.cpp @@ -0,0 +1,401 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/RemoteType.h" + +#include "OriginAttributes.h" +#include "ipc/IPCMessageUtilsSpecializations.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/NeverDestroyed.h" +#include "nsIURI.h" +#include "nsNetUtil.h" +#include "nsPrintfCString.h" +#include "nsURLHelper.h" + +namespace mozilla::dom { + +// URLParams value used to indicate a boolean 'true' value. +// The lack of the attribute is used to indicate 'false'. +static constexpr nsLiteralCString kRemoteTypeAttrTrue = "1"_ns; + +/* static */ +const RemoteType& RemoteType::NotRemote() { + static NeverDestroyed sNotRemote(Kind::NotRemote); + return *sNotRemote; +} + +/* static */ +RemoteType RemoteType::SharedWeb(const OriginAttributes& aAttrs) { + RemoteType type(Kind::WebContent); + type.mUserContextId = aAttrs.mUserContextId; + type.mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + type.mGeckoViewSessionContextId = aAttrs.mGeckoViewSessionContextId; + MOZ_ASSERT(type.CheckValidity()); + return type; +} + +RemoteType::RemoteType() = default; +RemoteType::~RemoteType() = default; + +RemoteType::RemoteType(RemoteType::Kind aKind) : mKind(aKind) { + MOZ_RELEASE_ASSERT(CheckValidity()); +} + +RemoteType::RemoteType(const RemoteType&) = default; +RemoteType& RemoteType::operator=(const RemoteType&) = default; + +bool RemoteType::operator==(const RemoteType& aOther) const { + bool isEqual = + mKind == aOther.mKind && mOriginNoSuffix == aOther.mOriginNoSuffix && + std::apply( + [&, this](auto&&... aAttrs) -> bool { + return ((this->*aAttrs.mMember == aOther.*aAttrs.mMember) && ...); + }, + kAttrs); + // Sanity checks to catch if someone misses a flag in one of the methods. + MOZ_ASSERT_IF(isEqual, Hash() == aOther.Hash()); + MOZ_ASSERT_IF(isEqual, Stringify() == aOther.Stringify()); + return isEqual; +} + +// We can directly add integers & enums to the hash, but need to call HashString +// before adding strings to the hash. +template +static auto PreHashAttr(const T& aValue) { + if constexpr (std::is_integral_v || std::is_enum_v) { + return aValue; + } else { + return HashString(aValue); + } +} + +HashNumber RemoteType::Hash() const { + return std::apply( + [&, this](auto&&... aAttrs) -> HashNumber { + return HashGeneric(PreHashAttr(mKind), HashString(mOriginNoSuffix), + PreHashAttr(this->*aAttrs.mMember)...); + }, + kAttrs); +} + +// NOTE: This specifically parses the "kind" part of the remote type string, +// rather than the value returned from `StringifyKind`. This is only relevant +// for `NotRemote`, which uses "parent" for `StringifyKind`, but VoidCString() +// for `Stringify`. +// +// FIXME: We should make this more aligned by changing the representation of +// `NotRemote` to "parent" (bug 1508757) +static RemoteType::Kind ParseKind(const nsACString& aKindStr) { + if (aKindStr.IsVoid()) { + return RemoteType::Kind::NotRemote; + } + if (aKindStr == "prealloc"_ns) { + return RemoteType::Kind::Prealloc; + } + // NOTE: The 'webIsolated' and 'web' prefixes are interpreted the same, and + // generated based on the presence of a URL in ToString() to maintain + // a level of backwards compatibility with tests assuming the old format. + if (aKindStr == "web"_ns || aKindStr == "webIsolated"_ns) { + return RemoteType::Kind::WebContent; + } + if (aKindStr == "webCOOP+COEP") { + return RemoteType::Kind::WebCoopCoep; + } + if (aKindStr == "webServiceWorker") { + return RemoteType::Kind::WebServiceWorker; + } + if (aKindStr == "file"_ns) { + return RemoteType::Kind::File; + } + if (aKindStr == "privilegedabout"_ns) { + return RemoteType::Kind::PrivilegedAbout; + } + if (aKindStr == "privilegedmozilla"_ns) { + return RemoteType::Kind::PrivilegedMozilla; + } + if (aKindStr == "extension"_ns) { + return RemoteType::Kind::Extension; + } + if (aKindStr == "inference"_ns) { + return RemoteType::Kind::Inference; + } + return RemoteType::Kind::Unknown; +} + +static bool ParseAttr(const nsACString& aValue, bool& aMember) { + aMember = true; + return aValue == kRemoteTypeAttrTrue; +} + +static bool ParseAttr(const nsACString& aValue, uint32_t& aMember) { + nsresult rv = NS_OK; + aMember = aValue.ToInteger(&rv); + return NS_SUCCEEDED(rv); +} + +static bool ParseAttr(const nsACString& aValue, nsString& aMember) { + aMember = NS_ConvertUTF8toUTF16(aValue); + return true; +} + +/* static */ RemoteType RemoteType::ParseNoValidityCheck( + const nsACString& aRemoteType) { + RemoteType type; + + int32_t equalIdx = aRemoteType.FindChar('='); + if (equalIdx == kNotFound) { + type.mKind = ParseKind(aRemoteType); + return type; + } + + type.mKind = ParseKind(Substring(aRemoteType, 0, equalIdx)); + nsDependentCSubstring site(aRemoteType, equalIdx + 1); + + int32_t caretIdx = site.RFindChar('^'); + if (caretIdx != kNotFound) { + bool ok = URLParams::Parse( + Substring(site, caretIdx + 1), true, + [&](const nsACString& aName, const nsACString& aValue) { + return std::apply( + [&](auto&&... aAttrs) { + return ((aName == aAttrs.mName && + ParseAttr(aValue, type.*aAttrs.mMember)) || + ...); + }, + kAttrs); + }); + NS_ENSURE_TRUE(ok, RemoteType{}); + type.mOriginNoSuffix = Substring(site, 0, caretIdx); + } else { + type.mOriginNoSuffix = site; + } + return type; +} + +/* static */ RemoteType RemoteType::Parse(const nsACString& aRemoteType) { + RemoteType type = ParseNoValidityCheck(aRemoteType); + + // Ensure the type parsed to a valid RemoteType, as we never want to expose an + // non-Unknown but invalid RemoteType outside of this .cpp file. + NS_ENSURE_TRUE(type.CheckValidity(), RemoteType{}); + + // Ensure the string representation of the remote type matches aRemoteType. + // This is much stricter than e.g. principal or OriginAttributes parsing, but + // we shouldn't be storing RemoteType instances in the profile, so it should + // be OK to be strict here. + NS_ENSURE_TRUE(type.Stringify() == aRemoteType, RemoteType{}); + return type; +} + +nsCString RemoteType::StringifyKind() const { + MOZ_ASSERT(CheckValidity()); + switch (mKind) { + case RemoteType::Kind::NotRemote: + // NOTE: Unlike other remote types, the full RemoteType string for + // NotRemote is VoidCString(). We hope to change this in bug 1508757. + return "parent"_ns; + case RemoteType::Kind::Prealloc: + return "prealloc"_ns; + case RemoteType::Kind::WebContent: + // NOTE: See the comment in ParseKind for why we do this. + return HasOrigin() ? "webIsolated"_ns : "web"_ns; + case RemoteType::Kind::WebCoopCoep: + return "webCOOP+COEP"_ns; + case RemoteType::Kind::WebServiceWorker: + return "webServiceWorker"_ns; + case RemoteType::Kind::File: + return "file"_ns; + case RemoteType::Kind::PrivilegedAbout: + return "privilegedabout"_ns; + case RemoteType::Kind::PrivilegedMozilla: + return "privilegedmozilla"_ns; + case RemoteType::Kind::Extension: + return "extension"_ns; + case RemoteType::Kind::Inference: + return "inference"_ns; + case RemoteType::Kind::Unknown: + // This is not a valid remote type, but we return a string here to avoid + // crashes in logs if an unknown remote type is printed. + return ""_ns; + default: + MOZ_CRASH("Unsupported Kind in StringifyKind"); + } +} + +static void SetAttr(URLParams& aParam, const nsACString& aName, + const bool& aMember) { + if (aMember) { + aParam.Set(aName, kRemoteTypeAttrTrue); + } +} + +static void SetAttr(URLParams& aParam, const nsACString& aName, + const uint32_t& aMember) { + if (aMember != 0) { + aParam.Set(aName, nsPrintfCString("%" PRIu32, aMember)); + } +} + +static void SetAttr(URLParams& aParam, const nsACString& aName, + const nsString& aMember) { + if (!aMember.IsEmpty()) { + aParam.Set(aName, NS_ConvertUTF16toUTF8(aMember)); + } +} + +nsAutoCString RemoteType::StringifyMeta() const { + MOZ_ASSERT(CheckValidity()); + + nsAutoCString meta(mOriginNoSuffix); + + if (HasAttrs()) { + URLParams params; + std::apply( + [&, this](auto&&... aAttrs) { + (SetAttr(params, aAttrs.mName, this->*aAttrs.mMember), ...); + }, + kAttrs); + + nsAutoCString paramsStr; + params.Serialize(paramsStr, /* encode */ true); + + meta += "^"_ns + paramsStr; + } + + return meta; +} + +nsCString RemoteType::Stringify() const { + MOZ_ASSERT(CheckValidity()); + + // FIXME: We should change the representation of not-remote! (bug 1508757) + if (IsNotRemote()) { + return VoidCString(); + } + + nsCString kindStr = StringifyKind(); + if (HasMeta()) { + kindStr += "="_ns + StringifyMeta(); + } + + return kindStr; +} + +static bool AttrIsSet(const bool& aValue) { return aValue; } +static bool AttrIsSet(const uint32_t& aValue) { return aValue != 0; } +static bool AttrIsSet(const nsString& aValue) { return !aValue.IsEmpty(); } + +bool RemoteType::HasAttrs() const { + return std::apply( + [this](auto&&... aArgs) { + return (AttrIsSet(this->*aArgs.mMember) || ...); + }, + kAttrs); +} + +bool RemoteType::CheckValidity() const { + // If we don't have a WebContent kind, no extra fields can be used. + if (!IsWeb() && HasMeta()) { + NS_WARNING("Invalid RemoteType: Non-web type has metadata"); + return false; + } + + if (HasOrigin()) { + nsCOMPtr uri; + if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), mOriginNoSuffix))) { + NS_WARNING("Invalid RemoteType: Invalid OriginNoSuffix URI"); + return false; + } + + nsCOMPtr principal = + BasePrincipal::CreateContentPrincipal(uri, GetOriginAttributes()); + if (!principal) { + NS_WARNING("Invalid RemoteType: Failed to create content principal"); + return false; + } + + // Currently we always isolate by site, never by origin, so a remote type + // should only contain a site origin. + nsAutoCString origin; + nsAutoCString siteOrigin; + MOZ_ALWAYS_SUCCEEDS(principal->GetOriginNoSuffix(origin)); + MOZ_ALWAYS_SUCCEEDS(principal->GetSiteOriginNoSuffix(siteOrigin)); + if (origin != mOriginNoSuffix || origin != siteOrigin) { + NS_WARNING("Invalid RemoteType: Non-canonical OriginNoSuffix"); + return false; + } + } else if (IsWebCoopCoep() || IsWebServiceWorker()) { + // These remote types require a URI specified. + NS_WARNING( + "Invalid RemoteType: Web{CoopCoep/ServiceWorker} without site origin"); + return false; + } + + return true; +} + +bool RemoteType::SupportsPrealloc() const { + MOZ_ASSERT(IsKnown()); + MOZ_ASSERT(mKind != Kind::Prealloc); + + // NOTE: Extension processes do not support prealloc due to bug 1638119 + return mKind != Kind::NotRemote && mKind != Kind::File && + mKind != Kind::PrivilegedAbout && mKind != Kind::Extension && + !mDisableJit; +} + +OriginAttributes RemoteType::GetOriginAttributes() const { + OriginAttributes attrs; + attrs.mUserContextId = mUserContextId; + attrs.mPrivateBrowsingId = mPrivateBrowsingId; + attrs.mGeckoViewSessionContextId = mGeckoViewSessionContextId; + return attrs; +} + +RemoteType RemoteType::WithDisableJit(bool aDisableJit) const { + MOZ_RELEASE_ASSERT(IsWeb()); + RemoteType copy(*this); + copy.mDisableJit = aDisableJit; + + MOZ_ASSERT(copy.CheckValidity()); + return copy; +} + +RemoteType RemoteType::WithSiteOrigin(const nsACString& aSiteOriginNoSuffix, + Kind aNewKind) const { + MOZ_RELEASE_ASSERT(IsSharedWeb()); + RemoteType copy(*this); + copy.mKind = aNewKind; + copy.mOriginNoSuffix = aSiteOriginNoSuffix; + + // NOTE: We release-assert validity, as an invalid aSiteOriginURI or Kind + // could create an invalid RemoteType. + MOZ_RELEASE_ASSERT(copy.CheckValidity()); + MOZ_RELEASE_ASSERT(copy.IsIsolatedWeb()); + return copy; +} + +} // namespace mozilla::dom + +// NOTE: This could probably be made more efficient by removing the +// serialization to a string, but this keeps the logic simpler for now. +namespace IPC { + +void ParamTraits::Write(MessageWriter* aWriter, + const paramType& aParam) { + MOZ_ASSERT(aParam.IsKnown(), "Cannot send unknown RemoteType"); + WriteParam(aWriter, aParam.Stringify()); +} + +bool ParamTraits::Read(MessageReader* aReader, + paramType* aResult) { + nsCString s; + if (!ReadParam(aReader, &s)) { + return false; + } + *aResult = mozilla::dom::RemoteType::Parse(s); + return aResult->IsKnown(); +} + +} // namespace IPC diff --git a/dom/ipc/RemoteType.h b/dom/ipc/RemoteType.h index 673135d1f518..08ea9dae3440 100644 --- a/dom/ipc/RemoteType.h +++ b/dom/ipc/RemoteType.h @@ -5,33 +5,251 @@ #ifndef mozilla_dom_RemoteType_h #define mozilla_dom_RemoteType_h -#include "nsReadableUtils.h" +#include "mozilla/HashFunctions.h" #include "nsString.h" -// These must match the similar ones in E10SUtils.sys.mjs and ProcInfo.h and -// ChromeUtils.webidl Process names as reported by about:memory are defined in -// ContentChild:RecvRemoteType. Add your value there too or it will be called -// "Web Content". -#define PREALLOC_REMOTE_TYPE "prealloc"_ns -#define WEB_REMOTE_TYPE "web"_ns -#define FILE_REMOTE_TYPE "file"_ns -#define EXTENSION_REMOTE_TYPE "extension"_ns -#define PRIVILEGEDABOUT_REMOTE_TYPE "privilegedabout"_ns -#define PRIVILEGEDMOZILLA_REMOTE_TYPE "privilegedmozilla"_ns -#define INFERENCE_REMOTE_TYPE "inference"_ns +namespace mozilla { +class OriginAttributes; +} -#define DEFAULT_REMOTE_TYPE WEB_REMOTE_TYPE +namespace IPC { +template +struct ParamTraits; +class MessageWriter; +class MessageReader; +} // namespace IPC -// These must start with the WEB_REMOTE_TYPE above. -#define FISSION_WEB_REMOTE_TYPE "webIsolated"_ns -#define WITH_COOP_COEP_REMOTE_TYPE "webCOOP+COEP"_ns -#define WITH_COOP_COEP_REMOTE_TYPE_PREFIX "webCOOP+COEP="_ns -#define SERVICEWORKER_REMOTE_TYPE "webServiceWorker"_ns +namespace mozilla::dom { -// A flag appended to the origin suffix to disable the JIT for that process. -#define DISABLE_JIT_REMOTE_TYPE_SUFFIX "disableJit=1"_ns +/** + * Parsed information about a given RemoteType string. A remote type is used as + * the key for determining which process type to load in. + */ +struct RemoteType { + // Primary "Kind" enum for the remote type. + // + // These must match the similar ones in E10SUtils.sys.mjs and ProcInfo.h and + // ChromeUtils.webidl. Process names as reported by about:memory are defined + // in ContentChild:RecvSetRemoteType. Add your value there too or it will be + // called "Web Content". + enum class Kind : uint8_t { + // Error case for an "invalid" RemoteType instance. + // Remote Types of this Kind are falsy, and cannot be sent over IPC. + Unknown, -// Remote type value used to represent being non-remote. -#define NOT_REMOTE_TYPE VoidCString() + // The parent process. + // This process is exclusively used for displaying core and/or legacy + // trusted browser UI. + NotRemote, + + // An unspecialized content process, which has loaded nothing. + // Only a process with this Kind can change its RemoteType at runtime. + Prealloc, + + // Process used to host arbitrary untrusted web content. + // Privileged interfaces should not be exposed to web content processes. + WebContent, + + // Process used to host arbitrary untrusted web content with the COOP and + // COEP headers. + // Privileged interfaces should not be exposed to web content processes. + WebCoopCoep, + + // Process used to host arbitrary untrusted web service workers. + // Privileged interfaces should not be exposed to web content processes. + WebServiceWorker, + + // Process used to host arbitrary untrusted content from the local + // filesystem (i.e. file:/// URIs). + // This process is less sandboxed, as by necessity it is allowed to read the + // local filesystem. + File, + + // Process used to host privileged browser UI. + // Privileged APIs used by pages like the newtab page must be restricted to + // only be usable within this remote type. + PrivilegedAbout, + + // Process used to host privileged web content, such as AMO and SUMO. + PrivilegedMozilla, + + // Process used to host WebExtension content, including background scripts, + // toplevel documents, and service workers. + Extension, + + // Process used to host inference models. + Inference, + }; + + // Static getter for the NotRemote remote type. + // + // This returns a `const RemoteType&` referencing a static `NotRemote` type to + // allow returning this type in context which otherwise would return a `const + // RemoteType&`. + // + // Other kinds should use the normal `RemoteType` constructor or `SharedWeb` + static const RemoteType& NotRemote(); + + // Static factory method for Web remote types. + // + // This creates a SharedWeb remote type without site isolation or other + // customizations. Use the `With*` methods to create isolated remote types. + static RemoteType SharedWeb(const OriginAttributes& aAttrs); + + RemoteType(); + ~RemoteType(); + RemoteType(const RemoteType&); + RemoteType& operator=(const RemoteType&); + + // NOTE: Currently we don't support move operators. + // If we decide to implement them in the future, it should probably be done + // manually to ensure the moved-from RemoteType becomes Unknown. + + explicit RemoteType(Kind aKind); + + // Support for equality & hashing operations on the RemoteType object. + bool operator==(const RemoteType& aOther) const; + bool operator!=(const RemoteType& aOther) const { return !(*this == aOther); } + HashNumber Hash() const; + + // Checking for validity. + bool IsKnown() const { return mKind != Kind::Unknown; } + explicit operator bool() const { return IsKnown(); } + + // Attempts to parse a stringified RemoteType. + // On failure, returns an `Unknown` RemoteType object. + static RemoteType Parse(const nsACString& aRemoteType); + + // Convert a parsed RemoteType back into its string representation. + // WARNING: The resulting value is not Telemetry-safe, see StringifyKind(). + nsCString Stringify() const; + + // Get a telemetry-safe kind string for this RemoteType. + nsCString StringifyKind() const; + + // String value encoding RemoteType metadata (e.g. site origin & OAs). + // WARNING: The resulting value is not Telemetry-safe. + nsAutoCString StringifyMeta() const; + + // Which kind of RemoteType is this? You can also use the helper methods below + // instead of matching on every case. + Kind GetKind() const { return mKind; } + + // Get the [Site]OriginNoSuffix used for isolating this process. + // Only valid to call if HasOrigin(). + const nsCString& OriginNoSuffix() const { + MOZ_ASSERT(HasOrigin()); + return mOriginNoSuffix; + } + + // NOTE: These origin attributes are only specified for web remote types, and + // will be left as default for all other remote types. + uint32_t UserContextId() const { return mUserContextId; } + uint32_t PrivateBrowsingId() const { return mPrivateBrowsingId; } + bool IsPrivateBrowsing() const { return mPrivateBrowsingId != 0; } + const nsString& GeckoViewSessionContextId() const { + return mGeckoViewSessionContextId; + } + + OriginAttributes GetOriginAttributes() const; + + // Check if there are any non-default attributes. + bool HasAttrs() const; + bool HasOrigin() const { return !mOriginNoSuffix.IsEmpty(); } + bool HasMeta() const { return HasOrigin() || HasAttrs(); } + + bool IsNotRemote() const { return mKind == Kind::NotRemote; } + bool IsPrealloc() const { return mKind == Kind::Prealloc; } + bool IsWeb() const { + return mKind == Kind::WebContent || mKind == Kind::WebCoopCoep || + mKind == Kind::WebServiceWorker; + } + bool IsSharedWeb() const { return IsWeb() && !HasOrigin(); } + bool IsIsolatedWeb() const { return IsWeb() && HasOrigin(); } + bool IsWebCoopCoep() const { return mKind == Kind::WebCoopCoep; } + bool IsWebServiceWorker() const { return mKind == Kind::WebServiceWorker; } + bool IsFile() const { return mKind == Kind::File; } + bool IsPrivilegedAbout() const { return mKind == Kind::PrivilegedAbout; } + bool IsPrivilegedMozilla() const { return mKind == Kind::PrivilegedMozilla; } + bool IsExtension() const { return mKind == Kind::Extension; } + bool IsInference() const { return mKind == Kind::Inference; } + bool IsJitDisabled() const { return mDisableJit; } + + // Does this RemoteType support being created from a prealloc process? + bool SupportsPrealloc() const; + + // Construct a new RemoteType identical to the current RemoteType, but with + // the "disableJit" flag set. + // WARNING: Asserts if called on a non-Web remote type. + RemoteType WithDisableJit(bool aDisableJit) const; + + // Turn this shared web RemoteType into an IsolatedWeb RemoteType which is + // isolated by the provided SiteOriginNoSuffix. A specific kind for the + // isolated remoteType can also be provided, and must be WebContent, + // WebServiceWorker, or WebCoopCoep. + // WARNING: Asserts if called on a non-SharedWeb remote type. + RemoteType WithSiteOrigin(const nsACString& aSiteOriginNoSuffix, + Kind aNewKind = Kind::WebContent) const; + + // Allow formatting a RemoteType with {fmt} or operator<< + friend nsCString format_as(const RemoteType& aRemoteType) { + return aRemoteType.Stringify(); + } + friend std::ostream& operator<<(std::ostream& aStream, + const RemoteType& aRemoteType) { + return aStream << aRemoteType.Stringify(); + } + + private: + // Implementation detail of `Parse`, which does not assert validity. + static RemoteType ParseNoValidityCheck(const nsACString& aRemoteType); + + // Check that the given RemoteType does not violate any internal invariants. + // An invalid RemoteType should never be exposed outside of RemoteType + // internals, so this is private. + [[nodiscard]] bool CheckValidity() const; + + Kind mKind = Kind::Unknown; + + // Additional Isolation Flags. + bool mDisableJit = false; + + // The [Site]OriginNoSuffix used for isolating this process. + nsCString mOriginNoSuffix; + + // This is a subset of the members from `OriginAttributes`, which are allowed + // to influence process selection. + uint32_t mUserContextId = 0; + uint32_t mPrivateBrowsingId = 0; + nsString mGeckoViewSessionContextId; + + template + struct Attr { + nsLiteralCString mName; + T RemoteType::* mMember; + }; + + // Tuple describing the various RemoteType attributes which should be + // serialized into the remote type with URIParams. + static constexpr std::tuple kAttrs{ + Attr{"userContextId"_ns, &RemoteType::mUserContextId}, + Attr{"privateBrowsingId"_ns, &RemoteType::mPrivateBrowsingId}, + Attr{"geckoViewUserContextId"_ns, + &RemoteType::mGeckoViewSessionContextId}, + Attr{"disableJit"_ns, &RemoteType::mDisableJit}}; +}; + +} // namespace mozilla::dom + +namespace IPC { + +template <> +struct ParamTraits { + using paramType = mozilla::dom::RemoteType; + static void Write(MessageWriter* aWriter, const paramType& aParam); + static bool Read(MessageReader* aReader, paramType* aResult); +}; + +} // namespace IPC #endif // mozilla_dom_RemoteType_h diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp index 9364d783a1f7..79524b0f44b4 100644 --- a/dom/ipc/WindowGlobalChild.cpp +++ b/dom/ipc/WindowGlobalChild.cpp @@ -712,7 +712,7 @@ mozilla::ipc::IPCResult WindowGlobalChild::RecvMakeFrameLocal( // Trigger a process switch into the current process. RemotenessOptions options; - options.mRemoteType = NOT_REMOTE_TYPE; + options.mRemoteType = dom::RemoteType::NotRemote().Stringify(); options.mPendingSwitchID.Construct(aPendingSwitchId); options.mSwitchingInProgressLoad = true; flo->ChangeRemoteness(options, IgnoreErrors()); @@ -1083,12 +1083,12 @@ void WindowGlobalChild::SetDocumentURI(nsIURI* aDocumentURI) { SendUpdateDocumentURI(WrapNotNull(aDocumentURI)); } -const nsACString& WindowGlobalChild::GetRemoteType() const { +const RemoteType& WindowGlobalChild::GetRemoteType() const { if (XRE_IsContentProcess()) { return ContentChild::GetSingleton()->GetRemoteType(); } - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } already_AddRefed WindowGlobalChild::GetActor( diff --git a/dom/ipc/WindowGlobalChild.h b/dom/ipc/WindowGlobalChild.h index 3678769f47a4..b20139f56132 100644 --- a/dom/ipc/WindowGlobalChild.h +++ b/dom/ipc/WindowGlobalChild.h @@ -155,7 +155,7 @@ class WindowGlobalChild final : public WindowGlobalActor, void BlockBFCacheFor(BFCacheStatus aStatus); protected: - const nsACString& GetRemoteType() const override; + const RemoteType& GetRemoteType() const override; already_AddRefed InitJSActor(JS::Handle aMaybeActor, const nsACString& aName, diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index a0c27a446c6b..e2337fa9db52 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -676,16 +676,16 @@ IPCResult WindowGlobalParent::RecvRawMessage(const JSActorMessageMeta& aMeta, return IPC_OK(); } -const nsACString& WindowGlobalParent::GetRemoteType() const { +const RemoteType& WindowGlobalParent::GetRemoteType() const { if (RefPtr browserParent = GetBrowserParent()) { return browserParent->Manager()->GetRemoteType(); } - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } void WindowGlobalParent::GetRemoteType(nsACString& aRemoteType) const { - aRemoteType = GetRemoteType(); + aRemoteType = GetRemoteType().Stringify(); } void WindowGlobalParent::NotifyContentBlockingEvent( @@ -2065,8 +2065,7 @@ bool WindowGlobalParent::ShouldTrackSiteOriginTelemetry() { } RefPtr browserParent = GetBrowserParent(); - if (!browserParent || - !IsWebRemoteType(browserParent->Manager()->GetRemoteType())) { + if (!browserParent || !browserParent->Manager()->GetRemoteType().IsWeb()) { return false; } diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h index 7b7818b29e15..55c881a76dc8 100644 --- a/dom/ipc/WindowGlobalParent.h +++ b/dom/ipc/WindowGlobalParent.h @@ -270,7 +270,7 @@ class WindowGlobalParent final : public WindowContext, void AddSecurityState(uint32_t aStateFlags); uint32_t GetSecurityFlags() { return mSecurityState; } - const nsACString& GetRemoteType() const override; + const RemoteType& GetRemoteType() const override; void GetRemoteType(nsACString& aRemoteType) const; void NotifySessionStoreUpdatesComplete(Element* aEmbedder); diff --git a/dom/ipc/gtest/ProcessIsolationTest.cpp b/dom/ipc/gtest/ProcessIsolationTest.cpp index b448148ccc51..cd466dd62aff 100644 --- a/dom/ipc/gtest/ProcessIsolationTest.cpp +++ b/dom/ipc/gtest/ProcessIsolationTest.cpp @@ -31,8 +31,8 @@ namespace { static bool gJitDisabled = false; struct RemoteTypes { - nsCString mIsolated; - nsCString mUnisolated; + RemoteType mIsolated; + RemoteType mUnisolated; }; struct WorkerExpectation { @@ -40,7 +40,7 @@ struct WorkerExpectation { WorkerKind mWorkerKind = WorkerKindShared; bool mJitDisabled = false; Result mExpected = Err(NS_ERROR_FAILURE); - nsCString mCurrentRemoteType = "fakeRemoteType"_ns; + RemoteType mCurrentRemoteType = RemoteType(RemoteType::Kind::WebContent); void Check(bool aUseRemoteSubframes) { nsAutoCString origin; @@ -50,7 +50,7 @@ struct WorkerExpectation { "origin: %s, workerKind: %s, currentRemoteType: %s, " "useRemoteSubframes: %d", origin.get(), mWorkerKind == WorkerKindShared ? "shared" : "service", - mCurrentRemoteType.get(), aUseRemoteSubframes); + mCurrentRemoteType.Stringify().get(), aUseRemoteSubframes); gJitDisabled = mJitDisabled; auto result = IsolationOptionsForWorker( @@ -59,12 +59,14 @@ struct WorkerExpectation { << "Unexpected status (expected " << (mExpected.isOk() ? "ok" : "err") << ") for " << describe; if (mExpected.isOk()) { - const nsCString& expected = aUseRemoteSubframes - ? mExpected.inspect().mIsolated - : mExpected.inspect().mUnisolated; + const RemoteType& expected = aUseRemoteSubframes + ? mExpected.inspect().mIsolated + : mExpected.inspect().mUnisolated; + EXPECT_TRUE(expected.IsKnown()) + << "invalid remote type expectation in test"; ASSERT_EQ(result.inspect().mRemoteType, expected) - << "Unexpected remote type (expected " << expected << ") for " - << describe; + << "Unexpected remote type (expected " << expected.Stringify() + << ") for " << describe; } } }; @@ -153,37 +155,11 @@ static void UnregisterMockPolicyService() { } // namespace -static nsCString WebIsolatedRemoteType(nsIPrincipal* aPrincipal, - bool aJitDisabled = false) { - nsAutoCString origin; - MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); - if (aJitDisabled) { - return FISSION_WEB_REMOTE_TYPE + "="_ns + origin + "^disableJit=1"_ns; - } - return FISSION_WEB_REMOTE_TYPE + "="_ns + origin; -} - -static nsCString CoopCoepRemoteType(nsIPrincipal* aPrincipal) { - nsAutoCString origin; - MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); - return WITH_COOP_COEP_REMOTE_TYPE + "="_ns + origin; -} - -static nsCString ServiceWorkerIsolatedRemoteType(nsIPrincipal* aPrincipal, - bool aJitDisabled = false) { - nsAutoCString origin; - MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); - if (aJitDisabled) { - return SERVICEWORKER_REMOTE_TYPE + "="_ns + origin + "^disableJit=1"_ns; - } - return SERVICEWORKER_REMOTE_TYPE + "="_ns + origin; -} - // When file URI process separation is disabled (as is the default on // Android), a file: shared worker is allowed to load in any remote type, // rather than being rejected when it isn't already in a file: process. static Result FileWorkerOutsideFileProcessExpected( - const nsCString& aFileRemoteType) { + const RemoteType& aFileRemoteType) { if (StaticPrefs::browser_tabs_remote_separateFileUriProcess()) { return Err(NS_ERROR_UNEXPECTED); } @@ -230,14 +206,14 @@ TEST(ProcessIsolationTest, WorkerOptions) nsCOMPtr nullSecureComPrecursorPrincipal = NullPrincipal::CreateWithInheritedAttributes(secureComPrincipal); - nsCString extensionRemoteType = + RemoteType extensionRemoteType = ExtensionPolicyService::GetSingleton().UseRemoteExtensions() - ? EXTENSION_REMOTE_TYPE - : NOT_REMOTE_TYPE; - nsCString fileRemoteType = + ? RemoteType(RemoteType::Kind::Extension) + : RemoteType::NotRemote(); + RemoteType fileRemoteType = StaticPrefs::browser_tabs_remote_separateFileUriProcess() - ? FILE_REMOTE_TYPE - : WEB_REMOTE_TYPE; + ? RemoteType(RemoteType::Kind::File) + : RemoteType(RemoteType::Kind::WebContent); WorkerExpectation expectations[] = { // Neither service not shared workers can have expanded principals @@ -265,55 +241,62 @@ TEST(ProcessIsolationTest, WorkerOptions) // Service workers with various content principals {.mPrincipal = secureComPrincipal, .mWorkerKind = WorkerKindService, - .mExpected = - RemoteTypes{ServiceWorkerIsolatedRemoteType(secureComPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = RemoteTypes{RemoteType::Parse( + "webServiceWorker=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, {.mPrincipal = secureOrgPrincipal, .mWorkerKind = WorkerKindService, - .mExpected = - RemoteTypes{ServiceWorkerIsolatedRemoteType(secureOrgPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = RemoteTypes{RemoteType::Parse( + "webServiceWorker=https://example.org"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, {.mPrincipal = extensionPrincipal, .mWorkerKind = WorkerKindService, .mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}, - .mCurrentRemoteType = EXTENSION_REMOTE_TYPE}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::Extension)}, {.mPrincipal = privilegedMozillaPrincipal, .mWorkerKind = WorkerKindService, .mExpected = Err(NS_ERROR_UNEXPECTED)}, {.mPrincipal = privilegedMozillaPrincipal, .mWorkerKind = WorkerKindService, - .mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE, - PRIVILEGEDMOZILLA_REMOTE_TYPE}, - .mCurrentRemoteType = PRIVILEGEDMOZILLA_REMOTE_TYPE}, + .mExpected = + RemoteTypes{RemoteType(RemoteType::Kind::PrivilegedMozilla), + RemoteType(RemoteType::Kind::PrivilegedMozilla)}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::PrivilegedMozilla)}, // Shared Worker loaded from within a webCOOP+COEP remote type process, // should load elsewhere. {.mPrincipal = secureComPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), - WEB_REMOTE_TYPE}, - .mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}, + .mCurrentRemoteType = + RemoteType::Parse("webCOOP+COEP=https://example.com"_ns)}, // Even precursorless null principal should load elsewhere. {.mPrincipal = nullPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WEB_REMOTE_TYPE, WEB_REMOTE_TYPE}, - .mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)}, + .mExpected = RemoteTypes{RemoteType(RemoteType::Kind::WebContent), + RemoteType(RemoteType::Kind::WebContent)}, + .mCurrentRemoteType = + RemoteType::Parse("webCOOP+COEP=https://example.com"_ns)}, {.mPrincipal = nullContainerPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WEB_REMOTE_TYPE "=^userContextId=1"_ns, - WEB_REMOTE_TYPE "=^userContextId=1"_ns}, - .mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)}, + .mExpected = RemoteTypes{RemoteType::Parse("web=^userContextId=1"_ns), + RemoteType::Parse("web=^userContextId=1"_ns)}, + .mCurrentRemoteType = + RemoteType::Parse("webCOOP+COEP=https://example.com"_ns)}, // System principal shared workers can only load in the parent process. {.mPrincipal = systemPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{NOT_REMOTE_TYPE, NOT_REMOTE_TYPE}, - .mCurrentRemoteType = NOT_REMOTE_TYPE}, + .mExpected = + RemoteTypes{RemoteType::NotRemote(), RemoteType::NotRemote()}, + .mCurrentRemoteType = RemoteType::NotRemote()}, {.mPrincipal = systemPrincipal, .mWorkerKind = WorkerKindShared, .mExpected = Err(NS_ERROR_UNEXPECTED), - .mCurrentRemoteType = PRIVILEGEDABOUT_REMOTE_TYPE}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::PrivilegedAbout)}, {.mPrincipal = systemPrincipal, .mWorkerKind = WorkerKindShared, .mExpected = Err(NS_ERROR_UNEXPECTED)}, @@ -324,53 +307,62 @@ TEST(ProcessIsolationTest, WorkerOptions) // Content principals should load in the appropriate remote types. {.mPrincipal = secureComPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, {.mPrincipal = secureOrgPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(secureOrgPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=https://example.org"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, {.mPrincipal = insecureOrgPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(insecureOrgPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=http://example.org"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, {.mPrincipal = filePrincipal, .mWorkerKind = WorkerKindShared, .mExpected = FileWorkerOutsideFileProcessExpected(fileRemoteType)}, {.mPrincipal = filePrincipal, .mWorkerKind = WorkerKindShared, .mExpected = RemoteTypes{fileRemoteType, fileRemoteType}, - .mCurrentRemoteType = FILE_REMOTE_TYPE}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::File)}, {.mPrincipal = extensionPrincipal, .mWorkerKind = WorkerKindShared, .mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}, - .mCurrentRemoteType = EXTENSION_REMOTE_TYPE}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::Extension)}, {.mPrincipal = privilegedMozillaPrincipal, .mWorkerKind = WorkerKindShared, .mExpected = Err(NS_ERROR_UNEXPECTED)}, {.mPrincipal = privilegedMozillaPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE, - PRIVILEGEDMOZILLA_REMOTE_TYPE}, - .mCurrentRemoteType = PRIVILEGEDMOZILLA_REMOTE_TYPE}, + .mExpected = + RemoteTypes{RemoteType(RemoteType::Kind::PrivilegedMozilla), + RemoteType(RemoteType::Kind::PrivilegedMozilla)}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::PrivilegedMozilla)}, {.mPrincipal = nullSecureComPrecursorPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), - WEB_REMOTE_TYPE}}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}}, // When the policy service calls for the JIT to be disabled the remote // type should reflect that. {.mPrincipal = secureComPrincipal, .mWorkerKind = WorkerKindShared, .mJitDisabled = true, - .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal, true), - SharedWebRemoteType(OriginAttributes{}, true)}}, + .mExpected = + RemoteTypes{RemoteType::Parse( + "webIsolated=https://example.com^disableJit=1"_ns), + RemoteType::Parse("web=^disableJit=1"_ns)}}, {.mPrincipal = secureComPrincipal, .mWorkerKind = WorkerKindService, .mJitDisabled = true, - .mExpected = RemoteTypes{ServiceWorkerIsolatedRemoteType( - secureComPrincipal, true), - SharedWebRemoteType(OriginAttributes{}, true)}}, + .mExpected = + RemoteTypes{ + RemoteType::Parse( + "webServiceWorker=https://example.com^disableJit=1"_ns), + RemoteType::Parse("web=^disableJit=1"_ns)}}, }; RegisterMockPolicyService(); @@ -413,10 +405,10 @@ TEST(ProcessIsolationTest, FileURIAllowlistedWorkerOptions) nsCOMPtr filePrincipal = MakeTestPrincipal("file:///path/to/dir"); - nsCString fileRemoteType = + RemoteType fileRemoteType( StaticPrefs::browser_tabs_remote_separateFileUriProcess() - ? FILE_REMOTE_TYPE - : WEB_REMOTE_TYPE; + ? RemoteType::Kind::File + : RemoteType::Kind::WebContent); WorkerExpectation expectations[] = { // Being in the file:// URI allowlist must not change worker process @@ -425,15 +417,16 @@ TEST(ProcessIsolationTest, FileURIAllowlistedWorkerOptions) // ServiceWorkerPrivate::Initialize() passes for a service worker. {.mPrincipal = allowlistedPrincipal, .mWorkerKind = WorkerKindService, - .mExpected = - RemoteTypes{ServiceWorkerIsolatedRemoteType(allowlistedPrincipal), - WEB_REMOTE_TYPE}, - .mCurrentRemoteType = WEB_REMOTE_TYPE}, + .mExpected = RemoteTypes{RemoteType::Parse( + "webServiceWorker=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::WebContent)}, {.mPrincipal = allowlistedPrincipal, .mWorkerKind = WorkerKindShared, - .mExpected = RemoteTypes{WebIsolatedRemoteType(allowlistedPrincipal), - WEB_REMOTE_TYPE}, - .mCurrentRemoteType = WEB_REMOTE_TYPE}, + .mExpected = + RemoteTypes{RemoteType::Parse("webIsolated=https://example.com"_ns), + RemoteType(RemoteType::Kind::WebContent)}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::WebContent)}, // An actual file: principal is still confined to the file process, // regardless of the allowlist. @@ -443,7 +436,7 @@ TEST(ProcessIsolationTest, FileURIAllowlistedWorkerOptions) {.mPrincipal = filePrincipal, .mWorkerKind = WorkerKindShared, .mExpected = RemoteTypes{fileRemoteType, fileRemoteType}, - .mCurrentRemoteType = FILE_REMOTE_TYPE}, + .mCurrentRemoteType = RemoteType(RemoteType::Kind::File)}, }; for (auto& expectation : expectations) { diff --git a/dom/ipc/gtest/RemoteTypeTest.cpp b/dom/ipc/gtest/RemoteTypeTest.cpp new file mode 100644 index 000000000000..af4e8ad18f82 --- /dev/null +++ b/dom/ipc/gtest/RemoteTypeTest.cpp @@ -0,0 +1,153 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "mozilla/OriginAttributes.h" +#include "mozilla/dom/RemoteType.h" +#include "mozilla/gtest/MozAssertions.h" + +namespace mozilla::dom { + +TEST(RemoteTypeTest, FormatSimple) +{ + // NotRemote is special in that it has a different value for Stringify() and + // StringifyKind(). This will be changed in the future. + EXPECT_TRUE(RemoteType::NotRemote().IsKnown()); + EXPECT_EQ(RemoteType::NotRemote().Stringify(), VoidCString()); + EXPECT_EQ(RemoteType::NotRemote().StringifyKind(), "parent"_ns); + EXPECT_FALSE(RemoteType::NotRemote().HasMeta()); + EXPECT_EQ(RemoteType::NotRemote().StringifyMeta(), ""_ns); + + auto formatSimple = [](RemoteType::Kind aKind, const nsACString& aString) { + RemoteType remoteType(aKind); + EXPECT_TRUE(remoteType.IsKnown()); + EXPECT_EQ(remoteType.StringifyKind(), aString); + EXPECT_FALSE(remoteType.HasMeta()); + EXPECT_EQ(remoteType.StringifyMeta(), ""_ns); + EXPECT_EQ(remoteType.Stringify(), aString); + }; + + formatSimple(RemoteType::Kind::Prealloc, "prealloc"_ns); + formatSimple(RemoteType::Kind::WebContent, "web"_ns); + formatSimple(RemoteType::Kind::File, "file"_ns); + formatSimple(RemoteType::Kind::PrivilegedAbout, "privilegedabout"_ns); + formatSimple(RemoteType::Kind::PrivilegedMozilla, "privilegedmozilla"_ns); + formatSimple(RemoteType::Kind::Extension, "extension"_ns); + formatSimple(RemoteType::Kind::Inference, "inference"_ns); +} + +TEST(RemoteTypeTest, FormatCompound) +{ + auto formatCompound = [](RemoteType aRemoteType, const nsACString& aKind, + const nsACString& aMeta) { + EXPECT_TRUE(aRemoteType.IsKnown()); + EXPECT_EQ(aRemoteType.StringifyKind(), aKind); + EXPECT_TRUE(aRemoteType.HasMeta()); + EXPECT_EQ(aRemoteType.StringifyMeta(), aMeta); + nsCString expected = aKind + "="_ns + aMeta; + EXPECT_EQ(aRemoteType.Stringify(), expected); + }; + + OriginAttributes attrs; + attrs.mUserContextId = 2; + attrs.mPrivateBrowsingId = 1; + + formatCompound( + RemoteType::SharedWeb(attrs).WithDisableJit(true).WithSiteOrigin( + "https://example.com"_ns), + "webIsolated"_ns, + "https://example.com^userContextId=2&privateBrowsingId=1&disableJit=1"_ns); + + formatCompound(RemoteType::SharedWeb({}) + .WithSiteOrigin("https://example.com"_ns) + .WithDisableJit(true), + "webIsolated"_ns, "https://example.com^disableJit=1"_ns); + formatCompound( + RemoteType::SharedWeb({}).WithSiteOrigin("https://example.com"_ns), + "webIsolated"_ns, "https://example.com"_ns); + + formatCompound(RemoteType::SharedWeb({}).WithSiteOrigin( + "https://example.com"_ns, RemoteType::Kind::WebCoopCoep), + "webCOOP+COEP"_ns, "https://example.com"_ns); + formatCompound( + RemoteType::SharedWeb({}).WithSiteOrigin( + "https://example.com"_ns, RemoteType::Kind::WebServiceWorker), + "webServiceWorker"_ns, "https://example.com"_ns); +} + +TEST(RemoteTypeTest, ParseValid) +{ + EXPECT_EQ(RemoteType::Parse(VoidCString()), RemoteType::NotRemote()); + + EXPECT_EQ(RemoteType::Parse("prealloc"_ns), + RemoteType(RemoteType::Kind::Prealloc)); + EXPECT_EQ(RemoteType::Parse("file"_ns), RemoteType(RemoteType::Kind::File)); + EXPECT_EQ(RemoteType::Parse("privilegedabout"_ns), + RemoteType(RemoteType::Kind::PrivilegedAbout)); + EXPECT_EQ(RemoteType::Parse("privilegedmozilla"_ns), + RemoteType(RemoteType::Kind::PrivilegedMozilla)); + EXPECT_EQ(RemoteType::Parse("extension"_ns), + RemoteType(RemoteType::Kind::Extension)); + EXPECT_EQ(RemoteType::Parse("inference"_ns), + RemoteType(RemoteType::Kind::Inference)); + + EXPECT_EQ(RemoteType::Parse("web"_ns), + RemoteType(RemoteType::Kind::WebContent)); + EXPECT_EQ(RemoteType::Parse("web=^disableJit=1"_ns), + RemoteType::SharedWeb({}).WithDisableJit(true)); + { + OriginAttributes attrs; + attrs.mUserContextId = 2; + attrs.mPrivateBrowsingId = 1; + EXPECT_EQ(RemoteType::Parse("web=^userContextId=2&privateBrowsingId=1"_ns), + RemoteType::SharedWeb(attrs)); + } + { + OriginAttributes attrs; + attrs.mGeckoViewSessionContextId = u"session 1"_ns; + EXPECT_EQ(RemoteType::Parse("web=^geckoViewUserContextId=session+1"_ns), + RemoteType::SharedWeb(attrs)); + } + + EXPECT_EQ(RemoteType::Parse("webIsolated=https://example.com"_ns), + RemoteType::SharedWeb({}).WithSiteOrigin("https://example.com"_ns)); + EXPECT_EQ(RemoteType::Parse("webCOOP+COEP=https://example.com"_ns), + RemoteType::SharedWeb({}).WithSiteOrigin( + "https://example.com"_ns, RemoteType::Kind::WebCoopCoep)); + EXPECT_EQ(RemoteType::Parse("webServiceWorker=https://example.com"_ns), + RemoteType::SharedWeb({}).WithSiteOrigin( + "https://example.com"_ns, RemoteType::Kind::WebServiceWorker)); +} + +TEST(RemoteTypeTest, ParseInvalid) +{ + constexpr nsLiteralCString kRemoteTypes[] = { + ""_ns, + "unknown"_ns, + "parent"_ns, + "web=^unknown=1"_ns, + "web=^disableJit=0"_ns, + "web=^disableJit=true"_ns, + "web=^userContextId=abc"_ns, + "web=^userContextId=1&userContextId=2"_ns, + "web=^privateBrowsingId=1&userContextId=2"_ns, + "web=https://example.com"_ns, + "web=^"_ns, + "webIsolated=https://example.com^"_ns, + "webIsolated=https://example.com/"_ns, + "webIsolated=https://user@example.com"_ns, + "webIsolated="_ns, + "webCOOP+COEP"_ns, + "webServiceWorker"_ns, + "file=^userContextId=1"_ns, + "privilegedabout=https://example.com"_ns, + "privilegedabout=^userContextId=1"_ns, + }; + + for (const auto& string : kRemoteTypes) { + EXPECT_FALSE(RemoteType::Parse(string)) << string; + } +} + +} // namespace mozilla::dom diff --git a/dom/ipc/gtest/moz.build b/dom/ipc/gtest/moz.build index 321241cd87c7..da147bc747b8 100644 --- a/dom/ipc/gtest/moz.build +++ b/dom/ipc/gtest/moz.build @@ -5,6 +5,7 @@ UNIFIED_SOURCES += [ "JSIPCValueTest.cpp", "ProcessIsolationTest.cpp", + "RemoteTypeTest.cpp", ] include("/ipc/chromium/chromium-config.mozbuild") diff --git a/dom/ipc/jsactor/JSActorManager.h b/dom/ipc/jsactor/JSActorManager.h index 18dd9477c79b..3bac8f5a3a87 100644 --- a/dom/ipc/jsactor/JSActorManager.h +++ b/dom/ipc/jsactor/JSActorManager.h @@ -8,6 +8,7 @@ #include "js/TypeDecls.h" #include "mozilla/dom/JSActor.h" #include "mozilla/dom/JSIPCValue.h" +#include "mozilla/dom/RemoteType.h" #include "nsRefPtrHashtable.h" #include "nsString.h" @@ -45,7 +46,7 @@ class JSActorManager : public nsISupports { void ReceiveRawMessage(const JSActorMessageMeta& aMetadata, JSIPCValue&& aData, ipc::StructuredCloneData* aStack); - virtual const nsACString& GetRemoteType() const = 0; + virtual const RemoteType& GetRemoteType() const = 0; protected: /** diff --git a/dom/ipc/jsactor/JSActorService.cpp b/dom/ipc/jsactor/JSActorService.cpp index 6068090bfd78..30a94d51d848 100644 --- a/dom/ipc/jsactor/JSActorService.cpp +++ b/dom/ipc/jsactor/JSActorService.cpp @@ -359,41 +359,26 @@ JSActorService::GetJSWindowActorProtocol(const nsACString& aName) { return mWindowActorDescriptors.Get(aName); } -static nsDependentCSubstring RemoteTypePrefixForMatch( - const nsACString& aRemoteType) { - nsDependentCSubstring remoteTypePrefix(RemoteTypePrefix(aRemoteType)); - // The actual remote type for the parent process is the empty string, so - // change it to something we can actually match. - MOZ_ASSERT(!StringBeginsWith(remoteTypePrefix, "parent"_ns)); - if (aRemoteType == NOT_REMOTE_TYPE) { - remoteTypePrefix.AssignLiteral("parent"); - } - return remoteTypePrefix; -} - -void JSActorProtocol::LogMatch(const nsACString& aRemoteType) { +void JSActorProtocol::LogMatch(const RemoteType& aRemoteType) { if (!MOZ_LOG_TEST(gJSActorServiceLog, LogLevel::Info)) { return; } - nsDependentCSubstring remoteTypePrefix(RemoteTypePrefixForMatch(aRemoteType)); - if (mLoggedRemoteTypes.Contains(remoteTypePrefix)) { + nsCString remoteTypeKind(aRemoteType.StringifyKind()); + if (mLoggedRemoteTypes.Contains(remoteTypeKind)) { return; } - mLoggedRemoteTypes.AppendElement(remoteTypePrefix); + mLoggedRemoteTypes.AppendElement(remoteTypeKind); MOZ_LOG_FMT(gJSActorServiceLog, LogLevel::Info, "JSActor '{}' matched remoteType '{}'", mName.get(), - PromiseFlatCString(remoteTypePrefix).get()); + remoteTypeKind.get()); } -bool JSActorProtocol::RemoteTypePrefixMatches(const nsACString& aRemoteType) { - nsDependentCSubstring remoteTypePrefix(RemoteTypePrefixForMatch(aRemoteType)); - +bool JSActorProtocol::RemoteTypeMatches(const RemoteType& aRemoteType) { if (StaticPrefs::dom_jsipc_check_safeForUntrustedWebProcess() && !mSafeForUntrustedWebProcess && - (StringBeginsWith(remoteTypePrefix, "web"_ns) || - StringBeginsWith(remoteTypePrefix, "file"_ns))) { + (aRemoteType.IsWeb() || aRemoteType.IsFile())) { return false; } @@ -401,9 +386,12 @@ bool JSActorProtocol::RemoteTypePrefixMatches(const nsACString& aRemoteType) { return true; } + // TODO: Consider using a more advanced matcher which is aware of the + // structure of RemoteType. See bug 2006165. + nsCString remoteTypeKind(aRemoteType.StringifyKind()); + for (auto& remoteType : mRemoteTypes) { - // TODO: Maybe this should use glob-style matching instead. See bug 2006165. - if (StringBeginsWith(remoteTypePrefix, remoteType)) { + if (StringBeginsWith(remoteTypeKind, remoteType)) { return true; } } diff --git a/dom/ipc/jsactor/JSActorService.h b/dom/ipc/jsactor/JSActorService.h index eec09dbdb63f..bb4b63e4e079 100644 --- a/dom/ipc/jsactor/JSActorService.h +++ b/dom/ipc/jsactor/JSActorService.h @@ -105,8 +105,8 @@ class JSActorProtocol : public nsISupports { protected: explicit JSActorProtocol(const nsACString& aName) : mName(aName) {} - void LogMatch(const nsACString& aRemoteType); - bool RemoteTypePrefixMatches(const nsACString& aRemoteType); + void LogMatch(const RemoteType& aRemoteType); + bool RemoteTypeMatches(const RemoteType& aRemoteType); nsCString mName; nsTArray mRemoteTypes; diff --git a/dom/ipc/jsactor/JSProcessActorProtocol.cpp b/dom/ipc/jsactor/JSProcessActorProtocol.cpp index 08679cf7080a..c8cb60495ac2 100644 --- a/dom/ipc/jsactor/JSProcessActorProtocol.cpp +++ b/dom/ipc/jsactor/JSProcessActorProtocol.cpp @@ -114,18 +114,18 @@ void JSProcessActorProtocol::RemoveObservers() { } } -bool JSProcessActorProtocol::Matches(const nsACString& aRemoteType, +bool JSProcessActorProtocol::Matches(const RemoteType& aRemoteType, ErrorResult& aRv) { - if (!mIncludeParent && aRemoteType.IsEmpty()) { + if (!mIncludeParent && aRemoteType.IsNotRemote()) { aRv.ThrowNotSupportedError(nsPrintfCString( "Process protocol '%s' doesn't match the parent process", mName.get())); return false; } - if (!RemoteTypePrefixMatches(aRemoteType)) { + if (!RemoteTypeMatches(aRemoteType)) { aRv.ThrowNotSupportedError(nsPrintfCString( "Process protocol '%s' doesn't support remote type '%s'", mName.get(), - PromiseFlatCString(aRemoteType).get())); + aRemoteType.Stringify().get())); return false; } diff --git a/dom/ipc/jsactor/JSProcessActorProtocol.h b/dom/ipc/jsactor/JSProcessActorProtocol.h index 9f1eb630a030..907ced906042 100644 --- a/dom/ipc/jsactor/JSProcessActorProtocol.h +++ b/dom/ipc/jsactor/JSProcessActorProtocol.h @@ -53,7 +53,7 @@ class JSProcessActorProtocol final : public JSActorProtocol, void AddObservers(); void RemoveObservers(); - bool Matches(const nsACString& aRemoteType, ErrorResult& aRv); + bool Matches(const RemoteType& aRemoteType, ErrorResult& aRv); private: explicit JSProcessActorProtocol(const nsACString& aName) diff --git a/dom/ipc/jsactor/JSWindowActorProtocol.cpp b/dom/ipc/jsactor/JSWindowActorProtocol.cpp index e64be334ea88..c672047f1a24 100644 --- a/dom/ipc/jsactor/JSWindowActorProtocol.cpp +++ b/dom/ipc/jsactor/JSWindowActorProtocol.cpp @@ -318,7 +318,7 @@ bool JSWindowActorProtocol::MessageManagerGroupMatches( } bool JSWindowActorProtocol::Matches(BrowsingContext* aBrowsingContext, - nsIURI* aURI, const nsACString& aRemoteType, + nsIURI* aURI, const RemoteType& aRemoteType, ErrorResult& aRv) { MOZ_ASSERT(aBrowsingContext, "DocShell without a BrowsingContext!"); MOZ_ASSERT(aURI, "Must have URI!"); @@ -336,10 +336,10 @@ bool JSWindowActorProtocol::Matches(BrowsingContext* aBrowsingContext, return false; } - if (!RemoteTypePrefixMatches(aRemoteType)) { + if (!RemoteTypeMatches(aRemoteType)) { aRv.ThrowNotSupportedError( nsPrintfCString("Window protocol '%s' doesn't match remote type '%s'", - mName.get(), PromiseFlatCString(aRemoteType).get())); + mName.get(), aRemoteType.Stringify().get())); return false; } diff --git a/dom/ipc/jsactor/JSWindowActorProtocol.h b/dom/ipc/jsactor/JSWindowActorProtocol.h index c233242f8e61..6e8df9bc4d93 100644 --- a/dom/ipc/jsactor/JSWindowActorProtocol.h +++ b/dom/ipc/jsactor/JSWindowActorProtocol.h @@ -71,7 +71,7 @@ class JSWindowActorProtocol final : public JSActorProtocol, void AddObservers(); void RemoveObservers(); bool Matches(BrowsingContext* aBrowsingContext, nsIURI* aURI, - const nsACString& aRemoteType, ErrorResult& aRv); + const RemoteType& aRemoteType, ErrorResult& aRv); private: explicit JSWindowActorProtocol(const nsACString& aName) diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index c149627f819e..58c9e15a4b66 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -157,6 +157,7 @@ UNIFIED_SOURCES += [ "ReferrerInfoUtils.cpp", "RefMessageBodyService.cpp", "RemoteBrowser.cpp", + "RemoteType.cpp", "RemoteWebProgressRequest.cpp", "SharedMap.cpp", "SharedMessageBody.cpp", diff --git a/dom/ipc/tests/test_headless_content_process.js b/dom/ipc/tests/test_headless_content_process.js index 28d9f60be370..fedf792cd67b 100644 --- a/dom/ipc/tests/test_headless_content_process.js +++ b/dom/ipc/tests/test_headless_content_process.js @@ -1,6 +1,6 @@ "use strict"; -const TEST_REMOTE_TYPE = "test"; +const TEST_REMOTE_TYPE = "inference"; function allTestProcs() { return ChromeUtils.getAllDOMProcesses().filter( diff --git a/dom/media/gmp/GMPProcessParent.cpp b/dom/media/gmp/GMPProcessParent.cpp index 62505b9e16a4..a90181e3e6d8 100644 --- a/dom/media/gmp/GMPProcessParent.cpp +++ b/dom/media/gmp/GMPProcessParent.cpp @@ -90,7 +90,7 @@ bool GMPProcessParent::Launch(int32_t aTimeoutMs) { auto prefSerializer = MakeUnique(); bool success = prefSerializer->SerializeToSharedMemory(GeckoProcessType_GMPlugin, - /* remoteType */ ""_ns); + /* remoteType */ {}); MonitorAutoLock lock(mMonitor); MOZ_ASSERT(!mComplete); diff --git a/dom/media/gmp/GMPServiceParent.cpp b/dom/media/gmp/GMPServiceParent.cpp index d24fa8a33062..c4f6c5d71173 100644 --- a/dom/media/gmp/GMPServiceParent.cpp +++ b/dom/media/gmp/GMPServiceParent.cpp @@ -365,7 +365,7 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject, mozilla::dom::Pref pref(strData, /* isLocked */ false, /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_GMPlugin, - /* remoteType */ ""_ns); + /* remoteType */ {}); return GMPDispatch(NewRunnableMethod( "gmp::GeckoMediaPluginServiceParent::OnPreferenceChanged", this, &GeckoMediaPluginServiceParent::OnPreferenceChanged, diff --git a/dom/media/ipc/RDDProcessHost.cpp b/dom/media/ipc/RDDProcessHost.cpp index 93ffedfc5dee..292d8f136ce2 100644 --- a/dom/media/ipc/RDDProcessHost.cpp +++ b/dom/media/ipc/RDDProcessHost.cpp @@ -46,7 +46,7 @@ bool RDDProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) { mPrefSerializer = MakeUnique(); if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_RDD, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { return false; } mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts); diff --git a/dom/media/ipc/RDDProcessManager.cpp b/dom/media/ipc/RDDProcessManager.cpp index 8b5a85e7987f..c1bc89d03320 100644 --- a/dom/media/ipc/RDDProcessManager.cpp +++ b/dom/media/ipc/RDDProcessManager.cpp @@ -104,7 +104,7 @@ void RDDProcessManager::OnPreferenceChange(const char16_t* aData) { /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_RDD, - /* remoteType */ ""_ns); + /* remoteType */ {}); if (!!mRDDChild) { MOZ_ASSERT(mQueuedPrefs.IsEmpty()); mRDDChild->SendPreferenceUpdate(pref); diff --git a/dom/media/webrtc/transport/ipc/WebrtcTCPSocket.cpp b/dom/media/webrtc/transport/ipc/WebrtcTCPSocket.cpp index 3dda7ca38aa4..28458bedcd1b 100644 --- a/dom/media/webrtc/transport/ipc/WebrtcTCPSocket.cpp +++ b/dom/media/webrtc/transport/ipc/WebrtcTCPSocket.cpp @@ -401,13 +401,14 @@ nsresult WebrtcTCPSocket::OpenWithHttpProxy() { nsCOMPtr 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. + // LoadInfoArgs. Pass in `RemoteType::NotRemote()` 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(mProxyConfig->loadInfoArgs(), - NOT_REMOTE_TYPE, getter_AddRefs(loadInfo)); + dom::RemoteType::NotRemote(), + getter_AddRefs(loadInfo)); if (NS_FAILED(rv)) { LOG("WebrtcTCPSocket {}: could not init load info\n", fmt::ptr(this)); return rv; diff --git a/dom/onnx/InferenceSession.cpp b/dom/onnx/InferenceSession.cpp index 8d8b7fc889c8..5087d5c4623f 100644 --- a/dom/onnx/InferenceSession.cpp +++ b/dom/onnx/InferenceSession.cpp @@ -240,8 +240,7 @@ bool InferenceSession::InInferenceProcess(JSContext*, JSObject*) { if (!ContentChild::GetSingleton()) { return false; } - return ContentChild::GetSingleton()->GetRemoteType().Equals( - INFERENCE_REMOTE_TYPE); + return ContentChild::GetSingleton()->GetRemoteType().IsInference(); } bool InferenceSession::IsAvailable(const GlobalObject&) { diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 42df7cce44c6..2464d8374286 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -690,7 +690,7 @@ static void DebugDoContentSecurityCheck(nsIChannel* aChannel, if (httpChannel || MOZ_LOG_TEST(sCSMLog, LogLevel::Verbose)) { MOZ_LOG(sCSMLog, LogLevel::Verbose, ("doContentSecurityCheck:\n")); - nsAutoCString remoteType; + RemoteType remoteType; if (XRE_IsParentProcess()) { nsCOMPtr parentChannel; NS_QueryNotificationCallbacks(aChannel, parentChannel); @@ -698,11 +698,10 @@ static void DebugDoContentSecurityCheck(nsIChannel* aChannel, parentChannel->GetRemoteType(remoteType); } } else { - remoteType.Assign( - mozilla::dom::ContentChild::GetSingleton()->GetRemoteType()); + remoteType = mozilla::dom::ContentChild::GetSingleton()->GetRemoteType(); } MOZ_LOG(sCSMLog, LogLevel::Verbose, - (" processType: \"%s\"\n", remoteType.get())); + (" processType: \"%s\"\n", remoteType.Stringify().get())); nsCOMPtr channelURI; nsAutoCString channelSpec; @@ -790,7 +789,7 @@ static void DebugDoContentSecurityCheck(nsIChannel* aChannel, /* static */ void nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads( - nsILoadInfo* aLoadInfo, nsIURI* aFinalURI, const nsACString& aRemoteType) { + nsILoadInfo* aLoadInfo, nsIURI* aFinalURI, const RemoteType& aRemoteType) { if (!StaticPrefs::dom_security_unexpected_system_load_telemetry_enabled()) { return; } @@ -845,9 +844,10 @@ void nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads( if (fileNameTypeAndDetails.second.isSome()) { loggedFileDetails.Assign(fileNameTypeAndDetails.second.value()); } - // sanitize remoteType because it may contain sensitive - // info, like URLs. e.g. `webIsolated=https://example.com` - nsAutoCString loggedRemoteType(dom::RemoteTypePrefix(aRemoteType)); + // We only include the kind part of the remote type, as the rest of the + // remote type may contain sensitive information like URLs. e.g. + // `webIsolated=https://example.com` + nsCString loggedRemoteType = aRemoteType.StringifyKind(); nsAutoCString loggedContentType(NS_CP_ContentTypeName(contentPolicyType)); MOZ_LOG(sUELLog, LogLevel::Debug, ("UnexpectedPrivilegedLoadTelemetry:\n")); @@ -995,7 +995,7 @@ nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext( // URI_IS_UI_RESOURCE, first remove layers of view-source:, if present. nsCOMPtr innerURI = NS_GetInnermostURI(finalURI); - nsAutoCString remoteType; + RemoteType remoteType; if (XRE_IsParentProcess()) { nsCOMPtr parentChannel; NS_QueryNotificationCallbacks(aChannel, parentChannel); @@ -1003,8 +1003,7 @@ nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext( parentChannel->GetRemoteType(remoteType); } } else { - remoteType.Assign( - mozilla::dom::ContentChild::GetSingleton()->GetRemoteType()); + remoteType = mozilla::dom::ContentChild::GetSingleton()->GetRemoteType(); } // GetInnerURI can return null for malformed nested URIs like moz-icon:trash @@ -1113,7 +1112,7 @@ nsresult nsContentSecurityManager::CheckAllowLoadInPrivilegedAboutContext( return NS_OK; } - nsAutoCString remoteType; + RemoteType remoteType; if (XRE_IsParentProcess()) { nsCOMPtr parentChannel; NS_QueryNotificationCallbacks(aChannel, parentChannel); @@ -1121,12 +1120,11 @@ nsresult nsContentSecurityManager::CheckAllowLoadInPrivilegedAboutContext( parentChannel->GetRemoteType(remoteType); } } else { - remoteType.Assign( - mozilla::dom::ContentChild::GetSingleton()->GetRemoteType()); + remoteType = mozilla::dom::ContentChild::GetSingleton()->GetRemoteType(); } // only perform check for privileged about process - if (!remoteType.Equals(PRIVILEGEDABOUT_REMOTE_TYPE)) { + if (!remoteType.IsPrivilegedAbout()) { return NS_OK; } @@ -1332,7 +1330,7 @@ static nsresult CheckAllowLoadByTriggeringRemoteType(nsIChannel* aChannel) { nsCOMPtr loadInfo = aChannel->LoadInfo(); - nsAutoCString triggeringRemoteType; + RemoteType triggeringRemoteType; nsresult rv = loadInfo->GetTriggeringRemoteType(triggeringRemoteType); NS_ENSURE_SUCCESS(rv, rv); @@ -1347,7 +1345,7 @@ static nsresult CheckAllowLoadByTriggeringRemoteType(nsIChannel* aChannel) { loadInfo->PrincipalToInherit()->GetOrigin(origin); MOZ_LOG(sUELLog, LogLevel::Warning, ("Unexpected PrincipalToInherit %s for remote %s", origin.get(), - triggeringRemoteType.get())); + triggeringRemoteType.Stringify().get())); } return NS_ERROR_CONTENT_BLOCKED; } @@ -1368,7 +1366,7 @@ static nsresult CheckAllowLoadByTriggeringRemoteType(nsIChannel* aChannel) { // For now, only restrict loads coming from web remote types. In the future we // may want to expand this a bit. - if (!StringBeginsWith(triggeringRemoteType, WEB_REMOTE_TYPE)) { + if (!triggeringRemoteType.IsWeb()) { return NS_OK; } @@ -1808,12 +1806,12 @@ nsresult nsContentSecurityManager::CheckForIncoherentResultPrincipal( return NS_ERROR_CONTENT_BLOCKED; } - nsAutoCString triggeringRemoteType; + RemoteType triggeringRemoteType; rv = loadInfo->GetTriggeringRemoteType(triggeringRemoteType); NS_ENSURE_SUCCESS(rv, rv); - if (triggeringRemoteType != NOT_REMOTE_TYPE && - triggeringRemoteType != EXTENSION_REMOTE_TYPE) { + if (!triggeringRemoteType.IsNotRemote() && + !triggeringRemoteType.IsExtension()) { MOZ_ASSERT_UNREACHABLE( "Generated addon background page in incorrect process"); return NS_ERROR_CONTENT_BLOCKED; diff --git a/dom/security/nsContentSecurityManager.h b/dom/security/nsContentSecurityManager.h index 854dca5fb0e5..d667890157d4 100644 --- a/dom/security/nsContentSecurityManager.h +++ b/dom/security/nsContentSecurityManager.h @@ -36,9 +36,9 @@ class nsContentSecurityManager : public nsIContentSecurityManager, static void ReportBlockedDataURI(nsIURI* aURI, nsILoadInfo* aLoadInfo, bool aIsRedirect = false); static bool AllowInsecureRedirectToDataURI(nsIChannel* aNewChannel); - static void MeasureUnexpectedPrivilegedLoads(nsILoadInfo* aLoadInfo, - nsIURI* aFinalURI, - const nsACString& aRemoteType); + static void MeasureUnexpectedPrivilegedLoads( + nsILoadInfo* aLoadInfo, nsIURI* aFinalURI, + const mozilla::dom::RemoteType& aRemoteType); enum CORSSecurityMapping { // Disables all CORS checking overriding the value of aCORSMode. All checks diff --git a/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp b/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp index db1b5197283e..a94353534c4f 100644 --- a/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp +++ b/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp @@ -80,7 +80,7 @@ TEST_F(TelemetryTestFixture, UnexpectedPrivilegedLoadsTelemetryTest) { // ..and test that we strip of URLs from remoteTypes "blob://000-000"_ns, nsContentPolicyType::TYPE_SCRIPT, - "webIsolated=https://blob.example/"_ns, + "webIsolated=https://blob.example"_ns, {"bloburi"_ns, "TYPE_SCRIPT"_ns, "webIsolated"_ns, "unknown"_ns, ""_ns}}, {// test for cases where finalURI is null, due to a broken nested URI // .. like malformed moz-icon URLs @@ -195,9 +195,12 @@ TEST_F(TelemetryTestFixture, UnexpectedPrivilegedLoadsTelemetryTest) { mockLoadInfo->AppendRedirectHistoryEntry(redirectChannel, false); } + auto remoteType = mozilla::dom::RemoteType::Parse(currentTest.remoteType); + ASSERT_TRUE(remoteType); + // this will record the event - nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads( - mockLoadInfo, uri, currentTest.remoteType); + nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads(mockLoadInfo, + uri, remoteType); // let's inspect the recorded Glean events auto optEvents = diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp index 63927bf28a58..7ca4c228ee3e 100644 --- a/dom/serviceworkers/ServiceWorkerPrivate.cpp +++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp @@ -729,7 +729,7 @@ nsresult ServiceWorkerPrivate::Initialize() { auto remoteType = RemoteWorkerManager::GetRemoteType( principal, WorkerKind::WorkerKindService, - SharedWebRemoteType(principal->OriginAttributesRef())); + RemoteType::SharedWeb(principal->OriginAttributesRef())); if (NS_WARN_IF(remoteType.isErr())) { return remoteType.unwrapErr(); } @@ -1816,8 +1816,7 @@ void ServiceWorkerPrivate::CreationFailed() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mControllerChild); - if (mRemoteWorkerData.remoteType().Find(SERVICEWORKER_REMOTE_TYPE) != - kNotFound) { + if (mRemoteWorkerData.remoteType().IsWebServiceWorker()) { glean::service_worker::isolated_launch_time.AccumulateRawDuration( TimeStamp::Now() - mServiceWorkerLaunchTimeStart); } else { @@ -1843,8 +1842,7 @@ void ServiceWorkerPrivate::CreationSucceeded() { return; } - if (mRemoteWorkerData.remoteType().Find(SERVICEWORKER_REMOTE_TYPE) != - kNotFound) { + if (mRemoteWorkerData.remoteType().IsWebServiceWorker()) { glean::service_worker::isolated_launch_time.AccumulateRawDuration( TimeStamp::Now() - mServiceWorkerLaunchTimeStart); } else { diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.cpp b/dom/workers/remoteworkers/RemoteWorkerManager.cpp index 67de2191e39b..c2ac93567466 100644 --- a/dom/workers/remoteworkers/RemoteWorkerManager.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerManager.cpp @@ -84,11 +84,11 @@ void TransmitPermissionsAndCookiesAndBlobURLsForPrincipalInfo( } // namespace // static -bool RemoteWorkerManager::MatchRemoteType(const nsACString& processRemoteType, - const nsACString& workerRemoteType) { +bool RemoteWorkerManager::MatchRemoteType(const RemoteType& processRemoteType, + const RemoteType& workerRemoteType) { LOG(("MatchRemoteType [processRemoteType=%s, workerRemoteType=%s]", - PromiseFlatCString(processRemoteType).get(), - PromiseFlatCString(workerRemoteType).get())); + processRemoteType.Stringify().get(), + workerRemoteType.Stringify().get())); // Respecting COOP and COEP requires processing headers in the parent // process in order to choose an appropriate content process, but the @@ -102,15 +102,15 @@ bool RemoteWorkerManager::MatchRemoteType(const nsACString& processRemoteType, // RemoteWorkerManager::GetRemoteType should not select this remoteType // and so workerRemoteType is not expected to be set to a coop+coep // remoteType and here we can just assert that it is not happening. - MOZ_ASSERT(!IsWebCoopCoepRemoteType(workerRemoteType)); + MOZ_ASSERT(!workerRemoteType.IsWebCoopCoep()); - return processRemoteType.Equals(workerRemoteType); + return processRemoteType == workerRemoteType; } // static -Result RemoteWorkerManager::GetRemoteType( +Result RemoteWorkerManager::GetRemoteType( const nsCOMPtr& aPrincipal, WorkerKind aWorkerKind, - const nsACString& aCurrentRemoteType) { + const RemoteType& aCurrentRemoteType) { AssertIsOnMainThread(); MOZ_ASSERT_IF(aWorkerKind == WorkerKind::WorkerKindService, @@ -120,7 +120,7 @@ Result RemoteWorkerManager::GetRemoteType( // to finish the load in the parent process. if (!BrowserTabsRemoteAutostart()) { LOG(("GetRemoteType: Loading in parent process as e10s is disabled")); - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } auto result = IsolationOptionsForWorker( @@ -139,8 +139,8 @@ Result RemoteWorkerManager::GetRemoteType( ("GetRemoteType workerType=%s, principal=%s, " "preferredRemoteType=%s, selectedRemoteType=%s", aWorkerKind == WorkerKind::WorkerKindService ? "service" : "shared", - principalOrigin.get(), PromiseFlatCString(aCurrentRemoteType).get(), - options.mRemoteType.get())); + principalOrigin.get(), aCurrentRemoteType.Stringify().get(), + options.mRemoteType.Stringify().get())); } return options.mRemoteType; @@ -326,7 +326,7 @@ void RemoteWorkerManager::AsyncCreationFailed( template void RemoteWorkerManager::ForEachActor( - Callback&& aCallback, const nsACString& aRemoteType, + Callback&& aCallback, const RemoteType& aRemoteType, Maybe aProcessId) const { AssertIsOnBackgroundThread(); @@ -431,7 +431,7 @@ RemoteWorkerManager::SelectTargetActor(const RemoteWorkerData& aData, // Extension principal workers are allowed to run on the parent process // when "extensions.webextensions.remote" pref is false. if (aProcessId == base::GetCurrentProcId() && - aData.remoteType().Equals(NOT_REMOTE_TYPE) && + aData.remoteType().IsNotRemote() && !StaticPrefs::extensions_webextensions_remote() && HasExtensionPrincipal(aData)) { MOZ_ASSERT(mParentActor); diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.h b/dom/workers/remoteworkers/RemoteWorkerManager.h index d61e120ab153..01fbe3c37b67 100644 --- a/dom/workers/remoteworkers/RemoteWorkerManager.h +++ b/dom/workers/remoteworkers/RemoteWorkerManager.h @@ -38,16 +38,16 @@ class RemoteWorkerManager final { void Launch(RemoteWorkerController* aController, const RemoteWorkerData& aData, base::ProcessId aProcessId); - static bool MatchRemoteType(const nsACString& processRemoteType, - const nsACString& workerRemoteType); + static bool MatchRemoteType(const RemoteType& processRemoteType, + const RemoteType& workerRemoteType); /** * Get the child process RemoteType where a RemoteWorker should be * launched. */ - static Result GetRemoteType( + static Result GetRemoteType( const nsCOMPtr& aPrincipal, WorkerKind aWorkerKind, - const nsACString& aCurrentRemoteType); + const RemoteType& aCurrentRemoteType); static bool HasExtensionPrincipal(const RemoteWorkerData& aData); @@ -93,7 +93,7 @@ class RemoteWorkerManager final { // doesn't need to worry about proxy-releasing the ContentParent if it isn't // moved out of the parameter. template - void ForEachActor(Callback&& aCallback, const nsACString& aRemoteType, + void ForEachActor(Callback&& aCallback, const RemoteType& aRemoteType, Maybe aProcessId = Nothing()) const; // The list of existing RemoteWorkerServiceParent actors for child processes. diff --git a/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp b/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp index 422671c34744..9ede7a2fd80f 100644 --- a/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp @@ -70,11 +70,11 @@ void RemoteWorkerServiceParent::ActorDestroy(IProtocol::ActorDestroyReason) { } } -nsCString RemoteWorkerServiceParent::GetRemoteType() const { +RemoteType RemoteWorkerServiceParent::GetRemoteType() const { if (mProcess) { return mProcess->GetRemoteType(); } - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } } // namespace dom diff --git a/dom/workers/remoteworkers/RemoteWorkerServiceParent.h b/dom/workers/remoteworkers/RemoteWorkerServiceParent.h index eecfb7dcadfe..7c0261e4355c 100644 --- a/dom/workers/remoteworkers/RemoteWorkerServiceParent.h +++ b/dom/workers/remoteworkers/RemoteWorkerServiceParent.h @@ -33,7 +33,7 @@ class RemoteWorkerServiceParent final : public PRemoteWorkerServiceParent { return mProcess; } - nsCString GetRemoteType() const; + RemoteType GetRemoteType() const; private: explicit RemoteWorkerServiceParent(ThreadsafeContentParentHandle* aProcess); diff --git a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh index f17323a39fc0..ababf915edff 100644 --- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh +++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh @@ -20,6 +20,7 @@ using mozilla::dom::WorkerOptions from "mozilla/dom/WorkerBinding.h"; using mozilla::StorageAccess from "mozilla/StorageAccess.h"; using mozilla::OriginTrials from "mozilla/OriginTrialsIPCUtils.h"; using mozilla::RFPTargetSet from "nsRFPService.h"; +using struct mozilla::dom::RemoteType from "mozilla/dom/RemoteType.h"; [RefCounted] using class nsIPrincipal from "nsIPrincipal.h"; @@ -99,7 +100,7 @@ struct RemoteWorkerData nsID agentClusterId; // Child process remote type where the worker should only run on. - nsCString remoteType; + RemoteType remoteType; nsCString languageOverrideLocale; nsString[] languageOverride; diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp index 18c047efea7e..764b90902b5a 100644 --- a/dom/workers/sharedworkers/SharedWorker.cpp +++ b/dom/workers/sharedworkers/SharedWorker.cpp @@ -274,8 +274,9 @@ already_AddRefed SharedWorker::Constructor( loadInfo.mIsOn3PCBExceptionList, OriginTrials::FromWindow(nsGlobalWindowInner::Cast(window)), void_t() /* OptionalServiceWorkerData */, agentClusterId, - DEFAULT_REMOTE_TYPE /* ignored */, loadInfo.mLanguageOverrideLocale, - loadInfo.mLanguageOverride.Clone(), loadInfo.mTimezoneOverride); + RemoteType(RemoteType::Kind::WebContent) /* ignored */, + loadInfo.mLanguageOverrideLocale, loadInfo.mLanguageOverride.Clone(), + loadInfo.mTimezoneOverride); PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor( remoteWorkerData, loadInfo.mWindowID, portIdentifier.release()); diff --git a/dom/workers/sharedworkers/SharedWorkerService.cpp b/dom/workers/sharedworkers/SharedWorkerService.cpp index 9e569c322bab..c5bf929691ab 100644 --- a/dom/workers/sharedworkers/SharedWorkerService.cpp +++ b/dom/workers/sharedworkers/SharedWorkerService.cpp @@ -236,7 +236,7 @@ void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread( // the ununsed remoteType field from the passed-in `RemoteWorkerData` with it. auto remoteType = RemoteWorkerManager::GetRemoteType( principal, WorkerKind::WorkerKindShared, - contentParent ? contentParent->GetRemoteType() : NOT_REMOTE_TYPE); + contentParent ? contentParent->GetRemoteType() : RemoteType::NotRemote()); if (NS_WARN_IF(remoteType.isErr())) { ErrorPropagationOnMainThread(aBackgroundEventTarget, aActor, remoteType.unwrapErr()); diff --git a/gfx/ipc/GPUProcessHost.cpp b/gfx/ipc/GPUProcessHost.cpp index e37ff4adb97b..e7f55a896c5e 100644 --- a/gfx/ipc/GPUProcessHost.cpp +++ b/gfx/ipc/GPUProcessHost.cpp @@ -60,7 +60,7 @@ bool GPUProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) { mPrefSerializer = MakeUnique(); if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_GPU, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { return false; } mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts); diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp index 84f5323fe8ed..f47c3c2753f5 100644 --- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -206,7 +206,7 @@ void GPUProcessManager::OnPreferenceChange(const char16_t* aData) { /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_GPU, - /* remoteType */ ""_ns); + /* remoteType */ {}); if (mGPUChild) { MOZ_ASSERT(mQueuedPrefs.IsEmpty()); mGPUChild->SendPreferenceUpdate(pref); diff --git a/gfx/vr/ipc/VRProcessManager.cpp b/gfx/vr/ipc/VRProcessManager.cpp index 7b1f5cb06c1d..a67ee5181de4 100644 --- a/gfx/vr/ipc/VRProcessManager.cpp +++ b/gfx/vr/ipc/VRProcessManager.cpp @@ -218,7 +218,7 @@ void VRProcessManager::OnPreferenceChange(const char16_t* aData) { /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_VR, - /* remoteType */ ""_ns); + /* remoteType */ {}); if (!!mVRChild) { MOZ_ASSERT(mQueuedPrefs.IsEmpty()); mVRChild->SendPreferenceUpdate(pref); diff --git a/gfx/vr/ipc/VRProcessParent.cpp b/gfx/vr/ipc/VRProcessParent.cpp index c8663fd09496..7d580506d783 100644 --- a/gfx/vr/ipc/VRProcessParent.cpp +++ b/gfx/vr/ipc/VRProcessParent.cpp @@ -52,7 +52,7 @@ bool VRProcessParent::Launch() { mPrefSerializer = MakeUnique(); if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_VR, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { return false; } mPrefSerializer->AddSharedPrefCmdLineArgs(*this, extraArgs); diff --git a/image/remote/RemoteImageProtocolHandler.cpp b/image/remote/RemoteImageProtocolHandler.cpp index 388c3396d9ec..66f95691cf4a 100644 --- a/image/remote/RemoteImageProtocolHandler.cpp +++ b/image/remote/RemoteImageProtocolHandler.cpp @@ -57,7 +57,7 @@ static UniqueContentParentKeepAlive GetLaunchingContentParentForDecode( // We use the extension process as a fallback, because // it is usually running, and should be OK to parse images. return ContentParent::GetNewOrUsedLaunchingBrowserProcess( - EXTENSION_REMOTE_TYPE, + dom::RemoteType(dom::RemoteType::Kind::Extension), /* aGroup */ nullptr, /* aPriority */ hal::PROCESS_PRIORITY_FOREGROUND, /* aPreferUsed */ true); diff --git a/ipc/glue/BackgroundImpl.cpp b/ipc/glue/BackgroundImpl.cpp index e763b2f72913..b3c0f9b2296d 100644 --- a/ipc/glue/BackgroundImpl.cpp +++ b/ipc/glue/BackgroundImpl.cpp @@ -677,10 +677,12 @@ uint64_t BackgroundParent::GetChildID(PBackgroundParent* aBackgroundActor) { } // static -nsCString BackgroundParent::GetRemoteType(PBackgroundParent* aBackgroundActor) { +mozilla::dom::RemoteType BackgroundParent::GetRemoteType( + PBackgroundParent* aBackgroundActor) { ThreadsafeContentParentHandle* handle = GetContentParentHandle(aBackgroundActor); - return handle ? handle->GetRemoteType() : NOT_REMOTE_TYPE; + return handle ? handle->GetRemoteType() + : mozilla::dom::RemoteType::NotRemote(); } // static diff --git a/ipc/glue/BackgroundParent.h b/ipc/glue/BackgroundParent.h index 286f7c081741..278dbd9c0f9f 100644 --- a/ipc/glue/BackgroundParent.h +++ b/ipc/glue/BackgroundParent.h @@ -87,7 +87,8 @@ class BackgroundParent final { static uint64_t GetChildID(PBackgroundParent* aBackgroundActor); - static nsCString GetRemoteType(PBackgroundParent* aBackgroundActor); + static mozilla::dom::RemoteType GetRemoteType( + PBackgroundParent* aBackgroundActor); // Whenever receiving a Principal we need to validate that Principal case // by case. The options can customize the behaviour of the checks. diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp index 4ad06e1ac4a1..baeb634e9f5e 100644 --- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -487,7 +487,7 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateFileSystemManagerParent( // The inference process uses ChromeWorkers which have a system principal, // so system principals must be allowed there. EnumSet options; - if (BackgroundParent::GetRemoteType(this) == INFERENCE_REMOTE_TYPE) { + if (BackgroundParent::GetRemoteType(this).IsInference()) { options += dom::ValidatePrincipalOptions::AllowSystemIfLoaded; } if (!BackgroundParent::ValidatePrincipalInfo(this, aPrincipalInfo, options)) { @@ -660,7 +660,7 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvPFileCreatorConstructor( if (!parent) { isFileRemoteType = true; } else { - isFileRemoteType = parent->GetRemoteType() == FILE_REMOTE_TYPE; + isFileRemoteType = parent->GetRemoteType().IsFile(); } dom::FileCreatorParent* actor = diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index f33564f23062..2251dad0e111 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -439,7 +439,7 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, SerializeURI(resultPrincipalURI, optionalResultPrincipalURI); } - nsCString triggeringRemoteType; + RemoteType triggeringRemoteType; rv = aLoadInfo->GetTriggeringRemoteType(triggeringRemoteType); NS_ENSURE_SUCCESS(rv, rv); @@ -618,13 +618,13 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, } nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, + const RemoteType& aOriginRemoteType, nsILoadInfo** outLoadInfo) { return LoadInfoArgsToLoadInfo(aLoadInfoArgs, aOriginRemoteType, nullptr, outLoadInfo); } nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, + const RemoteType& aOriginRemoteType, nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo) { RefPtr loadInfo; @@ -638,13 +638,13 @@ nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& aLoadInfoArgs, } nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, + const RemoteType& aOriginRemoteType, LoadInfo** outLoadInfo) { return LoadInfoArgsToLoadInfo(aLoadInfoArgs, aOriginRemoteType, nullptr, outLoadInfo); } nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& loadInfoArgs, - const nsACString& aOriginRemoteType, + const RemoteType& aOriginRemoteType, nsINode* aCspToInheritLoadingContext, LoadInfo** outLoadInfo) { nsCOMPtr loadingPrincipal; @@ -725,8 +725,8 @@ nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& loadInfoArgs, // 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 && + RemoteType triggeringRemoteType = loadInfoArgs.triggeringRemoteType(); + if (!aOriginRemoteType.IsNotRemote() && aOriginRemoteType != triggeringRemoteType) { triggeringRemoteType = aOriginRemoteType; } diff --git a/ipc/glue/BackgroundUtils.h b/ipc/glue/BackgroundUtils.h index 02c4d8291612..50559ba1d10f 100644 --- a/ipc/glue/BackgroundUtils.h +++ b/ipc/glue/BackgroundUtils.h @@ -138,20 +138,22 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, /** * Convert LoadInfoArgs to a LoadInfo. */ -nsresult LoadInfoArgsToLoadInfo(const mozilla::net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, - nsILoadInfo** outLoadInfo); -nsresult LoadInfoArgsToLoadInfo(const mozilla::net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, - nsINode* aCspToInheritLoadingContext, - nsILoadInfo** outLoadInfo); -nsresult LoadInfoArgsToLoadInfo(const net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, - mozilla::net::LoadInfo** outLoadInfo); -nsresult LoadInfoArgsToLoadInfo(const net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, - nsINode* aCspToInheritLoadingContext, - mozilla::net::LoadInfo** outLoadInfo); +nsresult LoadInfoArgsToLoadInfo( + const mozilla::net::LoadInfoArgs& aLoadInfoArgs, + const mozilla::dom::RemoteType& aOriginRemoteType, + nsILoadInfo** outLoadInfo); +nsresult LoadInfoArgsToLoadInfo( + const mozilla::net::LoadInfoArgs& aLoadInfoArgs, + const mozilla::dom::RemoteType& aOriginRemoteType, + nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo); +nsresult LoadInfoArgsToLoadInfo( + const net::LoadInfoArgs& aLoadInfoArgs, + const mozilla::dom::RemoteType& aOriginRemoteType, + mozilla::net::LoadInfo** outLoadInfo); +nsresult LoadInfoArgsToLoadInfo( + const net::LoadInfoArgs& aLoadInfoArgs, + const mozilla::dom::RemoteType& aOriginRemoteType, + nsINode* aCspToInheritLoadingContext, mozilla::net::LoadInfo** outLoadInfo); /** * Fills ParentLoadInfoForwarderArgs with properties we want to carry to child diff --git a/ipc/glue/ProcessUtils.h b/ipc/glue/ProcessUtils.h index 6eca8be3faeb..fe2a08547114 100644 --- a/ipc/glue/ProcessUtils.h +++ b/ipc/glue/ProcessUtils.h @@ -6,6 +6,7 @@ #define mozilla_ipc_ProcessUtils_h #include "mozilla/GeckoArgs.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/ipc/FileDescriptor.h" #include "mozilla/ipc/SharedMemoryHandle.h" #include "mozilla/ipc/SharedMemoryMapping.h" @@ -27,8 +28,9 @@ class SharedPreferenceSerializer final { SharedPreferenceSerializer(SharedPreferenceSerializer&& aOther); ~SharedPreferenceSerializer(); - bool SerializeToSharedMemory(const GeckoProcessType aDestinationProcessType, - const nsACString& aDestinationRemoteType); + bool SerializeToSharedMemory( + const GeckoProcessType aDestinationProcessType, + const mozilla::dom::RemoteType& aDestinationRemoteType); const ReadOnlySharedMemoryHandle& GetPrefsHandle() const { return mPrefsHandle; diff --git a/ipc/glue/ProcessUtils_common.cpp b/ipc/glue/ProcessUtils_common.cpp index e7f52a8d742b..1a87ab12dbf2 100644 --- a/ipc/glue/ProcessUtils_common.cpp +++ b/ipc/glue/ProcessUtils_common.cpp @@ -32,13 +32,12 @@ SharedPreferenceSerializer::SharedPreferenceSerializer( bool SharedPreferenceSerializer::SerializeToSharedMemory( const GeckoProcessType aDestinationProcessType, - const nsACString& aDestinationRemoteType) { + const mozilla::dom::RemoteType& aDestinationRemoteType) { mPrefMapHandle = Preferences::EnsureSnapshot(); bool destIsWebContent = aDestinationProcessType == GeckoProcessType_Content && - (StringBeginsWith(aDestinationRemoteType, WEB_REMOTE_TYPE) || - StringBeginsWith(aDestinationRemoteType, PREALLOC_REMOTE_TYPE)); + (aDestinationRemoteType.IsWeb() || aDestinationRemoteType.IsPrealloc()); // Serialize the early prefs. nsAutoCStringN<1024> prefs; diff --git a/ipc/glue/UtilityProcessHost.cpp b/ipc/glue/UtilityProcessHost.cpp index 16386a9fb5d8..f4b340a832de 100644 --- a/ipc/glue/UtilityProcessHost.cpp +++ b/ipc/glue/UtilityProcessHost.cpp @@ -92,7 +92,7 @@ bool UtilityProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) { mPrefSerializer = MakeUnique(); if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_Utility, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { return false; } mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts); diff --git a/ipc/glue/UtilityProcessManager.cpp b/ipc/glue/UtilityProcessManager.cpp index fc608e33dc96..e80799adc1ca 100644 --- a/ipc/glue/UtilityProcessManager.cpp +++ b/ipc/glue/UtilityProcessManager.cpp @@ -122,7 +122,7 @@ void UtilityProcessManager::OnPreferenceChange(const char16_t* aData) { mozilla::dom::Pref pref(strData, /* isLocked */ false, /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_Utility, - /* remoteType */ ""_ns); + /* remoteType */ {}); for (auto& p : mProcesses) { if (!p) { diff --git a/ipc/ipdl/test/gtest/IPDLUnitTest.cpp b/ipc/ipdl/test/gtest/IPDLUnitTest.cpp index 7f50215cc13a..8de1e8a28ae9 100644 --- a/ipc/ipdl/test/gtest/IPDLUnitTest.cpp +++ b/ipc/ipdl/test/gtest/IPDLUnitTest.cpp @@ -46,7 +46,7 @@ already_AddRefed IPDLUnitTestParent::CreateCrossProcess() { auto prefSerializer = MakeUnique(); if (!prefSerializer->SerializeToSharedMemory(GeckoProcessType_IPDLUnitTest, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { ADD_FAILURE() << "SharedPreferenceSerializer::SerializeToSharedMemory failed"; return nullptr; diff --git a/js/xpconnect/loader/ScriptPreloader.cpp b/js/xpconnect/loader/ScriptPreloader.cpp index 8aec5b88c7f3..1c779e72d157 100644 --- a/js/xpconnect/loader/ScriptPreloader.cpp +++ b/js/xpconnect/loader/ScriptPreloader.cpp @@ -235,11 +235,12 @@ void ScriptPreloader::InitContentChild(ContentParent& parent) { } } -ProcessType ScriptPreloader::GetChildProcessType(const nsACString& remoteType) { - if (remoteType == EXTENSION_REMOTE_TYPE) { +ProcessType ScriptPreloader::GetChildProcessType( + const dom::RemoteType& remoteType) { + if (remoteType.IsExtension()) { return ProcessType::Extension; } - if (remoteType == PRIVILEGEDABOUT_REMOTE_TYPE) { + if (remoteType.IsPrivilegedAbout()) { return ProcessType::PrivilegedAbout; } return ProcessType::Web; diff --git a/js/xpconnect/loader/ScriptPreloader.h b/js/xpconnect/loader/ScriptPreloader.h index 034666277f23..c9da15647761 100644 --- a/js/xpconnect/loader/ScriptPreloader.h +++ b/js/xpconnect/loader/ScriptPreloader.h @@ -42,7 +42,8 @@ namespace mozilla { namespace dom { class ContentParent; -} +struct RemoteType; +} // namespace dom namespace ipc { class FileDescriptor; } @@ -98,7 +99,7 @@ class ScriptPreloader : public nsIObserver, static void DeleteSingleton(); static void DeleteCacheDataSingleton(); - static ProcessType GetChildProcessType(const nsACString& remoteType); + static ProcessType GetChildProcessType(const dom::RemoteType& remoteType); // Fill some options that should be consistent across all scripts stored // into preloader cache. diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index f78806ec1f88..7d800a57e6f3 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -1069,7 +1069,7 @@ void PresShell::Destroy() { return false; } if (XRE_IsContentProcess() && - IsExtensionRemoteType(ContentChild::GetSingleton()->GetRemoteType())) { + ContentChild::GetSingleton()->GetRemoteType().IsExtension()) { // Also omit presShells from the extension process because they sometimes // can't be zoomed by the user. return false; diff --git a/mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp b/mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp index b6a30d4f3c23..dff674ded417 100644 --- a/mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp +++ b/mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp @@ -60,7 +60,7 @@ GeckoViewContentChannelParent::Delete() { } NS_IMETHODIMP -GeckoViewContentChannelParent::GetRemoteType(nsACString& aRemoteType) { +GeckoViewContentChannelParent::GetRemoteType(dom::RemoteType& aRemoteType) { if (!CanSend()) { return NS_ERROR_UNEXPECTED; } @@ -164,7 +164,7 @@ bool GeckoViewContentChannelParent::Init( return false; } - nsAutoCString remoteType; + dom::RemoteType remoteType; rv = GetRemoteType(remoteType); if (MOZ_UNLIKELY(NS_FAILED(rv))) { return false; diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 09c9ef5f008d..cf7596ff78c4 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -5257,13 +5257,12 @@ void Preferences::SetPreference(const dom::Pref& aDomPref) { /* static */ void Preferences::GetPreference(dom::Pref* aDomPref, const GeckoProcessType aDestinationProcessType, - const nsACString& aDestinationRemoteType) { + const dom::RemoteType& aDestinationRemoteType) { MOZ_ASSERT(XRE_IsParentProcess()); bool destIsWebContent = aDestinationProcessType == GeckoProcessType_Content && - (StringBeginsWith(aDestinationRemoteType, WEB_REMOTE_TYPE) || - StringBeginsWith(aDestinationRemoteType, PREALLOC_REMOTE_TYPE) || - StringBeginsWith(aDestinationRemoteType, PRIVILEGEDMOZILLA_REMOTE_TYPE)); + (aDestinationRemoteType.IsWeb() || aDestinationRemoteType.IsPrealloc() || + aDestinationRemoteType.IsPrivilegedMozilla()); Pref* pref = pref_HashTableLookup(aDomPref->name().get()); if (pref && pref->HasAdvisablySizedValues()) { diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index bb0f9494a5f1..188bea22c42f 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -15,6 +15,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/MozPromise.h" #include "mozilla/StaticPtr.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/ipc/SharedMemoryHandle.h" #include "nsCOMPtr.h" #include "nsIObserver.h" @@ -436,7 +437,7 @@ class Preferences final : public nsIPrefService, // used to pass the update to content processes. static void GetPreference(dom::Pref* aPref, const GeckoProcessType aDestinationProcessType, - const nsACString& aDestinationRemoteType); + const dom::RemoteType& aDestinationRemoteType); static void SetPreference(const dom::Pref& aPref); #ifdef DEBUG diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 18d89d2e1dc3..8296f069eac2 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -57,12 +57,12 @@ using namespace mozilla::dom; namespace mozilla::net { -static nsCString CurrentRemoteType() { +static const RemoteType& CurrentRemoteType() { MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsContentProcess()); if (ContentChild* cc = ContentChild::GetSingleton()) { - return nsCString(cc->GetRemoteType()); + return cc->GetRemoteType(); } - return NOT_REMOTE_TYPE; + return RemoteType::NotRemote(); } static nsContentPolicyType InternalContentPolicyTypeForFrame( @@ -141,7 +141,7 @@ bool LoadInfo::IsDocumentMissingClientInfo() { /* static */ already_AddRefed LoadInfo::CreateForDocument( dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI, - nsIPrincipal* aTriggeringPrincipal, const nsACString& aTriggeringRemoteType, + nsIPrincipal* aTriggeringPrincipal, const RemoteType& aTriggeringRemoteType, const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) { return MakeAndAddRef(aBrowsingContext, aURI, aTriggeringPrincipal, @@ -151,7 +151,7 @@ bool LoadInfo::IsDocumentMissingClientInfo() { /* static */ already_AddRefed LoadInfo::CreateForFrame( dom::CanonicalBrowsingContext* aBrowsingContext, - nsIPrincipal* aTriggeringPrincipal, const nsACString& aTriggeringRemoteType, + nsIPrincipal* aTriggeringPrincipal, const RemoteType& aTriggeringRemoteType, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) { return MakeAndAddRef(aBrowsingContext, aTriggeringPrincipal, aTriggeringRemoteType, aSecurityFlags, @@ -469,7 +469,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIURI* aURI, LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const RemoteType& aTriggeringRemoteType, const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) : mTriggeringPrincipal(aTriggeringPrincipal), @@ -564,7 +564,7 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const RemoteType& aTriggeringRemoteType, nsContentPolicyType aContentPolicyType, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) : mTriggeringPrincipal(aTriggeringPrincipal), @@ -693,7 +693,7 @@ LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP, // Used for TYPE_FRAME or TYPE_IFRAME load. LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const RemoteType& aTriggeringRemoteType, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) : LoadInfo(aBrowsingContext->GetParentWindowContext(), aTriggeringPrincipal, aTriggeringRemoteType, @@ -763,7 +763,7 @@ LoadInfo::LoadInfo( nsIURI* aResultPrincipalURI, nsICookieJarSettings* aCookieJarSettings, nsIPolicyContainer* aPolicyContainerToInherit, const Maybe& aContainerFeaturePolicyInfo, - const nsACString& aTriggeringRemoteType, + const RemoteType& aTriggeringRemoteType, const nsID& aSandboxedNullPrincipalID, const Maybe& aClientInfo, const Maybe& aReservedClientInfo, const Maybe& aInitialClientInfo, @@ -986,13 +986,19 @@ void LoadInfo::ResetSandboxedNullPrincipalID() { nsIPrincipal* LoadInfo::GetTopLevelPrincipal() { return mTopLevelPrincipal; } NS_IMETHODIMP -LoadInfo::GetTriggeringRemoteType(nsACString& aTriggeringRemoteType) { +LoadInfo::GetXPCOMTriggeringRemoteType(nsACString& aTriggeringRemoteType) { + aTriggeringRemoteType = mTriggeringRemoteType.Stringify(); + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetTriggeringRemoteType(RemoteType& aTriggeringRemoteType) { aTriggeringRemoteType = mTriggeringRemoteType; return NS_OK; } NS_IMETHODIMP -LoadInfo::SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType) { +LoadInfo::SetTriggeringRemoteType(const RemoteType& aTriggeringRemoteType) { mTriggeringRemoteType = aTriggeringRemoteType; return NS_OK; } diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 9e48f631d80c..7d4eb0f8ef0c 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -46,7 +46,7 @@ class WebTransportSessionProxy; namespace ipc { // we have to forward declare that function so we can use it as a friend. nsresult LoadInfoArgsToLoadInfo(const mozilla::net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, + const dom::RemoteType& aOriginRemoteType, nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo); @@ -255,7 +255,7 @@ class LoadInfo final : public nsILoadInfo { static already_AddRefed CreateForDocument( dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const dom::RemoteType& aTriggeringRemoteType, const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags); @@ -263,8 +263,8 @@ class LoadInfo final : public nsILoadInfo { static already_AddRefed CreateForFrame( dom::CanonicalBrowsingContext* aBrowsingContext, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, nsSecurityFlags aSecurityFlags, - uint32_t aSandboxFlags); + const dom::RemoteType& aTriggeringRemoteType, + nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags); // Use for non-{TYPE_DOCUMENT|TYPE_FRAME|TYPE_IFRAME} load. static already_AddRefed CreateForNonDocument( @@ -294,7 +294,7 @@ class LoadInfo final : public nsILoadInfo { // Used for TYPE_DOCUMENT load. LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const dom::RemoteType& aTriggeringRemoteType, const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags); @@ -302,14 +302,14 @@ class LoadInfo final : public nsILoadInfo { // Used for TYPE_FRAME or TYPE_IFRAME load. LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIPrincipal* aTriggeringPrincipal, - const nsACString& aTriggeringRemoteType, + const dom::RemoteType& 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, + const dom::RemoteType& aTriggeringRemoteType, nsContentPolicyType aContentPolicyType, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags); @@ -404,7 +404,7 @@ class LoadInfo final : public nsILoadInfo { nsICookieJarSettings* aCookieJarSettings, nsIPolicyContainer* aPolicyContainerToInherit, const Maybe& aContainerFeaturePolicyInfo, - const nsACString& aTriggeringRemoteType, + const dom::RemoteType& aTriggeringRemoteType, const nsID& aSandboxedNullPrincipalID, const Maybe& aClientInfo, const Maybe& aReservedClientInfo, @@ -443,8 +443,8 @@ class LoadInfo final : public nsILoadInfo { friend nsresult mozilla::ipc::LoadInfoArgsToLoadInfo( const mozilla::net::LoadInfoArgs& aLoadInfoArgs, - const nsACString& aOriginRemoteType, nsINode* aCspToInheritLoadingContext, - net::LoadInfo** outLoadInfo); + const dom::RemoteType& aOriginRemoteType, + nsINode* aCspToInheritLoadingContext, net::LoadInfo** outLoadInfo); ~LoadInfo(); @@ -488,7 +488,7 @@ class LoadInfo final : public nsILoadInfo { nsCOMPtr mCookieJarSettings; nsCOMPtr mPolicyContainerToInherit; Maybe mContainerFeaturePolicyInfo; - nsCString mTriggeringRemoteType; + dom::RemoteType mTriggeringRemoteType; nsID mSandboxedNullPrincipalID; Maybe mClientInfo; diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp index 9a4cf0648708..312dc82bc385 100644 --- a/netwerk/base/TRRLoadInfo.cpp +++ b/netwerk/base/TRRLoadInfo.cpp @@ -85,12 +85,17 @@ void TRRLoadInfo::ResetSandboxedNullPrincipalID() {} nsIPrincipal* TRRLoadInfo::GetTopLevelPrincipal() { return nullptr; } NS_IMETHODIMP -TRRLoadInfo::GetTriggeringRemoteType(nsACString& aTriggeringRemoteType) { +TRRLoadInfo::GetXPCOMTriggeringRemoteType(nsACString& aTriggeringRemoteType) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -TRRLoadInfo::SetTriggeringRemoteType(const nsACString& aTriggeringRemoteType) { +TRRLoadInfo::GetTriggeringRemoteType(RemoteType& aTriggeringRemoteType) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +TRRLoadInfo::SetTriggeringRemoteType(const RemoteType& aTriggeringRemoteType) { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/netwerk/base/nsBaseParentChannel.cpp b/netwerk/base/nsBaseParentChannel.cpp index cf51fbe2ee2b..ba7767aab901 100644 --- a/netwerk/base/nsBaseParentChannel.cpp +++ b/netwerk/base/nsBaseParentChannel.cpp @@ -43,8 +43,8 @@ nsBaseParentChannel::Delete() { } NS_IMETHODIMP -nsBaseParentChannel::GetRemoteType(nsACString& aRemoteType) { - aRemoteType = mRemoteType; +nsBaseParentChannel::GetRemoteType(mozilla::dom::RemoteType& _retval) { + _retval = mRemoteType; return NS_OK; } diff --git a/netwerk/base/nsBaseParentChannel.h b/netwerk/base/nsBaseParentChannel.h index 4268c7465b7f..2cf0179559cb 100644 --- a/netwerk/base/nsBaseParentChannel.h +++ b/netwerk/base/nsBaseParentChannel.h @@ -5,6 +5,7 @@ #ifndef nsBaseParentChannel_h #define nsBaseParentChannel_h +#include "mozilla/dom/RemoteType.h" #include "nsIParentChannel.h" // Basic type which implements a no-op nsIParentChannel instance. @@ -24,13 +25,13 @@ class nsBaseParentChannel : public nsIParentChannel { NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER - explicit nsBaseParentChannel(const nsACString& aRemoteType) + explicit nsBaseParentChannel(const mozilla::dom::RemoteType& aRemoteType) : mRemoteType(aRemoteType) {} protected: virtual ~nsBaseParentChannel() = default; - nsCString mRemoteType; + mozilla::dom::RemoteType mRemoteType; }; #endif // nsBaseParentChannel_h diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 5529ed0ea4c2..0cde3cee553a 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -34,6 +34,7 @@ class ClientInfo; class ClientSource; struct FeaturePolicyInfo; class PerformanceStorage; +struct RemoteType; class ServiceWorkerDescriptor; enum class RequestMode : uint8_t; enum class ForceMediaDocument : uint8_t; @@ -64,6 +65,8 @@ native OriginAttributes(mozilla::OriginAttributes); [ref] native const_FeaturePolicyInfoRef(const mozilla::dom::FeaturePolicyInfo); native MaybeRequestMode(mozilla::Maybe); native ForceMediaDocument(mozilla::dom::ForceMediaDocument); +[ref] native RemoteType(mozilla::dom::RemoteType); +[ref] native const_RemoteTypeRef(const mozilla::dom::RemoteType); typedef unsigned long nsSecurityFlags; @@ -339,7 +342,11 @@ interface nsILoadInfo : nsISupports * reset to the remote type of the sending process when sent from a content * process to the parent process. */ - attribute AUTF8String triggeringRemoteType; + [binaryname(XPCOMTriggeringRemoteType)] + readonly attribute AUTF8String triggeringRemoteType; + + [noscript] RemoteType getTriggeringRemoteType(); + [noscript] void setTriggeringRemoteType(in const_RemoteTypeRef aTriggeringRemoteType); /** * For non-document loads the principalToInherit is always null. For diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 2dd436d71707..73066c2678e0 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -715,7 +715,7 @@ void nsIOService::NotifySocketProcessPrefsChanged(const char* aName) { /* isSanitized */ false, Nothing(), Nothing()); Preferences::GetPreference(&pref, GeckoProcessType_Socket, - /* remoteType */ ""_ns); + /* remoteType */ {}); auto sendPrefUpdate = [pref = std::move(pref)]() mutable { (void)gIOService->mSocketProcess->GetActor()->SendPreferenceUpdate( std::move(pref)); diff --git a/netwerk/base/nsIParentChannel.idl b/netwerk/base/nsIParentChannel.idl index 92af6004934a..e6874ee8f8bc 100644 --- a/netwerk/base/nsIParentChannel.idl +++ b/netwerk/base/nsIParentChannel.idl @@ -9,6 +9,9 @@ interface nsIRemoteTab; %{C++ namespace mozilla { +namespace dom { +struct RemoteType; +} namespace net { class ParentChannelListener; } @@ -16,6 +19,7 @@ class ParentChannelListener; %} [ptr] native ParentChannelListener(mozilla::net::ParentChannelListener); +[ref] native RemoteType(mozilla::dom::RemoteType); /** * Implemented by chrome side of IPC protocols. @@ -72,5 +76,5 @@ interface nsIParentChannel : nsIStreamListener /** * The remote type of the target process for this load. */ - readonly attribute AUTF8String remoteType; + [noscript] RemoteType getRemoteType(); }; diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index 11747201b980..2a85d78c8123 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -243,9 +243,9 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( cspToInheritLoadingDocument = do_QueryReferent(ctx); } nsCOMPtr loadInfo; - MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(aArgs.loadInfo(), NOT_REMOTE_TYPE, - cspToInheritLoadingDocument, - getter_AddRefs(loadInfo))); + MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo( + aArgs.loadInfo(), RemoteType::NotRemote(), cspToInheritLoadingDocument, + getter_AddRefs(loadInfo))); mRedirectResolver = std::move(aResolve); diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index d9783f7852a3..6d94893fb020 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -912,7 +912,7 @@ auto DocumentLoadListener::Open(nsDocShellLoadState* aLoadState, if (aLoadState->GetRemoteTypeOverride()) { if (!mIsDocumentLoad || !NS_IsAboutBlank(aLoadState->URI()) || !loadingContext->IsTopContent() || - aLoadState->GetEffectiveTriggeringRemoteType() != NOT_REMOTE_TYPE || + !aLoadState->GetEffectiveTriggeringRemoteType().IsNotRemote() || aLoadState->LoadIsFromSessionHistory()) { LOG( ("DocumentLoadListener::Open with invalid remoteTypeOverride " @@ -2188,7 +2188,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch( return false; } - nsAutoCString currentRemoteType(NOT_REMOTE_TYPE); + RemoteType currentRemoteType = RemoteType::NotRemote(); if (mContentParent) { currentRemoteType = mContentParent->GetRemoteType(); } @@ -2232,21 +2232,21 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch( gProcessIsolationLog, LogLevel::Verbose, ("CheckIsolationForNavigation -> current:(%s) remoteType:(%s) replace:%d " "group:%" PRIx64 " bfcache:%d shentry:%p newTab:%d", - currentRemoteType.get(), options.mRemoteType.get(), - options.mReplaceBrowsingContext, options.mSpecificGroupId, - options.mTryUseBFCache, options.mActiveSessionHistoryEntry.get(), - switchToNewTab)); + currentRemoteType.Stringify().get(), + options.mRemoteType.Stringify().get(), options.mReplaceBrowsingContext, + options.mSpecificGroupId, options.mTryUseBFCache, + options.mActiveSessionHistoryEntry.get(), switchToNewTab)); // Check if a process switch is needed. if (currentRemoteType == options.mRemoteType && !options.mReplaceBrowsingContext && !switchToNewTab) { MOZ_LOG(gProcessIsolationLog, LogLevel::Info, ("Process Switch Abort: type (%s) is compatible", - options.mRemoteType.get())); + options.mRemoteType.Stringify().get())); return false; } - if (NS_WARN_IF(parentWindow && options.mRemoteType.IsEmpty())) { + if (NS_WARN_IF(parentWindow && options.mRemoteType.IsNotRemote())) { MOZ_LOG(gProcessIsolationLog, LogLevel::Error, ("Process Switch Abort: non-remote target process for subframe")); return false; @@ -2254,8 +2254,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch( // ParentProcessDocumentChannel applies the same check to loads which started // in the parent, so do it here for loads switching into the parent. - if (options.mRemoteType == NOT_REMOTE_TYPE && - currentRemoteType != NOT_REMOTE_TYPE) { + if (options.mRemoteType.IsNotRemote() && !currentRemoteType.IsNotRemote()) { nsCOMPtr uri; MOZ_ALWAYS_SUCCEEDS(NS_GetFinalChannelURI(mChannel, getter_AddRefs(uri))); if (NS_WARN_IF(!nsDocShell::CanLoadInParentProcess(uri))) { @@ -2266,7 +2265,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch( } } - *aWillSwitchToRemote = !options.mRemoteType.IsEmpty(); + *aWillSwitchToRemote = !options.mRemoteType.IsNotRemote(); // If we've decided to re-target this load into a new tab or window (see // `GetWhereToOpen`), do so before performing a process switch. This will @@ -2380,7 +2379,7 @@ void DocumentLoadListener::TriggerProcessSwitch( MOZ_LOG(gProcessIsolationLog, LogLevel::Info, ("Process Switch: Changing Remoteness from '%s' to '%s'", - currentRemoteType.get(), aOptions.mRemoteType.get())); + currentRemoteType.get(), aOptions.mRemoteType.Stringify().get())); } // Stash our stream filter requests to pass to TriggerRedirectToRealChannel, @@ -3356,7 +3355,7 @@ DocumentLoadListener::Delete() { } NS_IMETHODIMP -DocumentLoadListener::GetRemoteType(nsACString& aRemoteType) { +DocumentLoadListener::GetRemoteType(dom::RemoteType& aRemoteType) { // FIXME: The remote type here should be pulled from the remote process used // to create this DLL, not from the current `browsingContext`. RefPtr browsingContext = @@ -3365,11 +3364,8 @@ DocumentLoadListener::GetRemoteType(nsACString& aRemoteType) { return NS_ERROR_UNEXPECTED; } - ErrorResult error; - browsingContext->GetCurrentRemoteType(aRemoteType, error); - if (error.Failed()) { - aRemoteType = NOT_REMOTE_TYPE; - } + dom::ContentParent* cp = browsingContext->GetContentParent(); + aRemoteType = cp ? cp->GetRemoteType() : dom::RemoteType::NotRemote(); return NS_OK; } diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index bf56b47a7392..6461112fdd69 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -9,6 +9,7 @@ #include "mozilla/MozPromise.h" #include "mozilla/Variant.h" #include "mozilla/WeakPtr.h" +#include "mozilla/dom/RemoteType.h" #include "mozilla/dom/SessionHistoryEntry.h" #include "mozilla/ipc/Endpoint.h" #include "mozilla/net/NeckoCommon.h" @@ -608,7 +609,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor, // channel to the final document. RefPtr mParentProcessChannelHandle; - Maybe mRemoteTypeOverride; + Maybe mRemoteTypeOverride; // The ContentParent which this channel is currently connected to, or nullptr // if connected to the parent process. diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 2233543b6610..b6483ea7ae36 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -47,6 +47,7 @@ using mozilla::dom::UserNavigationInvolvement from "mozilla/dom/UserNavigationIn using mozilla::RFPTargetSet from "nsRFPService.h"; using PropertiesFile from "nsContentUtils.h"; [RefCounted] using mozilla::dom::ParentProcessChannelHandle from "mozilla/dom/ParentProcessChannelHandle.h"; +using struct mozilla::dom::RemoteType from "mozilla/dom/RemoteType.h"; namespace mozilla { namespace net { @@ -124,7 +125,7 @@ struct LoadInfoArgs PrincipalInfo? principalToInheritInfo; PrincipalInfo? topLevelPrincipalInfo; URIParams? resultPrincipalURI; - nsCString triggeringRemoteType; + RemoteType triggeringRemoteType; nsID sandboxedNullPrincipalID; uint32_t securityFlags; uint32_t sandboxFlags; diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index e414fac0fb1d..2e9fd59c8a79 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -754,20 +754,22 @@ mozilla::ipc::IPCResult NeckoParent::RecvEnsureHSTSData( mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream( nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs, GetPageThumbStreamResolver&& aResolver) { + const dom::RemoteType& remoteType = + ContentParent::Cast(Manager())->GetRemoteType(); + // Only the privileged about content process is allowed to access // things over the moz-page-thumb 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 (mozilla::ipc::ActorCast(Manager())->GetRemoteType() != - PRIVILEGEDABOUT_REMOTE_TYPE) { + if (!remoteType.IsPrivilegedAbout()) { return IPC_FAIL(this, "Wrong process type"); } nsCOMPtr loadInfo; - nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo( - aLoadInfoArgs, PRIVILEGEDABOUT_REMOTE_TYPE, getter_AddRefs(loadInfo)); + nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType, + getter_AddRefs(loadInfo)); if (NS_FAILED(rv)) { return IPC_FAIL(this, "moz-page-thumb request must include loadInfo"); } @@ -806,20 +808,22 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream( mozilla::ipc::IPCResult NeckoParent::RecvGetMozNewTabWallpaperStream( nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs, GetMozNewTabWallpaperStreamResolver&& aResolver) { + const dom::RemoteType& remoteType = + ContentParent::Cast(Manager())->GetRemoteType(); + // Only the privileged about content process is allowed to access // things over the moz-newtab-wallpaper 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 (mozilla::ipc::ActorCast(Manager())->GetRemoteType() != - PRIVILEGEDABOUT_REMOTE_TYPE) { + if (!remoteType.IsPrivilegedAbout()) { return IPC_FAIL(this, "Wrong process type"); } nsCOMPtr loadInfo; - nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo( - aLoadInfoArgs, PRIVILEGEDABOUT_REMOTE_TYPE, getter_AddRefs(loadInfo)); + nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType, + getter_AddRefs(loadInfo)); if (NS_FAILED(rv)) { return IPC_FAIL(this, "moz-newtab-wallpaper request must include loadInfo"); } @@ -860,7 +864,7 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream( nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs, GetPageIconStreamResolver&& aResolver) { #ifdef MOZ_PLACES - const nsACString& remoteType = + const dom::RemoteType& remoteType = ContentParent::Cast(Manager())->GetRemoteType(); // Only the privileged about content process is allowed to access @@ -869,7 +873,7 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream( // 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 (remoteType != PRIVILEGEDABOUT_REMOTE_TYPE) { + if (!remoteType.IsPrivilegedAbout()) { return IPC_FAIL(this, "Wrong process type"); } diff --git a/netwerk/ipc/ParentChannelWrapper.cpp b/netwerk/ipc/ParentChannelWrapper.cpp index f3edf4dea37c..912bd3027c6d 100644 --- a/netwerk/ipc/ParentChannelWrapper.cpp +++ b/netwerk/ipc/ParentChannelWrapper.cpp @@ -93,8 +93,8 @@ NS_IMETHODIMP ParentChannelWrapper::Delete() { return NS_OK; } NS_IMETHODIMP -ParentChannelWrapper::GetRemoteType(nsACString& aRemoteType) { - aRemoteType = NOT_REMOTE_TYPE; +ParentChannelWrapper::GetRemoteType(mozilla::dom::RemoteType& aRemoteType) { + aRemoteType = mozilla::dom::RemoteType::NotRemote(); return NS_OK; } diff --git a/netwerk/ipc/SocketProcessHost.cpp b/netwerk/ipc/SocketProcessHost.cpp index 9a69f0e73ebb..710de656a8e4 100644 --- a/netwerk/ipc/SocketProcessHost.cpp +++ b/netwerk/ipc/SocketProcessHost.cpp @@ -73,7 +73,7 @@ bool SocketProcessHost::Launch() { SharedPreferenceSerializer prefSerializer; if (!prefSerializer.SerializeToSharedMemory(GeckoProcessType_VR, - /* remoteType */ ""_ns)) { + /* remoteType */ {})) { return false; } prefSerializer.AddSharedPrefCmdLineArgs(*this, extraArgs); diff --git a/netwerk/protocol/file/nsFileChannel.cpp b/netwerk/protocol/file/nsFileChannel.cpp index d47e9acda151..f163633a4d67 100644 --- a/netwerk/protocol/file/nsFileChannel.cpp +++ b/netwerk/protocol/file/nsFileChannel.cpp @@ -572,7 +572,7 @@ nsresult nsFileChannel::MaybeSendFileOpenNotification() { /* static */ nsresult nsFileChannel::DoNotifyFileChannelOpened( - const nsACString& aRemoteType, + const mozilla::dom::RemoteType& aRemoteType, const mozilla::net::FileChannelInfo& aFileChannelInfo) { nsCOMPtr obsService = components::Observer::Service(); if (!obsService) { diff --git a/netwerk/protocol/file/nsFileChannel.h b/netwerk/protocol/file/nsFileChannel.h index 3174798ce198..e43325f9c75e 100644 --- a/netwerk/protocol/file/nsFileChannel.h +++ b/netwerk/protocol/file/nsFileChannel.h @@ -33,7 +33,7 @@ class nsFileChannel : public nsBaseChannel, nsresult Init(); static nsresult DoNotifyFileChannelOpened( - const nsACString& aRemoteType, + const mozilla::dom::RemoteType& aRemoteType, const mozilla::net::FileChannelInfo& aFileChannelInfo); protected: diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 1048d59a6b1f..43d24cc06b13 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -479,6 +479,10 @@ bool HttpChannelParent::DoAsyncOpen( return false; } + if (!CanSend()) { + return false; + } + LOG(("HttpChannelParent RecvAsyncOpen [this=%p uri=%s, gid=%" PRIu64 " browserid=%" PRIx64 "]\n", this, aURI->GetSpecOrDefault().get(), aChannelId, aBrowserId)); @@ -488,11 +492,10 @@ bool HttpChannelParent::DoAsyncOpen( aURI->GetSpecOrDefault(), aChannelId); nsresult rv; - nsAutoCString remoteType; - rv = GetRemoteType(remoteType); - if (NS_FAILED(rv)) { - return SendFailedAsyncOpen(rv); - } + + dom::PContentParent* pcp = Manager()->Manager(); + const dom::RemoteType& remoteType = + static_cast(pcp)->GetRemoteType(); nsCOMPtr loadInfo; rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType, @@ -1796,7 +1799,7 @@ HttpChannelParent::Delete() { } NS_IMETHODIMP -HttpChannelParent::GetRemoteType(nsACString& aRemoteType) { +HttpChannelParent::GetRemoteType(dom::RemoteType& aRemoteType) { if (!CanSend()) { return NS_ERROR_UNEXPECTED; } diff --git a/security/sandbox/linux/glue/SandboxPrefBridge.cpp b/security/sandbox/linux/glue/SandboxPrefBridge.cpp index 3d4314708449..60f7a77b34fd 100644 --- a/security/sandbox/linux/glue/SandboxPrefBridge.cpp +++ b/security/sandbox/linux/glue/SandboxPrefBridge.cpp @@ -6,7 +6,7 @@ #include "mozilla/Preferences.h" #include "mozilla/SandboxSettings.h" #include "mozilla/dom/ContentChild.h" -#include "mozilla/dom/ContentParent.h" // for FILE_REMOTE_TYPE +#include "mozilla/dom/ContentParent.h" namespace mozilla { @@ -27,7 +27,7 @@ ContentProcessSandboxParams::ForThisProcess( // (Otherwise, mBrokerFd will remain -1 from the default ctor.) auto* cc = dom::ContentChild::GetSingleton(); - params.mFileProcess = cc->GetRemoteType() == FILE_REMOTE_TYPE; + params.mFileProcess = cc->GetRemoteType().IsFile(); nsAutoCString extraSyscalls; nsresult rv = Preferences::GetCString( diff --git a/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp b/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp index 7c08184911cf..297ead5fb28e 100644 --- a/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp +++ b/toolkit/components/backgroundhangmonitor/BackgroundHangMonitor.cpp @@ -415,10 +415,10 @@ void BackgroundHangThread::ReportHang(TimeDuration aHangTime, // Recovered from a hang; called on the monitor thread // mManager->mLock IS locked - HangDetails hangDetails(aHangTime, - nsDependentCString(XRE_GetProcessTypeString()), - NOT_REMOTE_TYPE, mThreadName, mRunnableName, - std::move(mHangStack), std::move(mAnnotations)); + HangDetails hangDetails( + aHangTime, nsDependentCString(XRE_GetProcessTypeString()), + dom::RemoteType::NotRemote().Stringify(), mThreadName, mRunnableName, + std::move(mHangStack), std::move(mAnnotations)); PersistedToDisk persistedToDisk = aPersistedToDisk; if (aPersistedToDisk == PersistedToDisk::Yes && XRE_IsParentProcess() && diff --git a/toolkit/components/backgroundhangmonitor/HangDetails.cpp b/toolkit/components/backgroundhangmonitor/HangDetails.cpp index b9d02263a43b..a6674f5efcd4 100644 --- a/toolkit/components/backgroundhangmonitor/HangDetails.cpp +++ b/toolkit/components/backgroundhangmonitor/HangDetails.cpp @@ -11,7 +11,6 @@ #include "mozilla/FileUtils.h" #include "mozilla/gfx/GPUParent.h" #include "mozilla/dom/ContentChild.h" -#include "mozilla/dom/ContentParent.h" // For RemoteTypePrefix #include "mozilla/FileUtils.h" #include "mozilla/SchedulerGroup.h" #include "mozilla/GfxMessageUtils.h" // For ParamTraits @@ -290,10 +289,10 @@ void nsHangDetails::Submit() { case GeckoProcessType_Content: { auto cc = dom::ContentChild::GetSingleton(); if (cc) { - // Use the prefix so we don't get URIs from Fission isolated + // Use the kind so we don't get URIs from Fission isolated // processes. - hangDetails->mDetails.remoteType().Assign( - dom::RemoteTypePrefix(cc->GetRemoteType())); + hangDetails->mDetails.remoteType() = + cc->GetRemoteType().StringifyKind(); (void)cc->SendBHRThreadHang(hangDetails->mDetails); } break; diff --git a/toolkit/components/extensions/ExtensionPolicyService.cpp b/toolkit/components/extensions/ExtensionPolicyService.cpp index ac8206a409c1..aa472c4247fc 100644 --- a/toolkit/components/extensions/ExtensionPolicyService.cpp +++ b/toolkit/components/extensions/ExtensionPolicyService.cpp @@ -164,7 +164,7 @@ bool ExtensionPolicyService::IsExtensionProcess() const { if (isRemote && XRE_IsContentProcess()) { auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType(); - return remoteType == EXTENSION_REMOTE_TYPE; + return remoteType.IsExtension(); } return !isRemote && XRE_IsParentProcess(); } diff --git a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp index 0a9f39cb9c08..7f05548d4e2f 100644 --- a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp +++ b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp @@ -893,8 +893,8 @@ already_AddRefed ChannelWrapper::GetTraceableChannel( if (aContentParent) { RefPtr group = BrowsingContextGroup::GetExisting(aAddon.GetBrowsingContextGroupId()); - if (!group || - group->GetHostProcess(EXTENSION_REMOTE_TYPE) != aContentParent) { + if (!group || group->GetHostProcess(RemoteType( + RemoteType::Kind::Extension)) != aContentParent) { return nullptr; } } else { diff --git a/toolkit/components/glean/bindings/private/Labeled.cpp b/toolkit/components/glean/bindings/private/Labeled.cpp index 15a73a6ca23e..c2d0ab77df58 100644 --- a/toolkit/components/glean/bindings/private/Labeled.cpp +++ b/toolkit/components/glean/bindings/private/Labeled.cpp @@ -184,10 +184,10 @@ nsCString GetProcessTypeForTelemetry() { if (processType.EqualsLiteral("tab")) { auto* cc = mozilla::dom::ContentChild::GetSingleton(); if (cc) { - const nsACString& remoteType = cc->GetRemoteType(); - if (remoteType == EXTENSION_REMOTE_TYPE) { + const auto& remoteType = cc->GetRemoteType(); + if (remoteType.IsExtension()) { processType.AssignLiteral("extension"); - } else if (remoteType == INFERENCE_REMOTE_TYPE) { + } else if (remoteType.IsInference()) { processType.AssignLiteral("inference"); } // Otherwise keep "tab" for regular content processes diff --git a/toolkit/components/glean/ipc/FOGIPC.cpp b/toolkit/components/glean/ipc/FOGIPC.cpp index 84530f8a2eb3..9b881d98a6df 100644 --- a/toolkit/components/glean/ipc/FOGIPC.cpp +++ b/toolkit/components/glean/ipc/FOGIPC.cpp @@ -340,8 +340,7 @@ void RecordPowerMetrics() { if (XRE_IsContentProcess()) { auto* cc = mozilla::dom::ContentChild::GetSingleton(); if (cc) { - type.Assign(mozilla::dom::RemoteTypePrefix(cc->GetRemoteType())); - if (StringBeginsWith(type, WEB_REMOTE_TYPE)) { + if (cc->GetRemoteType().IsWeb()) { type.AssignLiteral("web"); switch (cc->GetProcessPriority()) { case hal::PROCESS_PRIORITY_BACKGROUND: @@ -364,9 +363,11 @@ void RecordPowerMetrics() { MOZ_ASSERT_UNREACHABLE("Unsuppored process type for cpu time"); break; } - } else if (type == INFERENCE_REMOTE_TYPE) { + } else if (cc->GetRemoteType().IsInference()) { type.AssignLiteral("inference"); gThisProcessType = ProcessType::eInferenceProcess; + } else { + type = cc->GetRemoteType().StringifyKind(); } GetTrackerType(trackerType); } else { diff --git a/toolkit/components/ml/backends/llama/LlamaRunner.cpp b/toolkit/components/ml/backends/llama/LlamaRunner.cpp index fbf8e7726591..c59ea39f4a5b 100644 --- a/toolkit/components/ml/backends/llama/LlamaRunner.cpp +++ b/toolkit/components/ml/backends/llama/LlamaRunner.cpp @@ -684,8 +684,7 @@ bool LlamaRunner::InInferenceProcess(JSContext*, JSObject*) { if (!ContentChild::GetSingleton()) { return false; } - return ContentChild::GetSingleton()->GetRemoteType().Equals( - INFERENCE_REMOTE_TYPE); + return ContentChild::GetSingleton()->GetRemoteType().IsInference(); } class MetadataCallback final : public nsIFileMetadataCallback { diff --git a/toolkit/modules/E10SUtils.sys.mjs b/toolkit/modules/E10SUtils.sys.mjs index 08ee146f3a99..2948e843daf2 100644 --- a/toolkit/modules/E10SUtils.sys.mjs +++ b/toolkit/modules/E10SUtils.sys.mjs @@ -429,18 +429,9 @@ export var E10SUtils = { return [tabPid, ...pids]; }, - /** - * The suffix after a `=` in a remoteType is dynamic, and used to control the - * process pool to use. The C++ version of this method is mozilla::dom::RemoteTypePrefix(). - */ - remoteTypePrefix(aRemoteType) { - return aRemoteType.split("=")[0]; - }, - /** * There are various types of remote types that are for web content processes, but - * they all start with "web". The C++ version of this method is - * mozilla::dom::IsWebRemoteType(). + * they all start with "web". The C++ version of this method is RemoteType::IsWeb(). */ isWebRemoteType(aRemoteType) { return aRemoteType.startsWith(WEB_REMOTE_TYPE); diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 1cf5753154ce..fb22d2956232 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1270,9 +1270,9 @@ nsXULAppInfo::GetUniqueProcessID(uint64_t* aResult) { NS_IMETHODIMP nsXULAppInfo::GetRemoteType(nsACString& aRemoteType) { if (XRE_IsContentProcess()) { - aRemoteType = ContentChild::GetSingleton()->GetRemoteType(); + aRemoteType = ContentChild::GetSingleton()->GetRemoteType().Stringify(); } else { - aRemoteType = NOT_REMOTE_TYPE; + aRemoteType = dom::RemoteType::NotRemote().Stringify(); } return NS_OK; diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index 22939d60120c..6d29b4232ff9 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -684,8 +684,8 @@ already_AddRefed GetOrCreateTestShellParent() { // this and you're sure you wouldn't be better off writing a "browser" // chrome mochitest where you can have multiple types of content // processes. - TestShellContentParent() = - ContentParent::GetNewOrUsedBrowserProcess(DEFAULT_REMOTE_TYPE); + TestShellContentParent() = ContentParent::GetNewOrUsedBrowserProcess( + mozilla::dom::RemoteType::SharedWeb({})); } else if (TestShellContentParent()->IsShuttingDown()) { return nullptr; } diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index 5d77ca6ba57c..f19813140759 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -455,7 +455,8 @@ NS_IMETHODIMP nsExtProtocolChannel::Delete() { return NS_OK; } -NS_IMETHODIMP nsExtProtocolChannel::GetRemoteType(nsACString& aRemoteType) { +NS_IMETHODIMP nsExtProtocolChannel::GetRemoteType( + mozilla::dom::RemoteType& aRemoteType) { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/xpcom/base/MemoryTelemetry.cpp b/xpcom/base/MemoryTelemetry.cpp index 66d16ec9740a..ec24691653b0 100644 --- a/xpcom/base/MemoryTelemetry.cpp +++ b/xpcom/base/MemoryTelemetry.cpp @@ -161,7 +161,7 @@ void MemoryTelemetry::Poke() { if (XRE_IsContentProcess()) { auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType(); - if (remoteType == PREALLOC_REMOTE_TYPE) { + if (remoteType.IsPrealloc()) { // Preallocated processes should stay dormant and not run this telemetry // code. return;