[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor-browser] 72/76: Bug 1760872 - land NSS NSS_3_68_3_RTM UPGRADE_NSS_RELEASE, r=djackson a=RyanVM



This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch tor-browser-91.8.0esr-11.0-1
in repository tor-browser.

commit 6e69482b8f03763e0cb4c97ecdd00cfbf883cf79
Author: John Schanck <jschanck@xxxxxxxxxxx>
AuthorDate: Mon Mar 28 17:23:11 2022 +0000

    Bug 1760872 - land NSS NSS_3_68_3_RTM UPGRADE_NSS_RELEASE, r=djackson a=RyanVM
    
    2022-03-23  John M. Schanck  <jschanck@xxxxxxxxxxx>
    
            * lib/dev/dev.h, lib/dev/devslot.c, lib/dev/devt.h,
            lib/dev/devtoken.c, lib/pk11wrap/dev3hack.c:
            Bug 1756271 - Remove token member from NSSSlot struct. r=rrelyea
    
            [e3da860d9d1c] [NSS_3_68_3_RTM] <NSS_3_68_3_BRANCH>
    
    2022-02-24  John M. Schanck  <jschanck@xxxxxxxxxxx>
    
            * lib/pki/trustdomain.c:
            Bug 1755555 - Hold tokensLock through nssToken_GetSlot calls in
            nssTrustDomain_GetActiveSlots. r=rrelyea
    
            [1931b2b09b55] <NSS_3_68_3_BRANCH>
    
    2022-02-23  John M. Schanck  <jschanck@xxxxxxxxxxx>
    
            * lib/certdb/crl.c, lib/certdb/stanpcertdb.c, lib/dev/devtoken.c,
            lib/dev/devutil.c, lib/pk11wrap/pk11auth.c, lib/pk11wrap/pk11cert.c,
            lib/pk11wrap/pk11nobj.c, lib/pk11wrap/pk11slot.c,
            lib/pk11wrap/pk11util.c, lib/pk11wrap/secmodti.h,
            lib/pki/pki3hack.c, lib/pki/trustdomain.c:
            Bug 1370866 - Check return value of PK11Slot_GetNSSToken. r=djackson
    
            [ba0086e6737d] <NSS_3_68_3_BRANCH>
    
    2022-03-25  John M. Schanck  <jschanck@xxxxxxxxxxx>
    
            * lib/nss/nss.h, lib/softoken/softkver.h, lib/util/nssutil.h:
            Set version numbers to 3.68.3 final
            [c7b7c2f03ef2] <NSS_3_68_3_BRANCH>
    
    2021-12-15  Benjamin Beurdouche  <bbeurdouche@xxxxxxxxxxx>
    
            * .hgtags:
            Added tag NSS_3_68_2_RTM for changeset 78d2f4a3339f
            [c55cf4a0cb0e] <NSS_3_68_2_BRANCH>
    
    Differential Revision: https://phabricator.services.mozilla.com/D142237
---
 security/nss/TAG-INFO                 |  2 +-
 security/nss/coreconf/coreconf.dep    |  1 -
 security/nss/lib/certdb/crl.c         |  2 +
 security/nss/lib/certdb/stanpcertdb.c |  6 +++
 security/nss/lib/dev/dev.h            |  5 ---
 security/nss/lib/dev/devslot.c        | 73 ++++++++++++++++++----------------
 security/nss/lib/dev/devt.h           |  1 -
 security/nss/lib/dev/devtoken.c       | 20 ++--------
 security/nss/lib/dev/devutil.c        | 18 +++------
 security/nss/lib/nss/nss.h            |  4 +-
 security/nss/lib/pk11wrap/dev3hack.c  | 19 ---------
 security/nss/lib/pk11wrap/pk11auth.c  |  9 ++++-
 security/nss/lib/pk11wrap/pk11cert.c  | 74 ++++++++++++++++++++++++-----------
 security/nss/lib/pk11wrap/pk11nobj.c  | 24 +++++++++---
 security/nss/lib/pk11wrap/pk11slot.c  | 73 ++++++++++++++++++++++++++--------
 security/nss/lib/pk11wrap/pk11util.c  | 27 ++++++++++---
 security/nss/lib/pk11wrap/secmodti.h  |  1 +
 security/nss/lib/pki/pki3hack.c       | 23 +++++++++--
 security/nss/lib/pki/trustdomain.c    | 28 +++++++------
 security/nss/lib/softoken/softkver.h  |  4 +-
 security/nss/lib/util/nssutil.h       |  4 +-
 21 files changed, 256 insertions(+), 162 deletions(-)

diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO
index 9e1cc8ce68cc9..3c0affe5d52d1 100644
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1 +1 @@
-NSS_3_68_2_RTM
\ No newline at end of file
+NSS_3_68_3_RTM
\ No newline at end of file
diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep
index 590d1bfaeee3f..5182f75552c81 100644
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -10,4 +10,3 @@
  */
 
 #error "Do not include this header file."
-
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
index cc5c71f20c843..d110841241630 100644
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -1391,6 +1391,7 @@ TokenCRLStillExists(CERTSignedCrl* crl)
     arena = NSSArena_Create();
     PORT_Assert(arena);
     if (!arena) {
+        (void)nssToken_Destroy(instance.token);
         return PR_FALSE;
     }
 
@@ -1412,6 +1413,7 @@ TokenCRLStillExists(CERTSignedCrl* crl)
         xstatus = PR_FALSE;
     }
     NSSArena_Destroy(arena);
+    (void)nssToken_Destroy(instance.token);
     return xstatus;
 }
 
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
index 8e1cf279ab23c..e255df10531e3 100644
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ b/security/nss/lib/certdb/stanpcertdb.c
@@ -299,9 +299,15 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
     /* Import the perm instance onto the internal token */
     slot = PK11_GetInternalKeySlot();
     internal = PK11Slot_GetNSSToken(slot);
