Avoid LIBUSB_ERROR_OVERFLOW errors#164
Avoid LIBUSB_ERROR_OVERFLOW errors#164bluetech wants to merge 1 commit intoLudovicRousseau:masterfrom
Conversation
| unsigned int length, unsigned char buffer[]) | ||
| { | ||
| unsigned char cmd[10+length+2]; /* CCID + Protocol Data Structure */ | ||
| unsigned char cmd[ROUND_UP_BUF(10+length+2)]; /* CCID + Protocol Data Structure */ |
There was a problem hiding this comment.
I am wary of using VLAs (see e.g. here). It might be better to use malloc. Though I checked and in this case all actual length arguments are small constant size, so it's not exploitable or such.
|
It would be easier to just modify ReadUSB() to use a temporary big buffer. Then no need to touch anything in commands.c Can you generate a pcscd trace with your patch applied? |
I am trying to get the CCID driver to work with a bit finicky industrial device. Occasionally the communication with the device fails with error LIBUSB_TRANSFER_OVERFLOW, and then things stop working. The reason for this error is described here: https://libusb.sourceforge.io/api-1.0/libusb_packetoverflow.html The errors look like this: pcscd 99999999 src/ccid_usb.c:1082:ReadUSB() read failed (1/14): LIBUSB_ERROR_OVERFLOW pcscd 00000038 src/ifdhandler.c:1244:IFDHPowerICC() PowerDown failed pcscd 63039068 src/ccid_usb.c:1082:ReadUSB() read failed (1/14): LIBUSB_ERROR_TIMEOUT pcscd 00000022 src/ifdhandler.c:1296:IFDHPowerICC() PowerUp failed pcscd 00000005 winscard.c:333:SCardConnect() Error powering up card: rv=SCARD_E_NOT_TRANSACTED pcscd 00000004 prothandler.c:86:PHSetProtocol() Protocol T=1 requested but unsupported by the card Reader: idVendor: 0x0483 iManufacturer: TITENG idProduct: 0x3258 iProduct: TIT-RFREADR-CL As described in the libusb doc, I was able to resolve the problem by tweaking the buffer sizes that CCID is passing to ReadPort (AKA ReadUSB) in the commands.c file. In principle, the needed tweak is to make the buffer sizes a multiple of the endpoint's wMaxPacketSize. This value can be queried from libusb. In all CCID readers I have, the value is always 64 bytes, however in the latest USB version (3.2, very unlikely to actually be used by CCID readers) it can go up to 1024 bytes if I understand correctly. So we can avoid dealing with wMaxPacketSize and just assume 1024. Fixes LudovicRousseau#161
|
I rebased to fix some conflicts, no other code changes.
I did try to avoid this extra copying in the transmit path. Adding the few
I'll try to do it. Unfortunately it's a bit of a hassle for me to get the devices set up and reproduce the issue with logging etc. so I need to find some time to do this. For reference the reader in question is the one embedded in card printers/dispensers from this company: https://www.pointman.co.kr/ENG/ |
I am trying to get the CCID driver to work with a bit finicky industrial device. Occasionally the communication with the device fails with error LIBUSB_TRANSFER_OVERFLOW, and then things stop working. The reason for this error is described here:
https://libusb.sourceforge.io/api-1.0/libusb_packetoverflow.html
The errors look like this:
Reader:
idVendor: 0x0483
iManufacturer: TITENG
idProduct: 0x3258
iProduct: TIT-RFREADR-CL
As described in the libusb doc, I was able to resolve the problem by tweaking the buffer sizes that CCID is passing to ReadPort (AKA ReadUSB) in the commands.c file. In principle, the needed tweak is to make the buffer sizes a multiple of the endpoint's wMaxPacketSize. This value can be queried from libusb. In all CCID readers I have, the value is always 64 bytes, however in the latest USB version (3.2, very unlikely to actually be used by CCID readers) it can go up to 1024 bytes if I understand correctly. So we can avoid dealing with wMaxPacketSize and just assume 1024.
Fixes #161