[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 4/8] usb-ccid: Fix ATR parsing
From: |
Marc-André Lureau |
Subject: |
Re: [Qemu-devel] [PATCH v2 4/8] usb-ccid: Fix ATR parsing |
Date: |
Thu, 20 Jul 2017 09:40:42 +0000 |
On Thu, Jul 20, 2017 at 11:05 AM Stefan Fritsch <address@hidden> wrote:
> From: Stefan Fritsch <address@hidden>
>
> - The number of parameter set TA_i...TD_i is unlimited. The list ends
> if TD_i is not present or the high nibble is zero.
> - If at least one protocol in any of the TD bytes is non-zero, the
> ATR must have a checksum.
> - Add a missing length check before accessing TD.
> - Fixup a wrong checksum but accept the ATR.
>
>
Could this patch be splitted to help review / bisect? Ideally, I would also
try to write tests for it. Thanks
> Signed-off-by: Stefan Fritsch <address@hidden>
> Signed-off-by: Christian Ehrhardt <address@hidden>
> ---
> hw/usb/ccid-card-passthru.c | 34 ++++++++++++++++++++++++++--------
> 1 file changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
> index 45d96b03c6..e2e94ac1ba 100644
> --- a/hw/usb/ccid-card-passthru.c
> +++ b/hw/usb/ccid-card-passthru.c
> @@ -146,8 +146,7 @@ static void ccid_card_vscard_handle_init(
>
> static int check_atr(PassthruState *card, uint8_t *data, int len)
> {
> - int historical_length, opt_bytes;
> - int td_count = 0;
> + int historical_length, opt_bytes, tck = 0;
> int td;
>
> if (len < 2) {
> @@ -160,10 +159,8 @@ static int check_atr(PassthruState *card, uint8_t
> *data, int len)
> data[0]);
> return 0;
> }
> - td_count = 0;
> td = data[1] >> 4;
> - while (td && td_count < 2 && opt_bytes + historical_length + 2 < len)
> {
> - td_count++;
> + while (td && opt_bytes + historical_length + 2 < len) {
> if (td & 0x1) {
> opt_bytes++;
> }
> @@ -175,16 +172,37 @@ static int check_atr(PassthruState *card, uint8_t
> *data, int len)
> }
> if (td & 0x8) {
> opt_bytes++;
> - td = data[opt_bytes + 2] >> 4;
> + if (opt_bytes + 1 >= len) {
> + break;
> + }
> + /* Checksum byte must be present if T!=0 */
> + if (data[opt_bytes + 1] & 0xf) {
> + tck = 1;
> + }
> + td = data[opt_bytes + 1] >> 4;
> + } else {
> + td = 0;
> }
> }
> - if (len < 2 + historical_length + opt_bytes) {
> + if (len < 2 + historical_length + opt_bytes + tck) {
> DPRINTF(card, D_WARN,
> "atr too short: len %d, but historical_len %d, T1 0x%X\n",
> len, historical_length, data[1]);
> return 0;
> }
> - if (len > 2 + historical_length + opt_bytes) {
> + if (tck) {
> + int i;
> + uint8_t cksum = 0;
> + for (i = 1; i < 2 + historical_length + opt_bytes; ++i) {
> + cksum ^= data[i];
> + }
> + if (cksum != data[i]) {
> + DPRINTF(card, D_WARN, "atr has bad checksum: "
> + "real=0x%x should be 0x%x (FIXED)\n", cksum, data[i]);
> + data[i] = cksum;
> + }
> + }
> + if (len > 2 + historical_length + opt_bytes + tck) {
> DPRINTF(card, D_WARN,
> "atr too long: len %d, but hist/opt %d/%d, T1 0x%X\n",
> len, historical_length, opt_bytes, data[1]);
> --
> 2.11.0
>
>
> --
Marc-André Lureau
- Re: [Qemu-devel] [PATCH v2 5/8] usb-ccid: Fix USB descriptor, (continued)
- [Qemu-devel] [PATCH v2 3/8] usb-ccid: Set protocol parameters based on card ATR, Stefan Fritsch, 2017/07/20
- [Qemu-devel] [PATCH v2 8/8] usb-ccid: Reduce logging at level WARN, Stefan Fritsch, 2017/07/20
- [Qemu-devel] [PATCH v2 1/8] usb-ccid: Add support to dump all USB packets, Stefan Fritsch, 2017/07/20
- [Qemu-devel] [PATCH v2 6/8] usb-ccid: Fix chaining fields in CCID USB messages, Stefan Fritsch, 2017/07/20
- [Qemu-devel] [PATCH v2 4/8] usb-ccid: Fix ATR parsing, Stefan Fritsch, 2017/07/20
- Re: [Qemu-devel] [PATCH v2 4/8] usb-ccid: Fix ATR parsing,
Marc-André Lureau <=