Bug 1526891 - Part 4: Add QuotaManager::IsPrincipalInfoValid checks to all quota clients; r=asuth
authorJan Varga <jan.varga@gmail.com>
Sat, 23 Feb 2019 17:03:40 +0100
changeset 520817 d6d4cb60bb71b533714f0269dc4af54cd9506ee3
parent 520816 cd67c16e6554d4e8d67388961ba403746efa221d
child 520818 8173a37df52bff6d1e207058d0fec29129fe449d
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1526891
milestone67.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 1526891 - Part 4: Add QuotaManager::IsPrincipalInfoValid checks to all quota clients; r=asuth Differential Revision: https://phabricator.services.mozilla.com/D20913
dom/asmjscache/AsmJSCache.cpp
dom/cache/CacheStorage.cpp
dom/cache/CacheStorageParent.cpp
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/IDBFactory.cpp
dom/simpledb/ActorsParent.cpp
dom/simpledb/SDBConnection.cpp
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -1143,16 +1143,21 @@ PAsmJSCacheEntryParent* AllocEntryParent
     return nullptr;
   }
 
   if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) {
     MOZ_ASSERT(false);
     return nullptr;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
+    MOZ_ASSERT(false);
+    return nullptr;
+  }
+
   RefPtr<ParentRunnable> runnable =
       new ParentRunnable(aPrincipalInfo, aOpenMode, aWriteParams);
 
   if (!sLiveParentActors) {
     sLiveParentActors = new ParentActorArray();
   }
 
   sLiveParentActors->AppendElement(runnable);
@@ -1403,16 +1408,21 @@ ChildRunnable::Run() {
 
       nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
       nsresult rv = PrincipalToPrincipalInfo(mPrincipal, principalInfo);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         Fail(JS::AsmJSCache_InternalError);
         return NS_OK;
       }
 
+      if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+        Fail(JS::AsmJSCache_InternalError);
+        return NS_OK;
+      }
+
       mPrincipalInfo = std::move(principalInfo);
 
       PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread();
       if (NS_WARN_IF(!actor)) {
         Fail(JS::AsmJSCache_InternalError);
         return NS_OK;
       }
 
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/dom/cache/AutoUtils.h"
 #include "mozilla/dom/cache/Cache.h"
 #include "mozilla/dom/cache/CacheChild.h"
 #include "mozilla/dom/cache/CacheStorageChild.h"
 #include "mozilla/dom/cache/CacheWorkerHolder.h"
 #include "mozilla/dom/cache/PCacheChild.h"
 #include "mozilla/dom/cache/ReadStream.h"
 #include "mozilla/dom/cache/TypeUtils.h"
+#include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/Document.h"
@@ -33,16 +34,17 @@
 #include "nsURLParsers.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 using mozilla::ErrorResult;
 using mozilla::Unused;
+using mozilla::dom::quota::QuotaManager;
 using mozilla::ipc::BackgroundChild;
 using mozilla::ipc::IProtocol;
 using mozilla::ipc::PBackgroundChild;
 using mozilla::ipc::PrincipalInfo;
 using mozilla::ipc::PrincipalToPrincipalInfo;
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::cache::CacheStorage);
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::cache::CacheStorage);
@@ -146,16 +148,22 @@ already_AddRefed<CacheStorage> CacheStor
 
   PrincipalInfo principalInfo;
   nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
     return nullptr;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(principalInfo))) {
+    NS_WARNING("CacheStorage not supported on invalid origins.");
+    RefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
+  }
+
   bool testingEnabled =
       aForceTrustedOrigin ||
       Preferences::GetBool("dom.caches.testing.enabled", false) ||
       StaticPrefs::dom_serviceWorkers_testing_enabled();
 
   if (!IsTrusted(principalInfo, testingEnabled)) {
     NS_WARNING("CacheStorage not supported on untrusted origins.");
     RefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
@@ -186,16 +194,21 @@ already_AddRefed<CacheStorage> CacheStor
   if (!workerHolder) {
     NS_WARNING("Worker thread is shutting down.");
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   const PrincipalInfo& principalInfo = aWorkerPrivate->GetPrincipalInfo();
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(principalInfo))) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
   // We have a number of cases where we want to skip the https scheme
   // validation:
   //
   // 1) Any worker when dom.caches.testing.enabled pref is true.
   // 2) Any worker when dom.serviceWorkers.testing.enabled pref is true.  This
   //    is mainly because most sites using SWs will expect Cache to work if
   //    SWs are enabled.
   // 3) If the window that created this worker has the devtools SW testing
