[PATCH 03/27] hw/usb/dev-smartcard-reader: fix assert on pending answers overflow
Marc-André Lureau <[email protected]> Wed, 05 Aug 2026 15:50:53 +0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
A guest can send PC_to_RDR_XfrBlock USB messages faster than the async
card backend can process them. When the pending_answers ring buffer
(128 entries) fills, ccid_add_pending_answer() hits an assert() and
crashes QEMU.
The CCID spec (section 4) states that a slot can only accept one
command at a time. A second command to a busy slot must be rejected
with CMD_SLOT_BUSY (section 6.2.6).
Enforce this by checking pending_answers_num before queuing a new
APDU. When the slot is already busy, report ERROR_CMD_SLOT_BUSY and
send a DataBlock error response back to the guest.
Fixes: CVE-2026-18410
Fixes: 367071447ec5 ("usb-ccid: add CCID bus")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3997
Signed-off-by: Marc-André Lureau <[email protected]>
---
hw/usb/dev-smartcard-reader.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 8241cd07648d..9fc6bbca0f2d 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -166,6 +166,7 @@ enum {
ERROR_XFR_PARITY_ERROR = -3,
ERROR_XFR_OVERRUN = -4,
ERROR_HW_ERROR = -5,
+ ERROR_CMD_SLOT_BUSY = -32,
};
/* 6.2.6 RDR_to_PC_SlotStatus definitions */
@@ -945,6 +946,13 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq);
return;
}
+ if (s->pending_answers_num > 0) {
+ DPRINTF(s, D_WARN,
+ "usb-ccid: slot already busy, rejecting apdu\n");
+ ccid_report_error_failed(s, ERROR_CMD_SLOT_BUSY);
+ ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq);
+ return;
+ }
len = le32_to_cpu(recv->hdr.dwLength);
DPRINTF(s, 1, "%s: seq %d, len %u\n", __func__,
recv->hdr.bSeq, len);
--
2.55.0