[PATCH 12/27] hw/usb/dev-smartcard-reader: fix RDR_to_PC_Parameters dwLength
Marc-André Lureau <[email protected]> Wed, 05 Aug 2026 15:51:02 +0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
dwLength in the RDR_to_PC_Parameters response was always set to 0
instead of the protocol-dependent size mandated by the CCID spec
(5 for T=0, 7 for T=1). Since bulk_in->len is what determines how
many bytes the guest actually reads, the reservation size must also
match the wire message size.
Set dwLength from bProtocolNum and compute the reservation size
accordingly, so the guest receives a spec-compliant response.
Fixes: 367071447ec5 ("usb-ccid: add CCID bus")
Signed-off-by: Marc-André Lureau <[email protected]>
---
hw/usb/dev-smartcard-reader.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 279fef03652b..16f248a0969f 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -748,19 +748,20 @@ static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv)
static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv)
{
CCID_Parameter *h;
+ uint32_t dwLength = s->bProtocolNum == 1 ? 7 : 5;
- h = ccid_reserve_recv_buf(s, sizeof(CCID_Parameter));
+ h = ccid_reserve_recv_buf(s, sizeof(h->b) + sizeof(h->bProtocolNum) + dwLength);
if (h == NULL) {
return;
}
h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_Parameters;
- h->b.hdr.dwLength = 0;
+ h->b.hdr.dwLength = cpu_to_le32(dwLength);
h->b.hdr.bSlot = recv->bSlot;
h->b.hdr.bSeq = recv->bSeq;
h->b.bStatus = ccid_calc_status(s);
h->b.bError = s->bError;
h->bProtocolNum = s->bProtocolNum;
- h->abProtocolDataStructure = s->abProtocolDataStructure;
+ memcpy(&h->abProtocolDataStructure, &s->abProtocolDataStructure, dwLength);
ccid_reset_error_status(s);
usb_wakeup(s->bulk, 0);
}
--
2.55.0