NSC_Finalize will now destroy 3 softoken free lists and one more
authornelsonb%netscape.com
Sat, 06 Dec 2003 06:41:51 +0000
changeset 4918 411ec7050ebf530fdb873cd08fdd55fae95deb1f
parent 4912 06c3066dcceef3893fd9c9c487d7661e57b62b33 (current diff)
parent 4916 b441456009a9eccdf7b94356d66abc366ffc6ce1 (diff)
child 4919 c772c03f94917fca65f2a8f5b491efa1483eb4f3
push idunknown
push userunknown
push dateunknown
bugs54301
NSC_Finalize will now destroy 3 softoken free lists and one more global pointer. Plugs some memory leaks. Bugscape bug 54301. r=wtc
security/nss/lib/softoken/pcert.h
security/nss/lib/softoken/pcertdb.c
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/pkcs11u.c
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -214,16 +214,19 @@ nsslowcert_needDBVerify(NSSLOWCERTCertDB
 
 void
 nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value);
 
 PRBool
 nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust);
 
 void
+nsslowcert_DestroyFreeLists(void);
+
+void
 nsslowcert_DestroyGlobalLocks(void);
 
 void
 pkcs11_freeNickname(char *nickname, char *space);
 
 char *
 pkcs11_copyNickname(char *nickname, char *space, int spaceLen);
 
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -1033,24 +1033,41 @@ CreateCertEntry(void)
     certDBEntryCert *entry;
 
     nsslowcert_LockFreeList();
     entry = entryListHead;
     if (entry) {
 	entryListCount--;
 	entryListHead = entry->next;
     }
+    PORT_Assert(entryListCount >= 0);
     nsslowcert_UnlockFreeList();
     if (entry) {
 	return entry;
     }
 
     return PORT_ZAlloc(sizeof(certDBEntryCert));
 }
 
+static void
+DestroyCertEntryFreeList(void)
+{
+    certDBEntryCert *entry;
+
+    nsslowcert_LockFreeList();
+    while (NULL != (entry = entryListHead)) {
+	entryListCount--;
+	entryListHead = entry->next;
+	PORT_Free(entry);
+    }
+    PORT_Assert(!entryListCount);
+    entryListCount = 0;
+    nsslowcert_UnlockFreeList();
+}
+
 /*
  * Read a certificate entry
  */
 static certDBEntryCert *
 ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
 {
     certDBEntryCert *entry;
     SECItem dbkey;
@@ -2676,44 +2693,44 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOW
     }
 
     entry = ReadDBSubjectEntry(dbhandle,derSubject);    
     if (entry == NULL) {
 	goto loser;
     } 
 
     if ( entry->emailAddrs ) {
-	for (i=0; i < entry->nemailAddrs; i++) {
+	for (i=0; i < (int)(entry->nemailAddrs); i++) {
 	    if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
 		index = i;
 	    }
 	}
     }
 
 
     if (updateType == nsslowcert_remove) {
 	if (index == -1) {
 	    return SECSuccess;
 	}
 
 	entry->nemailAddrs--;
-	for (i=index; i < entry->nemailAddrs; i++) {
+	for (i=index; i < (int)(entry->nemailAddrs); i++) {
 	   entry->emailAddrs[i] = entry->emailAddrs[i+1];
 	}
     } else {
 	char **newAddrs = NULL;
 	if (index != -1) {
 	    return SECSuccess;
 	}
 	newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena,
 		(entry->nemailAddrs+1)* sizeof(char *));
 	if (!newAddrs) {
 	    goto loser;
 	}
-	for (i=0; i < entry->nemailAddrs; i++) {
+	for (i=0; i < (int)(entry->nemailAddrs); i++) {
 	   newAddrs[i] = entry->emailAddrs[i];
 	}
 	newAddrs[entry->nemailAddrs] = 
 			PORT_ArenaStrdup(entry->common.arena,emailAddr);
 	if (!newAddrs[entry->nemailAddrs]) {
 	   goto loser;
 	}
 	entry->emailAddrs = newAddrs;
@@ -4291,27 +4308,44 @@ CreateTrust(void)
     NSSLOWCERTTrust *trust = NULL;
 
     nsslowcert_LockFreeList();
     trust = trustListHead;
     if (trust) {
 	trustListCount--;
 	trustListHead = trust->next;
     }
+    PORT_Assert(trustListCount >= 0);
     nsslowcert_UnlockFreeList();
     if (trust) {
 	return trust;
     }
 
     return PORT_ZAlloc(sizeof(NSSLOWCERTTrust));
 }
 
+static void
+DestroyTrustFreeList(void)
+{
+    NSSLOWCERTTrust *trust;
+
+    nsslowcert_LockFreeList();
+    while (NULL != (trust = trustListHead)) {
+	trustListCount--;
+	trustListHead = trust->next;
+	PORT_Free(trust);
+    }
+    PORT_Assert(!trustListCount);
+    trustListCount = 0;
+    nsslowcert_UnlockFreeList();
+}
 
 static NSSLOWCERTTrust * 
-DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,				SECItem *dbKey)
+DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry, 
+                 SECItem *dbKey)
 {
     NSSLOWCERTTrust *trust = CreateTrust();
     if (trust == NULL) {
 	return trust;
     }
     trust->dbhandle = handle;
     trust->dbEntry = entry;
     trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len,
@@ -4995,24 +5029,40 @@ nsslowcert_CreateCert(void)
 {
     NSSLOWCERTCertificate *cert;
     nsslowcert_LockFreeList();
     cert = certListHead;
     if (cert) {
 	certListHead = cert->next;
 	certListCount--;
     }
+    PORT_Assert(certListCount >= 0);
     nsslowcert_UnlockFreeList();
-
     if (cert) {
 	return cert;
     }
     return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate));
 }
 
