Bug 1551055 - StoragePrincipal should be supported by localStorage - part 3 - Validate storagePrincipal, r=asuth
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 14 May 2019 05:49:58 +0000
changeset 532558 83e3da605798ac92bb8d283d3fc1523c1dd50222
parent 532557 df4c74e2ecf7f94ea48cb16896d0be1e6c675ae4
child 532559 22dc1f7f426beafab8b1bb4c5a8b4ba3528cb0b8
push id11270
push userrgurzau@mozilla.com
push dateWed, 15 May 2019 15:07:19 +0000
treeherdermozilla-beta@571bc76da583 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1551055
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 1551055 - StoragePrincipal should be supported by localStorage - part 3 - Validate storagePrincipal, r=asuth Differential Revision: https://phabricator.services.mozilla.com/D30947
dom/localstorage/ActorsParent.cpp
toolkit/components/antitracking/StoragePrincipalHelper.cpp
toolkit/components/antitracking/StoragePrincipalHelper.h
--- a/dom/localstorage/ActorsParent.cpp
+++ b/dom/localstorage/ActorsParent.cpp
@@ -34,16 +34,17 @@
 #include "mozilla/dom/quota/UsageInfo.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundParent.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/Logging.h"
 #include "mozilla/storage/Variant.h"
+#include "mozilla/StoragePrincipalHelper.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsExceptionHandler.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsISimpleEnumerator.h"
 #include "nsNetUtil.h"
@@ -3375,16 +3376,17 @@ bool DeallocPBackgroundLSObserverParent(
   // Transfer ownership back from IPDL.
   RefPtr<Observer> actor = dont_AddRef(static_cast<Observer*>(aActor));
 
   return true;
 }
 
 bool VerifyPrincipalInfo(const Maybe<ContentParentId>& aContentParentId,
                          const PrincipalInfo& aPrincipalInfo,
+                         const PrincipalInfo& aStoragePrincipalInfo,
                          const Maybe<nsID>& aClientId) {
   AssertIsOnBackgroundThread();
 
   if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
     ASSERT_UNLESS_FUZZING();
     return false;
   }
 
@@ -3392,17 +3394,19 @@ bool VerifyPrincipalInfo(const Maybe<Con
     RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
     if (svc &&
         !svc->HasWindow(aContentParentId, aPrincipalInfo, aClientId.ref())) {
       ASSERT_UNLESS_FUZZING();
       return false;
     }
   }
 
