Bug 1517089 - Part 11: Verify principalInfo before creating any parent actors; r=asuth
authorJan Varga <jan.varga@gmail.com>
Fri, 08 Feb 2019 21:02:03 +0100
changeset 520804 5b51bc2a466c98cbebe7cadd1098a9cc48951a9e
parent 520803 1169146b040952314971d194587fde84536cf3f1
child 520805 a87a6189d20bdedd8ce554e9ec7f5334e690fc0a
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
bugs1517089
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 1517089 - Part 11: Verify principalInfo before creating any parent actors; r=asuth Differential Revision: https://phabricator.services.mozilla.com/D19205
dom/localstorage/ActorsParent.cpp
dom/localstorage/ActorsParent.h
dom/localstorage/LSObject.cpp
dom/localstorage/LocalStorageManager2.cpp
ipc/glue/BackgroundParentImpl.cpp
--- a/dom/localstorage/ActorsParent.cpp
+++ b/dom/localstorage/ActorsParent.cpp
@@ -3109,24 +3109,82 @@ bool DeallocPBackgroundLSObserverParent(
   MOZ_ASSERT(aActor);
 
   // Transfer ownership back from IPDL.
   RefPtr<Observer> actor = dont_AddRef(static_cast<Observer*>(aActor));
 
   return true;
 }
 
+bool VerifyPrincipalInfo(const PrincipalInfo& aPrincipalInfo) {
+  AssertIsOnBackgroundThread();
+
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
+    ASSERT_UNLESS_FUZZING();
+    return false;
+  }
+
+  return true;
+}
+
+bool VerifyRequestParams(const LSRequestParams& aParams) {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
+
+  switch (aParams.type()) {
+    case LSRequestParams::TLSRequestPrepareDatastoreParams: {
+      const LSRequestPrepareDatastoreParams& params =
+          aParams.get_LSRequestPrepareDatastoreParams();
+
+      if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo()))) {
+        ASSERT_UNLESS_FUZZING();
+        return false;
+      }
+      break;
+    }
+
+    case LSRequestParams::TLSRequestPrepareObserverParams: {
+      const LSRequestPrepareObserverParams& params =
+          aParams.get_LSRequestPrepareObserverParams();
+
+      if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo()))) {
+        ASSERT_UNLESS_FUZZING();
+        return false;
+      }
+      break;
+    }
+
+    default:
+      MOZ_CRASH("Should never get here!");
+  }
+
+  return true;
+}
+
 PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
     PBackgroundParent* aBackgroundActor, const LSRequestParams& aParams) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread())) {
     return nullptr;
   }
 
+#ifdef DEBUG
+  // Always verify parameters in DEBUG builds!
+  bool trustParams = false;
+#else
+  bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
+#endif
+
+  if (!trustParams && NS_WARN_IF(!VerifyRequestParams(aParams))) {
+    ASSERT_UNLESS_FUZZING();
+    return nullptr;
+  }
+
   // If we're in the same process as the actor, we need to get the target event
   // queue from the current RequestHelper.
   nsCOMPtr<nsIEventTarget> mainEventTarget;
   if (!BackgroundParent::IsOtherProcessActor(aBackgroundActor)) {
     mainEventTarget = LSObject::GetSyncLoopEventTarget();
   }
 
   RefPtr<LSRequestBase> actor;
@@ -3191,24 +3249,60 @@ bool DeallocPBackgroundLSRequestParent(P
 
   // Transfer ownership back from IPDL.
   RefPtr<LSRequestBase> actor =
       dont_AddRef(static_cast<LSRequestBase*>(aActor));
 
   return true;
 }
 
+bool VerifyRequestParams(const LSSimpleRequestParams& aParams) {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
+
+  switch (aParams.type()) {
+    case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
+      const LSSimpleRequestPreloadedParams& params =
+          aParams.get_LSSimpleRequestPreloadedParams();
+
+      if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo()))) {
+        ASSERT_UNLESS_FUZZING();
+        return false;
+      }
+      break;
+    }
+
+    default:
+      MOZ_CRASH("Should never get here!");
+  }
+
+  return true;
+}
+
 PBackgroundLSSimpleRequestParent* AllocPBackgroundLSSimpleRequestParent(
-    const LSSimpleRequestParams& aParams) {
+    PBackgroundParent* aBackgroundActor, const LSSimpleRequestParams& aParams) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread())) {
     return nullptr;
   }
 
