Blob Blame History Raw
diff --git a/lib/pki/pki3hack.c b/lib/pki/pki3hack.c
--- a/lib/pki/pki3hack.c
+++ b/lib/pki/pki3hack.c
@@ -849,18 +849,21 @@ fill_CERTCertificateFields(NSSCertificat
 }
 
 static CERTCertificate *
 stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
 {
     nssDecodedCert *dc = NULL;
     CERTCertificate *cc = NULL;
     CERTCertTrust certTrust;
+    nssPKIObject *object = &c->object;
 
-    nssPKIObject_Lock(&c->object);
+    /* make sure object does not go away until we finish */
+    nssPKIObject_AddRef(object);
+    nssPKIObject_Lock(object);
 
     dc = c->decoding;
     if (!dc) {
 	dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
 	if (!dc) {
             goto loser;
         }
 	cc = (CERTCertificate *)dc->data;
@@ -898,17 +901,18 @@ stan_GetCERTCertificate(NSSCertificate *
         trust = nssTrust_GetCERTCertTrustForCert(c, cc);
 
         CERT_LockCertTrust(cc);
         cc->trust = trust;
         CERT_UnlockCertTrust(cc);
     }
 
   loser:
-    nssPKIObject_Unlock(&c->object);
+    nssPKIObject_Unlock(object);
+    nssPKIObject_Destroy(object);
     return cc;
 }
 
 NSS_IMPLEMENT CERTCertificate *
 STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
 {
     if (c->decoding) {
 	return stan_GetCERTCertificate(c, PR_TRUE);
@@ -1265,16 +1269,17 @@ done:
 */
 static PRStatus
 DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject)
 {
     int numNotDestroyed = 0;     /* the ones skipped plus the failures */
     int failureCount = 0;        /* actual deletion failures by devices */
     int index;
 
+    nssPKIObject_AddRef(tObject);
     nssPKIObject_Lock(tObject);
     /* Keep going even if a module fails to delete. */
     for (index = 0; index < tObject->numInstances; index++) {
 	nssCryptokiObject *instance = tObject->instances[index];
 	if (!instance) {
 	    continue;
 	}
 
@@ -1298,16 +1303,17 @@ DeleteCertTrustMatchingSlot(PK11SlotInfo
     if (numNotDestroyed == 0) {
     	nss_ZFreeIf(tObject->instances);
     	tObject->numInstances = 0;
     } else {
     	tObject->numInstances = numNotDestroyed;
     }
 
     nssPKIObject_Unlock(tObject);
+    nssPKIObject_Destroy(tObject);
 
     return failureCount == 0 ? PR_SUCCESS : PR_FAILURE;
 }
 
 /*
 ** Delete trust objects matching the slot of the given certificate.
 ** Returns an error if any device fails to delete. 
 */
@@ -1324,30 +1330,32 @@ STAN_DeleteCertTrustMatchingSlot(NSSCert
     int i;
 
     /* Iterate through the cert and trust object instances looking for
      * those with matching pk11 slots to delete. Even if some device
      * can't delete we keep going. Keeping a status variable for the
      * loop so that once it's failed the other gets set.
      */
     NSSRWLock_LockRead(td->tokensLock);
+    nssPKIObject_AddRef(cobject);
     nssPKIObject_Lock(cobject);
     for (i = 0; i < cobject->numInstances; i++) {
 	nssCryptokiObject *cInstance = cobject->instances[i];
 	if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) {
 		PRStatus status;
 	    if (!tobject->numInstances || !tobject->instances) continue;
 	    status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject);
 	    if (status == PR_FAILURE) {
 	    	/* set the outer one but keep going */
 	    	nssrv = PR_FAILURE;
 	    }
 	}
     }
     nssPKIObject_Unlock(cobject);
+    nssPKIObject_Destroy(cobject);
     NSSRWLock_UnlockRead(td->tokensLock);
     return nssrv;
 }
 
 /* CERT_TraversePermCertsForSubject */
 NSS_IMPLEMENT PRStatus
 nssTrustDomain_TraverseCertificatesBySubject (
   NSSTrustDomain *td,
diff --git a/lib/pki/tdcache.c b/lib/pki/tdcache.c
--- a/lib/pki/tdcache.c
+++ b/lib/pki/tdcache.c
@@ -386,16 +386,17 @@ struct token_cert_dtor {
 
 static void 
 remove_token_certs(const void *k, void *v, void *a)
 {
     NSSCertificate *c = (NSSCertificate *)k;
     nssPKIObject *object = &c->object;
     struct token_cert_dtor *dtor = a;
     PRUint32 i;
+    nssPKIObject_AddRef(object);
     nssPKIObject_Lock(object);
     for (i=0; i<object->numInstances; i++) {
 	if (object->instances[i]->token == dtor->token) {
 	    nssCryptokiObject_Destroy(object->instances[i]);
 	    object->instances[i] = object->instances[object->numInstances-1];
 	    object->instances[object->numInstances-1] = NULL;
 	    object->numInstances--;
 	    dtor->certs[dtor->numCerts++] = c;
@@ -404,16 +405,17 @@ remove_token_certs(const void *k, void *
 		dtor->certs = nss_ZREALLOCARRAY(dtor->certs, 
 		                                NSSCertificate *,
 		                                dtor->arrSize);
 	    }
 	    break;
 	}
     }
     nssPKIObject_Unlock(object);
+    nssPKIObject_Destroy(object);
     return;
 }
 
 /* 
  * Remove all certs for the given token from the cache.  This is
  * needed if the token is removed. 
  */
 NSS_IMPLEMENT PRStatus