From f053f99ed0b0c6de7b7c4a07cbd7f7d213ddf0db Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 12 Apr 2017 11:21:08 +0900 Subject: [PATCH] scd: Handle unexpected suspend/resume by CCID driver. * scd/ccid-driver.c (bulk_in): Handle unexpected failure. -- GnuPG-bug-id: 3083 Signed-off-by: NIIBE Yutaka --- scd/ccid-driver.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index c10787ba6..fbbd1578d 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1980,7 +1980,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, goto retry; } - if (buffer[0] != expected_type) + if (buffer[0] != expected_type && buffer[0] != RDR_to_PC_SlotStatus) { DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); abort_cmd (handle, seqno); @@ -2020,11 +2020,23 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, switch ((buffer[7] & 0x03)) { case 0: /* no error */ break; - case 1: return CCID_DRIVER_ERR_CARD_INACTIVE; - case 2: return CCID_DRIVER_ERR_NO_CARD; + case 1: rc = CCID_DRIVER_ERR_CARD_INACTIVE; break; + case 2: rc = CCID_DRIVER_ERR_NO_CARD; break; case 3: /* RFU */ break; } - return 0; + + if (rc) + { + /* + * Communication failure by device side. + * Possibly, it was forcibly suspended and resumed. + */ + DEBUGOUT ("CCID: card inactive/removed\n"); + handle->powered_off = 1; + scd_kick_the_loop (); + } + + return rc; }