[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