Bug 1252722 - Fully implement nsNSSShutDownObject everywhere. r=keeler
authorCykesiopka <cykesiopka.bmo@gmail.com>
Thu, 31 Mar 2016 17:31:50 -0700
changeset 291231 419899bf45c5ca10612a059b1852a95d736e1b29
parent 291230 31b2154a19278fc2fbc2cb2566f564768a997aa7
child 291232 64c333e9b12a998019e80654b75686a1ce644aeb
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1252722
milestone48.0a1
Bug 1252722 - Fully implement nsNSSShutDownObject everywhere. r=keeler MozReview-Commit-ID: 4OZ6tCdCGEP
security/manager/ssl/nsPKCS11Slot.cpp
security/manager/ssl/nsPKCS11Slot.h
--- a/security/manager/ssl/nsPKCS11Slot.cpp
+++ b/security/manager/ssl/nsPKCS11Slot.cpp
@@ -21,21 +21,21 @@ nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo 
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return;
 
   PK11_ReferenceSlot(slot);
   mSlot = slot;
   mSeries = PK11_GetSlotSeries(slot);
-  refreshSlotInfo();
+  refreshSlotInfo(locker);
 }
 
 void
-nsPKCS11Slot::refreshSlotInfo()
+nsPKCS11Slot::refreshSlotInfo(const nsNSSShutDownPreventionLock& /*proofOfLock*/)
 {
   CK_SLOT_INFO slot_info;
   if (PK11_GetSlotInfo(mSlot, &slot_info) == SECSuccess) {
     // Set the Description field
     const char *ccDesc = (const char*)slot_info.slotDescription;
     const nsACString &cDesc = Substring(
       ccDesc, 
       ccDesc+PL_strnlen(ccDesc, sizeof(slot_info.slotDescription)));
@@ -54,17 +54,16 @@ nsPKCS11Slot::refreshSlotInfo()
     mSlotHWVersion.Append('.');
     mSlotHWVersion.AppendInt(slot_info.hardwareVersion.minor);
     // Set the Firmware Version field
     mSlotFWVersion = EmptyString();
     mSlotFWVersion.AppendInt(slot_info.firmwareVersion.major);
     mSlotFWVersion.Append('.');
     mSlotFWVersion.AppendInt(slot_info.firmwareVersion.minor);
   }
-
 }
 
 nsPKCS11Slot::~nsPKCS11Slot()
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
@@ -111,51 +110,66 @@ nsPKCS11Slot::GetName(char16_t **aName)
 NS_IMETHODIMP 
 nsPKCS11Slot::GetDesc(char16_t **aDesc)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
   if (mSeries != PK11_GetSlotSeries(mSlot)) {
-    refreshSlotInfo();
+    refreshSlotInfo(locker);
   }
 
   *aDesc = ToNewUnicode(mSlotDesc);
   if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetManID(char16_t **aManID)
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   if (mSeries != PK11_GetSlotSeries(mSlot)) {
-    refreshSlotInfo();
+    refreshSlotInfo(locker);
   }
   *aManID = ToNewUnicode(mSlotManID);
   if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetHWVersion(char16_t **aHWVersion)
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   if (mSeries != PK11_GetSlotSeries(mSlot)) {
-    refreshSlotInfo();
+    refreshSlotInfo(locker);
   }
   *aHWVersion = ToNewUnicode(mSlotHWVersion);
   if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetFWVersion(char16_t **aFWVersion)
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   if (mSeries != PK11_GetSlotSeries(mSlot)) {
-    refreshSlotInfo();
+    refreshSlotInfo(locker);
   }
   *aFWVersion = ToNewUnicode(mSlotFWVersion);
   if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetToken(nsIPK11Token **_retval)
@@ -177,17 +191,17 @@ nsPKCS11Slot::GetTokenName(char16_t **aN
     return NS_ERROR_NOT_AVAILABLE;
 
   if (!PK11_IsPresent(mSlot)) {
     *aName = nullptr;
     return NS_OK;
   }
 
   if (mSeries != PK11_GetSlotSeries(mSlot)) {
-    refreshSlotInfo();
+    refreshSlotInfo(locker);
   }
 
 
   *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot)));
   if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
