Created attachment 739694 [details]
Description of problem:
A pcsc-lite client program can be deadlocked due to an unreleased mutex in SCardBeginTransaction. This can happen when a smart card reader, temporarily, stops responding.
Version-Release number of selected component (if applicable):
Always reproducible with the card reader we have which goes "off-line" when entering a settings menu.
Steps to Reproduce:
1. A client program performs continuous calls to SCard-functions, e.g. SCardGetStatusChange(SCARD_STATE_UNAWARE).
2. Take reader off-line by entering an on-reader settings menu.
3. Take the reader on-line again by leaving the settings menu.
The client program will deadlock and never recover. It waits for a mutex that was never released in an earlier call to SCardBeginTransaction.
The client program should not deadlock and the reader should be accessible again after returning on-line.
Here's a patch that fixes the problem:
diff --git a/src/winscard_clnt.c b/src/winscard_clnt.c
index c190f45..1819158 100644
@@ -1149,10 +1149,19 @@ LONG SCardBeginTransaction(SCARDHANDLE hCard)
/* check the handle is still valid */
rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
+ /* firstname.lastname@example.org: The comment above about
+ * the mutex can't be correct. The mutex is held by
+ * this thread and must be release by this thread before
+ * returning. */
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
Can you reproduce the bug with pcsc-lite 1.5.5?
An even better solution is to upgrade and check with pcsc-lite 1.8.8 (latest version)
Tested with pcsc-lite 1.8.8. Problem is the same and the same suggested patch fixes it. IMHO it's plain that the mutex isn't released if SCardGetIndicesFromHandle fails. Releasing the mutex before returning from SCardBeginTransaction must be the right thing to do.
Opened upstream as https://alioth.debian.org/tracker/index.php?func=detail&aid=314227&group_id=30105&atid=410085
Since you now have pcsc-lite 1.8.8 can you use libpcscspy.so.0 to generate a log file (cat ~/pcsc-spy > logfile) and attach it here?
I can't trigger the problem with pcsc-spy activated and only seldom with the regular libpcsclite.so version 1.8.8. Version 1.8.8 seems to have different timing than 1.5.2 where I can trigger the deadlock 100% of the times I try.
I realize that my case is a bit weak and might not be an issue for anyone that doesn't need to use the smart card reader we use (Swedish Defense KT2).
I do however believe that many of the functions in winscard_clnt.c can potentialy cause deadlocks because they have return paths that don't unlock context mutexes.
Can you point me to a winscard_clnt.c function that can cause a deadlock for version 1.8.8?
The few time the deadlock occurred in 1.8.8 it was cased by returning from SCardBeginTransaction while still holding the mutex. I know this because I put printfs just before the return statement in every SCard-function that has the same logic, i.e. check the return value from SCardGetContextFromChannel and if -1, return without unlocking the mutex. Every time my test application got stuck waiting for a mutex in a call to SCardGetStatusChange, I could see from a printout from SCardBeginTransaction that it had returned prematurely.
Fredrik, I reviewed the code and I am puzzled by your bug.
In 1.8.8 the only way to return from SCardBeginTransaction is either:
- at the end after unlocking the lock
- in case SCardGetContextAndChannelFromHandle() fails
If SCardGetContextAndChannelFromHandle() fails it indicated the hCard parameter has been invalidated (the parameter hCard was valid on the initial SCardGetContextAndChannelFromHandle() call).
hCard is now invalid because SCardDisconnect() has been called for this hCard.
And if SCardDisconnect() has been called then the mutex has been released.
It would really help if you could reproduce the problem using pcsc-lite 1.8.8 and pcsc-spy to get a trace of the calls.
The bug has been fixed in revision 6639.
I will release a new version of pcsc-lite with the bug fixed "soon".
This request was not resolved in time for the current release.
Red Hat invites you to ask your support representative to
propose this request, if still desired, for consideration in
the next release of Red Hat Enterprise Linux.
Please provide steps to test and verify this. Also, what type of smart card and the reader is used?
(In reply to Asha Akkiangady from comment #11)
> Please provide steps to test and verify this. Also, what type of smart card
> and the reader is used?
I have verified this in the test setup I have. Problem is that the card and reader are specific to the Swedish Defense and not publically available.
Also note that the software that triggered this bug was not well-behaved and had itself threading issues. This was pointed out to me by Ludovic Rousseau and fixing that issue caused the bug not to be triggered.
To summarize: I believe that the bug is fixed and I have verified this but I can't think of a way for anyone else to test it.
It appears that this is an environment issue, not a pcsc-lite bug. Can we close this bug as NOTABUG?
Looks like upstream patch that still needs to be applied to RHEL 6.
Upstream patch applied (modified appropriately for the older code base).
[root@dhcp129-124 ~]# rpm -qi pcsc-lite
Name : pcsc-lite Relocations: (not relocatable)
Version : 1.5.2 Vendor: Red Hat, Inc.
Release : 15.el6 Build Date: Thu 26 Feb 2015 08:39:13 PM EST
Install Date: Fri 10 Apr 2015 12:06:37 PM EDT Build Host: x86-031.build.eng.bos.redhat.com
Group : System Environment/Daemons Source RPM: pcsc-lite-1.5.2-15.el6.src.rpm
Size : 402732 License: BSD
Signature : RSA/8, Wed 04 Mar 2015 07:22:07 AM EST, Key ID 938a80caf21541eb
Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
URL : http://pcsclite.alioth.debian.org/
Summary : PC/SC Lite smart card framework and applications
Sanity only, all supported smartcards were detected.
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.