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
106 lines
3.4 KiB
C++
106 lines
3.4 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/. */
|
|
|
|
#include "mozilla/dom/LoadedOriginSet.h"
|
|
|
|
#include "mozilla/dom/RemoteType.h"
|
|
#include "nsIPrincipal.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
LoadedOriginSet::LoadedOriginSet(const RemoteType& aRemoteType)
|
|
: mRemoteType(aRemoteType) {}
|
|
|
|
RemoteType LoadedOriginSet::GetRemoteType() {
|
|
MutexAutoLock lock(mMutex);
|
|
return mRemoteType;
|
|
}
|
|
|
|
void LoadedOriginSet::SetRemoteType(const RemoteType& aRemoteType) {
|
|
MutexAutoLock lock(mMutex);
|
|
MOZ_ASSERT(mRemoteType.IsPrealloc());
|
|
mRemoteType = aRemoteType;
|
|
}
|
|
|
|
bool LoadedOriginSet::Has(nsIPrincipal* aPrincipal, Level aThreshold,
|
|
uint32_t aStripAttributesFlags) {
|
|
if (aThreshold == Level::Unloaded) {
|
|
return true;
|
|
}
|
|
|
|
const OriginAttributes& attrs = aPrincipal->OriginAttributesRef();
|
|
nsAutoCString originNoSuffix;
|
|
if (aThreshold == Level::SiteOnly) {
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOriginNoSuffix(originNoSuffix));
|
|
} else {
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetOriginNoSuffix(originNoSuffix));
|
|
}
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
for (const auto& loadedAttrs : mLoadedOrigins) {
|
|
if (loadedAttrs.mAttrs.EqualsIgnoring(attrs, aStripAttributesFlags)) {
|
|
if (auto entry = loadedAttrs.mOrigins.Lookup(originNoSuffix);
|
|
entry && entry.Data().mLevel >= aThreshold) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
LoadedOriginSet::Level LoadedOriginSet::AddInternal(nsIPrincipal* aPrincipal,
|
|
bool aTentative) {
|
|
nsAutoCString originNoSuffix;
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetOriginNoSuffix(originNoSuffix));
|
|
nsAutoCString siteOriginNoSuffix;
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOriginNoSuffix(siteOriginNoSuffix));
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
AttributeBucket* found = nullptr;
|
|
for (auto& entry : mLoadedOrigins) {
|
|
if (entry.mAttrs == aPrincipal->OriginAttributesRef()) {
|
|
found = &entry;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
found = mLoadedOrigins.AppendElement(
|
|
AttributeBucket{.mAttrs = aPrincipal->OriginAttributesRef()});
|
|
}
|
|
|
|
Level previous = Level::Unloaded;
|
|
|
|
if (siteOriginNoSuffix != originNoSuffix) {
|
|
OriginEntry& siteEntry = found->mOrigins.LookupOrInsert(siteOriginNoSuffix);
|
|
previous = std::min(siteEntry.mLevel, Level::SiteOnly);
|
|
siteEntry.mLevel = std::max(siteEntry.mLevel, Level::SiteOnly);
|
|
}
|
|
|
|
OriginEntry& originEntry = found->mOrigins.LookupOrInsert(originNoSuffix);
|
|
previous = std::max(previous, originEntry.mLevel);
|
|
originEntry.mLevel =
|
|
std::max(originEntry.mLevel, aTentative ? Level::Tentative : Level::Full);
|
|
|
|
return previous;
|
|
}
|
|
|
|
bool LoadedOriginSet::ValidatePrincipal(
|
|
nsIPrincipal* aPrincipal,
|
|
const EnumSet<ValidatePrincipalOptions>& aOptions) {
|
|
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
|
|
// hope to tighten these checks.
|
|
return !StaticPrefs::dom_ipc_validatePrincipal_validateSiteLoaded() ||
|
|
Has(prin, Level::SiteOnly, OriginAttributes::STRIP_ALL);
|
|
};
|
|
return ValidatePrincipalCouldPotentiallyBeLoadedBy(
|
|
aPrincipal, remoteType, aOptions, isPrincipalLoaded);
|
|
}
|
|
|
|
} // namespace mozilla::dom
|