Bug 2052614 - Add a structured RemoteType representation. r=ipc-reviewers,necko-reviewers,geckoview-reviewers,extension-reviewers,media-playback-reviewers,webrtc-reviewers,places-reviewers,layout-reviewers,dom-worker-reviewers,ai-platform-reviewers,sandbox-reviewers,janerik,emilio,hiro,kershaw,bwc,asuth,mccr8,alwu,nordzilla,valentin,bobowen

Replace bare remote type strings in C++ process-selection plumbing with
a RemoteType type which stores the parsed kind, isolation URI, and
process selection attributes directly.

This preserves the existing serialized string form for IPC and JS-facing
APIs, while making native callers use explicit predicates and structured
fields instead of manually parsing remote type prefixes and suffixes.

No JS-exposed API for parsing or otherwise interpreting remote types are
currently exposed in this patch. My current expectation is that this
will likely look like a `nsIRemoteType` interface which wraps this
`RemoteType` value type, exposing helpful getters for JS callers.

Differential Revision: https://phabricator.services.mozilla.com/D310442
This commit is contained in:
Nika Layzell
2026-08-31 23:49:43 +00:00
committed by nlayzell@mozilla.com
parent a64f98f3bf
commit c51090b135
122 changed files with 1659 additions and 1016 deletions
@@ -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];
+1 -1
View File
@@ -1073,7 +1073,7 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags(
}
auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType();
if (remoteType == PRIVILEGEDABOUT_REMOTE_TYPE) {
if (remoteType.IsPrivilegedAbout()) {
return NS_OK;
}
}
+1 -2
View File
@@ -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(
+9 -7
View File
@@ -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);
}
+3 -2
View File
@@ -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<nsCStringHashKey, ContentParent> mHosts;
nsRefPtrHashtable<nsGenericHashKey<RemoteType>, ContentParent> mHosts;
// Whether or not a given http(s) origin uses origin or siteOrigin-keyed
// DocGroups/AgentClusters. Only contains entries for http(s) origins.
+8 -6
View File
@@ -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;
+4 -3
View File
@@ -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<BrowserParent>, RefPtr<CanonicalBrowsingContext>>,
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
+1 -1
View File
@@ -60,7 +60,7 @@ class CrashChannel final : public nsBaseChannel {
using ContentParent = mozilla::dom::ContentParent;
nsTArray<RefPtr<ContentParent>> toKill;
for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
if (cp->GetRemoteType() == EXTENSION_REMOTE_TYPE) {
if (cp->GetRemoteType().IsExtension()) {
toKill.AppendElement(cp);
}
}
+31 -18
View File
@@ -51,8 +51,8 @@ using namespace mozilla::dom;
static mozilla::StaticRefPtr<nsIURIFixup> 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<nsILoadInfo::SchemelessInputType>(
@@ -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)) &&
+10 -6
View File
@@ -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<nsCString>& GetRemoteTypeOverride() const {
const mozilla::Maybe<mozilla::dom::RemoteType>& 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<nsIURI> mUnstrippedURI;
// If set, the remote type which the load should be completed within.
mozilla::Maybe<nsCString> mRemoteTypeOverride;
mozilla::Maybe<mozilla::dom::RemoteType> 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 =
+59 -45
View File
@@ -2062,44 +2062,44 @@ already_AddRefed<Promise> 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<WindowInfo> windows;
@@ -2608,7 +2608,13 @@ already_AddRefed<Promise> 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(
+16 -10
View File
@@ -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> nsFrameLoader::Create(
}
bool isRemoteFrame = InitialLoadIsRemote(aOwner);
RefPtr<nsFrameLoader> 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
// <browser> 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<nsFrameLoader> 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");
+3 -2
View File
@@ -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<mozilla::dom::SessionStoreChild> mSessionStoreChild;
nsCString mRemoteType;
mozilla::dom::RemoteType mRemoteType;
bool mInitialized : 1;
bool mDepthTooGreat : 1;
+10 -5
View File
@@ -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<void()> 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);
}
@@ -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)) {
+1
View File
@@ -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"
+1 -1
View File
@@ -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<ValidatePrincipalOptions> options;
if (contentHandle->GetRemoteType() == INFERENCE_REMOTE_TYPE) {
if (contentHandle->GetRemoteType().IsInference()) {
options += ValidatePrincipalOptions::AllowSystemIfLoaded;
}
if (!contentHandle->ValidatePrincipal(principal, options)) {
@@ -79,7 +79,7 @@ FileSystemBackgroundRequestHandler::CreateFileSystemManagerChild(
// Throw if this process wouldn't be allowed to access storage.
EnumSet<ValidatePrincipalOptions> options;
if (CurrentRemoteType() == INFERENCE_REMOTE_TYPE) {
if (CurrentRemoteType().IsInference()) {
options += ValidatePrincipalOptions::AllowSystemIfLoaded;
}
if (!BackgroundChild::ValidatePrincipalInfo(aPrincipalInfo, options)) {
+1 -1
View File
@@ -2212,7 +2212,7 @@ already_AddRefed<DataTransfer> 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();
}
+68 -89
View File
@@ -646,7 +646,8 @@ ContentChild::ContentChild()
{
StaticMutexAutoLock lock(sLoadedOriginsMutex);
MOZ_ASSERT(!sLoadedOrigins);
sLoadedOrigins = MakeRefPtr<LoadedOriginSet>(PREALLOC_REMOTE_TYPE);
sLoadedOrigins =
MakeRefPtr<LoadedOriginSet>(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<nsIPrincipal> isolationPrincipal =
ContentParent::CreateRemoteTypeIsolationPrincipal(mRemoteType);
if (isolationPrincipal) {
if (isolationPrincipal->OriginAttributesRef().IsPrivateBrowsing()) {
return;
}
if (mRemoteType.IsPrivateBrowsing()) {
return;
}
mProcessName = aProfile + ":"_ns + mProcessName; //<profile_name>:example.com
@@ -861,35 +858,26 @@ void ContentChild::SetProcessName(const nsACString& aName,
// Requires pref flip
if (aSite && StaticPrefs::fission_processSiteNames()) {
nsCOMPtr<nsIPrincipal> 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<mozilla::ipc::FileDescriptor>& 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<LoadedOriginSet> loadedOrigins = CurrentLoadedOriginSet()) {
return loadedOrigins->GetRemoteType();
}
return PREALLOC_REMOTE_TYPE;
return RemoteType(RemoteType::Kind::Prealloc);
}
return NOT_REMOTE_TYPE;
return RemoteType::NotRemote();
}
already_AddRefed<LoadedOriginSet> CurrentLoadedOriginSet() {
@@ -2721,40 +2709,37 @@ already_AddRefed<LoadedOriginSet> 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<LoadedOriginSet> 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<PRemoteWorkerServiceChild>&& aEndpoint,
@@ -3541,7 +3520,7 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
nsCOMPtr<nsILoadInfo> 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<nsILoadInfo> 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();
+6 -7
View File
@@ -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<LoadedOriginSet> CurrentLoadedOriginSet();
+59 -150
View File
@@ -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<nsCStringHashKey, nsTArray<ContentParent*>>*
nsClassHashtable<nsGenericHashKey<RemoteType>, nsTArray<ContentParent*>>*
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<ContentParent> process = new ContentParent(PREALLOC_REMOTE_TYPE);
RefPtr<ContentParent> 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*>& ContentParent::GetOrCreatePool(
const nsACString& aContentProcessType) {
const RemoteType& aContentProcessType) {
if (!sBrowserContentParents) {
sBrowserContentParents =
new nsClassHashtable<nsCStringHashKey, nsTArray<ContentParent*>>;
sBrowserContentParents = new nsClassHashtable<nsGenericHashKey<RemoteType>,
nsTArray<ContentParent*>>;
}
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> ContentParent::MinTabSelect(
return candidate.forget();
}
/* static */
already_AddRefed<nsIPrincipal>
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<nsIPrincipal> principal;
ssm->CreateContentPrincipalFromOrigin(origin, getter_AddRefs(principal));
return principal.forget();
}
/*static*/
UniqueContentParentKeepAlive ContentParent::GetUsedBrowserProcess(
const nsACString& aRemoteType, nsTArray<ContentParent*>& aContentParents,
const RemoteType& aRemoteType, nsTArray<ContentParent*>& 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<ContentParent> newCp = new ContentParent(aRemoteType);
if (NS_WARN_IF(!newCp->BeginSubprocessLaunch(aPriority))) {
@@ -1099,7 +1018,7 @@ UniqueContentParentKeepAlive ContentParent::GetNewOrUsedLaunchingBrowserProcess(
/*static*/
RefPtr<ContentParent::LaunchPromise>
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<RemoteBrowser> 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<RemoteBrowser> 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<nsIAsyncShutdownClient> sXPCOMShutdownClient;
static StaticRefPtr<nsIAsyncShutdownClient> 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<TestShellParent> ContentParent::GetTestShellSingleton() {
void ContentParent::AppendDynamicSandboxParams(
std::vector<std::string>& 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<ContentParent>();
@@ -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<SandboxBroker::Policy> 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<nsHashPropertyBag>();
props->SetPropertyAsACString(u"remoteTypePrefix"_ns,
RemoteTypePrefix(mRemoteType));
mRemoteType.StringifyKind());
*aResult = props.forget().downcast<nsIWritablePropertyBag>().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<PRemoteWorkerServiceChild> childEp;
mRemoteWorkerServiceActor =
@@ -8234,7 +8143,7 @@ IPCResult ContentParent::RecvKillGPUProcess() {
}
#endif
nsCString ThreadsafeContentParentHandle::GetRemoteType() {
RemoteType ThreadsafeContentParentHandle::GetRemoteType() {
return mLoadedOrigins->GetRemoteType();
}
+20 -33
View File
@@ -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<ContentParent::LaunchPromise> 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<RemoteBrowser> 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<nsCStringHashKey, nsTArray<ContentParent*>>*
sBrowserContentParents;
static nsClassHashtable<nsGenericHashKey<RemoteType>,
nsTArray<ContentParent*>>* sBrowserContentParents;
static mozilla::StaticAutoPtr<LinkedList<ContentParent>> 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<ContentParent*>& GetOrCreatePool(
const nsACString& aContentProcessType);
const RemoteType& aContentProcessType);
mozilla::ipc::IPCResult RecvInitBackground(
Endpoint<mozilla::ipc::PBackgroundStarterParent>&& aEndpoint);
@@ -1447,9 +1448,6 @@ class ContentParent final : public PContentParent,
ErrorResult& aRv) override;
mozilla::ipc::IProtocol* AsNativeActor() override { return this; }
static already_AddRefed<nsIPrincipal> 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<ContentParent*>& aContentParents,
const RemoteType& aRemoteType, nsTArray<ContentParent*>& 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<nsIPrincipal> 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<LoadedOriginSet>(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<nsIDOMProcessParent*>(aContentParent);
}
+3 -2
View File
@@ -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;
+3 -1
View File
@@ -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<JSActor> InitJSActor(JS::Handle<JSObject*> aMaybeActor,
+1 -1
View File
@@ -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;
}
+3 -1
View File
@@ -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<JSActor> InitJSActor(JS::Handle<JSObject*> aMaybeActor,
+5 -5
View File
@@ -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<ValidatePrincipalOptions>& 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
+4 -4
View File
@@ -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<AttributeBucket> mLoadedOrigins MOZ_GUARDED_BY(mMutex);
};
+2 -1
View File
@@ -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.
+13 -14
View File
@@ -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);
}
+5 -3
View File
@@ -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
+122 -184
View File
@@ -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<nsIURI> 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<nsIURI> 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<nsCString, nsresult> SpecialBehaviorRemoteType(
IsolationBehavior aBehavior, const nsACString& aCurrentRemoteType,
static Result<RemoteType, nsresult> 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<nsCString, nsresult> 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<NavigationIsolationOptions, nsresult> 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<uint64_t>& aChannelId,
const Maybe<nsCString>& aRemoteTypeOverride) {
const Maybe<RemoteType>& aRemoteTypeOverride) {
// Get the final principal, used to select which process to load into.
nsCOMPtr<nsIPrincipal> resultPrincipal;
nsresult rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
@@ -688,7 +658,7 @@ Result<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> IsolationOptionsForNavigation(
nsAutoCString siteOriginNoSuffix;
MOZ_TRY(resultOrPrecursor->GetSiteOriginNoSuffix(siteOriginNoSuffix));
nsCOMPtr<nsIURI> 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<NavigationIsolationOptions, nsresult> 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<NavigationIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> IsolationOptionsForWorker(
nsAutoCString siteOriginNoSuffix;
MOZ_TRY(resultOrPrecursor->GetSiteOriginNoSuffix(siteOriginNoSuffix));
bool isJitAllowed = AllowJITForSiteOrigin(siteOriginNoSuffix, nullptr);
nsCOMPtr<nsIURI> 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<nsIURI> MaybeResolveWebAppHandler(nsIURI* aURI) {
return newURI.forget();
}
Result<nsCString, nsresult> PredictRemoteTypeForURI(
Result<RemoteType, nsresult> 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<nsCString, nsresult> 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<nsCString, nsresult> PredictRemoteTypeForURI(
nsAutoCString siteOriginNoSuffix;
MOZ_TRY(principal->GetSiteOriginNoSuffix(siteOriginNoSuffix));
bool isJitAllowed = AllowJITForSiteOrigin(siteOriginNoSuffix, nullptr);
nsAutoCString originSuffix = OriginSuffixForRemoteType(
principal->OriginAttributesRef(), !isJitAllowed);
nsCOMPtr<nsIURI> 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<ValidatePrincipalOptions>& aOptions,
FunctionRef<bool(nsIPrincipal*)> 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
+8 -15
View File
@@ -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<NavigationIsolationOptions, nsresult> 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<uint64_t>& aChannelId,
const Maybe<nsCString>& aRemoteTypeOverride);
const Maybe<RemoteType>& 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<WorkerIsolationOptions, nsresult> 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<WorkerIsolationOptions, nsresult> 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<nsCString, nsresult> PredictRemoteTypeForURI(
Result<RemoteType, nsresult> 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<ValidatePrincipalOptions>& aOptions,
FunctionRef<bool(nsIPrincipal*)> aIsPrincipalLoaded = nullptr);
+1 -1
View File
@@ -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;
}
+401
View File
@@ -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<RemoteType> 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 <typename T>
static auto PreHashAttr(const T& aValue) {
if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
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 "<unknown>"_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<nsIURI> uri;
if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), mOriginNoSuffix))) {
NS_WARNING("Invalid RemoteType: Invalid OriginNoSuffix URI");
return false;
}
nsCOMPtr<nsIPrincipal> 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<mozilla::dom::RemoteType>::Write(MessageWriter* aWriter,
const paramType& aParam) {
MOZ_ASSERT(aParam.IsKnown(), "Cannot send unknown RemoteType");
WriteParam(aWriter, aParam.Stringify());
}
bool ParamTraits<mozilla::dom::RemoteType>::Read(MessageReader* aReader,
paramType* aResult) {
nsCString s;
if (!ReadParam(aReader, &s)) {
return false;
}
*aResult = mozilla::dom::RemoteType::Parse(s);
return aResult->IsKnown();
}
} // namespace IPC
+240 -22
View File
@@ -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 <typename T>
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 <typename T>
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<mozilla::dom::RemoteType> {
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
+3 -3
View File
@@ -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<JSWindowActorChild> WindowGlobalChild::GetActor(
+1 -1
View File
@@ -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<JSActor> InitJSActor(JS::Handle<JSObject*> aMaybeActor,
const nsACString& aName,
+4 -5
View File
@@ -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> 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> browserParent = GetBrowserParent();
if (!browserParent ||
!IsWebRemoteType(browserParent->Manager()->GetRemoteType())) {
if (!browserParent || !browserParent->Manager()->GetRemoteType().IsWeb()) {
return false;
}
+1 -1
View File
@@ -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);
+85 -92
View File
@@ -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<RemoteTypes, nsresult> 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<RemoteTypes, nsresult> 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<nsIPrincipal> 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<nsIPrincipal> 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) {
+153
View File
@@ -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
+1
View File
@@ -5,6 +5,7 @@
UNIFIED_SOURCES += [
"JSIPCValueTest.cpp",
"ProcessIsolationTest.cpp",
"RemoteTypeTest.cpp",
]
include("/ipc/chromium/chromium-config.mozbuild")
+2 -1
View File
@@ -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:
/**
+12 -24
View File
@@ -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;
}
}
+2 -2
View File
@@ -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<nsCString> mRemoteTypes;
+4 -4
View File
@@ -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;
}
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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)
+1
View File
@@ -157,6 +157,7 @@ UNIFIED_SOURCES += [
"ReferrerInfoUtils.cpp",
"RefMessageBodyService.cpp",
"RemoteBrowser.cpp",
"RemoteType.cpp",
"RemoteWebProgressRequest.cpp",
"SharedMap.cpp",
"SharedMessageBody.cpp",
@@ -1,6 +1,6 @@
"use strict";
const TEST_REMOTE_TYPE = "test";
const TEST_REMOTE_TYPE = "inference";
function allTestProcs() {
return ChromeUtils.getAllDOMProcesses().filter(
+1 -1
View File
@@ -90,7 +90,7 @@ bool GMPProcessParent::Launch(int32_t aTimeoutMs) {
auto prefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
bool success =
prefSerializer->SerializeToSharedMemory(GeckoProcessType_GMPlugin,
/* remoteType */ ""_ns);
/* remoteType */ {});
MonitorAutoLock lock(mMonitor);
MOZ_ASSERT(!mComplete);
+1 -1
View File
@@ -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<mozilla::dom::Pref&&>(
"gmp::GeckoMediaPluginServiceParent::OnPreferenceChanged", this,
&GeckoMediaPluginServiceParent::OnPreferenceChanged,
+1 -1
View File
@@ -46,7 +46,7 @@ bool RDDProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) {
mPrefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_RDD,
/* remoteType */ ""_ns)) {
/* remoteType */ {})) {
return false;
}
mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts);
+1 -1
View File
@@ -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);
@@ -401,13 +401,14 @@ nsresult WebrtcTCPSocket::OpenWithHttpProxy() {
nsCOMPtr<nsILoadInfo> 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;
+1 -2
View File
@@ -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&) {
+19 -21
View File
@@ -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<nsIParentChannel> 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<nsIURI> 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<nsIURI> innerURI = NS_GetInnermostURI(finalURI);
nsAutoCString remoteType;
RemoteType remoteType;
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIParentChannel> 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<nsIParentChannel> 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<nsILoadInfo> 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;
+3 -3
View File
@@ -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
@@ -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 =
+3 -5
View File
@@ -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 {
@@ -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<nsCString, nsresult> RemoteWorkerManager::GetRemoteType(
Result<RemoteType, nsresult> RemoteWorkerManager::GetRemoteType(
const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind,
const nsACString& aCurrentRemoteType) {
const RemoteType& aCurrentRemoteType) {
AssertIsOnMainThread();
MOZ_ASSERT_IF(aWorkerKind == WorkerKind::WorkerKindService,
@@ -120,7 +120,7 @@ Result<nsCString, nsresult> 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<nsCString, nsresult> 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 <typename Callback>
void RemoteWorkerManager::ForEachActor(
Callback&& aCallback, const nsACString& aRemoteType,
Callback&& aCallback, const RemoteType& aRemoteType,
Maybe<base::ProcessId> 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);
@@ -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<nsCString, nsresult> GetRemoteType(
static Result<RemoteType, nsresult> GetRemoteType(
const nsCOMPtr<nsIPrincipal>& 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 <typename Callback>
void ForEachActor(Callback&& aCallback, const nsACString& aRemoteType,
void ForEachActor(Callback&& aCallback, const RemoteType& aRemoteType,
Maybe<base::ProcessId> aProcessId = Nothing()) const;
// The list of existing RemoteWorkerServiceParent actors for child processes.
@@ -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
@@ -33,7 +33,7 @@ class RemoteWorkerServiceParent final : public PRemoteWorkerServiceParent {
return mProcess;
}
nsCString GetRemoteType() const;
RemoteType GetRemoteType() const;
private:
explicit RemoteWorkerServiceParent(ThreadsafeContentParentHandle* aProcess);
@@ -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;
+3 -2
View File
@@ -274,8 +274,9 @@ already_AddRefed<SharedWorker> 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());
@@ -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());
+1 -1
View File
@@ -60,7 +60,7 @@ bool GPUProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) {
mPrefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_GPU,
/* remoteType */ ""_ns)) {
/* remoteType */ {})) {
return false;
}
mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts);
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -52,7 +52,7 @@ bool VRProcessParent::Launch() {
mPrefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_VR,
/* remoteType */ ""_ns)) {
/* remoteType */ {})) {
return false;
}
mPrefSerializer->AddSharedPrefCmdLineArgs(*this, extraArgs);
+1 -1
View File
@@ -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);
+4 -2
View File
@@ -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
+2 -1
View File
@@ -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.
+2 -2
View File
@@ -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<dom::ValidatePrincipalOptions> 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 =
+7 -7
View File
@@ -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> 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<nsIPrincipal> 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;
}
+16 -14
View File
@@ -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
+4 -2
View File
@@ -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;
+2 -3
View File
@@ -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;
+1 -1
View File
@@ -92,7 +92,7 @@ bool UtilityProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) {
mPrefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
if (!mPrefSerializer->SerializeToSharedMemory(GeckoProcessType_Utility,
/* remoteType */ ""_ns)) {
/* remoteType */ {})) {
return false;
}
mPrefSerializer->AddSharedPrefCmdLineArgs(*this, aExtraOpts);
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -46,7 +46,7 @@ already_AddRefed<IPDLUnitTestParent> IPDLUnitTestParent::CreateCrossProcess() {
auto prefSerializer = MakeUnique<ipc::SharedPreferenceSerializer>();
if (!prefSerializer->SerializeToSharedMemory(GeckoProcessType_IPDLUnitTest,
/* remoteType */ ""_ns)) {
/* remoteType */ {})) {
ADD_FAILURE()
<< "SharedPreferenceSerializer::SerializeToSharedMemory failed";
return nullptr;
+4 -3
View File
@@ -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;
+3 -2
View File
@@ -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.
+1 -1
View File
@@ -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;
@@ -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;
+3 -4
View File
@@ -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()) {
+2 -1
View File
@@ -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
+17 -11
View File
@@ -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> 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<LoadInfo>(aBrowsingContext, aURI, aTriggeringPrincipal,
@@ -151,7 +151,7 @@ bool LoadInfo::IsDocumentMissingClientInfo() {
/* static */ already_AddRefed<LoadInfo> LoadInfo::CreateForFrame(
dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal, const nsACString& aTriggeringRemoteType,
nsIPrincipal* aTriggeringPrincipal, const RemoteType& aTriggeringRemoteType,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags) {
return MakeAndAddRef<LoadInfo>(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<dom::FeaturePolicyInfo>& aContainerFeaturePolicyInfo,
const nsACString& aTriggeringRemoteType,
const RemoteType& aTriggeringRemoteType,
const nsID& aSandboxedNullPrincipalID, const Maybe<ClientInfo>& aClientInfo,
const Maybe<ClientInfo>& aReservedClientInfo,
const Maybe<ClientInfo>& 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;
}
+11 -11
View File
@@ -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<LoadInfo> 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<LoadInfo> 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<LoadInfo> 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<dom::FeaturePolicyInfo>& aContainerFeaturePolicyInfo,
const nsACString& aTriggeringRemoteType,
const dom::RemoteType& aTriggeringRemoteType,
const nsID& aSandboxedNullPrincipalID,
const Maybe<mozilla::dom::ClientInfo>& aClientInfo,
const Maybe<mozilla::dom::ClientInfo>& 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<nsICookieJarSettings> mCookieJarSettings;
nsCOMPtr<nsIPolicyContainer> mPolicyContainerToInherit;
Maybe<dom::FeaturePolicyInfo> mContainerFeaturePolicyInfo;
nsCString mTriggeringRemoteType;
dom::RemoteType mTriggeringRemoteType;
nsID mSandboxedNullPrincipalID;
Maybe<mozilla::dom::ClientInfo> mClientInfo;
+7 -2
View File
@@ -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;
}
+2 -2
View File
@@ -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;
}
+3 -2
View File
@@ -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
+8 -1
View File
@@ -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<mozilla::dom::RequestMode>);
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
+1 -1
View File
@@ -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));
+5 -1
View File
@@ -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();
};
+3 -3
View File
@@ -243,9 +243,9 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel(
cspToInheritLoadingDocument = do_QueryReferent(ctx);
}
nsCOMPtr<nsILoadInfo> 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);

Some files were not shown because too many files have changed in this diff Show More