[Pcsclite-muscle] [Newsletter] Re: Race condition during readerstate update
Marc Kewitz
Marc.Kewitz.ext at rohde-schwarz.com
Tue Sep 8 08:24:35 EDT 2020
Hi Ludovic,
I finally had the chance to test your changes.
> -----Original Message-----
> From: pcsclite-muscle <pcsclite-muscle-bounces at lists.infradead.org> On
> Behalf Of Ludovic Rousseau
> Sent: Monday, September 7, 2020 11:24 AM
> To: pcsclite-muscle at lists.infradead.org
> Subject: *EXT* [Newsletter] Re: [Pcsclite-muscle] Race condition during
> readerstate update
>
> Le ven. 28 août 2020 à 13:41, Marc Kewitz <Marc.Kewitz.ext at rohde-
> schwarz.com> a écrit :
> > Hi,
>
> Hello,
>
> > I need your advice/help on an issue. I will try to explain the general setup
> first and then the issue.
> >
> > We have a SOC running linux. This SOC is connected to another processor via
> usb. This processor is handling the smartcard ( and also other things ). Our
> software is running on the SOC using the pcsc-lite lib to communicate with the
> pcscd which communicates with the processor/smartcard. They are
> communicating via the ccid T1 protocol using the CCID driver lib on the SOC.
> We have 2 slots for this smartcard reader.
> >
> > Now to the issue. We are regularly sending requests ( PC_to_RDR_XfrBlock )
> to the smartcard to get random data. If someone pulls the smartcard during
> those requests, the request obviously fails. If that happens, the processor
> checks if the smartcard is still available ( in this case not ) and sends
> RDR_to_PC_NotifySlotChange via the interrupt channel back to the pcscd.
> After that the processor sends the answer RDR_to_PC_DataBlock with an error
> code.
> > This all works fine and we receive the notifyslotchange as well as the
> datablock answer.
> > As soon as our software on the SOC realizes that the request failed, it sends
> an SCardStatus request to the pcscd to check if the card is still available. Now
> the issue is that the readerStates that the pcscd receives in getReaderStates ( )
> have not been updated yet and we see that smartcard as available although it is
> not.
> >
> > It seems like the handling of interrupts in the ccid driver, Multi_PollingProc
> and Multi_InterruptRead, is too slow as I can see the reception of the
> RDR_to_PC_DataBlock answer and the following SCardStatus request before I
> see the InterruptRead return in the pcscd. The readerState update in
> EHStatusHandlerThread is consequently only happening after the SCardStatus
> request.
> >
> > Did anyone ever come across this issue? I really want to avoid touching
> pcscd-lite. My first idea was to get the smartcard status via IFDStatusICC (
> )/GetSlotStatus in SCardStatus. This also works and solves the problem, but I'd
> like to not mess with the pcsc-lite code. I also don't see delaying the
> SCardStatus call in the software running on the SOC as a viable solution as a
> sleep or similar is only concealing the actual problem.
>
> I fixed a problem in the CCID driver and PCSC-lite.
>
> Now when a smart card is removed during a SCardTransmit() you will
> (sometimes/often) receive the error SCARD_E_NO_SMARTCARD instead of
> SCARD_E_NOT_TRANSACTED.
> And the SCardStatus(), if it returns SCARD_S_SUCCESS, will indicate
> SCARD_ABSENT in pdwState.
> After "some time" SCardStatus() will return SCARD_W_REMOVED_CARD.
>
> I wrote "sometimes/often" because depending on the CCID error reported by
> the reader SCardTransmit() may still return SCARD_E_NOT_TRANSACTED.
> For example the reader may return the CCID error "Procedure byte conflict"
> instead of "Card absent or mute". In that case the driver does not know yet if
> the card is still present or not.
>
> You will have to build the current git versions of libccid and pcsc-lite to get this
> fix.
> Tell me if the fix works for you.
It works fine. I needed to add the flag CCID_ICC_ABSENT ( 0x02) in the status field of the answer in case the card was actually removed.
> Remarks:
> - on Windows I get SCARD_E_COMM_DATA_LOST for SCardTransmit() or a non-
> PCSC error 0x57 "The parameter is incorrect"
> - SCardStatus() returns SCARD_W_REMOVED_CARD immediately (as expected)
>
> On macOS (Catalina) I have the same behavior as on GNU/Linux before my
> changes. SCardTransmit() returns SCARD_E_NOT_TRANSACTED and
> SCardStatus() may return SCARD_S_SUCCESS immediately and
> SCARD_W_REMOVED_CARD after "some time".
>
>
> Questions:
> - maybe SCARD_W_REMOVED_CARD is even better than
> SCARD_E_NO_SMARTCARD for SCardTransmit()
I think SCARD_E_NO_SMARTCARD is good. It is an error in the transaction due to a missing smartcard ( ICC_ABSENT ). ( Do those E and W actually stand for error and warning ? )
> - SCardStatus() will return SCARD_S_SUCCESS (but with a correct
> pdwState) until the card removal is really detected. Do you think that is
> important to fix?
It works for us without it. The correct state can be deduced from the pdwState.
Do you plan on releasing a new version in the near future?
Kind regards,
Marc
More information about the pcsclite-muscle
mailing list