--- a/dom/cache/CacheStorageParent.cpp
+++ b/dom/cache/CacheStorageParent.cpp
@@ -5,29 +5,36 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/cache/CacheStorageParent.h"
 
 #include "mozilla/Unused.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/cache/CacheOpParent.h"
 #include "mozilla/dom/cache/ManagerId.h"
+#include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/ipc/PBackgroundParent.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
+using mozilla::dom::quota::QuotaManager;
 using mozilla::ipc::PBackgroundParent;
 using mozilla::ipc::PrincipalInfo;
 
 // declared in ActorUtils.h
 PCacheStorageParent* AllocPCacheStorageParent(
     PBackgroundParent* aManagingActor, Namespace aNamespace,
     const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
+    MOZ_ASSERT(false);
+    return nullptr;
+  }
+
   return new CacheStorageParent(aManagingActor, aNamespace, aPrincipalInfo);
 }
 
 // declared in ActorUtils.h
 void DeallocPCacheStorageParent(PCacheStorageParent* aActor) { delete aActor; }
 
 CacheStorageParent::CacheStorageParent(PBackgroundParent* aManagingActor,
                                        Namespace aNamespace,
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -12172,16 +12172,21 @@ Factory::AllocPBackgroundIDBFactoryReque
   }
 
   if (NS_WARN_IF(principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo &&
                  metadata.persistenceType() != PERSISTENCE_TYPE_PERSISTENT)) {
     ASSERT_UNLESS_FUZZING();
     return nullptr;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(principalInfo))) {
+    ASSERT_UNLESS_FUZZING();
+    return nullptr;
+  }
+
   RefPtr<ContentParent> contentParent =
       BackgroundParent::GetContentParent(Manager());
 
   RefPtr<FactoryOp> actor;
   if (aParams.type() == FactoryRequestParams::TOpenDatabaseRequestParams) {
     actor = new OpenDatabaseOp(this, contentParent.forget(), *commonParams);
   } else {
     actor = new DeleteDatabaseOp(this, contentParent.forget(), *commonParams);
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -128,16 +128,21 @@ nsresult IDBFactory::CreateForWindow(nsP
   if (NS_WARN_IF(NS_FAILED(rv))) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
              principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo);
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+    IDB_REPORT_INTERNAL_ERR();
+    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
+
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
 
   RefPtr<IDBFactory> factory = new IDBFactory();
   factory->mPrincipalInfo = std::move(principalInfo);
   factory->mWindow = aWindow;
   factory->mTabChild = TabChild::GetFrom(aWindow);
   factory->mEventTarget =
@@ -164,16 +169,20 @@ nsresult IDBFactory::CreateForMainThread
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   nsresult rv = PrincipalToPrincipalInfo(principal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
+
   rv = CreateForMainThreadJSInternal(aCx, aOwningObject, principalInfo,
                                      aFactory);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_ASSERT(!principalInfo);
 
@@ -579,16 +588,22 @@ already_AddRefed<IDBOpenDBRequest> IDBFa
     }
 
     if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
         principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
       IDB_REPORT_INTERNAL_ERR();
       aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
       return nullptr;
     }
+
+    if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(principalInfo))) {
+      IDB_REPORT_INTERNAL_ERR();
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
   } else {
     principalInfo = *mPrincipalInfo;
   }
 
   uint64_t version = 0;
   if (!aDeleting && aVersion.WasPassed()) {
     if (aVersion.Value() < 1) {
       aRv.ThrowTypeError<MSG_INVALID_VERSION>();
--- a/dom/simpledb/ActorsParent.cpp
+++ b/dom/simpledb/ActorsParent.cpp
@@ -492,16 +492,21 @@ PBackgroundSDBConnectionParent* AllocPBa
     return nullptr;
   }
 
   if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) {
     ASSERT_UNLESS_FUZZING();
     return nullptr;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
+    ASSERT_UNLESS_FUZZING();
+    return nullptr;
+  }
+
   RefPtr<Connection> actor = new Connection(aPrincipalInfo);
 
   return actor.forget().take();
 }
 
 bool RecvPBackgroundSDBConnectionConstructor(
     PBackgroundSDBConnectionParent* aActor,
     const PrincipalInfo& aPrincipalInfo) {
--- a/dom/simpledb/SDBConnection.cpp
+++ b/dom/simpledb/SDBConnection.cpp
@@ -216,16 +216,20 @@ SDBConnection::Init(nsIPrincipal* aPrinc
   }
 
   if (principalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
       principalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
     NS_WARNING("Simpledb not allowed for this principal!");
     return NS_ERROR_INVALID_ARG;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
   mPrincipalInfo = std::move(principalInfo);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SDBConnection::Open(const nsAString& aName, nsISDBRequest** _retval) {
   AssertIsOnOwningThread();