commit 67173fc914d1fb17b942e8f7b1c9de770a21a347
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Thu Oct 8 12:45:37 2015 -0700
Bug 15564: Isolate SharedWorker by first party domain
---
dom/workers/RuntimeService.cpp | 27 ++++++++++++++++++++-------
dom/workers/RuntimeService.h | 5 ++++-
dom/workers/WorkerPrivate.cpp | 5 +++++
dom/workers/WorkerPrivate.h | 8 ++++++++
4 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index 271c74f..4f5f363 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -64,6 +64,7 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "WorkerThread.h"
+#include "ThirdPartyUtil.h"
#ifdef ENABLE_TESTS
#include "BackgroundChildImpl.h"
@@ -269,11 +270,13 @@ GetWorkerPref(const nsACString& aPref,
// This function creates a key for a SharedWorker composed by "name|scriptSpec".
// If the name contains a '|', this will be replaced by '||'.
void
-GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName,
+GenerateSharedWorkerKey(const nsACString& aScriptSpec,
+ const nsACString& aIsolationKey,
+ const nsACString& aName,
nsCString& aKey)
{
aKey.Truncate();
- aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + 1);
+ aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + aIsolationKey.Length() + 2);
nsACString::const_iterator start, end;
aName.BeginReading(start);
@@ -288,6 +291,9 @@ GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName,
aKey.Append('|');
aKey.Append(aScriptSpec);
+
+ aKey.Append('|');
+ aKey.Append(aIsolationKey);
}
void
@@ -1402,13 +1408,16 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
if (isSharedOrServiceWorker) {
const nsCString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
+ const nsCString& isolationKey = aWorkerPrivate->IsolationKey();
nsAutoCString key;
- GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, key);
+ GenerateSharedWorkerKey(sharedWorkerScriptSpec, isolationKey, sharedWorkerName, key);
MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key));
SharedWorkerInfo* sharedWorkerInfo =
- new SharedWorkerInfo(aWorkerPrivate, sharedWorkerScriptSpec,
+ new SharedWorkerInfo(aWorkerPrivate,
+ sharedWorkerScriptSpec,
+ isolationKey,
sharedWorkerName);
domainInfo->mSharedWorkerInfos.Put(key, sharedWorkerInfo);
}
@@ -1509,7 +1518,9 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
if (match.mSharedWorkerInfo) {
nsAutoCString key;
GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec,
- match.mSharedWorkerInfo->mName, key);
+ match.mSharedWorkerInfo->mIsolationKey,
+ match.mSharedWorkerInfo->mName,
+ key);
domainInfo->mSharedWorkerInfos.Remove(key);
}
}
@@ -2293,7 +2304,7 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString key;
- GenerateSharedWorkerKey(scriptSpec, aName, key);
+ GenerateSharedWorkerKey(scriptSpec, aLoadInfo->mIsolationKey, aName, key);
if (mDomainMap.Get(aLoadInfo->mDomain, &domainInfo) &&
domainInfo->mSharedWorkerInfos.Get(key, &sharedWorkerInfo)) {
@@ -2368,7 +2379,9 @@ RuntimeService::ForgetSharedWorker(WorkerPrivate* aWorkerPrivate)
if (match.mSharedWorkerInfo) {
nsAutoCString key;
GenerateSharedWorkerKey(match.mSharedWorkerInfo->mScriptSpec,
- match.mSharedWorkerInfo->mName, key);
+ match.mSharedWorkerInfo->mIsolationKey,
+ match.mSharedWorkerInfo->mName,
+ key);
domainInfo->mSharedWorkerInfos.Remove(key);
}
}
diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h
index 94bff10..8036b60 100644
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -34,12 +34,15 @@ class RuntimeService final : public nsIObserver
{
WorkerPrivate* mWorkerPrivate;
nsCString mScriptSpec;
+ nsCString mIsolationKey;
nsCString mName;
SharedWorkerInfo(WorkerPrivate* aWorkerPrivate,
const nsACString& aScriptSpec,
+ const nsACString& aIsolationKey,
const nsACString& aName)
- : mWorkerPrivate(aWorkerPrivate), mScriptSpec(aScriptSpec), mName(aName)
+ : mWorkerPrivate(aWorkerPrivate), mScriptSpec(aScriptSpec),
+ mIsolationKey(aIsolationKey), mName(aName)
{ }
};
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 7057b3a..5d0064b 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4355,6 +4355,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
}
loadInfo.mDomain = aParent->Domain();
+ loadInfo.mIsolationKey = aParent->IsolationKey();
loadInfo.mFromWindow = aParent->IsFromWindow();
loadInfo.mWindowID = aParent->WindowID();
loadInfo.mIndexedDBAllowed = aParent->IsIndexedDBAllowed();
@@ -4421,6 +4422,10 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
loadInfo.mBaseURI = document->GetDocBaseURI();
loadInfo.mLoadGroup = document->GetDocumentLoadGroup();
+ nsCString isolationKey;
+ ThirdPartyUtil::GetFirstPartyHost(document, isolationKey);
+ loadInfo.mIsolationKey = isolationKey;
+
// Use the document's NodePrincipal as our principal if we're not being
// called from chrome.
if (!loadInfo.mPrincipal) {
diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
index a684e6d..a84407c 100644
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -169,6 +169,7 @@ public:
nsAutoPtr<PrincipalInfo> mPrincipalInfo;
nsCString mDomain;
+ nsCString mIsolationKey;
uint64_t mWindowID;
@@ -218,6 +219,7 @@ public:
mPrincipalInfo = aOther.mPrincipalInfo.forget();
mDomain = aOther.mDomain;
+ mIsolationKey = aOther.mIsolationKey;
mWindowID = aOther.mWindowID;
mFromWindow = aOther.mFromWindow;
mEvalAllowed = aOther.mEvalAllowed;
@@ -532,6 +534,12 @@ public:
return mLoadInfo.mDomain;
}
+ const nsCString&
+ IsolationKey() const
+ {
+ return mLoadInfo.mIsolationKey;
+ }
+
bool
IsFromWindow() const
{