263 lines
9.5 KiB
C++
263 lines
9.5 KiB
C++
/* 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/. */
|
|
|
|
#ifndef mozilla_dom_RemoteType_h
|
|
#define mozilla_dom_RemoteType_h
|
|
|
|
#include "mozilla/HashFunctions.h"
|
|
#include "mozilla/Result.h"
|
|
#include "nsString.h"
|
|
|
|
namespace mozilla {
|
|
class OriginAttributes;
|
|
}
|
|
|
|
namespace IPC {
|
|
template <typename T>
|
|
struct ParamTraits;
|
|
class MessageWriter;
|
|
class MessageReader;
|
|
} // namespace IPC
|
|
|
|
namespace mozilla::dom {
|
|
|
|
/**
|
|
* 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,
|
|
|
|
// 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]] Result<Ok, const char*> CheckValidity() const;
|
|
void ReleaseAssertValidity() const;
|
|
void DebugAssertValidity() const {
|
|
#ifdef DEBUG
|
|
ReleaseAssertValidity();
|
|
#endif
|
|
}
|
|
|
|
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
|