Bug 1443925 - Part 2: Make basic manipulation of nsIPrincipal threadsafe, r=ckerschb

This patch only makes the very basics of nsIPrincipal manipulation threadsafe,
such as reference counting, and some trivial methods. The more complex methods
will be made threadsafe in following parts.

Differential Revision: https://phabricator.services.mozilla.com/D163032
This commit is contained in:
Nika Layzell 2022-12-02 00:53:50 +00:00
Родитель bf9f3c01b4
Коммит e2f6bee4ab
7 изменённых файлов: 36 добавлений и 16 удалений

Просмотреть файл

@ -62,7 +62,7 @@ BasePrincipal::BasePrincipal(BasePrincipal* aOther,
mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
mOriginAttributes(aOriginAttributes),
mKind(aOther->mKind),
mHasExplicitDomain(aOther->mHasExplicitDomain) {}
mHasExplicitDomain(aOther->mHasExplicitDomain.load()) {}
BasePrincipal::~BasePrincipal() = default;

Просмотреть файл

@ -314,6 +314,7 @@ class BasePrincipal : public nsJSPrincipals {
bool aReport, uint64_t aInnerWindowID);
void SetHasExplicitDomain() { mHasExplicitDomain = true; }
bool GetHasExplicitDomain() { return mHasExplicitDomain; }
// KeyValT holds a principal subtype-specific key value and the associated
// parsed value after JSON parsing.
@ -352,7 +353,7 @@ class BasePrincipal : public nsJSPrincipals {
const OriginAttributes mOriginAttributes;
const PrincipalKind mKind;
bool mHasExplicitDomain;
std::atomic<bool> mHasExplicitDomain;
};
inline bool BasePrincipal::FastEquals(nsIPrincipal* aOther) {

Просмотреть файл

@ -325,21 +325,26 @@ uint32_t ContentPrincipal::GetHashValue() {
NS_IMETHODIMP
ContentPrincipal::GetDomain(nsIURI** aDomain) {
if (!mDomain) {
if (!GetHasExplicitDomain()) {
*aDomain = nullptr;
return NS_OK;
}
mozilla::MutexAutoLock lock(mMutex);
NS_ADDREF(*aDomain = mDomain);
return NS_OK;
}
NS_IMETHODIMP
ContentPrincipal::SetDomain(nsIURI* aDomain) {
AssertIsOnMainThread();
MOZ_ASSERT(aDomain);
mDomain = aDomain;
SetHasExplicitDomain();
{
mozilla::MutexAutoLock lock(mMutex);
mDomain = aDomain;
SetHasExplicitDomain();
}
// Set the changed-document-domain flag on compartments containing realms
// using this principal.
@ -515,6 +520,7 @@ nsresult ContentPrincipal::GetSiteIdentifier(SiteIdentifier& aSite) {
WebExtensionPolicy* ContentPrincipal::AddonPolicy() {
AssertIsOnMainThread();
mozilla::MutexAutoLock lock(mMutex);
if (!mAddon.isSome()) {
NS_ENSURE_TRUE(mURI, nullptr);
@ -600,6 +606,7 @@ ContentPrincipal::Deserializer::Read(nsIObjectInputStream* aStream) {
// Note: we don't call SetDomain here because we don't need the wrapper
// recomputation code there (we just created this principal).
if (domain) {
MutexAutoLock lock(principal->mMutex);
principal->mDomain = domain;
principal->SetHasExplicitDomain();
}
@ -628,10 +635,13 @@ nsresult ContentPrincipal::PopulateJSONObject(Json::Value& aObject) {
// Value
aObject[std::to_string(eURI)] = principalURI.get();
if (mDomain) {
if (GetHasExplicitDomain()) {
nsAutoCString domainStr;
rv = mDomain->GetSpec(domainStr);
NS_ENSURE_SUCCESS(rv, rv);
{
MutexAutoLock lock(mMutex);
rv = mDomain->GetSpec(domainStr);
NS_ENSURE_SUCCESS(rv, rv);
}
aObject[std::to_string(eDomain)] = domainStr.get();
}
@ -705,8 +715,9 @@ already_AddRefed<BasePrincipal> ContentPrincipal::FromProperties(
RefPtr<ContentPrincipal> principal =
new ContentPrincipal(principalURI, attrs, originNoSuffix);
principal->mDomain = domain;
if (principal->mDomain) {
if (domain) {
MutexAutoLock lock(principal->mMutex);
principal->mDomain = domain;
principal->SetHasExplicitDomain();
}

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsNetUtil.h"
#include "nsScriptSecurityManager.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Mutex.h"
#include "mozilla/extensions/WebExtensionPolicy.h"
namespace Json {
@ -75,8 +76,10 @@ class ContentPrincipal final : public BasePrincipal {
private:
const nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mDomain;
Maybe<RefPtr<extensions::WebExtensionPolicyCore>> mAddon;
mozilla::Mutex mMutex{"ContentPrincipal::mMutex"};
nsCOMPtr<nsIURI> mDomain MOZ_GUARDED_BY(mMutex);
Maybe<RefPtr<extensions::WebExtensionPolicyCore>> mAddon
MOZ_GUARDED_BY(mMutex);
};
} // namespace mozilla

Просмотреть файл

@ -171,10 +171,15 @@ bool ExpandedPrincipal::AddonAllowsLoad(nsIURI* aURI,
return false;
}
void ExpandedPrincipal::SetCsp(nsIContentSecurityPolicy* aCSP) { mCSP = aCSP; }
void ExpandedPrincipal::SetCsp(nsIContentSecurityPolicy* aCSP) {
AssertIsOnMainThread();
mCSP = new nsMainThreadPtrHolder<nsIContentSecurityPolicy>(
"ExpandedPrincipal::mCSP", aCSP);
}
NS_IMETHODIMP
ExpandedPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) {
AssertIsOnMainThread();
NS_IF_ADDREF(*aCsp = mCSP);
return NS_OK;
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsCOMPtr.h"
#include "nsJSPrincipals.h"
#include "nsProxyRelease.h"
#include "nsTArray.h"
#include "nsNetUtil.h"
#include "mozilla/BasePrincipal.h"
@ -83,7 +84,8 @@ class ExpandedPrincipal : public nsIExpandedPrincipal,
private:
const nsTArray<nsCOMPtr<nsIPrincipal>> mPrincipals;
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsMainThreadPtrHandle<nsIContentSecurityPolicy> mCSP
MOZ_GUARDED_BY(mozilla::sMainThreadCapability);
};
#define NS_EXPANDEDPRINCIPAL_CID \

Просмотреть файл

@ -26,7 +26,6 @@ using namespace mozilla::ipc;
NS_IMETHODIMP_(MozExternalRefCountType)
nsJSPrincipals::AddRef() {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
MOZ_ASSERT(int32_t(refcount) >= 0, "illegal refcnt");
nsrefcnt count = ++refcount;
NS_LOG_ADDREF(this, count, "nsJSPrincipals", sizeof(*this));
@ -35,7 +34,6 @@ nsJSPrincipals::AddRef() {
NS_IMETHODIMP_(MozExternalRefCountType)
nsJSPrincipals::Release() {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
MOZ_ASSERT(0 != refcount, "dup release");
nsrefcnt count = --refcount;
NS_LOG_RELEASE(this, count, "nsJSPrincipals");