[PATCH 04/27] hw/usb/dev-smartcard-reader: decode bulk-out length as little-endian
Marc-André Lureau <[email protected]> Wed, 05 Aug 2026 15:50:54 +0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
The CCID Rev 1.1 specification states in section 1.3, Document Conventions, that fields larger than one byte are stored in little-endian format. The bulk message header's dwLength field is a four-byte field described in section 6, CCID Messages. Decode dwLength with le32_to_cpu() before using it to assemble and validate Bulk-OUT messages. This fixes message handling on big-endian hosts. Signed-off-by: Marc-André Lureau <[email protected]> --- hw/usb/dev-smartcard-reader.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 9fc6bbca0f2d..3580465df368 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -989,6 +989,7 @@ static const char *ccid_message_type_to_str(uint8_t type) static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) { CCID_Header *ccid_header; + uint32_t payload_len; if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) { goto err; @@ -1001,17 +1002,18 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) } ccid_header = (CCID_Header *)s->bulk_out_data; - if ((s->bulk_out_pos - 10 < ccid_header->dwLength) && + payload_len = le32_to_cpu(ccid_header->dwLength); + if ((s->bulk_out_pos - 10 < payload_len) && (p->iov.size == CCID_MAX_PACKET_SIZE)) { DPRINTF(s, D_VERBOSE, "usb-ccid: bulk_in: expecting more packets (%u/%u)\n", - s->bulk_out_pos - 10, ccid_header->dwLength); + s->bulk_out_pos - 10, payload_len); return; } - if (s->bulk_out_pos - 10 != ccid_header->dwLength) { + if (s->bulk_out_pos - 10 != payload_len) { DPRINTF(s, 1, "usb-ccid: bulk_in: message size mismatch (got %u, expected %u)\n", - s->bulk_out_pos - 10, ccid_header->dwLength); + s->bulk_out_pos - 10, payload_len); goto err; } -- 2.55.0