[PATCH] hw/usb/host-libusb: Do not assert when detects invalid altsetting

Yang, Liang1 posted 1 patch 7 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/MW4PR11MB8291BDD718BE9BB5A160C839ACD4A@MW4PR11MB8291.namprd11.prod.outlook.com
[PATCH] hw/usb/host-libusb: Do not assert when detects invalid altsetting
Posted by Yang, Liang1 7 hours ago
Dear QEMU maintainers,

I would like to submit a patch for preventing the guest VM crash caused by the assertion failure in usb_host_ep_update() during USB hotplug/unplug on host passthrough.

QEMU issue submitted:
https://gitlab.com/qemu-project/qemu/-/issues/3189

Please help to review below patch, thanks!

===============================

Author: Liang1 Yang liang1.yang@intel.com<mailto:liang1.yang@intel.com>
Date:   Thu Oct 30 20:07:41 2025 +0800

    hw/usb/host-libusb: Do not assert when detects invalid alt

    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<mailto:liang1.yang@intel.com>

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 691bc881fb..3a08caafa5 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -885,6 +885,15 @@ static void usb_host_ep_update(USBHostDevice *s)
     trace_usb_host_parse_config(s->bus_num, s->addr,
                                 conf->bConfigurationValue, true);

+    /* 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 ? udev->product_desc : "unknown",
+            s->bus_num, s->addr);
+        return;
+    }
+
     for (i = 0; i < conf->bNumInterfaces; i++) {
         /*
          * The udev->altsetting array indexes alternate settings
@@ -896,7 +905,21 @@ static void usb_host_ep_update(USBHostDevice *s)
         alt = udev->altsetting[intf->bInterfaceNumber];

         if (alt != 0) {
-            assert(alt < conf->interface[i].num_altsetting);
+            if (alt >= conf->interface[i].num_altsetting) {
+                /*
+                 * Recommend fix: sometimes 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 invalid altsetting=%d (max=%d) "
+                    "for interface=%d on %s (bus=%03d, addr=%03d)",
+                    alt,
+                    conf->interface[i].num_altsetting ? conf->interface[i].num_altsetting - 1 : -1,
+                    i,
+                    udev->product_desc ? udev->product_desc : "unknown",
+                    s->bus_num, s->addr);
+                continue;
+            }
             intf = &conf->interface[i].altsetting[alt];
         }


Best regards,
Yang Liang