+    if (!internal) {
+        PK11_FreeSlot(slot);
+        PORT_SetError(SEC_ERROR_NO_TOKEN);
+        return SECFailure;
+    }
     permInstance = nssToken_ImportCertificate(
         internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding,
         &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE);
+    (void)nssToken_Destroy(internal);
     nss_ZFreeIf(stanNick);
     stanNick = NULL;
     PK11_FreeSlot(slot);
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index 26ac8957e9102..6430511442796 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -146,7 +146,6 @@ nssModule_GetCertOrder(
  * nssSlot_Destroy
  * nssSlot_AddRef
  * nssSlot_GetName
- * nssSlot_GetTokenName
  * nssSlot_IsTokenPresent
  * nssSlot_IsPermanent
  * nssSlot_IsFriendly
@@ -176,10 +175,6 @@ NSS_EXTERN NSSUTF8 *
 nssSlot_GetName(
     NSSSlot *slot);
 
-NSS_EXTERN NSSUTF8 *
-nssSlot_GetTokenName(
-    NSSSlot *slot);
-
 NSS_EXTERN NSSModule *
 nssSlot_GetModule(
     NSSSlot *slot);
diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c
index 5021408bf06f2..ccd90ac9729d6 100644
--- a/security/nss/lib/dev/devslot.c
+++ b/security/nss/lib/dev/devslot.c
@@ -12,7 +12,9 @@
 #include "ckhelper.h"
 #endif /* CKHELPER_H */
 
-#include "pk11pub.h"
+#include "pkim.h"
+#include "dev3hack.h"
+#include "pk11func.h"
 
 /* measured in seconds */
 #define NSSSLOT_TOKEN_DELAY_TIME 1
@@ -79,13 +81,6 @@ nssSlot_GetName(
     return slot->base.name;
 }
 
-NSS_IMPLEMENT NSSUTF8 *
-nssSlot_GetTokenName(
-    NSSSlot *slot)
-{
-    return nssToken_GetName(slot->token);
-}
-
 NSS_IMPLEMENT void
 nssSlot_ResetDelay(
     NSSSlot *slot)
@@ -123,11 +118,13 @@ nssSlot_IsTokenPresent(
 {
     CK_RV ckrv;
     PRStatus nssrv;
+    NSSToken *nssToken = NULL;
     /* XXX */
     nssSession *session;
     CK_SLOT_INFO slotInfo;
     void *epv;
     PRBool isPresent = PR_FALSE;
+    PRBool doUpdateCachedCerts = PR_FALSE;
 
     /* permanent slots are always present unless they're disabled */
     if (nssSlot_IsPermanent(slot)) {
@@ -169,23 +166,24 @@ nssSlot_IsTokenPresent(
 
     PZ_Unlock(slot->isPresentLock);
 
+    nssToken = PK11Slot_GetNSSToken(slot->pk11slot);
+    if (!nssToken) {
+        isPresent = PR_FALSE;
+        goto done;
+    }
+
     nssSlot_EnterMonitor(slot);
     ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo);
     nssSlot_ExitMonitor(slot);
     if (ckrv != CKR_OK) {
-        slot->token->base.name[0] = 0; /* XXX */
+        nssToken->base.name[0] = 0; /* XXX */
         isPresent = PR_FALSE;
         goto done;
     }
     slot->ckFlags = slotInfo.flags;
     /* check for the presence of the token */
     if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
-        if (!slot->token) {
-            /* token was never present */
-            isPresent = PR_FALSE;
-            goto done;
-        }
-        session = nssToken_GetDefaultSession(slot->token);
+        session = nssToken_GetDefaultSession(nssToken);
         if (session) {
             nssSession_EnterMonitor(session);
             /* token is not present */
@@ -197,21 +195,21 @@ nssSlot_IsTokenPresent(
             }
             nssSession_ExitMonitor(session);
         }
-        if (slot->token->base.name[0] != 0) {
+        if (nssToken->base.name[0] != 0) {
             /* notify the high-level cache that the token is removed */
-            slot->token->base.name[0] = 0; /* XXX */
-            nssToken_NotifyCertsNotVisible(slot->token);
+            nssToken->base.name[0] = 0; /* XXX */
+            nssToken_NotifyCertsNotVisible(nssToken);
         }
-        slot->token->base.name[0] = 0; /* XXX */
+        nssToken->base.name[0] = 0; /* XXX */
         /* clear the token cache */
-        nssToken_Remove(slot->token);
+        nssToken_Remove(nssToken);
         isPresent = PR_FALSE;
         goto done;
     }
     /* token is present, use the session info to determine if the card
      * has been removed and reinserted.
      */
-    session = nssToken_GetDefaultSession(slot->token);
+    session = nssToken_GetDefaultSession(nssToken);
     if (session) {
         PRBool tokenRemoved;
         nssSession_EnterMonitor(session);
@@ -237,17 +235,31 @@ nssSlot_IsTokenPresent(
      * a token it doesn't recognize. invalidate all the old
      * information we had on this token, if we can't refresh, clear
      * the present flag */
-    nssToken_NotifyCertsNotVisible(slot->token);
-    nssToken_Remove(slot->token);
-    /* token has been removed, need to refresh with new session */
-    nssrv = nssSlot_Refresh(slot);
-    isPresent = PR_TRUE;
+    nssToken_NotifyCertsNotVisible(nssToken);
+    nssToken_Remove(nssToken);
+    if (nssToken->base.name[0] == 0) {
+        doUpdateCachedCerts = PR_TRUE;
+    }
+    if (PK11_InitToken(slot->pk11slot, PR_FALSE) != SECSuccess) {
+        isPresent = PR_FALSE;
+        goto done;
+    }
+    if (doUpdateCachedCerts) {
+        nssTrustDomain_UpdateCachedTokenCerts(nssToken->trustDomain,
+                                              nssToken);
+    }
+    nssrv = nssToken_Refresh(nssToken);
     if (nssrv != PR_SUCCESS) {
-        slot->token->base.name[0] = 0; /* XXX */
+        nssToken->base.name[0] = 0; /* XXX */
         slot->ckFlags &= ~CKF_TOKEN_PRESENT;
         isPresent = PR_FALSE;
+        goto done;
     }
+    isPresent = PR_TRUE;
 done:
+    if (nssToken) {
+        (void)nssToken_Destroy(nssToken);
+    }
     /* Once we've set up the condition variable,
      * Before returning, it's necessary to:
      *  1) Set the lastTokenPingTime so that any other threads waiting on this
@@ -283,12 +295,7 @@ nssSlot_GetToken(
     NSSToken *rvToken = NULL;
 
     if (nssSlot_IsTokenPresent(slot)) {
-        /* Even if a token should be present, check `slot->token` too as it
-         * might be gone already. This would happen mostly on shutdown. */
-        nssSlot_EnterMonitor(slot);
-        if (slot->token)
-            rvToken = nssToken_AddRef(slot->token);
-        nssSlot_ExitMonitor(slot);
+        rvToken = PK11Slot_GetNSSToken(slot->pk11slot);
     }
 
     return rvToken;
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index 06a57ad05b19b..19af26f08177e 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -81,7 +81,6 @@ typedef enum {
 struct NSSSlotStr {
     struct nssDeviceBaseStr base;
     NSSModule *module; /* Parent */
-    NSSToken *token;   /* Peer */
     CK_SLOT_ID slotID;
     CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
     struct nssSlotAuthInfoStr authInfo;
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index fedc44b4b51f3..5e65dfdb1b555 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -32,13 +32,6 @@ nssToken_Destroy(
             PK11_FreeSlot(tok->pk11slot);
             PZ_DestroyLock(tok->base.lock);
             nssTokenObjectCache_Destroy(tok->cache);
-
-            /* We're going away, let the nssSlot know in case it's held
-             * alive by someone else. Usually we should hold the last ref. */
-            nssSlot_EnterMonitor(tok->slot);
-            tok->slot->token = NULL;
-            nssSlot_ExitMonitor(tok->slot);
-
             (void)nssSlot_Destroy(tok->slot);
             return nssArena_Destroy(tok->base.arena);
         }
@@ -53,13 +46,6 @@ nssToken_Remove(
     nssTokenObjectCache_Clear(tok->cache);
 }
 
-NSS_IMPLEMENT void
-NSSToken_Destroy(
-    NSSToken *tok)
-{
-    (void)nssToken_Destroy(tok);
-}
-
 NSS_IMPLEMENT NSSToken *
 nssToken_AddRef(
     NSSToken *tok)
@@ -996,8 +982,9 @@ sha1_hash(NSSItem *input, NSSItem *output)
     NSSToken *token = PK11Slot_GetNSSToken(internal);
     ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
     (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
-    PK11_FreeSlot(token->pk11slot);
     nss_ZFreeIf(ap);
+    (void)nssToken_Destroy(token);
+    PK11_FreeSlot(internal);
 }
 
 static void
@@ -1008,8 +995,9 @@ md5_hash(NSSItem *input, NSSItem *output)
     NSSToken *token = PK11Slot_GetNSSToken(internal);
     ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
     (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
-    PK11_FreeSlot(token->pk11slot);
     nss_ZFreeIf(ap);
+    (void)nssToken_Destroy(token);
+    PK11_FreeSlot(internal);
 }
 
 static CK_TRUST
diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c
index 7c30a0da2cb81..302a6b56270bf 100644
--- a/security/nss/lib/dev/devutil.c
+++ b/security/nss/lib/dev/devutil.c
@@ -56,7 +56,7 @@ nssCryptokiObject_Destroy(
     nssCryptokiObject *object)
 {
     if (object) {
-        nssToken_Destroy(object->token);
+        (void)nssToken_Destroy(object->token);
         nss_ZFreeIf(object->label);
         nss_ZFreeIf(object);
     }
@@ -150,19 +150,12 @@ nssTokenArray_Destroy(
     if (tokens) {
         NSSToken **tokenp;
         for (tokenp = tokens; *tokenp; tokenp++) {
-            nssToken_Destroy(*tokenp);
+            (void)nssToken_Destroy(*tokenp);
         }
         nss_ZFreeIf(tokens);
     }
 }
 
-NSS_IMPLEMENT void
-NSSTokenArray_Destroy(
-    NSSToken **tokens)
-{
-    nssTokenArray_Destroy(tokens);
-}
-
 NSS_IMPLEMENT void
 nssCryptokiObjectArray_Destroy(
     nssCryptokiObject **objects)
@@ -365,7 +358,7 @@ create_object(
     /* The cache is tied to the token, and therefore the objects
      * in it should not hold references to the token.
      */
-    nssToken_Destroy(object->token);
+    (void)nssToken_Destroy(object->token);
     rvCachedObject->object = object;
     rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes);
     if (!rvCachedObject->attributes) {
@@ -568,7 +561,7 @@ get_token_objects_for_cache(
                                                      &numObjects,
                                                      &status);
     if (status != PR_SUCCESS) {
-        nss_ZFreeIf(objects);
+        nssCryptokiObjectArray_Destroy(objects);
         return status;
     }
     for (i = 0; i < numObjects; i++) {
@@ -584,7 +577,8 @@ get_token_objects_for_cache(
     } else {
         PRUint32 j;
         for (j = 0; j < i; j++) {
-            /* sigh */
+            /* Any token references that were removed in successful loop iterations
+             * need to be restored before we call nssCryptokiObjectArray_Destroy */
             nssToken_AddRef(cache->objects[objectType][j]->object->token);
             nssArena_Destroy(cache->objects[objectType][j]->arena);
         }
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index c87fa1ec9725e..d0c1a1f19a28e 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -22,10 +22,10 @@
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION "3.68.2" _NSS_CUSTOMIZED
+#define NSS_VERSION "3.68.3" _NSS_CUSTOMIZED
 #define NSS_VMAJOR 3
 #define NSS_VMINOR 68
-#define NSS_VPATCH 2
+#define NSS_VPATCH 3
 #define NSS_VBUILD 0
 #define NSS_BETA PR_FALSE
 
diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
index 4877f945053a0..2d41a34d85282 100644
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -179,7 +179,6 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
     if (!rvToken->slot) {
         goto loser;
     }
-    rvToken->slot->token = rvToken;
     if (rvToken->defaultSession)
         rvToken->defaultSession->slot = rvToken->slot;
     return rvToken;
@@ -227,24 +226,6 @@ nssToken_Refresh(NSSToken *token)
     return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
 }
 
-NSS_IMPLEMENT PRStatus
-nssSlot_Refresh(NSSSlot *slot)
-{
-    PK11SlotInfo *nss3slot = slot->pk11slot;
-    PRBool doit = PR_FALSE;
-    if (slot->token && slot->token->base.name[0] == 0) {
-        doit = PR_TRUE;
-    }
-    if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
-        return PR_FAILURE;
-    }
-    if (doit) {
-        nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
-                                              slot->token);
-    }
-    return nssToken_Refresh(slot->token);
-}
-
 NSS_IMPLEMENT PRStatus
 nssToken_GetTrustOrder(NSSToken *tok)
 {
diff --git a/security/nss/lib/pk11wrap/pk11auth.c b/security/nss/lib/pk11wrap/pk11auth.c
index c633e53f7bc8c..42e64e1c9a575 100644
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ b/security/nss/lib/pk11wrap/pk11auth.c
@@ -4,6 +4,8 @@
 /*
  * This file deals with PKCS #11 passwords and authentication.
  */
+#include "dev.h"
+#include "dev3hack.h"
 #include "seccomon.h"
 #include "secmod.h"
 #include "secmodi.h"
@@ -637,8 +639,11 @@ PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
     }
     if (rv == SECSuccess) {
         if (!contextSpecific && !PK11_IsFriendly(slot)) {
-            nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
-                                                  slot->nssToken);
+            NSSToken *token = PK11Slot_GetNSSToken(slot);
+            if (token) {
+                nssTrustDomain_UpdateCachedTokenCerts(token->trustDomain, token);
+                (void)nssToken_Destroy(token);
+            }
         }
     } else if (!attempt)
         PORT_SetError(SEC_ERROR_BAD_PASSWORD);
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 9c745d7b824df..84d8300357a4f 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -242,16 +242,17 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
     NSSCertificate *c;
     nssCryptokiObject *co = NULL;
     nssPKIObject *pkio;
-    NSSToken *token;
     NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
 
     /* Get the cryptoki object from the handle */
-    token = PK11Slot_GetNSSToken(slot);
-    if (token && token->defaultSession) {
-        co = nssCryptokiObject_Create(token, token->defaultSession, certID);
-    } else {
+    NSSToken *token = PK11Slot_GetNSSToken(slot);
+    if (!token || !token->defaultSession) {
+        (void)nssToken_Destroy(token); /* null token is ok */
         PORT_SetError(SEC_ERROR_NO_TOKEN);
+        return NULL;
     }
+    co = nssCryptokiObject_Create(token, token->defaultSession, certID);
+    (void)nssToken_Destroy(token);
     if (!co) {
         return NULL;
     }
@@ -754,7 +755,7 @@ find_certs_from_uri(const char *uriString, void *wincx)
             nssPKIObjectCollection_AddInstances(collection, instances, 0);
             nss_ZFreeIf(instances);
         }
-        nssToken_Destroy(*tok);
+        (void)nssToken_Destroy(*tok);
     }
     nss_ZFreeIf(tokens);
     nssList_Destroy(certList);
@@ -863,9 +864,7 @@ find_certs_from_nickname(const char *nickname, void *wincx)
     } else {
         slot = PK11_GetInternalKeySlot();
         token = PK11Slot_GetNSSToken(slot);
-        if (token) {
-            nssToken_AddRef(token);
-        } else {
+        if (!token) {
             PORT_SetError(SEC_ERROR_NO_TOKEN);
         }
     }
@@ -929,7 +928,7 @@ find_certs_from_nickname(const char *nickname, void *wincx)
     }
 loser:
     if (token) {
-        nssToken_Destroy(token);
+        (void)nssToken_Destroy(token);
     }
     if (slot) {
         PK11_FreeSlot(slot);
@@ -1129,15 +1128,15 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
     PRStatus status;
     NSSCertificate *c;
     nssCryptokiObject *keyobj, *certobj;
-    NSSToken *token = PK11Slot_GetNSSToken(slot);
-    SECItem *keyID = pk11_mkcertKeyID(cert);
+    NSSToken *token = NULL;
     char *emailAddr = NULL;
     nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
     nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
-
+    SECItem *keyID = pk11_mkcertKeyID(cert);
     if (keyID == NULL) {
         goto loser; /* error code should be set already */
     }
+    token = PK11Slot_GetNSSToken(slot);
     if (!token) {
         PORT_SetError(SEC_ERROR_NO_TOKEN);
         goto loser;
@@ -1230,8 +1229,12 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
     (void)STAN_ForceCERTCertificateUpdate(c);
     nssCertificate_Destroy(c);
     SECITEM_FreeItem(keyID, PR_TRUE);
+    (void)nssToken_Destroy(token);
     return SECSuccess;
 loser:
+    if (token) {
+        (void)nssToken_Destroy(token);
+    }
     CERT_MapStanError();
     SECITEM_FreeItem(keyID, PR_TRUE);
     if (PORT_GetError() != SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
@@ -1466,7 +1469,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
     NSSCertificate *cert = NULL;
     NSSDER issuer, serial;
     NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
-    NSSToken *token = slot->nssToken;
+    NSSToken *token = NULL;
     nssSession *session;
     nssCryptokiObject *instance = NULL;
     nssPKIObject *object = NULL;
@@ -1481,12 +1484,18 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
         return NULL;
     }
 
-    /* Paranoia */
-    if (token == NULL) {
+    token = PK11Slot_GetNSSToken(slot);
+    if (!token) {
         PORT_SetError(SEC_ERROR_NO_TOKEN);
         return NULL;
     }
 
+    session = nssToken_GetDefaultSession(token); /* non-owning */
+    if (!session) {
+        (void)nssToken_Destroy(token);
+        return NULL;
+    }
+
     /* PKCS#11 needs to use DER-encoded serial numbers.  Create a
      * CERTIssuerAndSN that actually has the encoded value and pass that
      * to PKCS#11 (and the crypto context).
@@ -1495,20 +1504,17 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
                                    &issuerSN->serialNumber,
                                    SEC_ASN1_GET(SEC_IntegerTemplate));
     if (!derSerial) {
+        (void)nssToken_Destroy(token);
         return NULL;
     }
 
     NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
     NSSITEM_FROM_SECITEM(&serial, derSerial);
 
-    session = nssToken_GetDefaultSession(token);
-    if (!session) {
-        goto loser;
-    }
-
     instance = nssToken_FindCertificateByIssuerAndSerialNumber(token, session,
                                                                &issuer, &serial, nssTokenSearchType_TokenForced, &status);
 
+    (void)nssToken_Destroy(token);
     SECITEM_FreeItem(derSerial, PR_TRUE);
 
     if (!instance) {
@@ -2177,16 +2183,22 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
     td = STAN_GetDefaultTrustDomain();
     NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
     token = PK11Slot_GetNSSToken(slot);
+    if (!token) {
+        return SECSuccess;
+    }
     if (!nssToken_IsPresent(token)) {
+        (void)nssToken_Destroy(token);
         return SECSuccess;
     }
     collection = nssCertificateCollection_Create(td, NULL);
     if (!collection) {
+        (void)nssToken_Destroy(token);
         return SECFailure;
     }
     subjectList = nssList_Create(NULL, PR_FALSE);
     if (!subjectList) {
         nssPKIObjectCollection_Destroy(collection);
+        (void)nssToken_Destroy(token);
         return SECFailure;
     }
     (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
@@ -2201,6 +2213,7 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
     certs = nssPKIObjectCollection_GetCertificates(collection,
                                                    NULL, 0, NULL);
     nssPKIObjectCollection_Destroy(collection);
+    (void)nssToken_Destroy(token);
     if (certs) {
         CERTCertificate *oldie;
         NSSCertificate **cp;
@@ -2234,7 +2247,8 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
     nssList *nameList = NULL;
     nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
     token = PK11Slot_GetNSSToken(slot);
-    if (!nssToken_IsPresent(token)) {
+    if (!token || !nssToken_IsPresent(token)) {
+        (void)nssToken_Destroy(token);
         return SECSuccess;
     }
     if (nickname->data[nickname->len - 1] != '\0') {
@@ -2264,6 +2278,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
     certs = nssPKIObjectCollection_GetCertificates(collection,
                                                    NULL, 0, NULL);
     nssPKIObjectCollection_Destroy(collection);
+    (void)nssToken_Destroy(token);
     if (certs) {
         CERTCertificate *oldie;
         NSSCertificate **cp;
@@ -2283,6 +2298,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
         nss_ZFreeIf(nick);
     return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
 loser:
+    (void)nssToken_Destroy(token);
     if (created) {
         nss_ZFreeIf(nick);
     }
@@ -2308,16 +2324,22 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
     NSSCertificate **certs;
     nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
     tok = PK11Slot_GetNSSToken(slot);
+    if (!tok) {
+        return SECSuccess;
+    }
     if (!nssToken_IsPresent(tok)) {
+        (void)nssToken_Destroy(tok);
         return SECSuccess;
     }
     collection = nssCertificateCollection_Create(td, NULL);
     if (!collection) {
+        (void)nssToken_Destroy(tok);
         return SECFailure;
     }
     certList = nssList_Create(NULL, PR_FALSE);
     if (!certList) {
         nssPKIObjectCollection_Destroy(collection);
+        (void)nssToken_Destroy(tok);
         return SECFailure;
     }
     (void)nssTrustDomain_GetCertsFromCache(td, certList);
@@ -2330,6 +2352,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
     certs = nssPKIObjectCollection_GetCertificates(collection,
                                                    NULL, 0, NULL);
     nssPKIObjectCollection_Destroy(collection);
+    (void)nssToken_Destroy(tok);
     if (certs) {
         CERTCertificate *oldie;
         NSSCertificate **cp;
@@ -2369,7 +2392,6 @@ PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert,
     SECStatus rv;
     CERTCertificate *cert = NULL;
 
-    tok = PK11Slot_GetNSSToken(slot);
     NSSITEM_FROM_SECITEM(&derCert, inDerCert);
     rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
     if (rv != SECSuccess) {
@@ -2377,8 +2399,14 @@ PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert,
         return NULL;
     }
 
+    tok = PK11Slot_GetNSSToken(slot);
+    if (!tok) {
+        PK11_FreeSlot(slot);
+        return NULL;
+    }
     co = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert,
                                                       nssTokenSearchType_TokenOnly, NULL);
+    (void)nssToken_Destroy(tok);
 
     if (co) {
         cert = PK11_MakeCertFromHandle(slot, co->handle, NULL);
diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c
index 80bc009f78907..586ed80e32aa3 100644
--- a/security/nss/lib/pk11wrap/pk11nobj.c
+++ b/security/nss/lib/pk11wrap/pk11nobj.c
@@ -413,12 +413,17 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
         nssPKIObjectCollection *collection;
         nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
         NSSToken *token = PK11Slot_GetNSSToken(*slot);
+        if (!token) {
+            goto loser;
+        }
         collection = nssCRLCollection_Create(td, NULL);
         if (!collection) {
+            (void)nssToken_Destroy(token);
             goto loser;
         }
         instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
                                                tokenOnly, 0, NULL);
+        (void)nssToken_Destroy(token);
         nssPKIObjectCollection_AddInstances(collection, instances, 0);
         nss_ZFreeIf(instances);
         crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
@@ -482,16 +487,21 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
             char *url, int type)
 {
     NSSItem derCRL, derSubject;
-    NSSToken *token = PK11Slot_GetNSSToken(slot);
+    NSSToken *token;
     nssCryptokiObject *object;
     PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
     CK_OBJECT_HANDLE rvH;
 
     NSSITEM_FROM_SECITEM(&derSubject, name);
     NSSITEM_FROM_SECITEM(&derCRL, crl);
-
+    token = PK11Slot_GetNSSToken(slot);
+    if (!token) {
+        PORT_SetError(SEC_ERROR_NO_TOKEN);
+        return CK_INVALID_HANDLE;
+    }
     object = nssToken_ImportCRL(token, NULL,
                                 &derSubject, &derCRL, isKRL, url, PR_TRUE);
+    (void)nssToken_Destroy(token);
 
     if (object) {
         rvH = object->handle;
@@ -510,8 +520,8 @@ SECStatus
 SEC_DeletePermCRL(CERTSignedCrl *crl)
 {
     PRStatus status;
-    NSSToken *token;
     nssCryptokiObject *object;
+    NSSToken *token;
     PK11SlotInfo *slot = crl->slot;
 
     if (slot == NULL) {
@@ -520,13 +530,17 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
         PORT_SetError(SEC_ERROR_CRL_INVALID);
         return SECFailure;
     }
-    token = PK11Slot_GetNSSToken(slot);
 
+    token = PK11Slot_GetNSSToken(slot);
+    if (!token) {
+        return SECFailure;
+    }
     object = nss_ZNEW(NULL, nssCryptokiObject);
     if (!object) {
+        (void)nssToken_Destroy(token);
         return SECFailure;
     }
-    object->token = nssToken_AddRef(token);
+    object->token = token; /* object takes ownership */
     object->handle = crl->pkcs11ID;
     object->isTokenObject = PR_TRUE;
 
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index c320019f9397d..99be9528f0b34 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -362,19 +362,24 @@ PK11_NewSlotInfo(SECMODModule *mod)
     PK11SlotInfo *slot;
 
     slot = (PK11SlotInfo *)PORT_Alloc(sizeof(PK11SlotInfo));
-    if (slot == NULL)
+    if (slot == NULL) {
         return slot;
-
-    slot->sessionLock = mod->isThreadSafe ? PZ_NewLock(nssILockSession) : mod->refLock;
-    if (slot->sessionLock == NULL) {
-        PORT_Free(slot);
-        return NULL;
     }
     slot->freeListLock = PZ_NewLock(nssILockFreelist);
     if (slot->freeListLock == NULL) {
-        if (mod->isThreadSafe) {
-            PZ_DestroyLock(slot->sessionLock);
-        }
+        PORT_Free(slot);
+        return NULL;
+    }
+    slot->nssTokenLock = PZ_NewLock(nssILockOther);
+    if (slot->nssTokenLock == NULL) {
+        PZ_DestroyLock(slot->freeListLock);
+        PORT_Free(slot);
+        return NULL;
+    }
+    slot->sessionLock = mod->isThreadSafe ? PZ_NewLock(nssILockSession) : mod->refLock;
+    if (slot->sessionLock == NULL) {
+        PZ_DestroyLock(slot->nssTokenLock);
+        PZ_DestroyLock(slot->freeListLock);
         PORT_Free(slot);
         return NULL;
     }
@@ -462,6 +467,10 @@ PK11_DestroySlot(PK11SlotInfo *slot)
         PZ_DestroyLock(slot->freeListLock);
         slot->freeListLock = NULL;
     }
+    if (slot->nssTokenLock) {
+        PZ_DestroyLock(slot->nssTokenLock);
+        slot->nssTokenLock = NULL;
+    }
 
     /* finally Tell our parent module that we've gone away so it can unload */
     if (slot->module) {
@@ -1260,6 +1269,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
     CK_RV crv;
     SECStatus rv;
     PRStatus status;
+    NSSToken *nssToken;
 
     /* set the slot flags to the current token values */
     if (!slot->isThreadSafe)
@@ -1297,7 +1307,9 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
     slot->maxPassword = slot->tokenInfo.ulMaxPinLen;
     PORT_Memcpy(slot->serial, slot->tokenInfo.serialNumber, sizeof(slot->serial));
 
-    nssToken_UpdateName(slot->nssToken);
+    nssToken = PK11Slot_GetNSSToken(slot);
+    nssToken_UpdateName(nssToken); /* null token is OK */
+    (void)nssToken_Destroy(nssToken);
 
     slot->defRWSession = (PRBool)((!slot->readOnly) &&
                                   (slot->tokenInfo.ulMaxSessionCount == 1));
@@ -1365,7 +1377,9 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
             PK11_ExitSlotMonitor(slot);
     }
 
-    status = nssToken_Refresh(slot->nssToken);
+    nssToken = PK11Slot_GetNSSToken(slot);
+    status = nssToken_Refresh(nssToken); /* null token is OK */
+    (void)nssToken_Destroy(nssToken);
     if (status != PR_SUCCESS)
         return SECFailure;
 
@@ -1598,8 +1612,11 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
         return PR_TRUE;
     }
 
-    if (slot->nssToken) {
-        return nssToken_IsPresent(slot->nssToken);
+    NSSToken *nssToken = PK11Slot_GetNSSToken(slot);
+    if (nssToken) {
+        PRBool present = nssToken_IsPresent(nssToken);
+        (void)nssToken_Destroy(nssToken);
+        return present;
     }
 
     /* removable slots have a flag that says they are present */
@@ -2649,20 +2666,44 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
         PORT_SetError(PK11_MapError(crv));
         return SECFailure;
     }
-    nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
-                                          slot->nssToken);
+    NSSToken *token = PK11Slot_GetNSSToken(slot);
+    if (token) {
+        nssTrustDomain_UpdateCachedTokenCerts(token->trustDomain, token);
+        (void)nssToken_Destroy(token);
+    }
     return SECSuccess;
 }
+
 void
 PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
 {
+    NSSToken *old;
+    if (nsst) {
+        nsst = nssToken_AddRef(nsst);
+    }
+
+    PZ_Lock(sl->nssTokenLock);
+    old = sl->nssToken;
     sl->nssToken = nsst;
+    PZ_Unlock(sl->nssTokenLock);
+
+    if (old) {
+        (void)nssToken_Destroy(old);
+    }
 }
 
 NSSToken *
 PK11Slot_GetNSSToken(PK11SlotInfo *sl)
 {
-    return sl->nssToken;
+    NSSToken *rv = NULL;
+
+    PZ_Lock(sl->nssTokenLock);
+    if (sl->nssToken) {
+        rv = nssToken_AddRef(sl->nssToken);
+    }
+    PZ_Unlock(sl->nssTokenLock);
+
+    return rv;
 }
 
 PRBool
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
index 08c793bf32fa6..0862ee28918d9 100644
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -13,6 +13,7 @@
 #include "pki3hack.h"
 #include "secerr.h"
 #include "dev.h"
+#include "dev3hack.h"
 #include "utilpars.h"
 #include "pkcs11uri.h"
 
@@ -1266,8 +1267,14 @@ SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
     }
     /* if we are in the delay period for the "isPresent" call, reset
      * the delay since we know things have probably changed... */
-    if (slot && slot->nssToken && slot->nssToken->slot) {
-        nssSlot_ResetDelay(slot->nssToken->slot);
+    if (slot) {
+        NSSToken *nssToken = PK11Slot_GetNSSToken(slot);
+        if (nssToken) {
+            if (nssToken->slot) {
+                nssSlot_ResetDelay(nssToken->slot);
+            }
+            (void)nssToken_Destroy(nssToken);
+        }
     }
     return slot;
 
@@ -1500,8 +1507,12 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
     if (slot) {
         /* if we are in the delay period for the "isPresent" call, reset
          * the delay since we know things have probably changed... */
-        if (slot->nssToken && slot->nssToken->slot) {
-            nssSlot_ResetDelay(slot->nssToken->slot);
+        NSSToken *nssToken = PK11Slot_GetNSSToken(slot);
+        if (nssToken) {
+            if (nssToken->slot) {
+                nssSlot_ResetDelay(nssToken->slot);
+            }
+            (void)nssToken_Destroy(nssToken);
         }
         /* force the slot info structures to properly reset */
         (void)PK11_IsPresent(slot);
@@ -1631,8 +1642,12 @@ SECMOD_CloseUserDB(PK11SlotInfo *slot)
     PR_smprintf_free(sendSpec);
     /* if we are in the delay period for the "isPresent" call, reset
      * the delay since we know things have probably changed... */
-    if (slot->nssToken && slot->nssToken->slot) {
-        nssSlot_ResetDelay(slot->nssToken->slot);
+    NSSToken *nssToken = PK11Slot_GetNSSToken(slot);
+    if (nssToken) {
+        if (nssToken->slot) {
+            nssSlot_ResetDelay(nssToken->slot);
+        }
+        (void)nssToken_Destroy(nssToken);
         /* force the slot info structures to properly reset */
         (void)PK11_IsPresent(slot);
     }
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index 04c63a8690fd6..5dca1e46cda14 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -107,6 +107,7 @@ struct PK11SlotInfoStr {
     unsigned int lastState;
     /* for Stan */
     NSSToken *nssToken;
+    PZLock *nssTokenLock;
     /* the tokeninfo struct */
     CK_TOKEN_INFO tokenInfo;
     /* fast mechanism lookup */
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index 7fe9113e4a610..5556cd17695f8 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -72,12 +72,16 @@ STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot)
         }
     }
     token = nssToken_CreateFromPK11SlotInfo(td, slot);
-    PK11Slot_SetNSSToken(slot, token);
-    /* Don't add nonexistent token to TD's token list */
     if (token) {
+        /* PK11Slot_SetNSSToken increments the refcount on |token| to 2 */
+        PK11Slot_SetNSSToken(slot, token);
+
+        /* we give our reference to |td->tokenList| */
         NSSRWLock_LockWrite(td->tokensLock);
         nssList_Add(td->tokenList, token);
         NSSRWLock_UnlockWrite(td->tokensLock);
+    } else {
+        PK11Slot_SetNSSToken(slot, NULL);
     }
     return PR_SUCCESS;
 }
@@ -188,7 +192,8 @@ STAN_RemoveModuleFromDefaultTrustDomain(
             nssList_Remove(td->tokenList, token);
             NSSRWLock_UnlockWrite(td->tokensLock);
             PK11Slot_SetNSSToken(module->slots[i], NULL);
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token); /* for the |td->tokenList| reference */
+            (void)nssToken_Destroy(token); /* for our PK11Slot_GetNSSToken reference */
         }
     }
     NSSRWLock_LockWrite(td->tokensLock);
@@ -1076,7 +1081,11 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
             nssArena_Destroy(arena);
             return NULL;
         }
-        instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
+        instance->token = PK11Slot_GetNSSToken(cc->slot);
+        if (!instance->token) {
+            nssArena_Destroy(arena);
+            return NULL;
+        }
         instance->handle = cc->pkcs11ID;
         instance->isTokenObject = PR_TRUE;
         if (cc->nickname) {
@@ -1269,6 +1278,10 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
             NSSASCII7 *email = c->email;
             tok = PK11Slot_GetNSSToken(slot);
             PK11_FreeSlot(slot);
+            if (!tok) {
+                nssrv = PR_FAILURE;
+                goto done;
+            }
 
             newInstance = nssToken_ImportCertificate(tok, NULL,
                                                      NSSCertificateType_PKIX,
@@ -1283,6 +1296,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
             nss_ZFreeIf(nickname);
             nickname = NULL;
             if (!newInstance) {
+                (void)nssToken_Destroy(tok);
                 nssrv = PR_FAILURE;
                 goto done;
             }
@@ -1294,6 +1308,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
                                                nssTrust->codeSigning,
                                                nssTrust->emailProtection,
                                                nssTrust->stepUpApproved, PR_TRUE);
+            (void)nssToken_Destroy(tok);
         }
         if (newInstance) {
             nssCryptokiObject_Destroy(newInstance);
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index 151b888750d07..c8f9f1d5b988c 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -11,6 +11,7 @@
 #endif /* PKIM_H */
 
 #include "cert.h"
+#include "dev3hack.h"
 #include "pki3hack.h"
 #include "pk11pub.h"
 #include "nssrwlk.h"
@@ -61,11 +62,14 @@ static void
 token_destructor(void *t)
 {
     NSSToken *tok = (NSSToken *)t;
-    /* The token holds the first/last reference to the slot.
-     * When the token is actually destroyed (ref count == 0),
-     * the slot will also be destroyed.
-     */
-    nssToken_Destroy(tok);
+    /* Remove the token list's reference to the token */
+    (void)nssToken_Destroy(tok);
+
+    /* Signal that the slot should not give out any more references to the
+     * token. The token might still have a positive refcount after this call.
+     * The token has a reference to the slot, so the slot will not be destroyed
+     * until after the token's refcount drops to 0. */
+    PK11Slot_SetNSSToken(tok->pk11slot, NULL);
 }
 
 NSS_IMPLEMENT PRStatus
@@ -127,7 +131,6 @@ nssTrustDomain_GetActiveSlots(
         return NULL;
     }
     nssList_GetArray(td->tokenList, (void **)tokens, count);
-    NSSRWLock_UnlockRead(td->tokensLock);
     count = 0;
     for (tp = tokens; *tp; tp++) {
         NSSSlot *slot = nssToken_GetSlot(*tp);
@@ -137,6 +140,7 @@ nssTrustDomain_GetActiveSlots(
             nssSlot_Destroy(slot);
         }
     }
+    NSSRWLock_UnlockRead(td->tokensLock);
     nss_ZFreeIf(tokens);
     if (!count) {
         nss_ZFreeIf(slots);
@@ -469,7 +473,7 @@ nssTrustDomain_FindCertificatesByNickname(
                                                                 numRemaining,
                                                                 &status);
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
             if (status != PR_SUCCESS) {
                 errors++;
                 continue;
@@ -618,7 +622,7 @@ nssTrustDomain_FindCertificatesBySubject(
                                                                numRemaining,
                                                                &status);
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
             if (status != PR_SUCCESS) {
                 errors++;
                 continue;
@@ -779,7 +783,7 @@ nssTrustDomain_FindCertificateByIssuerAndSerialNumber(
                     tokenOnly,
                     &status);
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
             if (status != PR_SUCCESS) {
                 continue;
             }
@@ -1022,7 +1026,7 @@ NSSTrustDomain_TraverseCertificates(
                                                     collector,
                                                     collection);
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
         }
     }
 
@@ -1076,7 +1080,7 @@ nssTrustDomain_FindTrustForCertificate(
                     nssCryptokiObject_Destroy(to);
                 }
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
         }
     }
     if (pkio) {
@@ -1126,7 +1130,7 @@ nssTrustDomain_FindCRLsBySubject(
                 instances = nssToken_FindCRLsBySubject(token, session, subject,
                                                        tokenOnly, 0, &status);
             }
-            nssToken_Destroy(token);
+            (void)nssToken_Destroy(token);
             if (status == PR_SUCCESS) {
                 /* add the found CRL's to the collection */
                 status = nssPKIObjectCollection_AddInstances(collection,
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
index f3506b6e461fd..929b9809e7b4c 100644
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -17,10 +17,10 @@
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION "3.68.2" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.68.3" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR 3
 #define SOFTOKEN_VMINOR 68
-#define SOFTOKEN_VPATCH 2
+#define SOFTOKEN_VPATCH 3
 #define SOFTOKEN_VBUILD 0
 #define SOFTOKEN_BETA PR_FALSE
 
diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h
index 28e0f1e8b4025..8548404b4755d 100644
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -19,10 +19,10 @@
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION "3.68.2"
+#define NSSUTIL_VERSION "3.68.3"
 #define NSSUTIL_VMAJOR 3
 #define NSSUTIL_VMINOR 68
-#define NSSUTIL_VPATCH 2
+#define NSSUTIL_VPATCH 3
 #define NSSUTIL_VBUILD 0
 #define NSSUTIL_BETA PR_FALSE
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits