Bug 1536411 - StoragePrincipal - part 3 - IDBFactory, r=Ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 12 Apr 2019 05:31:13 +0000
changeset 528041 5b98a535f40d9036cf3f2db281393f3b4ed41877
parent 528040 382b8c528545e55f11deb83bc7bff63958f2b45e
child 528042 8593e3e867723fd4d52147fe3236f0c01498ff2b
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1536411
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1536411 - StoragePrincipal - part 3 - IDBFactory, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D24027
dom/base/nsGlobalWindowInner.cpp
dom/indexedDB/IDBFactory.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -6892,16 +6892,19 @@ void nsGlobalWindowInner::StorageAccessG
 
     if (NextGenLocalStorageEnabled() && mListenerManager &&
         mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
       auto object = static_cast<LSObject*>(mLocalStorage.get());
 
       object->EnsureObserver();
     }
   }
+
+  // Reset the IndexedDB factory.
+  mIndexedDB = nullptr;
 }
 
 mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() {
   return nsGlobalWindowInner::Cast(this)->TabGroupInner();
 }
 
 /* static */
 already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -296,24 +296,29 @@ nsresult IDBFactory::AllowedForWindowInt
   }
 
   nsContentUtils::StorageAccess access =
       nsContentUtils::StorageAllowedForWindow(aWindow);
 
   // the factory callsite records whether the browser is in private browsing.
   // and thus we don't have to respect that setting here. IndexedDB has no
   // concept of session-local storage, and thus ignores it.
-  if (access <= nsContentUtils::StorageAccess::eDeny) {
+  if (access == nsContentUtils::StorageAccess::eDeny) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  if (access == nsContentUtils::StorageAccess::ePartitionedOrDeny &&
+      !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
   MOZ_ASSERT(sop);
 
-  nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
+  nsCOMPtr<nsIPrincipal> principal = sop->GetEffectiveStoragePrincipal();
   if (NS_WARN_IF(!principal)) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   if (nsContentUtils::IsSystemPrincipal(principal)) {
     principal.forget(aPrincipal);
     return NS_OK;
   }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3355,16 +3355,21 @@ bool WorkerPrivate::ThawInternal() {
   return true;
 }
 
 void WorkerPrivate::PropagateFirstPartyStorageAccessGrantedInternal() {
   MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
 
   mLoadInfo.mFirstPartyStorageAccessGranted = true;
 
+  WorkerGlobalScope* globalScope = GlobalScope();
+  if (globalScope) {
+    globalScope->FirstPartyStorageAccessGranted();
+  }
+
   for (uint32_t index = 0; index < data->mChildWorkers.Length(); index++) {
     data->mChildWorkers[index]->PropagateFirstPartyStorageAccessGranted();
   }
 }
 
 void WorkerPrivate::TraverseTimeouts(nsCycleCollectionTraversalCallback& cb) {
   MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
   for (uint32_t i = 0; i < data->mTimeouts.Length(); ++i) {
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -388,24 +388,33 @@ already_AddRefed<Promise> WorkerGlobalSc
 
 already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
     ErrorResult& aErrorResult) {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
   RefPtr<IDBFactory> indexedDB = mIndexedDB;
 
   if (!indexedDB) {
-    if (mWorkerPrivate->StorageAccess() <=
-        nsContentUtils::StorageAccess::eDeny) {
+    nsContentUtils::StorageAccess access = mWorkerPrivate->StorageAccess();
+
+    if (access == nsContentUtils::StorageAccess::eDeny) {
       NS_WARNING("IndexedDB is not allowed in this worker!");
       aErrorResult = NS_ERROR_DOM_SECURITY_ERR;
       return nullptr;
     }
 
-    const PrincipalInfo& principalInfo = mWorkerPrivate->GetPrincipalInfo();
+    if (access == nsContentUtils::StorageAccess::ePartitionedOrDeny &&
+        !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) {
+      NS_WARNING("IndexedDB is not allowed in this worker!");
+      aErrorResult = NS_ERROR_DOM_SECURITY_ERR;
+      return nullptr;
+    }
+
+    const PrincipalInfo& principalInfo =
+        mWorkerPrivate->GetEffectiveStoragePrincipalInfo();
 
     nsresult rv = IDBFactory::CreateForWorker(this, principalInfo,
                                               mWorkerPrivate->WindowID(),
                                               getter_AddRefs(indexedDB));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aErrorResult = rv;
       return nullptr;
     }
@@ -483,16 +492,20 @@ WorkerGlobalScope::GetOrCreateServiceWor
       GetServiceWorkerRegistration(aDescriptor);
   if (!ref) {
     ref = ServiceWorkerRegistration::CreateForWorker(mWorkerPrivate, this,
                                                      aDescriptor);
   }
   return ref.forget();
 }
 
+void WorkerGlobalScope::FirstPartyStorageAccessGranted() {
+  mIndexedDB = nullptr;
+}
+
 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(
     WorkerPrivate* aWorkerPrivate, const nsString& aName)
     : WorkerGlobalScope(aWorkerPrivate), mName(aName) {}
 
 bool DedicatedWorkerGlobalScope::WrapGlobalObject(
     JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -185,16 +185,18 @@ class WorkerGlobalScope : public DOMEven
   Maybe<ServiceWorkerDescriptor> GetController() const override;
 
   RefPtr<mozilla::dom::ServiceWorkerRegistration> GetServiceWorkerRegistration(
       const ServiceWorkerRegistrationDescriptor& aDescriptor) const override;
 
   RefPtr<mozilla::dom::ServiceWorkerRegistration>
   GetOrCreateServiceWorkerRegistration(
       const ServiceWorkerRegistrationDescriptor& aDescriptor) override;
+
+  void FirstPartyStorageAccessGranted();
 };
 
 class DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
   const nsString mName;
 
   ~DedicatedWorkerGlobalScope() {}
 
  public: