Bug 1425462 Refactor the static members into static globals to avoid leakchecks r?ckerschb draft
authorTom Ritter <tom@mozilla.com>
Thu, 01 Mar 2018 05:24:36 -0600
changeset 762576 f34b14780516f65cfe6b957954a77ec0559bb4ae
parent 762575 eb60cda4c59f54b2f92c56fa1c41d0b323bf0204
child 762577 0979a1279bca516c2a7c9869ef6f14fab84199e5
push id101207
push userbmo:tom@mozilla.com
push dateFri, 02 Mar 2018 17:45:38 +0000
reviewersckerschb
bugs1425462
milestone60.0a1
Bug 1425462 Refactor the static members into static globals to avoid leakchecks r?ckerschb MozReview-Commit-ID: 2lm1Skf3KEH
toolkit/components/resistfingerprinting/nsRFPService.cpp
toolkit/components/resistfingerprinting/nsRFPService.h
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -81,19 +81,17 @@ Atomic<bool, Relaxed> nsRFPService::sPri
 // Note: anytime you want to use this variable, you should probably use TimerResolution() instead
 Atomic<uint32_t, Relaxed> sResolutionUSec;
 Atomic<bool, Relaxed> sJitter;
 static uint32_t sVideoFramesPerSec;
 static uint32_t sVideoDroppedRatio;
 static uint32_t sTargetVideoRes;
 nsDataHashtable<KeyboardHashKey, const SpoofingKeyboardCode*>*
   nsRFPService::sSpoofingKeyboardCodes = nullptr;
-UniquePtr<LRUCache> nsRFPService::sCache;
-UniquePtr<uint8_t[]> nsRFPService::sSecretMidpointSeed;
-mozilla::Mutex* nsRFPService::sLock = nullptr;
+static mozilla::StaticMutex sLock;
 
 /* static */
 nsRFPService*
 nsRFPService::GetOrCreate()
 {
   if (!sInitialized) {
     sRFPService = new nsRFPService();
     nsresult rv = sRFPService->Init();
@@ -230,16 +228,19 @@ private:
       this->data = obj.data;
     }
   };
 
   AutoTArray<CacheEntry, LRU_CACHE_SIZE> cache;
   mozilla::Mutex mLock;
 };
 
