Bug 1346759 - Use URI comparison for null principals instead of pointer comparison. r=ckerschb,bholley
authorJonathan Kingston <jkt@mozilla.com>
Mon, 11 Feb 2019 18:03:12 +0000
changeset 458555 ef4325327e46517ba3cfd72a9b4e02c6ccbf9080
parent 458554 1dc5c6572cf1eca5c283741ba043a9ecf2f7ac39
child 458556 6d8e6f960446fe8145ccb028d6644db879f2caa6
push id111855
push userbtara@mozilla.com
push dateMon, 11 Feb 2019 22:01:49 +0000
treeherdermozilla-inbound@42a097167d36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb, bholley
bugs1346759
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 1346759 - Use URI comparison for null principals instead of pointer comparison. r=ckerschb,bholley Differential Revision: https://phabricator.services.mozilla.com/D12154
Cargo.lock
Cargo.toml
caps/BasePrincipal.h
caps/NullPrincipal.cpp
caps/NullPrincipal.h
caps/NullPrincipalURI.cpp
layout/style/RunCbindgen.py
toolkit/library/rust/shared/Cargo.toml
toolkit/library/rust/shared/lib.rs
toolkit/mozapps/extensions/AddonManager.jsm
xpcom/base/GkRustUtils.cpp
xpcom/base/GkRustUtils.h
xpcom/base/moz.build
xpcom/base/nsInterfaceRequestorAgg.cpp
xpcom/rust/gkrust_utils/Cargo.toml
xpcom/rust/gkrust_utils/cbindgen.toml
xpcom/rust/gkrust_utils/src/lib.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1118,16 +1118,17 @@ dependencies = [
  "audioipc-server 0.2.3",
  "cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "cubeb-pulse 0.2.0",
  "cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_glue 0.1.0",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geckoservo 0.0.1",
+ "gkrust_utils 0.1.0",
  "jsrust_shared 0.1.0",
  "kvstore 0.1.0",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozurl 0.0.1",
  "mp4parse_capi 0.11.2",
  "netwerk_helper 0.0.1",
  "nserror 0.1.0",
  "nsstring 0.1.0",
@@ -1136,16 +1137,24 @@ dependencies = [
  "rsdparsa_capi 0.1.0",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "u2fhid 0.2.3",
  "webrender_bindings 0.1.0",
  "xpcom 0.1.0",
 ]
 
 [[package]]
+name = "gkrust_utils"
+version = "0.1.0"
+dependencies = [
+ "nsstring 0.1.0",
+ "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "gl_generator"
 version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "khronos_api 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,16 +31,17 @@ exclude = [
 
   # Excluded because they are used only as dependencies, not top-level targets,
   # so we don't need to vendor their dev-dependencies.
   "dom/webauthn/u2f-hid-rs",
   "gfx/webrender_bindings",
   "media/mp4parse-rust/mp4parse",
   "media/mp4parse-rust/mp4parse_capi",
   "media/mp4parse-rust/mp4parse_fallible",
+  "xpcom/rust/gkrust_utils",
 ]
 
 # Explicitly specify what our profiles use.  The opt-level setting here is
 # a total fiction; see the setup of MOZ_RUST_DEFAULT_FLAGS for what the
 # opt-level setting will be as a result of various other configure flags.
 [profile.dev]
 opt-level = 1
 rpath = false
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -274,23 +274,21 @@ inline bool BasePrincipal::FastEquals(ns
   if (Kind() != other->Kind()) {
     // Principals of different kinds can't be equal.
     return false;
   }
 
   // Two principals are considered to be equal if their origins are the same.
   // If the two principals are codebase principals, their origin attributes
   // (aka the origin suffix) must also match.
-  // If the two principals are null principals, they're only equal if they're
-  // the same object.
-  if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
+  if (Kind() == eSystemPrincipal) {
     return this == other;
   }
 
-  if (Kind() == eCodebasePrincipal) {
+  if (Kind() == eCodebasePrincipal || Kind() == eNullPrincipal) {
     return mOriginNoSuffix == other->mOriginNoSuffix &&
            mOriginSuffix == other->mOriginSuffix;
   }
 
   MOZ_ASSERT(Kind() == eExpandedPrincipal);
   return mOriginNoSuffix == other->mOriginNoSuffix;
 }
 
@@ -303,23 +301,16 @@ inline bool BasePrincipal::FastEqualsCon
   }
 
   return Subsumes(aOther, ConsiderDocumentDomain) &&
          other->Subsumes(this, ConsiderDocumentDomain);
 }
 
 inline bool BasePrincipal::FastSubsumes(nsIPrincipal* aOther) {
   // If two principals are equal, then they both subsume each other.
-  // We deal with two special cases first:
-  // Null principals only subsume each other if they are equal, and are only
-  // equal if they're the same object.
-  auto other = Cast(aOther);
-  if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
-    return this == other;
-  }
   if (FastEquals(aOther)) {
     return true;
   }
 
   // Otherwise, fall back to the slow path.
   return Subsumes(aOther, DontConsiderDocumentDomain);
 }
 