+static void
+DestroyCertFreeList(void)
+{
+    NSSLOWCERTCertificate *cert;
+
+    nsslowcert_LockFreeList();
+    while (NULL != (cert = certListHead)) {
+	certListCount--;
+	certListHead = cert->next;
+	PORT_Free(cert);
+    }
+    PORT_Assert(!certListCount);
+    certListCount = 0;
+    nsslowcert_UnlockFreeList();
+}
+
 void
 nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
 {
     certDBEntryCert *entry  = trust->dbEntry;
 
     if ( entry ) {
 	DestroyDBEntry((certDBEntry *)entry);
     }
@@ -5243,18 +5293,31 @@ nsslowcert_SaveSMimeProfile(NSSLOWCERTCe
 
     rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr, 
 	 derSubject, emailProfile, profileTime);
     
     db_FinishTransaction(dbhandle->permCertDB, rv != SECSuccess);
     return(rv);
 }
 
+/* If the freeListLock doesn't exist when this function is called,
+** this function will create it, use it 3 times, and delete it.
+*/
 void
-nsslowcert_DestroyGlobalLocks()
+nsslowcert_DestroyFreeLists(void)
+{
+    DestroyCertEntryFreeList();
+    DestroyTrustFreeList();
+    DestroyCertFreeList();
+    PZ_DestroyLock(freeListLock);
+    freeListLock = NULL;
+}
+
+void
+nsslowcert_DestroyGlobalLocks(void)
 {
     if (dbLock) {
 	PZ_DestroyLock(dbLock);
 	dbLock = NULL;
     }
     if (certRefCountLock) {
 	PZ_DestroyLock(certRefCountLock);
 	certRefCountLock = NULL;
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -2847,32 +2847,33 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pR
     /* don't muck with the globals is our peer is still initialized */
     if (isFIPS && nsc_init) {
 	return CKR_OK;
     }
     if (!isFIPS && nsf_init) {
 	return CKR_OK;
     }
 
+    pk11_CleanupFreeLists();
+    nsslowcert_DestroyFreeLists();
     nsslowcert_DestroyGlobalLocks();
 
 #ifdef LEAK_TEST
     /*
      * do we really want to throw away all our hard earned entropy here!!?
      * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the 
      * initial call to RNG_Init(). So the only reason to call this is to clean
      * up leak detection warnings on shutdown. In many cases we *don't* want
      * to free up the global RNG context because the application has Finalized
      * simply to swap profiles. We don't want to loose the entropy we've 
      * already collected.
      */
     RNG_RNGShutdown();
 #endif
 
-    pk11_CleanupFreeLists();
     /* tell freeBL to clean up after itself */
     BL_Cleanup();
     /* clean up the default OID table */
     SECOID_Shutdown();
     nsc_init = PR_FALSE;
 
     return CKR_OK;
 }
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -40,16 +40,17 @@
 #include "pkcs11.h"
 #include "pkcs11i.h"
 #include "pcertt.h"
 #include "lowkeyi.h"
 #include "pcert.h"
 #include "secasn1.h"
 #include "blapi.h"
 #include "secerr.h"
+#include "prnetdb.h" /* for PR_ntohl */
 
 /*
  * ******************** Attribute Utilities *******************************
  */
 
 /*
  * create a new attribute with type, value, and length. Space is allocated
  * to hold value.
@@ -1318,17 +1319,16 @@ pk11_GetLengthInBits(unsigned char *buf,
  */
 CK_RV
 pk11_ConstrainAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type, 
 			int minLength, int maxLength, int minMultiple)
 {
     PK11Attribute *attribute;
     unsigned int size;
     unsigned char *ptr;
-    int i,j;
 
     attribute = pk11_FindAttribute(object, type);
     if (!attribute) {
 	return CKR_TEMPLATE_INCOMPLETE;
     }
     ptr = (unsigned char *) attribute->attrib.pValue;
     if (ptr == NULL) {
 	pk11_FreeAttribute(attribute);
@@ -1917,17 +1917,16 @@ pk11_Attribute2SecItem(PLArenaPool *aren
     pk11_FreeAttribute(attribute);
     return CKR_OK;
 }
 
 CK_RV
 pk11_GetULongAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
 							 CK_ULONG *longData)
 {
-    int len;
     PK11Attribute *attribute;
 
     attribute = pk11_FindAttribute(object, type);
     if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
 
     if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
 	return CKR_ATTRIBUTE_VALUE_INVALID;
     }