summaryrefslogtreecommitdiff
path: root/libs/nss/src/lib/dev/devslot.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/nss/src/lib/dev/devslot.c')
-rw-r--r--libs/nss/src/lib/dev/devslot.c36
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