Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCardGetStatusChange: Race condition when attaching multiple readers at the same time #190

Open
kgraefe opened this issue Jun 11, 2024 · 7 comments

Comments

@kgraefe
Copy link

kgraefe commented Jun 11, 2024

Versions

❯ /usr/sbin/pcscd --version
pcsc-lite version 2.0.0.
Copyright (C) 1999-2002 by David Corcoran <[email protected]>.
Copyright (C) 2001-2022 by Ludovic Rousseau <[email protected]>.
Copyright (C) 2003-2004 by Damien Sauveron <[email protected]>.
Report bugs to <[email protected]>.
Enabled features: Linux x86_64-pc-linux-gnu libsystemd serial usb libudev usbdropdir=/usr/lib/pcsc/drivers ipcdir=/run/pcscd filter configdir=/etc/reader.conf.d
MAX_READERNAME: 128, PCSCLITE_MAX_READERS_CONTEXTS: 16
❯ pcsc_scan -V
PC/SC device scanner
V 1.6.2 (c) 2001-2022, Ludovic Rousseau <[email protected]>

Platform

  • Operating system or GNU/Linux distribution name and version: Ubuntu 23.10
  • Smart card middleware name and version
  • Smart card reader manufacturer name and reader model name: Generic USB2.0-CRW [Smart Card Reader Interface] (20070818000000000)
  • Smart card name

Issue

  • What do you do? run pcsc_scan -n and attach a USB hub with two USB card readers attached
  • What result do you expect? both readers should be detected
  • What result do you get instead?

I encountered the issue in my own program using rust-pcsc but could also reproduce with pcsc_scan. I think what happens is the following:

  1. Both readers are enumerated sequentially
  2. When the first reader is enumerated \\?PnP?\Notification fires, SCardGetStatusChange returns. What happens next, depends on when the second reader is enumerated
  3. pcsc_scan calls SCardListReaders to get the number of readers. If the second reader is already enumerated, both will be detected.
  4. pcsc_scan calls SCardListReaders with the buffer. If the second reader is now enumerated but wasn't before, the call will fail with SCARD_E_INSUFFICIENT_BUFFER and none will be detected.
  5. pcsc_scan calls SCardListReaders. If the second reader is now enumerated but wasn't before, \\?PnP?\Notification does not fire and the second reader will not be detected. Otherwise it will fire at some point and go back to 3. so that both readers are detected.

In my own program I can mitigate 4. quite easily. However, how to treat 5.? The only thing I could come up with is polling but the point of SCardGetStatusChange is to avoid that.

Log

see above

@LudovicRousseau
Copy link
Owner

Yes, it is a known limitation of SCardGetStatusChange(). You can't detect a reader connection/disconnection between 2 calls of SCardGetStatusChange().

One solution would be to use dwEventState for the special reader \\?PnP?\Notification to store the number of reader events. If that number has changed between two calls of SCardGetStatusChange() then we return.

This field is already used by Windows to store the number of readers. I could not find the documentation for that.
See https://salsa.debian.org/rousseau/PCSC/-/issues/5

@kgraefe
Copy link
Author

kgraefe commented Jun 12, 2024

Thank you for your response. IMHO an event count would be better as the number of readers may loose events if a reader is detached and another is attached between two calls of SCardGetStatusChange(). However, that seems rather theoretic and I cannot oversee the Windows / macOS situation.

I read your comment I don't think it is a good idea to implement something that would work for pcsc-lite only, and not for Windows or macOS. so that this will not / cannot be fixed any time soon, sadly. Feel free to close this ticket if you like.

@LudovicRousseau
Copy link
Owner

I may implement the idea I presented. It will only work on GNU/Linux but at least it would be possible to have a "safe" SCardGetStatusChange() on this platform.

I do not expect Apple or Microsoft to do anything on their own implementation of WinSCard.

@LudovicRousseau
Copy link
Owner

I think I fixed the issue in a beta version.
See http:https://lists.infradead.org/pipermail/pcsclite-muscle/2024-June/001498.html

@LudovicRousseau
Copy link
Owner

Hello @kgraefe
Have you had a chance to test my proposed code?
Does it solve the problem for you?

@kgraefe
Copy link
Author

kgraefe commented Jul 5, 2024

It's on my list. I could not find the time yet.

@kgraefe
Copy link
Author

kgraefe commented Jul 10, 2024

Does it solve the problem for you?

yes it does! thank you 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants