diff --git a/dom/workers/Principal.cpp b/dom/workers/Principal.cpp index 1cfc91776d26..d910cb9435bf 100644 --- a/dom/workers/Principal.cpp +++ b/dom/workers/Principal.cpp @@ -13,36 +13,23 @@ namespace mozilla { namespace dom { -struct WorkerPrincipal final : public JSPrincipals { - bool write(JSContext* aCx, JSStructuredCloneWriter* aWriter) override { - return JS_WriteUint32Pair(aWriter, SCTAG_DOM_WORKER_PRINCIPAL, 0); - } -}; - -JSPrincipals* GetWorkerPrincipal() { - static WorkerPrincipal sPrincipal; - - /* - * To make sure the the principals refcount is initialized to one, atomically - * increment it on every pass though this function. If we discover this wasn't - * the first time, decrement it again. This avoids the need for - * synchronization. - */ - int32_t prevRefcount = sPrincipal.refcount++; - if (prevRefcount > 0) { - --sPrincipal.refcount; - } else { -#ifdef DEBUG - sPrincipal.debugToken = workerinternals::kJSPrincipalsDebugToken; -#endif - } - - return &sPrincipal; +WorkerPrincipal::WorkerPrincipal(bool aIsSystemOrAddonPrincipal) + : JSPrincipals(), mIsSystemOrAddonPrincipal(aIsSystemOrAddonPrincipal) { + setDebugToken(workerinternals::kJSPrincipalsDebugToken); } -void DestroyWorkerPrincipals(JSPrincipals* aPrincipals) { - MOZ_ASSERT_UNREACHABLE( - "Worker principals refcount should never fall below one"); +WorkerPrincipal::~WorkerPrincipal() = default; + +bool WorkerPrincipal::write(JSContext* aCx, JSStructuredCloneWriter* aWriter) { + return JS_WriteUint32Pair(aWriter, SCTAG_DOM_WORKER_PRINCIPAL, 0); +} + +bool WorkerPrincipal::isSystemOrAddonPrincipal() { + return mIsSystemOrAddonPrincipal; +} + +void WorkerPrincipal::Destroy(JSPrincipals* aPrincipals) { + delete static_cast(aPrincipals); } } // namespace dom diff --git a/dom/workers/Principal.h b/dom/workers/Principal.h index 3b3690ccfafa..f6d5d057f9f0 100644 --- a/dom/workers/Principal.h +++ b/dom/workers/Principal.h @@ -12,9 +12,23 @@ namespace mozilla { namespace dom { -JSPrincipals* GetWorkerPrincipal(); +struct MOZ_HEAP_CLASS WorkerPrincipal final : public JSPrincipals { + explicit WorkerPrincipal(bool aIsSystemOrAddonPrincipal); -void DestroyWorkerPrincipals(JSPrincipals* aPrincipals); + bool write(JSContext* aCx, JSStructuredCloneWriter* aWriter) override; + + // We don't distinguish between System or Addon because the only use + // case for this right now doesn't need to. When you need to distinguish + // add a second bool. + bool isSystemOrAddonPrincipal() override; + + // Callback for JS_InitDestroyPrincipalsCallback() + static void Destroy(JSPrincipals* aPrincipals); + + private: + ~WorkerPrincipal(); + bool mIsSystemOrAddonPrincipal; +}; } // namespace dom } // namespace mozilla diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index d6109c641e10..619287afa80d 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -965,7 +965,7 @@ class WorkerJSContext final : public mozilla::CycleCollectedJSContext { JSContext* cx = Context(); js::SetPreserveWrapperCallback(cx, PreserveWrapper); - JS_InitDestroyPrincipalsCallback(cx, DestroyWorkerPrincipals); + JS_InitDestroyPrincipalsCallback(cx, WorkerPrincipal::Destroy); JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks); if (mWorkerPrivate->IsDedicatedWorker()) { JS_SetFutexCanWait(cx); diff --git a/dom/workers/WorkerLoadInfo.cpp b/dom/workers/WorkerLoadInfo.cpp index 3383b8352a40..5934e37a82db 100644 --- a/dom/workers/WorkerLoadInfo.cpp +++ b/dom/workers/WorkerLoadInfo.cpp @@ -89,6 +89,7 @@ WorkerLoadInfoData::WorkerLoadInfoData() mReportCSPViolations(false), mXHRParamsAllowed(false), mPrincipalIsSystem(false), + mPrincipalIsAddonOrExpandedAddon(false), mWatchedByDevtools(false), mStorageAccess(StorageAccess::eDeny), mFirstPartyStorageAccessGranted(false), @@ -104,6 +105,8 @@ nsresult WorkerLoadInfo::SetPrincipalsAndCSPOnMainThread( mPrincipal = aPrincipal; mStoragePrincipal = aStoragePrincipal; mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); + mPrincipalIsAddonOrExpandedAddon = + aPrincipal->GetIsAddonOrExpandedAddonPrincipal(); mCSP = aCsp; diff --git a/dom/workers/WorkerLoadInfo.h b/dom/workers/WorkerLoadInfo.h index c20bd2703c24..d82c94ea4687 100644 --- a/dom/workers/WorkerLoadInfo.h +++ b/dom/workers/WorkerLoadInfo.h @@ -126,6 +126,7 @@ struct WorkerLoadInfoData { bool mReportCSPViolations; bool mXHRParamsAllowed; bool mPrincipalIsSystem; + bool mPrincipalIsAddonOrExpandedAddon; bool mWatchedByDevtools; StorageAccess mStorageAccess; bool mFirstPartyStorageAccessGranted; diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 557b7e1a85de..6cbf39bb9372 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -695,6 +695,9 @@ class WorkerPrivate : public RelativeTimeline { } bool UsesSystemPrincipal() const { return mLoadInfo.mPrincipalIsSystem; } + bool UsesAddonOrExpandedAddonPrincipal() const { + return mLoadInfo.mPrincipalIsAddonOrExpandedAddon; + } const mozilla::ipc::PrincipalInfo& GetPrincipalInfo() const { return *mLoadInfo.mPrincipalInfo; diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 0d16d661f250..9fac4a2fd48f 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -614,7 +614,10 @@ bool DedicatedWorkerGlobalScope::WrapGlobalObject( xpc::SetPrefableRealmOptions(options); return DedicatedWorkerGlobalScope_Binding::Wrap( - aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); + aCx, this, this, options, + new WorkerPrincipal(usesSystemPrincipal || + mWorkerPrivate->UsesAddonOrExpandedAddonPrincipal()), + true, aReflector); } void DedicatedWorkerGlobalScope::PostMessage( @@ -650,7 +653,10 @@ bool SharedWorkerGlobalScope::WrapGlobalObject( mWorkerPrivate->CopyJSRealmOptions(options); return SharedWorkerGlobalScope_Binding::Wrap( - aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); + aCx, this, this, options, + new WorkerPrincipal(mWorkerPrivate->UsesSystemPrincipal() || + mWorkerPrivate->UsesAddonOrExpandedAddonPrincipal()), + true, aReflector); } void SharedWorkerGlobalScope::Close() { @@ -690,7 +696,10 @@ bool ServiceWorkerGlobalScope::WrapGlobalObject( mWorkerPrivate->CopyJSRealmOptions(options); return ServiceWorkerGlobalScope_Binding::Wrap( - aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); + aCx, this, this, options, + new WorkerPrincipal(mWorkerPrivate->UsesSystemPrincipal() || + mWorkerPrivate->UsesAddonOrExpandedAddonPrincipal()), + true, aReflector); } already_AddRefed ServiceWorkerGlobalScope::GetClients() { @@ -941,7 +950,10 @@ bool WorkerDebuggerGlobalScope::WrapGlobalObject( mWorkerPrivate->CopyJSRealmOptions(options); return WorkerDebuggerGlobalScope_Binding::Wrap( - aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); + aCx, this, this, options, + new WorkerPrincipal(mWorkerPrivate->UsesSystemPrincipal() || + mWorkerPrivate->UsesAddonOrExpandedAddonPrincipal()), + true, aReflector); } void WorkerDebuggerGlobalScope::GetGlobal(JSContext* aCx,