@samitouri / QOSamiQemu / commits / 68809288c7

hw/usb/core: Avoid possible assert() in do_parameter() --> usb_packet_copy()

usb_packet_copy() uses assert(p->actual_length + bytes <= iov->size) to make sure that there is enough space in the the iov. This assert() can be triggered from do_parameter() if the guest programs the XHCI in a weird way. Avoid the hard error by checking for the condition in do_parameter() first and signalling a USB_RET_STALL to the guest, just like it is done for another error condition here already some lines earlier. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3746 Reported-by: Yunhe Wang <yunhewwww@163.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-ID: <20260721185140.247775-1-thuth@redhat.com>

Thomas Huth committed Jul 21, 2026 at 20:51 UTC 68809288c7e5bf2a9a9edeb55af8c368f52442ad
1 file changed +10
hw/usb/core.c
+10
@@ -26,6 +26,7 @@
26 #include "qemu/osdep.h"
27 #include "hw/usb/usb.h"
28 #include "qemu/iov.h"
29 +#include "qemu/log.h"
30 #include "trace.h"
31
32 void usb_pick_speed(USBPort *port)
@@ -288,6 +289,15 @@ static void do_parameter(USBDevice *s, USBPacket *p)
289 p->status = USB_RET_STALL;
290 return;
291 }
292 + if ((p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_IN) &&
293 + setup_len > p->iov.size) {
294 + qemu_log_mask(LOG_GUEST_ERROR,
295 + "xhci: setup state param length %u > iov size %zu\n",
296 + setup_len, p->iov.size);
297 + p->status = USB_RET_STALL;
298 + return;
299 + }
300 +
301 s->setup_len = setup_len;
302
303 if (p->pid == USB_TOKEN_OUT) {