--- a/caps/NullPrincipal.cpp
+++ b/caps/NullPrincipal.cpp
@@ -166,17 +166,19 @@ NullPrincipal::SetDomain(nsIURI* aDomain
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 bool NullPrincipal::MayLoadInternal(nsIURI* aURI) {
   // Also allow the load if we are the principal of the URI being checked.
   nsCOMPtr<nsIPrincipal> blobPrincipal;
   if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
           aURI, getter_AddRefs(blobPrincipal))) {
-    return blobPrincipal == this;
+    MOZ_ASSERT(blobPrincipal);
+    return SubsumesInternal(blobPrincipal,
+                            BasePrincipal::ConsiderDocumentDomain);
   }
 
   return false;
 }
 
 NS_IMETHODIMP
 NullPrincipal::GetBaseDomain(nsACString& aBaseDomain) {
   // For a null principal, we use our unique uuid as the base domain.
--- a/caps/NullPrincipal.h
+++ b/caps/NullPrincipal.h
@@ -82,17 +82,18 @@ class NullPrincipal final : public BaseP
     return NS_OK;
   }
 
  protected:
   virtual ~NullPrincipal() = default;
 
   bool SubsumesInternal(nsIPrincipal* aOther,
                         DocumentDomainConsideration aConsideration) override {
-    return aOther == this;
+    MOZ_ASSERT(aOther);
+    return FastEquals(aOther);
   }
 
   bool MayLoadInternal(nsIURI* aURI) override;
 
   nsCOMPtr<nsIURI> mURI;
 
  private:
   // If aIsFirstParty is true, this NullPrincipal will be initialized base on
--- a/caps/NullPrincipalURI.cpp
+++ b/caps/NullPrincipalURI.cpp
@@ -10,40 +10,31 @@
 #include "mozilla/MemoryReporting.h"
 
 #include "mozilla/ipc/URIParams.h"
 
 #include "nsEscape.h"
 #include "nsCRT.h"
 #include "nsIUUIDGenerator.h"
 