+// We make a single LRUCache
+static StaticAutoPtr<LRUCache> sCache;
+
 /**
  * The purpose of this function is to deterministicly generate a random midpoint
  * between a lower clamped value and an upper clamped value. Assuming a clamping
  * resolution of 100, here is an example:
  *
  * |---------------------------------------|--------------------------|
  * lower clamped value (e.g. 300)          |           upper clamped value (400)
  *                              random midpoint (e.g. 360)
@@ -295,21 +296,23 @@ nsresult
 nsRFPService::RandomMidpoint(long long aClampedTimeUSec,
                              long long aResolutionUSec,
                              long long* aMidpointOut,
                              uint8_t * aSecretSeed /* = nullptr */)
 {
   nsresult rv;
   const int kSeedSize = 16;
   const int kClampTimesPerDigest = HASH_DIGEST_SIZE_BITS / 32;
+  static uint8_t * sSecretMidpointSeed = nullptr;
 
   if(MOZ_UNLIKELY(!sCache)) {
-    MutexAutoLock lock(*sLock);
+    StaticMutexAutoLock lock(sLock);
     if(MOZ_LIKELY(!sCache)) {
-      sCache = MakeUnique<LRUCache>();
+      sCache = new LRUCache();
+      ClearOnShutdown(&sCache);
     }
   }
 
   if(MOZ_UNLIKELY(!aMidpointOut)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   /*
@@ -335,37 +338,34 @@ nsRFPService::RandomMidpoint(long long a
   long long reducedResolution = aResolutionUSec * kClampTimesPerDigest;
   long long extraClampedTime = (aClampedTimeUSec / reducedResolution) * reducedResolution;
 
   nsCString hashResult = sCache->Get(extraClampedTime);
 
   if(hashResult.Length() != HASH_DIGEST_SIZE_BYTES) { // Cache Miss =(
     // If someone has pased in the testing-only parameter, replace our seed with it
     if (aSecretSeed != nullptr) {
-      MutexAutoLock lock(*sLock);
+      StaticMutexAutoLock lock(sLock);
       if (sSecretMidpointSeed) {
-        // Deletes the object pointed to as well
-        sSecretMidpointSeed = nullptr;
+        delete[] sSecretMidpointSeed;
       }
-      sSecretMidpointSeed = MakeUnique<uint8_t[]>(kSeedSize);
-      memcpy(sSecretMidpointSeed.get(), aSecretSeed, kSeedSize);
+      sSecretMidpointSeed = new uint8_t[kSeedSize];
+      memcpy(sSecretMidpointSeed, aSecretSeed, kSeedSize);
     }
 
     // If we don't have a seed, we need to get one.
     if(MOZ_UNLIKELY(!sSecretMidpointSeed)) {
-      MutexAutoLock lock(*sLock);
+      StaticMutexAutoLock lock(sLock);
       if(MOZ_LIKELY(!sSecretMidpointSeed)) {
         nsCOMPtr<nsIRandomGenerator> randomGenerator =
             do_GetService("@mozilla.org/security/random-generator;1", &rv);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-        uint8_t* buffer;
-        rv = randomGenerator->GenerateRandomBytes(kSeedSize, &buffer);
+        rv = randomGenerator->GenerateRandomBytes(kSeedSize, &sSecretMidpointSeed);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-        sSecretMidpointSeed.reset(buffer);
       }
     }
 
     /*
      * Use a cryptographicly secure hash function, but do _not_ use an HMAC.
      * Obviously we're not using this data for authentication purposes, but
      * even still an HMAC is a perfect fit here, as we're hashing a value
      * using a seed that never changes, and an input that does. So why not
@@ -389,17 +389,17 @@ nsRFPService::RandomMidpoint(long long a
 
      // Then hash extraClampedTime and store it in the cache
      nsCOMPtr<nsICryptoHash> hasher = do_CreateInstance("@mozilla.org/security/hash;1", &rv);
      NS_ENSURE_SUCCESS(rv, rv);
 
      rv = hasher->Init(nsICryptoHash::SHA256);
      NS_ENSURE_SUCCESS(rv, rv);
 
-     rv = hasher->Update(sSecretMidpointSeed.get(), kSeedSize);
+     rv = hasher->Update(sSecretMidpointSeed, kSeedSize);
      NS_ENSURE_SUCCESS(rv, rv);
 
      rv = hasher->Update((const uint8_t *)&extraClampedTime, sizeof(extraClampedTime));
      NS_ENSURE_SUCCESS(rv, rv);
 
      nsAutoCStringN<HASH_DIGEST_SIZE_BYTES> derivedSecret;
      rv = hasher->Finish(false, derivedSecret);
      NS_ENSURE_SUCCESS(rv, rv);
@@ -637,18 +637,16 @@ nsRFPService::GetSpoofedUserAgent(nsACSt
 
 nsresult
 nsRFPService::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsresult rv;
 
-  sLock = new mozilla::Mutex("mozilla.resistFingerprinting.mLock");
-
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE);
 
   rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
 #if defined(XP_WIN)
   rv = obs->AddObserver(this, PROFILE_INITIALIZED_TOPIC, false);
@@ -775,22 +773,16 @@ nsRFPService::StartShutdown()
 
     if (prefs) {
       prefs->RemoveObserver(RESIST_FINGERPRINTING_PREF, this);
       prefs->RemoveObserver(RFP_TIMER_PREF, this);
       prefs->RemoveObserver(RFP_TIMER_VALUE_PREF, this);
       prefs->RemoveObserver(RFP_JITTER_VALUE_PREF, this);
     }
   }
-
-  sSecretMidpointSeed = nullptr;
-  sCache = nullptr;
-
-  delete sLock;
-  sLock = nullptr;
 }
 
 /* static */
 void
 nsRFPService::MaybeCreateSpoofingKeyCodes(const KeyboardLangs aLang,
                                           const KeyboardRegions aRegion)
 {
   if (!sSpoofingKeyboardCodes) {
--- a/toolkit/components/resistfingerprinting/nsRFPService.h
+++ b/toolkit/components/resistfingerprinting/nsRFPService.h
@@ -268,18 +268,14 @@ private:
                                     const WidgetKeyboardEvent* aKeyboardEvent,
                                     SpoofingKeyboardCode& aOut);
 
   static Atomic<bool, Relaxed> sPrivacyResistFingerprinting;
   static Atomic<bool, Relaxed> sPrivacyTimerPrecisionReduction;
 
   static nsDataHashtable<KeyboardHashKey, const SpoofingKeyboardCode*>* sSpoofingKeyboardCodes;
 
-  static mozilla::Mutex* sLock;
-  static UniquePtr<LRUCache> sCache;
-  static UniquePtr<uint8_t[]> sSecretMidpointSeed;
-
   nsCString mInitialTZValue;
 };
 
 } // mozilla namespace
 
 #endif /* __nsRFPService_h__ */