Bug 1551055 - StoragePrincipal should be supported by localStorage - part 3 - Validate storagePrincipal, r=asuth
☠☠ backed out by 5abfe3566f38 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 13 May 2019 18:45:12 +0000
changeset 532463 21e44ad9c6df3e31355ab73e4fdfb23be8fe255b
parent 532462 8727e61ab69bd9ce729e66f890a74a95e96577cc
child 532464 5c3bfb23d0cee0bff3751d0c089c1c5c28dbcf82
push id11268
push usercsabou@mozilla.com
push dateTue, 14 May 2019 15:24:22 +0000
treeherdermozilla-beta@5fb7fcd568d6 [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