[Pcsclite-muscle] Insufficient checks in CCID
Maksim Ivanov
emaxx at google.com
Tue Aug 4 20:56:50 EDT 2020
Hello,
The CCID free software driver is missing a few checks and graceful
handling of some error cases:
1. The device's |bVoltageSupport| having none of the low three bits
set. (The consequence of this issue is a hang in CmdPowerOn() in
"check_again: ... goto check_again". The specs say that the other bits
are reserved for future use, but theoretically this means that the
three lowest bits can be unset for some devices.)
2. Wrong (too big) ATR size received from the device. (Would lead to a
buffer overrun in CmdPowerOn() when doing memmove() in the buffer:
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/commands.c#L294
.)
3. memcmp() reading past the end-of-buffer when
IFDHSetProtocolParameters() is called with the ATR of length exceeding
20 bytes. (Specifically, when comparing the ATR with |openpgp_atr|:
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/ifdhandler.c#L1001
.)
4. Read of uninitialized buffer in CmdGetSlotStatus() at
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/commands.c#L1201
- in case when the control transfer returned only 1 instead of 3
bytes.
5. Read of uninitialized buffer in ReadUSB() at
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/ccid_usb.c#L912
. (Because of the wrong ">=" size check - it should be a strict ">".)
6. Read of uninitialized |convention| in IFDHSetProtocolParameters() -
in case ATR_GetConvention() returned a failure on a malformed ATR.
7. Read of uninitialized buffer in PPS_Match() at
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/towitoko/pps.c#L101
- in case |len_confirm| is unexpectedly small.
8. Read of uninitialized |chain_parameter| in
CmdXfrBlockAPDU_extended() - in case the reading in CCID_Receive()
returned unexpectedly few bytes, less than CHAIN_PARAMETER_OFFSET from
which the |chain_parameter| is read. (The problem is also partially
caused by code in CmdXfrBlockAPDU_extended() that ignores
IFD_ERROR_INSUFFICIENT_BUFFER:
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/commands.c#L1701
)
9. Read of uninitialized buffer in PPS_Exchange() at
https://salsa.debian.org/rousseau/CCID/-/blob/4d5cbf703c268b31c734931166c52dcb9920c0fe/src/towitoko/pps.c#L79
- in case when |len_request| is unexpectedly small.
10. Reads of uninitialized buffer in CmdPowerOn(), CCID_Receive(),
CmdGetSlotStatus() - in case when the read buffer is too small to
contain the |ERROR_OFFSET| index.)
P.S. Posted to the public mailing list, since I don't think these
errors are exploitable (not considering the case of a malicious
device, but USB is fundamentally insecure anyway).
Regards,
Maksim
More information about the pcsclite-muscle
mailing list