+#ifdef DEBUG
+  // Always verify parameters in DEBUG builds!
+  bool trustParams = false;
+#else
+  bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
+#endif
+
+  if (!trustParams && NS_WARN_IF(!VerifyRequestParams(aParams))) {
+    ASSERT_UNLESS_FUZZING();
+    return nullptr;
+  }
+
   RefPtr<LSSimpleRequestBase> actor;
 
   switch (aParams.type()) {
     case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
       RefPtr<PreloadedOp> preloadedOp = new PreloadedOp(aParams);
 
       actor = std::move(preloadedOp);
 
--- a/dom/localstorage/ActorsParent.h
+++ b/dom/localstorage/ActorsParent.h
@@ -57,16 +57,17 @@ PBackgroundLSRequestParent* AllocPBackgr
     const LSRequestParams& aParams);
 
 bool RecvPBackgroundLSRequestConstructor(PBackgroundLSRequestParent* aActor,
                                          const LSRequestParams& aParams);
 
 bool DeallocPBackgroundLSRequestParent(PBackgroundLSRequestParent* aActor);
 
 PBackgroundLSSimpleRequestParent* AllocPBackgroundLSSimpleRequestParent(
+    mozilla::ipc::PBackgroundParent* aBackgroundActor,
     const LSSimpleRequestParams& aParams);
 
 bool RecvPBackgroundLSSimpleRequestConstructor(
     PBackgroundLSSimpleRequestParent* aActor,
     const LSSimpleRequestParams& aParams);
 
 bool DeallocPBackgroundLSSimpleRequestParent(
     PBackgroundLSSimpleRequestParent* aActor);
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -230,16 +230,20 @@ nsresult LSObject::CreateForWindow(nsPID
   nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
   rv = PrincipalToPrincipalInfo(principal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo);
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+    return NS_ERROR_FAILURE;
+  }
+
   nsCString suffix;
   nsCString origin;
   rv = QuotaManager::GetInfoFromPrincipal(principal, &suffix, nullptr, &origin);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_ASSERT(originAttrSuffix == suffix);
@@ -289,16 +293,20 @@ nsresult LSObject::CreateForPrincipal(ns
   rv = PrincipalToPrincipalInfo(aPrincipal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
              principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo);
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
+    return NS_ERROR_FAILURE;
+  }
+
   nsCString suffix;
   nsCString origin;
 
   if (principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo) {
     QuotaManager::GetInfoForChrome(&suffix, nullptr, &origin);
   } else {
     rv = QuotaManager::GetInfoFromPrincipal(aPrincipal, &suffix, nullptr,
                                             &origin);
--- a/dom/localstorage/LocalStorageManager2.cpp
+++ b/dom/localstorage/LocalStorageManager2.cpp
@@ -77,16 +77,20 @@ nsresult CheckedPrincipalToPrincipalInfo
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aPrincipal);
 
   nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
+    return NS_ERROR_FAILURE;
+  }
+
   if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
       aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -362,17 +362,17 @@ bool BackgroundParentImpl::DeallocPBackg
 }
 
 BackgroundParentImpl::PBackgroundLSSimpleRequestParent*
 BackgroundParentImpl::AllocPBackgroundLSSimpleRequestParent(
     const LSSimpleRequestParams& aParams) {
   AssertIsInMainOrSocketProcess();
   AssertIsOnBackgroundThread();
 
-  return mozilla::dom::AllocPBackgroundLSSimpleRequestParent(aParams);
+  return mozilla::dom::AllocPBackgroundLSSimpleRequestParent(this, aParams);
 }
 
 mozilla::ipc::IPCResult
 BackgroundParentImpl::RecvPBackgroundLSSimpleRequestConstructor(
     PBackgroundLSSimpleRequestParent* aActor,
     const LSSimpleRequestParams& aParams) {
   AssertIsInMainOrSocketProcess();
   AssertIsOnBackgroundThread();