Bug 1793995 - Part 6: Allow looking up a WebExtensionPolicyCore from any thread, r=kmag

In order to make WebAccessibleResource threadsafe, as well as other places, it
needs to be possible to look up a `WebExtensionPolicyCore` from any thread.
This is handled by using a static method on the ExtensionPolicyService for this
task, and keeping a seperate mutex-guarded static table under the hood.

Theoretically the table within `ExtensionPolicyService()` could also be
removed, however I held off on doing that in case it would have a negative
performance impact to take extra locks and follow extra pointers.

Differential Revision: https://phabricator.services.mozilla.com/D158884
This commit is contained in:
Nika Layzell 2022-10-13 21:47:00 +00:00
Родитель 233d36d3c4
Коммит a4606b1d02
3 изменённых файлов: 47 добавлений и 1 удалений

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

@ -24,6 +24,7 @@
#include "mozIExtensionProcessScript.h"
#include "nsEscape.h"
#include "nsGkAtoms.h"
#include "nsHashKeys.h"
#include "nsIChannel.h"
#include "nsIContentPolicy.h"
#include "mozilla/dom/Document.h"
@ -62,6 +63,13 @@ static const char kDocElementInserted[] = "initial-document-element-inserted";
* ExtensionPolicyService
*****************************************************************************/
using CoreByHostMap = nsTHashMap<nsCStringASCIICaseInsensitiveHashKey,
RefPtr<extensions::WebExtensionPolicyCore>>;
static StaticMutex sCoreByHostMutex;
static StaticAutoPtr<CoreByHostMap> sCoreByHost
MOZ_GUARDED_BY(sCoreByHostMutex);
/* static */
mozIExtensionProcessScript& ExtensionPolicyService::ProcessScript() {
static nsCOMPtr<mozIExtensionProcessScript> sProcessScript;
@ -78,6 +86,8 @@ mozIExtensionProcessScript& ExtensionPolicyService::ProcessScript() {
}
/* static */ ExtensionPolicyService& ExtensionPolicyService::GetSingleton() {
MOZ_ASSERT(NS_IsMainThread());
static RefPtr<ExtensionPolicyService> sExtensionPolicyService;
if (MOZ_UNLIKELY(!sExtensionPolicyService)) {
@ -88,6 +98,13 @@ mozIExtensionProcessScript& ExtensionPolicyService::ProcessScript() {
return *sExtensionPolicyService.get();
}
/* static */
RefPtr<extensions::WebExtensionPolicyCore>
ExtensionPolicyService::GetCoreByHost(const nsACString& aHost) {
StaticMutexAutoLock lock(sCoreByHostMutex);
return sCoreByHost ? sCoreByHost->Get(aHost) : nullptr;
}
ExtensionPolicyService::ExtensionPolicyService() {
mObs = services::GetObserverService();
MOZ_RELEASE_ASSERT(mObs);
@ -96,10 +113,22 @@ ExtensionPolicyService::ExtensionPolicyService() {
mDefaultCSPV3.SetIsVoid(true);
RegisterObservers();
{
StaticMutexAutoLock lock(sCoreByHostMutex);
MOZ_DIAGNOSTIC_ASSERT(!sCoreByHost,
"ExtensionPolicyService created twice?");
sCoreByHost = new CoreByHostMap();
}
}
ExtensionPolicyService::~ExtensionPolicyService() {
UnregisterWeakMemoryReporter(this);
{
StaticMutexAutoLock lock(sCoreByHostMutex);
sCoreByHost = nullptr;
}
}
bool ExtensionPolicyService::UseRemoteExtensions() const {
@ -144,6 +173,11 @@ bool ExtensionPolicyService::RegisterExtension(WebExtensionPolicy& aPolicy) {
mExtensions.InsertOrUpdate(aPolicy.Id(), RefPtr{&aPolicy});
mExtensionHosts.InsertOrUpdate(aPolicy.MozExtensionHostname(),
RefPtr{&aPolicy});
{
StaticMutexAutoLock lock(sCoreByHostMutex);
sCoreByHost->InsertOrUpdate(aPolicy.MozExtensionHostname(), aPolicy.Core());
}
return true;
}
@ -158,6 +192,11 @@ bool ExtensionPolicyService::UnregisterExtension(WebExtensionPolicy& aPolicy) {
mExtensions.Remove(aPolicy.Id());
mExtensionHosts.Remove(aPolicy.MozExtensionHostname());
{
StaticMutexAutoLock lock(sCoreByHostMutex);
sCoreByHost->Remove(aPolicy.MozExtensionHostname());
}
return true;
}

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

@ -60,6 +60,12 @@ class ExtensionPolicyService final : public nsIAddonPolicyService,
return do_AddRef(&GetSingleton());
}
// Unlike the other methods on the ExtensionPolicyService, this method is
// threadsafe, and can look up a WebExtensionPolicyCore by hostname on any
// thread.
static RefPtr<extensions::WebExtensionPolicyCore> GetCoreByHost(
const nsACString& aHost);
WebExtensionPolicy* GetByID(const nsAtom* aAddonId) {
return mExtensions.GetWeak(aAddonId);
}

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

@ -165,7 +165,8 @@ bool WebAccessibleResource::IsExtensionMatch(const URLInfo& aURI) {
if (!mExtensionIDs) {
return false;
}
WebExtensionPolicy* policy = EPS().GetByHost(aURI.Host());
RefPtr<WebExtensionPolicyCore> policy =
ExtensionPolicyService::GetCoreByHost(aURI.Host());
return policy && (mExtensionIDs->Contains(nsGkAtoms::_asterisk) ||
mExtensionIDs->Contains(policy->Id()));
}