Bug 1576254 - Cut WorkerPrincipal over to a real object and implement isSystemOrAddonPrincipal r=baku

Unlike WorkletPrincipal, a WorkerPrincipal had been a simple static object shared by
all Workers. We never needed to consult it about an individual Worker before. Now we
do. So we cut it over from a static object to individual objects for each Worker.

We have an off main thread access problem for the Principal however, WorkerPrivate
has a method UsesSystemPrincipal that returns a bool that was initialized from the
Principal on the main thread. We copy that pattern and add a
UsesAddonOrExpandedAddonPrincipal method that will be called by the
isSystemOrAddonPrincipal method we must implement so we can inheirt from JSPrincipal.

Differential Revision: https://phabricator.services.mozilla.com/D47476

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tom Ritter 2019-10-04 17:37:09 +00:00
Родитель 446f05f035
Коммит cdd2029b79
7 изменённых файлов: 55 добавлений и 35 удалений

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

@ -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<WorkerPrincipal*>(aPrincipals);
}
} // namespace dom

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

@ -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

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

@ -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);

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

@ -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;

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

@ -126,6 +126,7 @@ struct WorkerLoadInfoData {
bool mReportCSPViolations;
bool mXHRParamsAllowed;
bool mPrincipalIsSystem;
bool mPrincipalIsAddonOrExpandedAddon;
bool mWatchedByDevtools;
StorageAccess mStorageAccess;
bool mFirstPartyStorageAccessGranted;

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

@ -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;

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

@ -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<Clients> 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,