[Pcsclite-cvs-commit] r6639 - /trunk/PCSC/src/winscard_clnt.c

rousseau at users.alioth.debian.org rousseau at users.alioth.debian.org
Thu May 30 11:21:05 UTC 2013


Author: rousseau
Date: Thu May 30 11:21:05 2013
New Revision: 6639

URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=6639
Log:
Unlock the mutex if hCard has been invalidated by SCardDisconnect()

SCardBeginTransaction() was not correctly releasing a mutex when the
hCard handle was invalidated.
The problem is that hCard can be invalidated by:
- SCardReleaseContext and all the context is invalid
- SCardDisconnect and only the hCard is invalid, not the mutex

The problem was that SCardGetStatusChange() was blocked because
SCardBeginTransaction() had not released the context mutex.

Thanks to Fredrik Axelsson for the bug report
https://bugzilla.redhat.com/show_bug.cgi?id=956530

Modified:
    trunk/PCSC/src/winscard_clnt.c

Modified: trunk/PCSC/src/winscard_clnt.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_clnt.c?rev=6639&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_clnt.c (original)
+++ trunk/PCSC/src/winscard_clnt.c Thu May 30 11:21:05 2013
@@ -661,9 +661,9 @@
 	/* check the context is still opened */
 	currentContextMap = SCardGetContext(hContext);
 	if (NULL == currentContextMap)
-		/* the context is now invalid
+		/* the hContext context is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked */
 	{
 		rv = SCARD_E_INVALID_HANDLE;
 		goto error;
@@ -802,9 +802,9 @@
 	/* check the context is still opened */
 	currentContextMap = SCardGetContext(hContext);
 	if (NULL == currentContextMap)
-		/* the context is now invalid
+		/* the hContext context is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked */
 		return SCARD_E_INVALID_HANDLE;
 
 	strlcpy(scConnectStruct.szReader, szReader, sizeof scConnectStruct.szReader);
@@ -957,10 +957,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	scReconnectStruct.hCard = hCard;
 	scReconnectStruct.dwShareMode = dwShareMode;
@@ -1061,10 +1067,14 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
-	{
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+	{
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		rv = SCARD_E_INVALID_HANDLE;
 		goto error;
 	}
@@ -1168,10 +1178,16 @@
 		rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 			&pChannelMap);
 		if (rv == -1)
-			/* the handle is now invalid
+		{
+			/* the hCard handle is now invalid
 			 * -> another thread may have called SCardReleaseContext
-			 * -> so the mMutex has been unlocked */
+			 *    so the mMutex has been unlocked (and is now invalid)
+			 * -> another thread may have called SCardDisconnect
+			 *    so the mMutex is STILL locked
+			 * since we don't know just unlock the mutex */
+			(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 			return SCARD_E_INVALID_HANDLE;
+		}
 
 		scBeginStruct.hCard = hCard;
 		scBeginStruct.rv = SCARD_S_SUCCESS;
@@ -1272,10 +1288,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	scEndStruct.hCard = hCard;
 	scEndStruct.dwDisposition = dwDisposition;
@@ -1462,10 +1484,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	/* synchronize reader states with daemon */
 	rv = getReaderStates(currentContextMap);
@@ -1764,9 +1792,9 @@
 	/* check the context is still opened */
 	currentContextMap = SCardGetContext(hContext);
 	if (NULL == currentContextMap)
-		/* the context is now invalid
+		/* the hContext context is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked */
 	{
 		rv = SCARD_E_INVALID_HANDLE;
 		goto error;
@@ -2281,10 +2309,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
 		|| (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
@@ -2573,10 +2607,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	if (*pcbAttrLen > MAX_BUFFER_SIZE)
 	{
@@ -2728,10 +2768,16 @@
 	rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
 		&pChannelMap);
 	if (rv == -1)
-		/* the handle is now invalid
+	{
+		/* the hCard handle is now invalid
 		 * -> another thread may have called SCardReleaseContext
-		 * -> so the mMutex has been unlocked */
+		 *    so the mMutex has been unlocked (and is now invalid)
+		 * -> another thread may have called SCardDisconnect
+		 *    so the mMutex is STILL locked
+		 * since we don't know just unlock the mutex */
+		(void)pthread_mutex_unlock(&currentContextMap->mMutex);
 		return SCARD_E_INVALID_HANDLE;
+	}
 
 	if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
 		|| (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
@@ -2899,7 +2945,7 @@
 	/* check the context is still opened */
 	currentContextMap = SCardGetContext(hContext);
 	if (NULL == currentContextMap)
-		/* the context is now invalid
+		/* the hContext context is now invalid
 		 * -> another thread may have called SCardReleaseContext
 		 * -> so the mMutex has been unlocked */
 		return SCARD_E_INVALID_HANDLE;
@@ -3088,7 +3134,7 @@
 	/* check the context is still opened */
 	currentContextMap = SCardGetContext(hContext);
 	if (NULL == currentContextMap)
-		/* the context is now invalid
+		/* the hContext context is now invalid
 		 * -> another thread may have called SCardReleaseContext
 		 * -> so the mMutex has been unlocked */
 		return SCARD_E_INVALID_HANDLE;




More information about the Pcsclite-cvs-commit mailing list