hw/usb/host-libusb.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
From: Liang1 Yang <liang1.yang@intel.com>
Log warning and skip the interface instead of asserting in qemu
host-libusb when there is invalid altsetting index during fast
USB device hotplug/unplug.
This is to prevent guest vm from crashing which is caused by
QEMU task abort.
Signed-off-by: Liang1 Yang <liang1.yang@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
---
hw/usb/host-libusb.c | 37 +++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 629505c6d3..56cfc90f9b 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -884,10 +884,32 @@ static void usb_host_ep_update(USBHostDevice *s)
if (rc != 0) {
return;
}
+
+ /* Log and skip if configuration is NULL or has no interfaces */
+ if (!conf || conf->bNumInterfaces == 0) {
+ warn_report("usb-host: ignoring invalid configuration "
+ "for device %s (bus=%03d, addr=%03d)",
+ udev->product_desc, s->bus_num, s->addr);
+
+ if (conf) {
+ libusb_free_config_descriptor(conf);
+ }
+
+ return;
+ }
+
trace_usb_host_parse_config(s->bus_num, s->addr,
conf->bConfigurationValue, true);
for (i = 0; i < conf->bNumInterfaces; i++) {
+ if (conf->interface[i].num_altsetting == 0 ||
+ !conf->interface[i].altsetting) {
+ warn_report("usb-host: skipping interface (index %d) with no "
+ "alternate settings on %s (bus=%03d, addr=%03d)",
+ i, udev->product_desc, s->bus_num, s->addr);
+ continue;
+ }
+
/*
* The udev->altsetting array indexes alternate settings
* by the interface number. Get the 0th alternate setting
@@ -897,8 +919,19 @@ static void usb_host_ep_update(USBHostDevice *s)
intf = &conf->interface[i].altsetting[0];
alt = udev->altsetting[intf->bInterfaceNumber];
- if (alt != 0) {
- assert(alt < conf->interface[i].num_altsetting);
+ if (alt > 0) {
+ if (alt >= conf->interface[i].num_altsetting) {
+ /*
+ * libusb reports a temporary invalid altsetting index during
+ * fast hotplug/unplug. Instead of aborting, log a warning and
+ * skip the interface.
+ */
+ warn_report("usb-host: ignoring out-of-bounds altsetting=%d "
+ "for interface %d (index %d) on %s (bus=%03d, addr=%03d)",
+ alt, intf->bInterfaceNumber, i,
+ udev->product_desc, s->bus_num, s->addr);
+ continue;
+ }
intf = &conf->interface[i].altsetting[alt];
}
--
2.43.0
© 2016 - 2026 Red Hat, Inc.