* [PATCH 0/2] usb-host: validate and release configuration descriptors @ 2026-10-04 4:27 Junjie Cao 2026-10-04 4:27 ` [PATCH 1/2] usb-host: validate interface number before indexing altsetting Junjie Cao 2026-10-04 4:27 ` [PATCH 2/2] usb-host: free configuration descriptors on error paths Junjie Cao 0 siblings, 2 replies; 6+ messages in thread From: Junjie Cao @ 2026-10-04 4:27 UTC (permalink / raw) To: qemu-devel; +Cc: thuth, kraxel, philmd, junjie.cao The libusb host backend reads interface numbers from the active configuration descriptor while opening a device. An out-of-range number can index past USBDevice.altsetting. The backend also leaves an allocated descriptor behind on endpoint parse and interface claim failures. Junjie Cao (2): usb-host: validate interface number before indexing altsetting usb-host: free configuration descriptors on error paths hw/usb/host-libusb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] usb-host: validate interface number before indexing altsetting 2026-10-04 4:27 [PATCH 0/2] usb-host: validate and release configuration descriptors Junjie Cao @ 2026-10-04 4:27 ` Junjie Cao 2026-10-04 16:42 ` Marc-André Lureau 2026-10-04 4:27 ` [PATCH 2/2] usb-host: free configuration descriptors on error paths Junjie Cao 1 sibling, 1 reply; 6+ messages in thread From: Junjie Cao @ 2026-10-04 4:27 UTC (permalink / raw) To: qemu-devel; +Cc: thuth, kraxel, philmd, junjie.cao, qemu-stable From: Junjie Cao <junjie.cao@intel.com> 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: qemu-stable@nongnu.org Signed-off-by: Junjie Cao <junjie.cao@intel.com> --- 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; + } 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 && -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] usb-host: validate interface number before indexing altsetting 2026-10-04 4:27 ` [PATCH 1/2] usb-host: validate interface number before indexing altsetting Junjie Cao @ 2026-10-04 16:42 ` Marc-André Lureau 0 siblings, 0 replies; 6+ messages in thread From: Marc-André Lureau @ 2026-10-04 16:42 UTC (permalink / raw) To: Junjie Cao; +Cc: qemu-devel, thuth, kraxel, philmd, qemu-stable Hi On Sun, Oct 4, 2026 at 4:11 PM Junjie Cao <junjie.cao@linux.dev> wrote: > > From: Junjie Cao <junjie.cao@intel.com> > > 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: qemu-stable@nongnu.org > Signed-off-by: Junjie Cao <junjie.cao@intel.com> > --- > 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 <marcandre.lureau@redhat.com> > usb_ep_set_halted(udev, pid, ep, 0); > #ifdef HAVE_STREAMS > if (type == LIBUSB_TRANSFER_TYPE_BULK && > -- > 2.43.0 > > -- Marc-André Lureau ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] usb-host: free configuration descriptors on error paths 2026-10-04 4:27 [PATCH 0/2] usb-host: validate and release configuration descriptors Junjie Cao 2026-10-04 4:27 ` [PATCH 1/2] usb-host: validate interface number before indexing altsetting Junjie Cao @ 2026-10-04 4:27 ` Junjie Cao 2026-10-04 16:34 ` Marc-André Lureau 1 sibling, 1 reply; 6+ messages in thread From: Junjie Cao @ 2026-10-04 4:27 UTC (permalink / raw) To: qemu-devel; +Cc: thuth, kraxel, philmd, junjie.cao, qemu-stable From: Junjie Cao <junjie.cao@intel.com> usb_host_ep_update() returns before freeing the active configuration descriptor when an endpoint address is invalid or duplicated. usb_host_claim_interfaces() also returns without freeing it when fewer interfaces can be claimed than the descriptor declares. Each failure leaves one descriptor allocated. Fixes: 2b2325ff64 ("use libusb for usb-host") Cc: qemu-stable@nongnu.org Signed-off-by: Junjie Cao <junjie.cao@intel.com> --- hw/usb/host-libusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index fd4a16ee8a..491302feb7 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -921,12 +921,12 @@ static void usb_host_ep_update(USBHostDevice *s) if (ep == 0) { trace_usb_host_parse_error(s->bus_num, s->addr, "invalid endpoint address"); - return; + goto out; } if (usb_ep_get_type(udev, pid, ep) != USB_ENDPOINT_XFER_INVALID) { trace_usb_host_parse_error(s->bus_num, s->addr, "duplicate endpoint address"); - return; + goto out; } trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep, @@ -949,6 +949,7 @@ static void usb_host_ep_update(USBHostDevice *s) } } +out: libusb_free_config_descriptor(conf); } @@ -1375,6 +1376,7 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration) } } if (claimed != conf->bNumInterfaces) { + libusb_free_config_descriptor(conf); return USB_RET_STALL; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] usb-host: free configuration descriptors on error paths 2026-10-04 4:27 ` [PATCH 2/2] usb-host: free configuration descriptors on error paths Junjie Cao @ 2026-10-04 16:34 ` Marc-André Lureau 2026-10-05 5:45 ` Junjie Cao 0 siblings, 1 reply; 6+ messages in thread From: Marc-André Lureau @ 2026-10-04 16:34 UTC (permalink / raw) To: Junjie Cao; +Cc: qemu-devel, thuth, kraxel, philmd, qemu-stable Hi On Sun, Oct 4, 2026 at 4:11 PM Junjie Cao <junjie.cao@linux.dev> wrote: > > From: Junjie Cao <junjie.cao@intel.com> > > usb_host_ep_update() returns before freeing the active configuration > descriptor when an endpoint address is invalid or duplicated. > usb_host_claim_interfaces() also returns without freeing it when fewer > interfaces can be claimed than the descriptor declares. Each failure > leaves one descriptor allocated. > > Fixes: 2b2325ff64 ("use libusb for usb-host") > Cc: qemu-stable@nongnu.org > Signed-off-by: Junjie Cao <junjie.cao@intel.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Although it's an opportunity to introduce g_auto support: typedef struct libusb_config_descriptor libusb_config_descriptor; G_DEFINE_AUTOPTR_CLEANUP_FUNC(libusb_config_descriptor, libusb_free_config_descriptor) Then declaration should become: g_autoptr(libusb_config_descriptor) conf = NULL; And we can drop free paths. Up to you if you want to make a v2 > --- > hw/usb/host-libusb.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c > index fd4a16ee8a..491302feb7 100644 > --- a/hw/usb/host-libusb.c > +++ b/hw/usb/host-libusb.c > @@ -921,12 +921,12 @@ static void usb_host_ep_update(USBHostDevice *s) > if (ep == 0) { > trace_usb_host_parse_error(s->bus_num, s->addr, > "invalid endpoint address"); > - return; > + goto out; > } > if (usb_ep_get_type(udev, pid, ep) != USB_ENDPOINT_XFER_INVALID) { > trace_usb_host_parse_error(s->bus_num, s->addr, > "duplicate endpoint address"); > - return; > + goto out; > } > > trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep, > @@ -949,6 +949,7 @@ static void usb_host_ep_update(USBHostDevice *s) > } > } > > +out: > libusb_free_config_descriptor(conf); > } > > @@ -1375,6 +1376,7 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration) > } > } > if (claimed != conf->bNumInterfaces) { > + libusb_free_config_descriptor(conf); > return USB_RET_STALL; > } > > -- > 2.43.0 > > -- Marc-André Lureau ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] usb-host: free configuration descriptors on error paths 2026-10-04 16:34 ` Marc-André Lureau @ 2026-10-05 5:45 ` Junjie Cao 0 siblings, 0 replies; 6+ messages in thread From: Junjie Cao @ 2026-10-05 5:45 UTC (permalink / raw) To: marcandre.lureau Cc: qemu-devel, thuth, kraxel, philmd, qemu-stable, junjie.cao Thanks for the review. Will send v2 with the g_autoptr conversion. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-05 5:46 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-04 4:27 [PATCH 0/2] usb-host: validate and release configuration descriptors Junjie Cao 2026-10-04 4:27 ` [PATCH 1/2] usb-host: validate interface number before indexing altsetting Junjie Cao 2026-10-04 16:42 ` Marc-André Lureau 2026-10-04 4:27 ` [PATCH 2/2] usb-host: free configuration descriptors on error paths Junjie Cao 2026-10-04 16:34 ` Marc-André Lureau 2026-10-05 5:45 ` Junjie Cao
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.