+#include "mozilla/GkRustUtils.h"
+
 using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////////////
 //// NullPrincipalURI
 
 NullPrincipalURI::NullPrincipalURI() {}
 
 NullPrincipalURI::NullPrincipalURI(const NullPrincipalURI& aOther) {
   mPath.Assign(aOther.mPath);
 }
 
 nsresult NullPrincipalURI::Init() {
-  // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
-  nsCOMPtr<nsIUUIDGenerator> uuidgen = services::GetUUIDGenerator();
-  NS_ENSURE_TRUE(uuidgen, NS_ERROR_NOT_AVAILABLE);
-
-  nsID id;
-  nsresult rv = uuidgen->GenerateUUIDInPlace(&id);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mPath.SetLength(NSID_LENGTH - 1);  // -1 because NSID_LENGTH counts the '\0'
-  id.ToProvidedString(
-      *reinterpret_cast<char(*)[NSID_LENGTH]>(mPath.BeginWriting()));
-
+  GkRustUtils::GenerateUUID(mPath);
   MOZ_ASSERT(mPath.Length() == NSID_LENGTH - 1);
   MOZ_ASSERT(strlen(mPath.get()) == NSID_LENGTH - 1);
 
   return NS_OK;
 }
 
 /* static */
 already_AddRefed<NullPrincipalURI> NullPrincipalURI::Create() {
--- a/layout/style/RunCbindgen.py
+++ b/layout/style/RunCbindgen.py
@@ -5,16 +5,18 @@
 from __future__ import print_function
 import buildconfig
 import mozpack.path as mozpath
 import os
 import subprocess
 
 CARGO_LOCK = mozpath.join(buildconfig.topsrcdir, "Cargo.lock")
 
+# cbindgen_crate_path needs to match the crate name
+# EG: /xpcom/rust/gkrust_utils is the path for the "gkrust_utils" crate
 def generate(output, cbindgen_crate_path, *in_tree_dependencies):
     env = os.environ.copy()
     env['CARGO'] = str(buildconfig.substs['CARGO'])
 
     p = subprocess.Popen([
         buildconfig.substs['CBINDGEN'],
         mozpath.join(buildconfig.topsrcdir, "toolkit", "library", "rust"),
         "--lockfile",
--- a/toolkit/library/rust/shared/Cargo.toml
+++ b/toolkit/library/rust/shared/Cargo.toml
@@ -19,16 +19,17 @@ mozurl = { path = "../../../../netwerk/b
 webrender_bindings = { path = "../../../../gfx/webrender_bindings", optional = true }
 cubeb-pulse = { path = "../../../../media/libcubeb/cubeb-pulse-rs", optional = true, features=["pulse-dlopen"] }
 cubeb-sys = { version = "0.5.0", optional = true, features=["gecko-in-tree"] }
 encoding_c = "0.9.0"
 encoding_glue = { path = "../../../../intl/encoding_glue" }
 audioipc-client = { path = "../../../../media/audioipc/client", optional = true }
 audioipc-server = { path = "../../../../media/audioipc/server", optional = true }
 u2fhid = { path = "../../../../dom/webauthn/u2f-hid-rs" }
+gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
 rsdparsa_capi = { path = "../../../../media/webrtc/signaling/src/sdp/rsdparsa_capi" }
 # We have these to enforce common feature sets for said crates.
 log = {version = "0.4", features = ["release_max_level_info"]}
 env_logger = {version = "0.5", default-features = false} # disable `regex` to reduce code size
 cose-c = { version = "0.1.5" }
 jsrust_shared = { path = "../../../../js/src/rust/shared", optional = true }
 arrayvec = "0.4"
 
--- a/toolkit/library/rust/shared/lib.rs
+++ b/toolkit/library/rust/shared/lib.rs
@@ -24,16 +24,17 @@ extern crate cubeb_pulse;
 extern crate encoding_c;
 extern crate encoding_glue;
 #[cfg(feature = "cubeb-remoting")]
 extern crate audioipc_client;
 #[cfg(feature = "cubeb-remoting")]
 extern crate audioipc_server;
 extern crate env_logger;
 extern crate u2fhid;
+extern crate gkrust_utils;
 extern crate log;
 extern crate cosec;
 extern crate rsdparsa_capi;
 #[cfg(feature = "spidermonkey_rust")]
 extern crate jsrust_shared;
 
 extern crate arrayvec;
 
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -1896,17 +1896,17 @@ var AddonManagerInternal = {
 
     try {
       if (!this.isInstallEnabled(aMimetype)) {
         aInstall.cancel();
 
         this.installNotifyObservers("addon-install-disabled", topBrowser,
                                     aInstallingPrincipal.URI, aInstall);
         return;
-      } else if (!aBrowser.contentPrincipal || !aInstallingPrincipal.subsumes(aBrowser.contentPrincipal)) {
+      } else if (aInstallingPrincipal.isNullPrincipal || !aBrowser.contentPrincipal || !aInstallingPrincipal.subsumes(aBrowser.contentPrincipal)) {
         aInstall.cancel();
 
         this.installNotifyObservers("addon-install-origin-blocked", topBrowser,
                                     aInstallingPrincipal.URI, aInstall);
         return;
       }
 
       // The install may start now depending on the web install listener,
new file mode 100644
--- /dev/null
+++ b/xpcom/base/GkRustUtils.cpp
@@ -0,0 +1,15 @@
+/* -*- 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 "gk_rust_utils_ffi_generated.h"
+#include "nsString.h"
+#include "GkRustUtils.h"
+
+using namespace mozilla;
+
+/* static */ void GkRustUtils::GenerateUUID(nsACString& aResult) {
+  GkRustUtils_GenerateUUID(&aResult);
+};
new file mode 100644
--- /dev/null
+++ b/xpcom/base/GkRustUtils.h
@@ -0,0 +1,11 @@
+#ifndef __mozilla_GkRustUtils_h
+#define __mozilla_GkRustUtils_h
+
+#include "nsString.h"
+
+class GkRustUtils {
+ public:
+  static void GenerateUUID(nsACString& aResult);
+};
+
+#endif
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -110,16 +110,17 @@ EXPORTS.mozilla += [
     'CountingAllocatorBase.h',
     'CycleCollectedJSContext.h',
     'CycleCollectedJSRuntime.h',
     'Debug.h',
     'DebuggerOnGCRunnable.h',
     'DeferredFinalize.h',
     'EnumeratedArrayCycleCollection.h',
     'ErrorNames.h',
+    'GkRustUtils.h',
     'HoldDropJSObjects.h',
     'IntentionalCrash.h',
     'JSObjectHolder.h',
     'Logging.h',
     'MemoryInfo.h',
     'MemoryMapping.h',
     'MemoryReportingProcess.h',
     'MemoryTelemetry.h',
@@ -144,16 +145,17 @@ UNIFIED_SOURCES += [
     'AvailableMemoryTracker.cpp',
     'ClearOnShutdown.cpp',
     'CycleCollectedJSContext.cpp',
     'CycleCollectedJSRuntime.cpp',
     'Debug.cpp',
     'DebuggerOnGCRunnable.cpp',
     'DeferredFinalize.cpp',
     'ErrorNames.cpp',
+    'GkRustUtils.cpp',
     'HoldDropJSObjects.cpp',
     'JSObjectHolder.cpp',
     'LogCommandLineHandler.cpp',
     'Logging.cpp',
     'LogModulePrefWatcher.cpp',
     'MemoryTelemetry.cpp',
     'nsClassInfoImpl.cpp',
     'nsCOMPtr.cpp',
@@ -210,16 +212,31 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
     SOURCES += [
         'nsMacUtilsImpl.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'nsCrashOnException.cpp',
     ]
 
+if CONFIG['COMPILE_ENVIRONMENT']:
+    GENERATED_FILES += [
+        'gk_rust_utils_ffi_generated.h',
+    ]
+
+    EXPORTS.mozilla += [
+        '!gk_rust_utils_ffi_generated.h',
+    ]
+
+    ffi_generated = GENERATED_FILES['gk_rust_utils_ffi_generated.h']
+    ffi_generated.script = '/layout/style/RunCbindgen.py:generate'
+    ffi_generated.inputs = [
+        '/xpcom/rust/gkrust_utils',
+    ]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../build',
     '/dom/base',
     '/mfbt',
--- a/xpcom/base/nsInterfaceRequestorAgg.cpp
+++ b/xpcom/base/nsInterfaceRequestorAgg.cpp
@@ -17,17 +17,17 @@ class nsInterfaceRequestorAgg final : pu
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINTERFACEREQUESTOR
 
   nsInterfaceRequestorAgg(nsIInterfaceRequestor* aFirst,
                           nsIInterfaceRequestor* aSecond,
                           nsIEventTarget* aConsumerTarget = nullptr)
       : mFirst(aFirst), mSecond(aSecond), mConsumerTarget(aConsumerTarget) {
     if (!mConsumerTarget) {
-      mConsumerTarget = GetCurrentThreadEventTarget();
+      mConsumerTarget = mozilla::GetCurrentThreadEventTarget();
     }
   }
 
  private:
   ~nsInterfaceRequestorAgg();
 
   nsCOMPtr<nsIInterfaceRequestor> mFirst, mSecond;
   nsCOMPtr<nsIEventTarget> mConsumerTarget;
new file mode 100644
--- /dev/null
+++ b/xpcom/rust/gkrust_utils/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "gkrust_utils"
+version = "0.1.0"
+authors = ["Jonathan Kingston <jkt@mozilla.com>"]
+
+[dependencies]
+uuid = { version = "0.6", features = ["v4"] }
+nsstring = { path = "../nsstring" }
new file mode 100644
--- /dev/null
+++ b/xpcom/rust/gkrust_utils/cbindgen.toml
@@ -0,0 +1,31 @@
+header = """/* 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/. */"""
+autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
+ * To generate this file:
+ *   1. Get the latest cbindgen using `cargo install --force cbindgen`
+ *      a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release
+ *   2. Run `rustup run nightly cbindgen xpcom/rust/gkrust_utils --lockfile Cargo.lock --crate gkrust_utils -o xpcom/base/gk_rust_utils_ffi_generated.h`
+ */
+#include "nsError.h"
+#include "nsString.h"
+"""
+include_version = true
+braces = "SameLine"
+line_length = 100
+tab_width = 2
+language = "C++"
+namespaces = ["mozilla"]
+
+[export]
+# Skip constants because we don't have any
+item_types = ["globals", "enums", "structs", "unions", "typedefs", "opaque", "functions"]
+
+[enum]
+add_sentinel = true
+derive_helper_methods = true
+
+[defines]
+"target_os = windows" = "XP_WIN"
+"target_os = macos" = "XP_MACOSX"
+"target_os = android" = "ANDROID"
new file mode 100644
--- /dev/null
+++ b/xpcom/rust/gkrust_utils/src/lib.rs
@@ -0,0 +1,13 @@
+extern crate nsstring;
+extern crate uuid;
+use nsstring::nsACString;
+use uuid::Uuid;
+
+use std::fmt::Write;
+
+#[no_mangle]
+pub extern "C" fn GkRustUtils_GenerateUUID(res: &mut nsACString) {
+    // TODO once the vendored Uuid implementation is >7 this likely can use Hyphenated instead of to_string
+    let uuid = Uuid::new_v4().hyphenated().to_string();
+    write!(res, "{{{}}}", uuid).expect("Unexpected uuid generated");
+}