The right side of the comparison is the return value of can_read(): VSCARD_IN_SIZE - card->vscard_in_pos. Since the 'size' argument of chardev::read() is bound to what chardev::can_read() returns, this condition can never happen.
Add an assertion, which will always fail if card->vscard_in_pos >= VSCARD_IN_SIZE), since size > 0. This is a quick fix for CVE-2018-18438 "Integer overflow in ccid_card_vscard_read() allows memory corruption". Fixes: CVE-2018-18438 Reported-by: Arash Tohidi Chafi <tohidi.ar...@gmail.com> Suggested-by: Paolo Bonzini <pbonz...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé <phi...@redhat.com> --- hw/usb/ccid-card-passthru.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c index 8bb1314f49..1676b5fc05 100644 --- a/hw/usb/ccid-card-passthru.c +++ b/hw/usb/ccid-card-passthru.c @@ -264,24 +264,12 @@ static void ccid_card_vscard_handle_message(PassthruState *card, } } -static void ccid_card_vscard_drop_connection(PassthruState *card) -{ - qemu_chr_fe_deinit(&card->cs, true); - card->vscard_in_pos = card->vscard_in_hdr = 0; -} - static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, int size) { PassthruState *card = opaque; VSCMsgHeader *hdr; - if (card->vscard_in_pos + size > VSCARD_IN_SIZE) { - error_report("no room for data: pos %u + size %d > %" PRId64 "." - " dropping connection.", - card->vscard_in_pos, size, VSCARD_IN_SIZE); - ccid_card_vscard_drop_connection(card); - return; - } + assert(size <= VSCARD_IN_SIZE - card->vscard_in_pos); assert(card->vscard_in_hdr < VSCARD_IN_SIZE); memcpy(card->vscard_in_data + card->vscard_in_pos, buf, size); card->vscard_in_pos += size; -- 2.20.1