Hi On Thu, Feb 14, 2019 at 9:20 PM Philippe Mathieu-Daudé <phi...@redhat.com> wrote: > > 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.
I think so too, because vscard_in_pos is unchanged between the 2 callbacks (or set to 0 in break event). > > Add an assertion, which will always fail if card->vscard_in_pos >= > VSCARD_IN_SIZE), since size > 0. If "size > VSCARD_IN_SIZE - card->vscard_in_pos" this is a chardev bug. But which backend does that? Iow, did we ever reach the "no room for data" error? > > This is a quick fix for CVE-2018-18438 "Integer overflow in > ccid_card_vscard_read() allows memory corruption". I have a hard time to find how that memory corruption can happen. It would be a broken chardev (one calling qemu_chr_be_write() with a size bigger than qemu_chr_be_can_write()). It would need to be fixed. But which one does that? > > 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 >