Bug 1123374 - Fix CertBlocklist initialization when revocations.txt does not exist. r=mgoodwin, a=sledru
authorDavid Keeler <dkeeler@mozilla.com>
Tue, 20 Jan 2015 10:18:29 -0800
changeset 249419 d5403861ce26825757d88cb004ddb5d1e0186bfe
parent 249418 936d24a4d78ae09fc69c495a0b9a3f809aee314c
child 249420 bdaf3ef842c9200953c93290bac0649588dc0e5e
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgoodwin, sledru
bugs1123374
milestone37.0a2
Bug 1123374 - Fix CertBlocklist initialization when revocations.txt does not exist. r=mgoodwin, a=sledru
security/manager/boot/src/CertBlocklist.cpp
--- a/security/manager/boot/src/CertBlocklist.cpp
+++ b/security/manager/boot/src/CertBlocklist.cpp
@@ -93,16 +93,17 @@ CertBlocklistItem::Hash() const
   }
   return hash;
 }
 
 CertBlocklist::CertBlocklist()
   : mMutex("CertBlocklist::mMutex")
   , mModified(false)
   , mBackingFileIsInitialized(false)
+  , mBackingFile(nullptr)
 {
   if (!gCertBlockPRLog) {
     gCertBlockPRLog = PR_NewLogModule("CertBlock");
   }
 }
 
 CertBlocklist::~CertBlocklist()
 {
@@ -116,66 +117,66 @@ CertBlocklist::Init()
   // Init must be on main thread for getting the profile directory
   if (!NS_IsMainThread()) {
     PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
            ("CertBlocklist::Init - called off main thread"));
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
   // Get the profile directory
-  PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
-         ("CertBlocklist::Init - not initialized; initializing"));
   nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                        getter_AddRefs(mBackingFile));
   if (NS_FAILED(rv) || !mBackingFile) {
     PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
            ("CertBlocklist::Init - couldn't get profile dir"));
+    // Since we're returning NS_OK here, set mBackingFile to a safe value.
+    // (We need initialization to succeed and CertBlocklist to be in a
+    // well-defined state if the profile directory doesn't exist.)
+    mBackingFile = nullptr;
+    return NS_OK;
   }
+  rv = mBackingFile->Append(NS_LITERAL_STRING("revocations.txt"));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  nsAutoCString path;
+  rv = mBackingFile->GetNativePath(path);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
+         ("CertBlocklist::Init certList path: %s", path.get()));
+
   return NS_OK;
 }
 
 nsresult
 CertBlocklist::EnsureBackingFileInitialized(mozilla::MutexAutoLock& lock)
 {
   PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
          ("CertBlocklist::EnsureBackingFileInitialized"));
   if (mBackingFileIsInitialized || !mBackingFile) {
     return NS_OK;
   }
 
   PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
          ("CertBlocklist::EnsureBackingFileInitialized - not initialized"));
 
-  // Load the revocations file into the cert blocklist
-  nsresult rv = mBackingFile->Append(NS_LITERAL_STRING("revocations.txt"));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  nsAutoCString path;
-  rv = mBackingFile->GetNativePath(path);
+  bool exists = false;
+  nsresult rv = mBackingFile->Exists(&exists);
   if (NS_FAILED(rv)) {
     return rv;
   }
-
-  PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
-        ("CertBlocklist::Init certList path: %s", path.get()));
-
-  bool exists = false;
-  rv = mBackingFile->Exists(&exists);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
   if (!exists) {
     PR_LOG(gCertBlockPRLog, PR_LOG_WARN,
-           ("CertBlocklist::Init no revocations file"));
+           ("CertBlocklist::EnsureBackingFileInitialized no revocations file"));
     return NS_OK;
   }
 
+  // Load the revocations file into the cert blocklist
   nsCOMPtr<nsIFileInputStream> fileStream(
       do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   rv = fileStream->Init(mBackingFile, -1, -1, false);
   if (NS_FAILED(rv)) {
@@ -207,40 +208,41 @@ CertBlocklist::EnsureBackingFileInitiali
     serial = line;
     serial.Trim(" ", true, false, false);
     // serial numbers 'belong' to the last issuer line seen; if no issuer has
     // been seen, the serial number is ignored
     if (issuer.IsEmpty() || serial.IsEmpty()) {
       continue;
     }
     PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
-           ("CertBlocklist::Init adding: %s %s",
+           ("CertBlocklist::EnsureBackingFileInitialized adding: %s %s",
            issuer.get(), serial.get()));
     rv = AddRevokedCertInternal(issuer.get(),
                                 serial.get(),
                                 CertOldFromLocalCache,
                                 lock);
     if (NS_FAILED(rv)) {
       // we warn here, rather than abandoning, since we need to
       // ensure that as many items as possible are read
       PR_LOG(gCertBlockPRLog, PR_LOG_WARN,
-             ("CertBlocklist::Init adding revoked cert failed"));
+             ("CertBlocklist::EnsureBackingFileInitialized adding revoked cert "
+              "failed"));
     }
   } while (more);
   mBackingFileIsInitialized = true;
   return NS_OK;
 }
 
 // void addRevokedCert (in string issuer, in string serialNumber);
 NS_IMETHODIMP
 CertBlocklist::AddRevokedCert(const char* aIssuer,
                               const char* aSerialNumber)
 {
   PR_LOG(gCertBlockPRLog, PR_LOG_DEBUG,
-         ("CertBlocklist::addRevokedCert - issuer is: %s and serial: %s",
+         ("CertBlocklist::AddRevokedCert - issuer is: %s and serial: %s",
           aIssuer, aSerialNumber));
   mozilla::MutexAutoLock lock(mMutex);
   return AddRevokedCertInternal(aIssuer,
                                 aSerialNumber,
                                 CertNewFromBlocklist,
                                 lock);
 }
 
@@ -470,18 +472,20 @@ CertBlocklist::SaveEntries()
   mModified = false;
   return NS_OK;
 }
 
 // boolean isCertRevoked([const, array, size_is(issuerLength)] in octet issuer,
 //                       in unsigned long issuerLength,
 //                       [const, array, size_is(serialLength)] in octet serial,
 //                       in unsigned long serialLength);
-NS_IMETHODIMP CertBlocklist::IsCertRevoked(const uint8_t* aIssuer, uint32_t aIssuerLength,
-                                           const uint8_t* aSerial, uint32_t aSerialLength,
+NS_IMETHODIMP CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
+                                           uint32_t aIssuerLength,
+                                           const uint8_t* aSerial,
+                                           uint32_t aSerialLength,
                                            bool* _retval)
 {
   mozilla::MutexAutoLock lock(mMutex);
 
   nsresult rv = EnsureBackingFileInitialized(lock);
   if (NS_FAILED(rv)) {
     return rv;
   }