Fix for bug 399304 . Initialize cert trust and refcount locks early. r=relyea, nelson NSS_3_11_BRANCH
authorjulien.pierre.boogz%sun.com
Sat, 10 Nov 2007 04:26:12 +0000
branchNSS_3_11_BRANCH
changeset 8216 2ed2e9196457fd43df9de359524f0103b9080127
parent 8210 7bee51caa3330b87becabc58bd9d0f8e8442e875 (current diff)
parent 8211 f749643eabc2d3b9e77ab59b55dce02bcbc52845 (diff)
child 8224 21d23295868d42ca2b3dcc6508203f2f2f53f01d
push idunknown
push userunknown
push dateunknown
reviewersrelyea, nelson
bugs399304
Fix for bug 399304 . Initialize cert trust and refcount locks early. r=relyea, nelson
security/nss/lib/certdb/certdb.c
security/nss/lib/certdb/certi.h
security/nss/lib/nss/nssinit.c
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -2735,21 +2735,17 @@ static PZLock *certRefCountLock = NULL;
  * Acquire the cert reference count lock
  * There is currently one global lock for all certs, but I'm putting a cert
  * arg here so that it will be easy to make it per-cert in the future if
  * that turns out to be necessary.
  */
 void
 CERT_LockCertRefCount(CERTCertificate *cert)
 {
-    if ( certRefCountLock == NULL ) {
-	nss_InitLock(&certRefCountLock, nssILockRefLock);
-	PORT_Assert(certRefCountLock != NULL);
-    }
-    
+    PORT_Assert(certRefCountLock != NULL);
     PZ_Lock(certRefCountLock);
     return;
 }
 
 /*
  * Free the cert reference count lock
  */
 void
@@ -2772,25 +2768,67 @@ static PZLock *certTrustLock = NULL;
  * Acquire the cert trust lock
  * There is currently one global lock for all certs, but I'm putting a cert
  * arg here so that it will be easy to make it per-cert in the future if
  * that turns out to be necessary.
  */
 void
 CERT_LockCertTrust(CERTCertificate *cert)
 {
-    if ( certTrustLock == NULL ) {
-	nss_InitLock(&certTrustLock, nssILockCertDB);
-	PORT_Assert(certTrustLock != NULL);
-    }
-    
+    PORT_Assert(certTrustLock != NULL);
     PZ_Lock(certTrustLock);
     return;
 }
 
+SECStatus
+cert_InitLocks(void)
+{
+    if ( certRefCountLock == NULL ) {
+        nss_InitLock(&certRefCountLock, nssILockRefLock);
+        PORT_Assert(certRefCountLock != NULL);
+        if (!certRefCountLock) {
+            return SECFailure;
+        }
+    }
+
+    if ( certTrustLock == NULL ) {
+        nss_InitLock(&certTrustLock, nssILockCertDB);
+        PORT_Assert(certTrustLock != NULL);
+        if (!certTrustLock) {
+            PZ_DestroyLock(certRefCountLock);
+            return SECFailure;
+        }
+    }    
+
+    return SECSuccess;
+}
+
+SECStatus
+cert_DestroyLocks(void)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(certRefCountLock != NULL);
+    if (certRefCountLock) {
+        PZ_DestroyLock(certRefCountLock);
+        certRefCountLock = NULL;
+    } else {
+        rv = SECFailure;
+    }
+
+    PORT_Assert(certTrustLock != NULL);
+    if (certTrustLock) {
+        PZ_DestroyLock(certTrustLock);
+        certTrustLock = NULL;
+    } else {
+        rv = SECFailure;
+    }
+    return rv;
+}
+
 /*
  * Free the cert trust lock
  */
 void
 CERT_UnlockCertTrust(CERTCertificate *cert)
 {
     PRStatus prstat;
 
--- a/security/nss/lib/certdb/certi.h
+++ b/security/nss/lib/certdb/certi.h
@@ -238,10 +238,14 @@ SECStatus
 cert_DestroySubjectKeyIDHashTable(void);
 
 SECItem*
 cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
 
 /* return maximum length of AVA value based on its type OID tag. */
 extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
 
+SECStatus cert_InitLocks(void);
+
+SECStatus cert_DestroyLocks(void);
+
 #endif /* _CERTI_H_ */
 
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -421,16 +421,20 @@ nss_Init(const char *configdir, const ch
 
     if (nss_IsInitted) {
 	return SECSuccess;
     }
 
     /* New option bits must not change the size of CERTCertificate. */
     PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
 
+    if (SECSuccess != cert_InitLocks()) {
+        return SECFailure;
+    }
+
     if (SECSuccess != InitCRLCache()) {
         return SECFailure;
     }
     
     if (SECSuccess != OCSP_InitGlobal()) {
         return SECFailure;
     }
 
@@ -782,16 +786,17 @@ NSS_Shutdown(void)
 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	return SECFailure;
     }
 
     rv = nss_ShutdownShutdownList();
     if (rv != SECSuccess) {
 	shutdownRV = SECFailure;
     }
+    cert_DestroyLocks();
     ShutdownCRLCache();
     OCSP_ShutdownCache();
     SECOID_Shutdown();
     status = STAN_Shutdown();
     cert_DestroySubjectKeyIDHashTable();
     rv = SECMOD_Shutdown();
     if (rv != SECSuccess) {
 	shutdownRV = SECFailure;