Skip to content

Commit

Permalink
Bug 1663661 - Guard against NULL token in nssSlot_IsTokenPresent. r=jcj
Browse files Browse the repository at this point in the history
This patch addresses locking inconsistency in `nssSlot_IsTokenPresent` by retaining the slot lock for the duration of accesses to `slot->token`. This is already done correctly elsewhere. As a side effect, this introduces an ordering requirement: we take `slot->lock` followed by `session->lock`.

Differential Revision: https://phabricator.services.mozilla.com/D95636

--HG--
extra : moz-landing-system : lando
  • Loading branch information
Kevin Jacobs committed Nov 3, 2020
1 parent aa23578 commit d1f32b4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
22 changes: 16 additions & 6 deletions lib/dev/devslot.c
Expand Up @@ -171,19 +171,20 @@ 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 */
if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
if (!slot->token) {
/* token was never present */
isPresent = PR_FALSE;
goto done;
goto done; /* slot lock held */
}
session = nssToken_GetDefaultSession(slot->token);
if (session) {
Expand All @@ -206,8 +207,16 @@ 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.
*/
Expand All @@ -230,7 +239,7 @@ nssSlot_IsTokenPresent(
/* token not removed, finished */
if (!tokenRemoved) {
isPresent = PR_TRUE;
goto done;
goto done; /* slot lock held */
}
}
/* the token has been removed, and reinserted, or the slot contains
Expand All @@ -248,6 +257,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
Expand Down
3 changes: 3 additions & 0 deletions lib/dev/devt.h
Expand Up @@ -96,6 +96,9 @@ struct NSSSlotStr {
};

struct nssSessionStr {
/* Must not hold slot->lock when taking lock.
* See ordering in nssSlot_IsTokenPresent.
*/
PZLock *lock;
CK_SESSION_HANDLE handle;
NSSSlot *slot;
Expand Down

0 comments on commit d1f32b4

Please sign in to comment.