diff options
Diffstat (limited to 'libs/nss/src/lib/dev/devslot.c')
-rw-r--r-- | libs/nss/src/lib/dev/devslot.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/libs/nss/src/lib/dev/devslot.c b/libs/nss/src/lib/dev/devslot.c index 5021408bf..3f4e54e06 100644 --- a/libs/nss/src/lib/dev/devslot.c +++ b/libs/nss/src/lib/dev/devslot.c @@ -171,11 +171,12 @@ nssSlot_IsTokenPresent( 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 */ + if (slot->token) { + slot->token->base.name[0] = 0; /* XXX */ + } isPresent = PR_FALSE; - goto done; + goto done; /* slot lock held */ } slot->ckFlags = slotInfo.flags; /* check for the presence of the token */ @@ -183,10 +184,11 @@ nssSlot_IsTokenPresent( if (!slot->token) { /* token was never present */ isPresent = PR_FALSE; - goto done; + goto done; /* slot lock held */ } session = nssToken_GetDefaultSession(slot->token); if (session) { + nssSlot_ExitMonitor(slot); nssSession_EnterMonitor(session); /* token is not present */ if (session->handle != CK_INVALID_HANDLE) { @@ -196,6 +198,12 @@ nssSlot_IsTokenPresent( session->handle = CK_INVALID_HANDLE; } nssSession_ExitMonitor(session); + nssSlot_EnterMonitor(slot); + if (!slot->token) { + /* Check token presence after re-acquiring lock */ + isPresent = PR_FALSE; + goto done; /* slot lock held */ + } } if (slot->token->base.name[0] != 0) { /* notify the high-level cache that the token is removed */ @@ -206,14 +214,23 @@ nssSlot_IsTokenPresent( /* clear the token cache */ nssToken_Remove(slot->token); isPresent = PR_FALSE; - goto done; + goto done; /* slot lock held */ + } + if (!slot->token) { + /* This should not occur, based on the fact that the + * below calls will dereference NULL otherwise. */ + PORT_Assert(0); + isPresent = PR_FALSE; + goto done; /* slot lock held */ } + /* token is present, use the session info to determine if the card * has been removed and reinserted. */ session = nssToken_GetDefaultSession(slot->token); if (session) { PRBool tokenRemoved; + nssSlot_ExitMonitor(slot); nssSession_EnterMonitor(session); if (session->handle != CK_INVALID_HANDLE) { CK_SESSION_INFO sessionInfo; @@ -227,10 +244,16 @@ nssSlot_IsTokenPresent( } tokenRemoved = (session->handle == CK_INVALID_HANDLE); nssSession_ExitMonitor(session); + nssSlot_EnterMonitor(slot); /* token not removed, finished */ if (!tokenRemoved) { isPresent = PR_TRUE; - goto done; + goto done; /* slot lock held */ + } + if (!slot->token) { + /* Check token presence after re-acquiring lock */ + isPresent = PR_FALSE; + goto done; /* slot lock held */ } } /* the token has been removed, and reinserted, or the slot contains @@ -248,6 +271,7 @@ nssSlot_IsTokenPresent( isPresent = PR_FALSE; } done: + nssSlot_ExitMonitor(slot); /* 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 |