diff options
Diffstat (limited to 'security/nss/lib/dev/devslot.c')
-rw-r--r-- | security/nss/lib/dev/devslot.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c index 5b0bb371a..9f0bd8226 100644 --- a/security/nss/lib/dev/devslot.c +++ b/security/nss/lib/dev/devslot.c @@ -31,6 +31,7 @@ nssSlot_Destroy( { if (slot) { if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { + PK11_FreeSlot(slot->pk11slot); PZ_DestroyLock(slot->base.lock); return nssArena_Destroy(slot->base.arena); } @@ -91,7 +92,7 @@ nssSlot_ResetDelay( } static PRBool -within_token_delay_period(NSSSlot *slot) +within_token_delay_period(const NSSSlot *slot) { PRIntervalTime time, lastTime; /* Set the delay time for checking the token presence */ @@ -103,7 +104,6 @@ within_token_delay_period(NSSSlot *slot) if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { return PR_TRUE; } - slot->lastTokenPing = time; return PR_FALSE; } @@ -136,6 +136,7 @@ nssSlot_IsTokenPresent( nssSlot_ExitMonitor(slot); if (ckrv != CKR_OK) { slot->token->base.name[0] = 0; /* XXX */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } slot->ckFlags = slotInfo.flags; @@ -143,6 +144,7 @@ nssSlot_IsTokenPresent( if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { if (!slot->token) { /* token was never present */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } session = nssToken_GetDefaultSession(slot->token); @@ -165,6 +167,7 @@ nssSlot_IsTokenPresent( slot->token->base.name[0] = 0; /* XXX */ /* clear the token cache */ nssToken_Remove(slot->token); + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } /* token is present, use the session info to determine if the card @@ -187,8 +190,10 @@ nssSlot_IsTokenPresent( isPresent = session->handle != CK_INVALID_SESSION; nssSession_ExitMonitor(session); /* token not removed, finished */ - if (isPresent) + if (isPresent) { + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; + } } /* the token has been removed, and reinserted, or the slot contains * a token it doesn't recognize. invalidate all the old @@ -201,8 +206,11 @@ nssSlot_IsTokenPresent( if (nssrv != PR_SUCCESS) { slot->token->base.name[0] = 0; /* XXX */ slot->ckFlags &= ~CKF_TOKEN_PRESENT; + /* TODO: insert a barrier here to avoid reordering of the assingments */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; } @@ -217,10 +225,18 @@ NSS_IMPLEMENT NSSToken * nssSlot_GetToken( NSSSlot *slot) { + NSSToken *rvToken = NULL; + if (nssSlot_IsTokenPresent(slot)) { - return nssToken_AddRef(slot->token); + /* 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); } - return (NSSToken *)NULL; + + return rvToken; } NSS_IMPLEMENT PRStatus |