@@ -352,47 +366,65 @@ nsPKCS11Module::ListSlots(nsISimpleEnume
 NS_IMPL_ISUPPORTS(nsPKCS11ModuleDB, nsIPKCS11ModuleDB, nsICryptoFIPSInfo)
 
 nsPKCS11ModuleDB::nsPKCS11ModuleDB()
 {
 }
 
 nsPKCS11ModuleDB::~nsPKCS11ModuleDB()
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return;
+  }
+
+  shutdown(calledFromObject);
 }
 
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::GetInternal(nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   SECMODModule *nssMod = 
     SECMOD_CreateModule(nullptr, SECMOD_INT_NAME, nullptr, SECMOD_INT_FLAGS);
   nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
   SECMOD_DestroyModule(nssMod);
   module.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::GetInternalFIPS(nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   SECMODModule *nssMod = 
     SECMOD_CreateModule(nullptr, SECMOD_FIPS_NAME, nullptr, SECMOD_FIPS_FLAGS);
   nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
   SECMOD_DestroyModule(nssMod);
   module.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::FindModuleByName(const char16_t *aName,
                                    nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   NS_ConvertUTF16toUTF8 aUtf8Name(aName);
   SECMODModule *mod =
     SECMOD_FindModule(const_cast<char *>(aUtf8Name.get()));
   if (!mod)
     return NS_ERROR_FAILURE;
   nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod);
   SECMOD_DestroyModule(mod);
   module.forget(_retval);
@@ -402,31 +434,39 @@ nsPKCS11ModuleDB::FindModuleByName(const
 /* This is essentially the same as nsIPK11Token::findTokenByName, except
  * that it returns an nsIPKCS11Slot, which may be desired.
  */
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::FindSlotByName(const char16_t *aName,
                                  nsIPKCS11Slot **_retval)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   NS_ConvertUTF16toUTF8 aUtf8Name(aName);
   PK11SlotInfo *slotinfo =
    PK11_FindSlotByName(const_cast<char*>(aUtf8Name.get()));
   if (!slotinfo)
     return NS_ERROR_FAILURE;
   nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
   PK11_FreeSlot(slotinfo);
   slot.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPKCS11ModuleDB::ListModules(nsISimpleEnumerator** _retval)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID);
   if (!array) {
     return NS_ERROR_FAILURE;
   }
 
   /* lock down the list for reading */
   AutoSECMODListReadLock lock;
   for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list;
@@ -449,24 +489,32 @@ nsPKCS11ModuleDB::ListModules(nsISimpleE
   }
 
   return array->Enumerate(_retval);
 }
 
 NS_IMETHODIMP nsPKCS11ModuleDB::GetCanToggleFIPS(bool *aCanToggleFIPS)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   *aCanToggleFIPS = SECMOD_CanDeleteInternalModule();
   return NS_OK;
 }
 
 
 NS_IMETHODIMP nsPKCS11ModuleDB::ToggleFIPSMode()
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   // The way to toggle FIPS mode in NSS is extremely obscure.
   // Basically, we delete the internal module, and voila it
   // gets replaced with the opposite module, ie if it was 
   // FIPS before, then it becomes non-FIPS next.
   SECMODModule *internal;
 
   // This function returns us a pointer to a local copy of 
   // the internal module stashed in NSS.  We don't want to
@@ -484,16 +532,20 @@ NS_IMETHODIMP nsPKCS11ModuleDB::ToggleFI
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPKCS11ModuleDB::GetIsFIPSEnabled(bool *aIsFIPSEnabled)
 {
   nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   *aIsFIPSEnabled = PK11_IsFIPS();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPKCS11ModuleDB::GetIsFIPSModeActive(bool *aIsFIPSModeActive)
 {
   return GetIsFIPSEnabled(aIsFIPSModeActive);
 }
--- a/security/manager/ssl/nsPKCS11Slot.h
+++ b/security/manager/ssl/nsPKCS11Slot.h
@@ -24,24 +24,23 @@ public:
   NS_DECL_NSIPKCS11SLOT
 
   explicit nsPKCS11Slot(PK11SlotInfo *slot);
 
 protected:
   virtual ~nsPKCS11Slot();
 
 private:
-
   PK11SlotInfo *mSlot;
   nsString mSlotDesc, mSlotManID, mSlotHWVersion, mSlotFWVersion;
   int mSeries;
 
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
-  void refreshSlotInfo();
+  void refreshSlotInfo(const nsNSSShutDownPreventionLock& proofOfLock);
 };
 
 class nsPKCS11Module : public nsIPKCS11Module,
                        public nsNSSShutDownObject
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPKCS11MODULE
@@ -53,29 +52,32 @@ protected:
 
 private:
   SECMODModule *mModule;
 
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
 };
 
-class nsPKCS11ModuleDB : public nsIPKCS11ModuleDB,
-                         public nsICryptoFIPSInfo
+class nsPKCS11ModuleDB : public nsIPKCS11ModuleDB
+                       , public nsICryptoFIPSInfo
+                       , public nsNSSShutDownObject
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPKCS11MODULEDB
   NS_DECL_NSICRYPTOFIPSINFO
 
   nsPKCS11ModuleDB();
 
 protected:
   virtual ~nsPKCS11ModuleDB();
-  /* additional members */
+
+  // Nothing to release.
+  virtual void virtualDestroyNSSReference() override {}
 };
 
 #define NS_PKCS11MODULEDB_CID \
 { 0xff9fbcd7, 0x9517, 0x4334, \
   { 0xb9, 0x7a, 0xce, 0xed, 0x78, 0x90, 0x99, 0x74 }}
 
 class MOZ_RAII AutoSECMODListReadLock final
 {