Hi
On Sun, Oct 4, 2026 at 4:11 PM Junjie Cao <[email protected]> wrote:
>
> From: Junjie Cao <[email protected]>
>
> 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: 0dbe4768b95 ("usb-host: use correct altsetting in usb_host_ep_update")
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3975
> Cc: [email protected]
> Signed-off-by: Junjie Cao <[email protected]>
> ---
> hw/usb/host-libusb.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> 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;
> + }
unlikely to happen, but better be safe.
> 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);
ack, it happens to match generally by accident
Reviewed-by: Marc-André Lureau <[email protected]>
> usb_ep_set_halted(udev, pid, ep, 0);
> #ifdef HAVE_STREAMS
> if (type == LIBUSB_TRANSFER_TYPE_BULK &&
> --
> 2.43.0
>
>
--
Marc-André Lureau