Commit e1b7f5e2a6 for qemu.org

commit e1b7f5e2a6715c4f7e9f5a4356101dc45b24b64f
Author: Junjie Cao <junjie.cao@intel.com>
Date:   Mon Oct 5 00:46:25 2026 -0500

    usb-host: validate interface number before indexing altsetting

    usb_host_ep_update() indexes USBDevice.altsetting with the interface
    number supplied by the active configuration descriptor. A descriptor
    with bInterfaceNumber >= USB_MAX_INTERFACES reads past that array while
    the host device is opened. Skip such interfaces before the lookup.

    Record the descriptor's interface number on its endpoints as well. The
    loop index identifies the descriptor's position in the configuration,
    which need not equal bInterfaceNumber.

    Fixes: 0dbe4768b95e ("usb-host: use correct altsetting in usb_host_ep_update")
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3975
    Cc: qemu-stable@nongnu.org
    Signed-off-by: Junjie Cao <junjie.cao@intel.com>
    Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
    Message-ID: <20261005054626.131577-2-junjie.cao@linux.dev>
    Signed-off-by: Thomas Huth <thuth@redhat.com>

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 629505c6d3..fd4a16ee8a 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -895,6 +895,11 @@ static void usb_host_ep_update(USBHostDevice *s)
          * then correct the alternate setting value if necessary.
          */
         intf = &conf->interface[i].altsetting[0];
+        if (intf->bInterfaceNumber >= USB_MAX_INTERFACES) {
+            trace_usb_host_parse_error(s->bus_num, s->addr,
+                                       "invalid interface number");
+            continue;
+        }
         alt = udev->altsetting[intf->bInterfaceNumber];

         if (alt != 0) {
@@ -930,7 +935,7 @@ static void usb_host_ep_update(USBHostDevice *s)
             usb_ep_set_max_packet_size(udev, pid, ep,
                                        endp->wMaxPacketSize);
             usb_ep_set_type(udev, pid, ep, type);
-            usb_ep_set_ifnum(udev, pid, ep, i);
+            usb_ep_set_ifnum(udev, pid, ep, intf->bInterfaceNumber);
             usb_ep_set_halted(udev, pid, ep, 0);
 #ifdef HAVE_STREAMS
             if (type == LIBUSB_TRANSFER_TYPE_BULK &&