|
|
619821 |
From b71bd2f7f4a259183fa3d38e6e891cffb86683e2 Mon Sep 17 00:00:00 2001
|
|
|
619821 |
From: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
619821 |
Date: Tue, 14 Mar 2017 08:52:54 +0100
|
|
|
619821 |
Subject: [PATCH 21/24] usb-ccid: better bulk_out error handling
|
|
|
619821 |
MIME-Version: 1.0
|
|
|
619821 |
Content-Type: text/plain; charset=UTF-8
|
|
|
619821 |
Content-Transfer-Encoding: 8bit
|
|
|
619821 |
|
|
|
619821 |
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
619821 |
Message-id: <1489481576-26911-3-git-send-email-kraxel@redhat.com>
|
|
|
619821 |
Patchwork-id: 74289
|
|
|
619821 |
O-Subject: [RHEL-7.4 qemu-kvm PATCH 2/4] usb-ccid: better bulk_out error handling
|
|
|
619821 |
Bugzilla: 1419818
|
|
|
619821 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
619821 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
619821 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
619821 |
|
|
|
619821 |
Add err goto label where we can jump to from all error conditions.
|
|
|
619821 |
STALL request on all errors. Reset position on all errors.
|
|
|
619821 |
|
|
|
619821 |
Normal request processing is not in a else branch any more, so this code
|
|
|
619821 |
is reintended, there are no code changes in that part of the code
|
|
|
619821 |
though.
|
|
|
619821 |
|
|
|
619821 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
619821 |
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
619821 |
Message-id: 1487250819-23764-2-git-send-email-kraxel@redhat.com
|
|
|
619821 |
(cherry picked from commit 0aeebc73b7976bae5cb7e9768e3d9a0fd9d634e8)
|
|
|
619821 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
619821 |
---
|
|
|
619821 |
hw/usb/dev-smartcard-reader.c | 116 ++++++++++++++++++++++--------------------
|
|
|
619821 |
1 file changed, 61 insertions(+), 55 deletions(-)
|
|
|
619821 |
|
|
|
619821 |
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
|
|
|
619821 |
index 0e0b363..672a7bf 100644
|
|
|
619821 |
--- a/hw/usb/dev-smartcard-reader.c
|
|
|
619821 |
+++ b/hw/usb/dev-smartcard-reader.c
|
|
|
619821 |
@@ -999,8 +999,7 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
|
|
|
619821 |
CCID_Header *ccid_header;
|
|
|
619821 |
|
|
|
619821 |
if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
|
|
|
619821 |
- p->status = USB_RET_STALL;
|
|
|
619821 |
- return;
|
|
|
619821 |
+ goto err;
|
|
|
619821 |
}
|
|
|
619821 |
ccid_header = (CCID_Header *)s->bulk_out_data;
|
|
|
619821 |
usb_packet_copy(p, s->bulk_out_data + s->bulk_out_pos, p->iov.size);
|
|
|
619821 |
@@ -1015,64 +1014,71 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
|
|
|
619821 |
DPRINTF(s, 1,
|
|
|
619821 |
"%s: bad USB_TOKEN_OUT length, should be at least 10 bytes\n",
|
|
|
619821 |
__func__);
|
|
|
619821 |
- } else {
|
|
|
619821 |
- DPRINTF(s, D_MORE_INFO, "%s %x %s\n", __func__,
|
|
|
619821 |
- ccid_header->bMessageType,
|
|
|
619821 |
- ccid_message_type_to_str(ccid_header->bMessageType));
|
|
|
619821 |
- switch (ccid_header->bMessageType) {
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
|
|
|
619821 |
- ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
|
|
|
619821 |
- DPRINTF(s, 1, "%s: PowerOn: %d\n", __func__,
|
|
|
619821 |
+ goto err;
|
|
|
619821 |
+ }
|
|
|
619821 |
+
|
|
|
619821 |
+ DPRINTF(s, D_MORE_INFO, "%s %x %s\n", __func__,
|
|
|
619821 |
+ ccid_header->bMessageType,
|
|
|
619821 |
+ ccid_message_type_to_str(ccid_header->bMessageType));
|
|
|
619821 |
+ switch (ccid_header->bMessageType) {
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
|
|
|
619821 |
+ ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
|
|
|
619821 |
+ DPRINTF(s, 1, "%s: PowerOn: %d\n", __func__,
|
|
|
619821 |
((CCID_IccPowerOn *)(ccid_header))->bPowerSelect);
|
|
|
619821 |
- s->powered = true;
|
|
|
619821 |
- if (!ccid_card_inserted(s)) {
|
|
|
619821 |
- ccid_report_error_failed(s, ERROR_ICC_MUTE);
|
|
|
619821 |
- }
|
|
|
619821 |
- /* atr is written regardless of error. */
|
|
|
619821 |
- ccid_write_data_block_atr(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff:
|
|
|
619821 |
- ccid_reset_error_status(s);
|
|
|
619821 |
- s->powered = false;
|
|
|
619821 |
- ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
|
|
|
619821 |
- ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters:
|
|
|
619821 |
- ccid_reset_error_status(s);
|
|
|
619821 |
- ccid_set_parameters(s, ccid_header);
|
|
|
619821 |
- ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters:
|
|
|
619821 |
- ccid_reset_error_status(s);
|
|
|
619821 |
- ccid_reset_parameters(s);
|
|
|
619821 |
- ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters:
|
|
|
619821 |
- ccid_reset_error_status(s);
|
|
|
619821 |
- ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical:
|
|
|
619821 |
- ccid_report_error_failed(s, 0);
|
|
|
619821 |
- ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- default:
|
|
|
619821 |
- DPRINTF(s, 1,
|
|
|
619821 |
+ s->powered = true;
|
|
|
619821 |
+ if (!ccid_card_inserted(s)) {
|
|
|
619821 |
+ ccid_report_error_failed(s, ERROR_ICC_MUTE);
|
|
|
619821 |
+ }
|
|
|
619821 |
+ /* atr is written regardless of error. */
|
|
|
619821 |
+ ccid_write_data_block_atr(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff:
|
|
|
619821 |
+ ccid_reset_error_status(s);
|
|
|
619821 |
+ s->powered = false;
|
|
|
619821 |
+ ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
|
|
|
619821 |
+ ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters:
|
|
|
619821 |
+ ccid_reset_error_status(s);
|
|
|
619821 |
+ ccid_set_parameters(s, ccid_header);
|
|
|
619821 |
+ ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters:
|
|
|
619821 |
+ ccid_reset_error_status(s);
|
|
|
619821 |
+ ccid_reset_parameters(s);
|
|
|
619821 |
+ ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters:
|
|
|
619821 |
+ ccid_reset_error_status(s);
|
|
|
619821 |
+ ccid_write_parameters(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical:
|
|
|
619821 |
+ ccid_report_error_failed(s, 0);
|
|
|
619821 |
+ ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
+ default:
|
|
|
619821 |
+ DPRINTF(s, 1,
|
|
|
619821 |
"handle_data: ERROR: unhandled message type %Xh\n",
|
|
|
619821 |
ccid_header->bMessageType);
|
|
|
619821 |
- /*
|
|
|
619821 |
- * The caller is expecting the device to respond, tell it we
|
|
|
619821 |
- * don't support the operation.
|
|
|
619821 |
- */
|
|
|
619821 |
- ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
|
|
|
619821 |
- ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
- break;
|
|
|
619821 |
- }
|
|
|
619821 |
+ /*
|
|
|
619821 |
+ * The caller is expecting the device to respond, tell it we
|
|
|
619821 |
+ * don't support the operation.
|
|
|
619821 |
+ */
|
|
|
619821 |
+ ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
|
|
|
619821 |
+ ccid_write_slot_status(s, ccid_header);
|
|
|
619821 |
+ break;
|
|
|
619821 |
}
|
|
|
619821 |
s->bulk_out_pos = 0;
|
|
|
619821 |
+ return;
|
|
|
619821 |
+
|
|
|
619821 |
+err:
|
|
|
619821 |
+ p->status = USB_RET_STALL;
|
|
|
619821 |
+ s->bulk_out_pos = 0;
|
|
|
619821 |
+ return;
|
|
|
619821 |
}
|
|
|
619821 |
|
|
|
619821 |
static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
|
|
|
619821 |
--
|
|
|
619821 |
1.8.3.1
|
|
|
619821 |
|