From b582df1238e17371fb68d5711e80ddf106a814a4 Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Fri, 2 Dec 2022 00:53:51 +0000 Subject: [PATCH] Bug 1443925 - Part 5: Make it possible to get the system principal from any thread, r=ckerschb This is required because the script security manager which currently owns the singleton is main-thread only. This change still ties the lifecycle of the static to that service, but also makes it generally available from any thread. Differential Revision: https://phabricator.services.mozilla.com/D163035 --- caps/SystemPrincipal.cpp | 29 ++++++++++++++++++++++++++--- caps/SystemPrincipal.h | 9 ++++++++- caps/nsScriptSecurityManager.cpp | 5 ++--- dom/ipc/PermissionMessageUtils.cpp | 2 -- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/caps/SystemPrincipal.cpp b/caps/SystemPrincipal.cpp index 615e977f1f52..f92b5cc6b487 100644 --- a/caps/SystemPrincipal.cpp +++ b/caps/SystemPrincipal.cpp @@ -7,6 +7,7 @@ #include "nscore.h" #include "SystemPrincipal.h" +#include "mozilla/ClearOnShutdown.h" #include "nsCOMPtr.h" #include "nsReadableUtils.h" #include "nsCRT.h" @@ -29,9 +30,31 @@ SystemPrincipal::SystemPrincipal() : BasePrincipal(eSystemPrincipal, kSystemPrincipalSpec, OriginAttributes()) {} -already_AddRefed SystemPrincipal::Create() { - RefPtr sp = new SystemPrincipal(); - return sp.forget(); +static StaticMutex sSystemPrincipalMutex; +static StaticRefPtr sSystemPrincipal + MOZ_GUARDED_BY(sSystemPrincipalMutex); + +already_AddRefed SystemPrincipal::Get() { + StaticMutexAutoLock lock(sSystemPrincipalMutex); + return do_AddRef(sSystemPrincipal); +} + +already_AddRefed SystemPrincipal::Init() { + AssertIsOnMainThread(); + StaticMutexAutoLock lock(sSystemPrincipalMutex); + if (MOZ_UNLIKELY(sSystemPrincipal)) { + MOZ_ASSERT_UNREACHABLE("SystemPrincipal::Init() may only be called once"); + } else { + sSystemPrincipal = new SystemPrincipal(); + } + return do_AddRef(sSystemPrincipal); +} + +void SystemPrincipal::Shutdown() { + AssertIsOnMainThread(); + StaticMutexAutoLock lock(sSystemPrincipalMutex); + MOZ_ASSERT(sSystemPrincipal); + sSystemPrincipal = nullptr; } nsresult SystemPrincipal::GetScriptLocation(nsACString& aStr) { diff --git a/caps/SystemPrincipal.h b/caps/SystemPrincipal.h index d58cf6941401..7b89d7ddff57 100644 --- a/caps/SystemPrincipal.h +++ b/caps/SystemPrincipal.h @@ -22,6 +22,8 @@ } #define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1" +class nsScriptSecurityManager; + namespace Json { class Value; } @@ -32,7 +34,7 @@ class SystemPrincipal final : public BasePrincipal, public nsISerializable { SystemPrincipal(); public: - static already_AddRefed Create(); + static already_AddRefed Get(); static PrincipalKind Kind() { return eSystemPrincipal; } @@ -61,8 +63,13 @@ class SystemPrincipal final : public BasePrincipal, public nsISerializable { } protected: + friend class ::nsScriptSecurityManager; + virtual ~SystemPrincipal() = default; + static already_AddRefed Init(); + static void Shutdown(); + bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override { return true; diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 8418d9dabbe4..bf0899abcb2f 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -1554,9 +1554,7 @@ nsresult nsScriptSecurityManager::Init() { InitPrefs(); // Create our system principal singleton - RefPtr system = SystemPrincipal::Create(); - - mSystemPrincipal = system; + mSystemPrincipal = SystemPrincipal::Init(); return NS_OK; } @@ -1600,6 +1598,7 @@ nsScriptSecurityManager::~nsScriptSecurityManager(void) { void nsScriptSecurityManager::Shutdown() { NS_IF_RELEASE(sIOService); BundleHelper::Shutdown(); + SystemPrincipal::Shutdown(); } nsScriptSecurityManager* nsScriptSecurityManager::GetScriptSecurityManager() { diff --git a/dom/ipc/PermissionMessageUtils.cpp b/dom/ipc/PermissionMessageUtils.cpp index 4d3e8a349b00..19d232a7bca6 100644 --- a/dom/ipc/PermissionMessageUtils.cpp +++ b/dom/ipc/PermissionMessageUtils.cpp @@ -15,8 +15,6 @@ namespace mozilla::ipc { void IPDLParamTraits::Write(IPC::MessageWriter* aWriter, IProtocol* aActor, nsIPrincipal* aParam) { - MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread()); - Maybe info; if (aParam) { info.emplace();