You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.3 KiB
112 lines
3.3 KiB
diff -up nss/lib/pki/tdcache.c.fix_deadlock nss/lib/pki/tdcache.c |
|
--- nss/lib/pki/tdcache.c.fix_deadlock 2017-01-13 17:10:36.055530248 +0100 |
|
+++ nss/lib/pki/tdcache.c 2017-01-13 17:14:04.015338438 +0100 |
|
@@ -374,13 +374,19 @@ struct token_cert_dtor { |
|
PRUint32 numCerts, arrSize; |
|
}; |
|
|
|
-static void |
|
-remove_token_certs(const void *k, void *v, void *a) |
|
+static void cert_iter(const void *k, void *v, void *a) |
|
{ |
|
+ nssList *certList = (nssList *)a; |
|
NSSCertificate *c = (NSSCertificate *)k; |
|
+ nssList_Add(certList, nssCertificate_AddRef(c)); |
|
+} |
|
+ |
|
+static void |
|
+remove_token_certs(NSSCertificate *c, struct token_cert_dtor *dtor) |
|
+{ |
|
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++) { |
|
@@ -416,6 +422,11 @@ nssTrustDomain_RemoveTokenCertsFromCache |
|
NSSCertificate **certs; |
|
PRUint32 i, arrSize = 10; |
|
struct token_cert_dtor dtor; |
|
+ nssList *certList; |
|
+ PRStatus nspr_rv = PR_FAILURE; |
|
+ nssListIterator *iter; |
|
+ NSSCertificate *c; |
|
+ |
|
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize); |
|
if (!certs) { |
|
return PR_FAILURE; |
|
@@ -425,8 +436,33 @@ nssTrustDomain_RemoveTokenCertsFromCache |
|
dtor.certs = certs; |
|
dtor.numCerts = 0; |
|
dtor.arrSize = arrSize; |
|
+ |
|
+ certList = nssList_Create(NULL, PR_FALSE); |
|
+ if (!certList) { |
|
+ goto loser; |
|
+ } |
|
+ /* fetch the list of certs in the cache */ |
|
+ PZ_Lock(td->cache->lock); |
|
+ nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList); |
|
+ PZ_Unlock(td->cache->lock); |
|
+ |
|
+ /* find the certs that match this token without olding the td cache lock */ |
|
+ iter=nssList_CreateIterator(certList); |
|
+ if (!iter) { |
|
+ goto loser; |
|
+ } |
|
+ for (c = (NSSCertificate *)nssListIterator_Start(iter); |
|
+ c != (NSSCertificate *)NULL; |
|
+ c = (NSSCertificate *)nssListIterator_Next(iter)) { |
|
+ remove_token_certs( c, &dtor); |
|
+ } |
|
+ nssListIterator_Finish(iter); |
|
+ nssListIterator_Destroy(iter); |
|
+ nssList_Destroy(certList); |
|
+ certList = NULL; |
|
+ |
|
+ /* now remove theose certs attached to this token */ |
|
PZ_Lock(td->cache->lock); |
|
- nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, &dtor); |
|
for (i = 0; i < dtor.numCerts; i++) { |
|
if (dtor.certs[i]->object.numInstances == 0) { |
|
nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]); |
|
@@ -437,14 +473,22 @@ nssTrustDomain_RemoveTokenCertsFromCache |
|
} |
|
} |
|
PZ_Unlock(td->cache->lock); |
|
+ |
|
+ /* clean up */ |
|
for (i = 0; i < dtor.numCerts; i++) { |
|
if (dtor.certs[i]) { |
|
STAN_ForceCERTCertificateUpdate(dtor.certs[i]); |
|
nssCertificate_Destroy(dtor.certs[i]); |
|
} |
|
} |
|
+ |
|
+ nspr_rv = PR_SUCCESS; |
|
+loser: |
|
+ if (certList) { |
|
+ nssList_Destroy(certList); |
|
+ } |
|
nss_ZFreeIf(dtor.certs); |
|
- return PR_SUCCESS; |
|
+ return nspr_rv; |
|
} |
|
|
|
NSS_IMPLEMENT PRStatus |
|
@@ -1058,14 +1102,6 @@ nssTrustDomain_GetCertByDERFromCache( |
|
return rvCert; |
|
} |
|
|
|
-static void |
|
-cert_iter(const void *k, void *v, void *a) |
|
-{ |
|
- nssList *certList = (nssList *)a; |
|
- NSSCertificate *c = (NSSCertificate *)k; |
|
- nssList_Add(certList, nssCertificate_AddRef(c)); |
|
-} |
|
- |
|
NSS_EXTERN NSSCertificate ** |
|
nssTrustDomain_GetCertsFromCache( |
|
NSSTrustDomain *td,
|
|
|