-  return true;
+  return StoragePrincipalHelper::
+      VerifyValidStoragePrincipalInfoForPrincipalInfo(aStoragePrincipalInfo,
+                                                      aPrincipalInfo);
 }
 
 bool VerifyOriginKey(const nsACString& aOriginKey,
                      const PrincipalInfo& aPrincipalInfo) {
   AssertIsOnBackgroundThread();
 
   nsCString originAttrSuffix;
   nsCString originKey;
@@ -3427,18 +3431,19 @@ bool VerifyRequestParams(const Maybe<Con
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
 
   switch (aParams.type()) {
     case LSRequestParams::TLSRequestPreloadDatastoreParams: {
       const LSRequestCommonParams& params =
           aParams.get_LSRequestPreloadDatastoreParams().commonParams();
 
-      if (NS_WARN_IF(!VerifyPrincipalInfo(aContentParentId,
-                                          params.principalInfo(), Nothing()))) {
+      if (NS_WARN_IF(
+              !VerifyPrincipalInfo(aContentParentId, params.principalInfo(),
+                                   params.storagePrincipalInfo(), Nothing()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
       }
 
       if (NS_WARN_IF(
               !VerifyOriginKey(params.originKey(), params.principalInfo()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
@@ -3447,19 +3452,19 @@ bool VerifyRequestParams(const Maybe<Con
     }
 
     case LSRequestParams::TLSRequestPrepareDatastoreParams: {
       const LSRequestPrepareDatastoreParams& params =
           aParams.get_LSRequestPrepareDatastoreParams();
 
       const LSRequestCommonParams& commonParams = params.commonParams();
 
-      if (NS_WARN_IF(!VerifyPrincipalInfo(aContentParentId,
-                                          commonParams.principalInfo(),
-                                          params.clientId()))) {
+      if (NS_WARN_IF(!VerifyPrincipalInfo(
+              aContentParentId, commonParams.principalInfo(),
+              commonParams.storagePrincipalInfo(), params.clientId()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
       }
 
       if (NS_WARN_IF(!VerifyOriginKey(commonParams.originKey(),
                                       commonParams.principalInfo()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
@@ -3467,17 +3472,18 @@ bool VerifyRequestParams(const Maybe<Con
       break;
     }
 
     case LSRequestParams::TLSRequestPrepareObserverParams: {
       const LSRequestPrepareObserverParams& params =
           aParams.get_LSRequestPrepareObserverParams();
 
       if (NS_WARN_IF(!VerifyPrincipalInfo(
-              aContentParentId, params.principalInfo(), params.clientId()))) {
+              aContentParentId, params.principalInfo(),
+              params.storagePrincipalInfo(), params.clientId()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
       }
       break;
     }
 
     default:
       MOZ_CRASH("Should never get here!");
@@ -3588,18 +3594,19 @@ bool VerifyRequestParams(const Maybe<Con
   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(aContentParentId,
-                                          params.principalInfo(), Nothing()))) {
+      if (NS_WARN_IF(
+              !VerifyPrincipalInfo(aContentParentId, params.principalInfo(),
+                                   params.storagePrincipalInfo(), Nothing()))) {
         ASSERT_UNLESS_FUZZING();
         return false;
       }
       break;
     }
 
     default:
       MOZ_CRASH("Should never get here!");
--- a/toolkit/components/antitracking/StoragePrincipalHelper.cpp
+++ b/toolkit/components/antitracking/StoragePrincipalHelper.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "StoragePrincipalHelper.h"
 
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsContentUtils.h"
 #include "nsIHttpChannel.h"
 
 namespace mozilla {
 
 namespace {
@@ -92,9 +93,93 @@ nsresult StoragePrincipalHelper::Prepare
     return NS_OK;
   }
 
   aOriginAttributes.SetFirstPartyDomain(false, principalURI,
                                         true /* aForced */);
   return NS_OK;
 }
 
+// static
+bool StoragePrincipalHelper::VerifyValidStoragePrincipalInfoForPrincipalInfo(
+    const mozilla::ipc::PrincipalInfo& aStoragePrincipalInfo,
+    const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
+  if (aStoragePrincipalInfo.type() != aPrincipalInfo.type()) {
+    return false;
+  }
+
+  if (aStoragePrincipalInfo.type() ==
+      mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
+    const mozilla::ipc::ContentPrincipalInfo& spInfo =
+        aStoragePrincipalInfo.get_ContentPrincipalInfo();
+    const mozilla::ipc::ContentPrincipalInfo& pInfo =
+        aPrincipalInfo.get_ContentPrincipalInfo();
+
+    if (!spInfo.attrs().EqualsIgnoringFPD(pInfo.attrs()) ||
+        spInfo.originNoSuffix() != pInfo.originNoSuffix() ||
+        spInfo.spec() != pInfo.spec() || spInfo.domain() != pInfo.domain() ||
+        spInfo.baseDomain() != pInfo.baseDomain() ||
+        spInfo.securityPolicies().Length() !=
+            pInfo.securityPolicies().Length()) {
+      return false;
+    }
+
+    for (uint32_t i = 0; i < spInfo.securityPolicies().Length(); ++i) {
+      if (spInfo.securityPolicies()[i].policy() !=
+              pInfo.securityPolicies()[i].policy() ||
+          spInfo.securityPolicies()[i].reportOnlyFlag() !=
+              pInfo.securityPolicies()[i].reportOnlyFlag() ||
+          spInfo.securityPolicies()[i].deliveredViaMetaTagFlag() !=
+              pInfo.securityPolicies()[i].deliveredViaMetaTagFlag()) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  if (aStoragePrincipalInfo.type() ==
+      mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
+    // Nothing to check here.
+    return true;
+  }
+
+  if (aStoragePrincipalInfo.type() ==
+      mozilla::ipc::PrincipalInfo::TNullPrincipalInfo) {
+    const mozilla::ipc::NullPrincipalInfo& spInfo =
+        aStoragePrincipalInfo.get_NullPrincipalInfo();
+    const mozilla::ipc::NullPrincipalInfo& pInfo =
+        aPrincipalInfo.get_NullPrincipalInfo();
+
+    return spInfo.spec() == pInfo.spec() &&
+           spInfo.attrs().EqualsIgnoringFPD(pInfo.attrs());
+  }
+
+  if (aStoragePrincipalInfo.type() ==
+      mozilla::ipc::PrincipalInfo::TExpandedPrincipalInfo) {
+    const mozilla::ipc::ExpandedPrincipalInfo& spInfo =
+        aStoragePrincipalInfo.get_ExpandedPrincipalInfo();
+    const mozilla::ipc::ExpandedPrincipalInfo& pInfo =
+        aPrincipalInfo.get_ExpandedPrincipalInfo();
+
+    if (!spInfo.attrs().EqualsIgnoringFPD(pInfo.attrs())) {
+      return false;
+    }
+
+    if (spInfo.allowlist().Length() != pInfo.allowlist().Length()) {
+      return false;
+    }
+
+    for (uint32_t i = 0; i < spInfo.allowlist().Length(); ++i) {
+      if (!VerifyValidStoragePrincipalInfoForPrincipalInfo(
+              spInfo.allowlist()[i], pInfo.allowlist()[i])) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  MOZ_CRASH("Invalid principalInfo type");
+  return false;
+}
+
 }  // namespace mozilla
--- a/toolkit/components/antitracking/StoragePrincipalHelper.h
+++ b/toolkit/components/antitracking/StoragePrincipalHelper.h
@@ -116,22 +116,30 @@
  * ServiceWorkers in partitioned context, this part must be revisited.
  */
 
 class nsIChannel;
 class nsIPrincipal;
 
 namespace mozilla {
 
+namespace ipc {
+class PrincipalInfo;
+}
+
 class OriginAttributes;
 
 class StoragePrincipalHelper final {
  public:
   static nsresult Create(nsIChannel* aChannel, nsIPrincipal* aPrincipal,
                          nsIPrincipal** aStoragePrincipal);
 
   static nsresult PrepareOriginAttributes(nsIChannel* aChannel,
                                           OriginAttributes& aOriginAttributes);
+
+  static bool VerifyValidStoragePrincipalInfoForPrincipalInfo(
+      const mozilla::ipc::PrincipalInfo& aStoragePrincipalInfo,
+      const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
 };
 
 }  // namespace mozilla
 
 #endif  // mozilla_StoragePrincipalHelper_h