[Pcsclite-muscle] [Newsletter] Re: Race condition during readerstate update

Ludovic Rousseau ludovic.rousseau at gmail.com
Tue Sep 8 09:13:33 EDT 2020


Le mar. 8 sept. 2020 à 14:24, Marc Kewitz
<Marc.Kewitz.ext at rohde-schwarz.com> a écrit :
>
> Hi Ludovic,

Hello,

> 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.

Yes, If the card is no more present then CCID_ICC_ABSENT should be set
in the response from the reader.

> > 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 ? )

I also think E is for error and W for warning. But I am not sure.
We also have F like in SCARD_F_COMM_ERROR and P like in
SCARD_P_SHUTDOWN. I don't know what F and P can be.

> > - 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.

OK. Correct answer :-)

> Do you plan on releasing a new version in the near future?

I don't know.
It will depend on my free time and motivation.

Regards,

-- 
 Dr. Ludovic Rousseau



More information about the pcsclite-muscle mailing list