|
|
5f1c2b |
diff -up nss/lib/pk11wrap/dev3hack.c.init-token-race nss/lib/pk11wrap/dev3hack.c
|
|
|
5f1c2b |
--- nss/lib/pk11wrap/dev3hack.c.init-token-race 2017-01-13 17:58:55.485868744 +0100
|
|
|
5f1c2b |
+++ nss/lib/pk11wrap/dev3hack.c 2017-01-13 18:02:27.126675831 +0100
|
|
|
5f1c2b |
@@ -231,6 +231,16 @@ nssSlot_Refresh(NSSSlot *slot)
|
|
|
1b6f66 |
if (slot->token && slot->token->base.name[0] == 0) {
|
|
|
5f1c2b |
doit = PR_TRUE;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+ /* invalidate the session in the nss3slot if we haven't done an init
|
|
|
1b6f66 |
+ * token since we noticed that the token->default session is invalid.
|
|
|
1b6f66 |
+ * This works because the monitor lock and the token session lock are the
|
|
|
1b6f66 |
+ * same locks */
|
|
|
1b6f66 |
+ PK11_EnterSlotMonitor(nss3slot);
|
|
|
1b6f66 |
+ if ((slot->token == NULL) || (slot->token->defaultSession == NULL) ||
|
|
|
1b6f66 |
+ (slot->token->defaultSession->handle == CK_INVALID_SESSION)) {
|
|
|
1b6f66 |
+ nss3slot->session = CK_INVALID_SESSION;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(nss3slot);
|
|
|
1b6f66 |
if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
|
|
|
5f1c2b |
return PR_FAILURE;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
@@ -238,7 +248,8 @@ nssSlot_Refresh(NSSSlot *slot)
|
|
|
5f1c2b |
nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
|
|
|
5f1c2b |
slot->token);
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
- return nssToken_Refresh(slot->token);
|
|
|
1b6f66 |
+ /* no need to call nssToken_Refresh since PK11_Init has already done so */
|
|
|
1b6f66 |
+ return PR_SUCCESS;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
NSS_IMPLEMENT PRStatus
|
|
|
5f1c2b |
diff -up nss/lib/pk11wrap/pk11auth.c.init-token-race nss/lib/pk11wrap/pk11auth.c
|
|
|
5f1c2b |
--- nss/lib/pk11wrap/pk11auth.c.init-token-race 2017-01-13 17:58:55.485868744 +0100
|
|
|
5f1c2b |
+++ nss/lib/pk11wrap/pk11auth.c 2017-01-13 18:05:07.650739842 +0100
|
|
|
5f1c2b |
@@ -73,8 +73,6 @@ pk11_CheckPassword(PK11SlotInfo *slot, C
|
|
|
5f1c2b |
(unsigned char *)pw, len);
|
|
|
5f1c2b |
slot->lastLoginCheck = 0;
|
|
|
5f1c2b |
mustRetry = PR_FALSE;
|
|
|
5f1c2b |
- if (!alreadyLocked)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
switch (crv) {
|
|
|
5f1c2b |
/* if we're already logged in, we're good to go */
|
|
|
5f1c2b |
case CKR_OK:
|
|
|
5f1c2b |
@@ -101,7 +99,16 @@ pk11_CheckPassword(PK11SlotInfo *slot, C
|
|
|
5f1c2b |
break;
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
if (retry++ == 0) {
|
|
|
5f1c2b |
+ /* we already know the this session is invalid */
|
|
|
5f1c2b |
+ slot->session = CK_INVALID_SESSION;
|
|
|
5f1c2b |
+ /* can't enter PK11_InitToken holding the lock
|
|
|
5f1c2b |
+ * This is safe because the only places that tries to
|
|
|
5f1c2b |
+ * hold the slot monitor over this call pass their own
|
|
|
5f1c2b |
+ * session, which would have failed above.
|
|
|
5f1c2b |
+ * (session != slot->session) */
|
|
|
5f1c2b |
+ PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
rv = PK11_InitToken(slot, PR_FALSE);
|
|
|
5f1c2b |
+ PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
if (rv == SECSuccess) {
|
|
|
5f1c2b |
if (slot->session != CK_INVALID_SESSION) {
|
|
|
5f1c2b |
session = slot->session; /* we should have
|
|
|
5f1c2b |
@@ -119,6 +126,8 @@ pk11_CheckPassword(PK11SlotInfo *slot, C
|
|
|
5f1c2b |
PORT_SetError(PK11_MapError(crv));
|
|
|
5f1c2b |
rv = SECFailure; /* some failure we can't fix by retrying */
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
+ if (!alreadyLocked)
|
|
|
5f1c2b |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
} while (mustRetry);
|
|
|
1b6f66 |
return rv;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
@@ -465,14 +474,18 @@ done:
|
|
|
1b6f66 |
slot->lastLoginCheck = 0;
|
|
|
5f1c2b |
PK11_RestoreROSession(slot, rwsession);
|
|
|
1b6f66 |
if (rv == SECSuccess) {
|
|
|
1b6f66 |
+ PK11_EnterSlotMonitor(slot);
|
|
|
1b6f66 |
/* update our view of the world */
|
|
|
1b6f66 |
+ if (slot->session != CK_INVALID_SESSION) {
|
|
|
1b6f66 |
+ PK11_GETTAB(slot)->C_CloseSession(slot->session);
|
|
|
1b6f66 |
+ slot->session = CK_INVALID_SESSION;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
PK11_InitToken(slot, PR_TRUE);
|
|
|
5f1c2b |
if (slot->needLogin) {
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
PK11_GETTAB(slot)->C_Login(slot->session, CKU_USER,
|
|
|
5f1c2b |
(unsigned char *)userpw, len);
|
|
|
5f1c2b |
slot->lastLoginCheck = 0;
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
return rv;
|
|
|
5f1c2b |
@@ -520,7 +533,7 @@ PK11_ChangePW(PK11SlotInfo *slot, const
|
|
|
5f1c2b |
PK11_RestoreROSession(slot, rwsession);
|
|
|
1b6f66 |
|
|
|
1b6f66 |
/* update our view of the world */
|
|
|
5f1c2b |
- PK11_InitToken(slot, PR_TRUE);
|
|
|
1b6f66 |
+ /* PK11_InitToken(slot,PR_TRUE); */
|
|
|
1b6f66 |
return rv;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
5f1c2b |
diff -up nss/lib/pk11wrap/pk11slot.c.init-token-race nss/lib/pk11wrap/pk11slot.c
|
|
|
5f1c2b |
--- nss/lib/pk11wrap/pk11slot.c.init-token-race 2017-01-13 17:58:55.486868720 +0100
|
|
|
5f1c2b |
+++ nss/lib/pk11wrap/pk11slot.c 2017-01-13 18:12:50.869381900 +0100
|
|
|
5f1c2b |
@@ -1085,6 +1085,7 @@ PK11_ReadMechanismList(PK11SlotInfo *slo
|
|
|
1b6f66 |
CK_ULONG count;
|
|
|
1b6f66 |
CK_RV crv;
|
|
|
1b6f66 |
PRUint32 i;
|
|
|
1b6f66 |
+ char mechanismBits[sizeof(slot->mechanismBits)];
|
|
|
1b6f66 |
|
|
|
1b6f66 |
if (slot->mechanismList) {
|
|
|
5f1c2b |
PORT_Free(slot->mechanismList);
|
|
|
5f1c2b |
@@ -1092,12 +1093,8 @@ PK11_ReadMechanismList(PK11SlotInfo *slo
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
slot->mechanismCount = 0;
|
|
|
1b6f66 |
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID, NULL, &count);
|
|
|
1b6f66 |
if (crv != CKR_OK) {
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
PORT_SetError(PK11_MapError(crv));
|
|
|
5f1c2b |
return SECFailure;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
@@ -1105,14 +1102,10 @@ PK11_ReadMechanismList(PK11SlotInfo *slo
|
|
|
1b6f66 |
slot->mechanismList = (CK_MECHANISM_TYPE *)
|
|
|
5f1c2b |
PORT_Alloc(count * sizeof(CK_MECHANISM_TYPE));
|
|
|
1b6f66 |
if (slot->mechanismList == NULL) {
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
return SECFailure;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID,
|
|
|
5f1c2b |
slot->mechanismList, &count);
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
if (crv != CKR_OK) {
|
|
|
5f1c2b |
PORT_Free(slot->mechanismList);
|
|
|
5f1c2b |
slot->mechanismList = NULL;
|
|
|
5f1c2b |
@@ -1120,14 +1113,16 @@ PK11_ReadMechanismList(PK11SlotInfo *slo
|
|
|
5f1c2b |
return SECSuccess;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
slot->mechanismCount = count;
|
|
|
1b6f66 |
- PORT_Memset(slot->mechanismBits, 0, sizeof(slot->mechanismBits));
|
|
|
1b6f66 |
+ PORT_Memset(mechanismBits, 0, sizeof(slot->mechanismBits));
|
|
|
1b6f66 |
|
|
|
5f1c2b |
for (i = 0; i < count; i++) {
|
|
|
5f1c2b |
CK_MECHANISM_TYPE mech = slot->mechanismList[i];
|
|
|
5f1c2b |
if (mech < 0x7ff) {
|
|
|
5f1c2b |
- slot->mechanismBits[mech & 0xff] |= 1 << (mech >> 8);
|
|
|
1b6f66 |
+ mechanismBits[mech & 0xff] |= 1 << (mech >> 8);
|
|
|
5f1c2b |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+ PORT_Memcpy(slot->mechanismBits, mechanismBits,
|
|
|
1b6f66 |
+ sizeof(slot->mechanismBits));
|
|
|
1b6f66 |
return SECSuccess;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
5f1c2b |
@@ -1144,14 +1139,20 @@ PK11_InitToken(PK11SlotInfo *slot, PRBoo
|
|
|
1b6f66 |
CK_RV crv;
|
|
|
1b6f66 |
SECStatus rv;
|
|
|
1b6f66 |
PRStatus status;
|
|
|
1b6f66 |
+ CK_SESSION_HANDLE session;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ PK11_EnterSlotMonitor(slot);
|
|
|
1b6f66 |
+ if (slot->session != CK_INVALID_SESSION) {
|
|
|
1b6f66 |
+ /* The reason for doing an InitToken has already been satisfied by
|
|
|
1b6f66 |
+ * another thread. Just return */
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
+ return SECSuccess;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
|
|
|
1b6f66 |
/* set the slot flags to the current token values */
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &tokenInfo);
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
if (crv != CKR_OK) {
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
PORT_SetError(PK11_MapError(crv));
|
|
|
5f1c2b |
return SECFailure;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
@@ -1186,8 +1187,10 @@ PK11_InitToken(PK11SlotInfo *slot, PRBoo
|
|
|
5f1c2b |
slot->defRWSession = (PRBool)((!slot->readOnly) &&
|
|
|
5f1c2b |
(tokenInfo.ulMaxSessionCount == 1));
|
|
|
1b6f66 |
rv = PK11_ReadMechanismList(slot);
|
|
|
5f1c2b |
- if (rv != SECSuccess)
|
|
|
5f1c2b |
- return rv;
|
|
|
1b6f66 |
+ if (rv != SECSuccess) {
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
+ return rv;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
|
|
|
1b6f66 |
slot->hasRSAInfo = PR_FALSE;
|
|
|
1b6f66 |
slot->RSAInfoFlags = 0;
|
|
|
5f1c2b |
@@ -1202,56 +1205,23 @@ PK11_InitToken(PK11SlotInfo *slot, PRBoo
|
|
|
5f1c2b |
slot->maxKeyCount = tokenInfo.ulMaxSessionCount / 2;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
- /* Make sure our session handle is valid */
|
|
|
1b6f66 |
- if (slot->session == CK_INVALID_SESSION) {
|
|
|
5f1c2b |
- /* we know we don't have a valid session, go get one */
|
|
|
5f1c2b |
- CK_SESSION_HANDLE session;
|
|
|
1b6f66 |
-
|
|
|
5f1c2b |
- /* session should be Readonly, serial */
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
- crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
|
|
|
1b6f66 |
+ /* we know we don't have a valid session, go get one */
|
|
|
1b6f66 |
+ /* session should be Readonly, serial */
|
|
|
1b6f66 |
+ crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
|
|
|
5f1c2b |
(slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION,
|
|
|
5f1c2b |
slot, pk11_notify, &session);
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
- if (crv != CKR_OK) {
|
|
|
5f1c2b |
- PORT_SetError(PK11_MapError(crv));
|
|
|
5f1c2b |
- return SECFailure;
|
|
|
5f1c2b |
- }
|
|
|
5f1c2b |
- slot->session = session;
|
|
|
1b6f66 |
- } else {
|
|
|
5f1c2b |
- /* The session we have may be defunct (the token associated with it)
|
|
|
5f1c2b |
- * has been removed */
|
|
|
5f1c2b |
- CK_SESSION_INFO sessionInfo;
|
|
|
1b6f66 |
-
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
- crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session, &sessionInfo);
|
|
|
1b6f66 |
- if (crv == CKR_DEVICE_ERROR) {
|
|
|
5f1c2b |
- PK11_GETTAB(slot)
|
|
|
5f1c2b |
- ->C_CloseSession(slot->session);
|
|
|
5f1c2b |
- crv = CKR_SESSION_CLOSED;
|
|
|
5f1c2b |
- }
|
|
|
5f1c2b |
- if ((crv == CKR_SESSION_CLOSED) || (crv == CKR_SESSION_HANDLE_INVALID)) {
|
|
|
5f1c2b |
- crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
|
|
|
5f1c2b |
- (slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION,
|
|
|
5f1c2b |
- slot, pk11_notify, &slot->session);
|
|
|
5f1c2b |
- if (crv != CKR_OK) {
|
|
|
5f1c2b |
- PORT_SetError(PK11_MapError(crv));
|
|
|
5f1c2b |
- slot->session = CK_INVALID_SESSION;
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
- return SECFailure;
|
|
|
5f1c2b |
- }
|
|
|
5f1c2b |
- }
|
|
|
5f1c2b |
- if (!slot->isThreadSafe)
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
+ if (crv != CKR_OK) {
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
+ PORT_SetError(PK11_MapError(crv));
|
|
|
1b6f66 |
+ return SECFailure;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+ slot->session = session;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
status = nssToken_Refresh(slot->nssToken);
|
|
|
1b6f66 |
- if (status != PR_SUCCESS)
|
|
|
1b6f66 |
+ if (status != PR_SUCCESS) {
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
return SECFailure;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
|
|
|
1b6f66 |
if (!(slot->isInternal) && (slot->hasRandom)) {
|
|
|
5f1c2b |
/* if this slot has a random number generater, use it to add entropy
|
|
|
5f1c2b |
@@ -1264,28 +1234,20 @@ PK11_InitToken(PK11SlotInfo *slot, PRBoo
|
|
|
5f1c2b |
/* if this slot can issue random numbers, get some entropy from
|
|
|
5f1c2b |
* that random number generater and give it to our internal token.
|
|
|
5f1c2b |
*/
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session, random_bytes, sizeof(random_bytes));
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
if (crv == CKR_OK) {
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(int_slot);
|
|
|
5f1c2b |
PK11_GETTAB(int_slot)
|
|
|
5f1c2b |
->C_SeedRandom(int_slot->session,
|
|
|
5f1c2b |
random_bytes, sizeof(random_bytes));
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(int_slot);
|
|
|
5f1c2b |
}
|
|
|
1b6f66 |
|
|
|
5f1c2b |
/* Now return the favor and send entropy to the token's random
|
|
|
5f1c2b |
* number generater */
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(int_slot);
|
|
|
5f1c2b |
crv = PK11_GETTAB(int_slot)->C_GenerateRandom(int_slot->session,
|
|
|
5f1c2b |
random_bytes, sizeof(random_bytes));
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(int_slot);
|
|
|
5f1c2b |
if (crv == CKR_OK) {
|
|
|
5f1c2b |
- PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session,
|
|
|
5f1c2b |
random_bytes, sizeof(random_bytes));
|
|
|
5f1c2b |
- PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
PK11_FreeSlot(int_slot);
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
@@ -1318,6 +1280,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBoo
|
|
|
5f1c2b |
->C_CloseSession(session);
|
|
|
5f1c2b |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
5f1c2b |
|
|
|
1b6f66 |
return SECSuccess;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
@@ -1433,6 +1396,8 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
/* if the token is present, initialize it */
|
|
|
1b6f66 |
if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) {
|
|
|
1b6f66 |
+ /* session was initialized to CK_INVALID_SESSION when the slot
|
|
|
1b6f66 |
+ * was created */
|
|
|
5f1c2b |
rv = PK11_InitToken(slot, PR_TRUE);
|
|
|
5f1c2b |
/* the only hard failures are on permanent devices, or function
|
|
|
5f1c2b |
* verify failures... function verify failures are already handled
|
|
|
5f1c2b |
@@ -1888,10 +1853,14 @@ PK11_DoesMechanism(PK11SlotInfo *slot, C
|
|
|
5f1c2b |
return (slot->mechanismBits[type & 0xff] & (1 << (type >> 8))) ? PR_TRUE : PR_FALSE;
|
|
|
1b6f66 |
}
|
|
|
5f1c2b |
|
|
|
1b6f66 |
+ PK11_EnterSlotMonitor(slot);
|
|
|
5f1c2b |
for (i = 0; i < (int)slot->mechanismCount; i++) {
|
|
|
5f1c2b |
- if (slot->mechanismList[i] == type)
|
|
|
5f1c2b |
- return PR_TRUE;
|
|
|
1b6f66 |
+ if (slot->mechanismList[i] == type) {
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
+ return PR_TRUE;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+ PK11_ExitSlotMonitor(slot);
|
|
|
1b6f66 |
return PR_FALSE;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
5f1c2b |
diff -up nss/lib/pk11wrap/pk11util.c.init-token-race nss/lib/pk11wrap/pk11util.c
|
|
|
5f1c2b |
--- nss/lib/pk11wrap/pk11util.c.init-token-race 2017-01-13 17:58:55.487868695 +0100
|
|
|
5f1c2b |
+++ nss/lib/pk11wrap/pk11util.c 2017-01-13 18:01:21.280291292 +0100
|
|
|
5f1c2b |
@@ -1624,6 +1624,11 @@ SECMOD_RestartModules(PRBool force)
|
|
|
1b6f66 |
* older modules require it, and it doesn't hurt (compliant modules
|
|
|
1b6f66 |
* will return CKR_NOT_INITIALIZED */
|
|
|
5f1c2b |
(void)PK11_GETTAB(mod)->C_Finalize(NULL);
|
|
|
1b6f66 |
+ /* finalize clears the session, mark them dead in the
|
|
|
1b6f66 |
+ * slot as well */
|
|
|
1b6f66 |
+ for (i=0; i < mod->slotCount; i++) {
|
|
|
1b6f66 |
+ mod->slots[i]->session = CK_INVALID_SESSION;
|
|
|
1b6f66 |
+ }
|
|
|
5f1c2b |
/* now initialize the module, this function reinitializes
|
|
|
5f1c2b |
* a module in place, preserving existing slots (even if they
|
|
|
5f1c2b |
* no longer exist) */
|
|
|
5f1c2b |
@@ -1643,17 +1648,18 @@ SECMOD_RestartModules(PRBool force)
|
|
|
5f1c2b |
/* get new token sessions, bump the series up so that
|
|
|
5f1c2b |
* we refresh other old sessions. This will tell much of
|
|
|
5f1c2b |
* NSS to flush cached handles it may hold as well */
|
|
|
5f1c2b |
- rv = PK11_InitToken(mod->slots[i], PR_TRUE);
|
|
|
1b6f66 |
+ PK11SlotInfo *slot = mod->slots[i];
|
|
|
1b6f66 |
+ rv = PK11_InitToken(slot,PR_TRUE);
|
|
|
5f1c2b |
/* PK11_InitToken could fail if the slot isn't present.
|
|
|
5f1c2b |
* If it is present, though, something is wrong and we should
|
|
|
5f1c2b |
* disable the slot and let the caller know. */
|
|
|
5f1c2b |
- if (rv != SECSuccess && PK11_IsPresent(mod->slots[i])) {
|
|
|
1b6f66 |
+ if (rv != SECSuccess && PK11_IsPresent(slot)) {
|
|
|
5f1c2b |
/* save the last error code */
|
|
|
5f1c2b |
lastError = PORT_GetError();
|
|
|
5f1c2b |
rrv = rv;
|
|
|
5f1c2b |
/* disable the token */
|
|
|
5f1c2b |
- mod->slots[i]->disabled = PR_TRUE;
|
|
|
5f1c2b |
- mod->slots[i]->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
|
|
|
1b6f66 |
+ slot->disabled = PR_TRUE;
|
|
|
1b6f66 |
+ slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
}
|
|
|
5f1c2b |
}
|