We are using pcscd version 1.4.102 in a project and got a race condition
there. This race condition is likely to be also present in 1.8.5, as the
code regarding hLockId is very similar.
However, I was not yet able to reproduce the problem there.

The problem occured quite seldom if an USB-based smartcard reader (used
via libccid version 1.3.8) is removed. Then the value dwLockId is set to
0xffff within EHDestroyEventHandler() to inform the
EHStatusHandlerThread() to stop operation.

However, in some cases the EHStatusHandlerThread() never exited. This
resulted in no new chipcard reader being recognized, likely because the
thread scanning for new readers hanging in SYS_ThreadJoin/pthread_join.

In our user szenario where the smartcard is used to grant access to the
system the only solution was to turn of the system.

I did some test runs and identified the function MSGRemoveContext() as
the place where the value of dwLockId was changed from 0xffff to 0, so
that the thread never had a chance of seing this value. On average,
about 50 smartcard reader removals were required to trigger the problem.

During the removal some clients were reading card information involving
some transactions with SCardBeginTransaction.

I worked around the problem introducing an additional signalling
variable to the reader context. That variable is set and queried in
addition to dwLockId (and was succesful in exiting the thread even if
dwLockId was reset to 0 in the meantime).

See the attached patch on how this workaround was implemented.

        Torsten Hilbrich
diff -Narup pcsc-lite-1.4.102.orig/src/eventhandler.c pcsc-lite-1.4.102/src/eventhandler.c
--- pcsc-lite-1.4.102.orig/src/eventhandler.c	2008-06-27 05:07:05.000000000 +0200
+++ pcsc-lite-1.4.102/src/eventhandler.c	2012-09-12 13:26:01.146286768 +0200
@@ -120,6 +120,7 @@ LONG EHDestroyEventHandler(PREADER_CONTE
 	 * Set the thread to 0 to exit thread
 	 */
 	rContext->dwLockId = 0xFFFF;
+	rContext->dwThreadRunning = 0;
 
 	Log1(PCSC_LOG_INFO, "Stomping thread.");
 
@@ -318,6 +319,7 @@ void EHStatusHandlerThread(PREADER_CONTE
 		rContext->dwContexts;
 
 	SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+	rContext->dwThreadRunning = 1;
 
 	while (1)
 	{
@@ -497,6 +499,13 @@ void EHStatusHandlerThread(PREADER_CONTE
 			rContext->dwLockId = 0;
 			SYS_ThreadExit(NULL);
 		}
+
+		if (rContext->dwThreadRunning == 0)
+		{
+			Log2(PCSC_LOG_ERROR, "Force-died: %08x", rContext->dwLockId);
+			rContext->dwLockId = 0;
+			SYS_ThreadExit(NULL);
+		}
 	}
 }
 
diff -Narup pcsc-lite-1.4.102.orig/src/readerfactory.h pcsc-lite-1.4.102/src/readerfactory.h
--- pcsc-lite-1.4.102.orig/src/readerfactory.h	2008-05-09 16:59:08.000000000 +0200
+++ pcsc-lite-1.4.102/src/readerfactory.h	2012-09-12 13:26:01.146286768 +0200
@@ -129,6 +129,7 @@ extern "C"
 		int32_t dwContexts;		/**< Number of open contexts */
 		PDWORD pdwFeeds;		/**< Number of shared client to lib */
 		PDWORD pdwMutex;		/**< Number of client to mutex */
+		volatile DWORD dwThreadRunning;
 
 		struct pubReaderStatesList *readerState; /**< link to the reader state */
 		/* we can't use PREADER_STATE here since eventhandler.h can't be
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to