Commit 322894eed3 for qemu.org

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

    usb-host: free configuration descriptors on error paths

    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: 2b2325ff6491 ("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>
    Message-ID: <20261005054626.131577-3-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 fd4a16ee8a..cd566b91a3 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -68,6 +68,10 @@ typedef struct USBHostRequest USBHostRequest;
 typedef struct USBHostIsoXfer USBHostIsoXfer;
 typedef struct USBHostIsoRing USBHostIsoRing;

+typedef struct libusb_config_descriptor libusb_config_descriptor;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(libusb_config_descriptor,
+                            libusb_free_config_descriptor)
+
 struct USBAutoFilter {
     uint32_t bus_num;
     uint32_t addr;
@@ -869,7 +873,7 @@ static void usb_host_ep_update(USBHostDevice *s)
         [USB_ENDPOINT_XFER_INT]     = "int",
     };
     USBDevice *udev = USB_DEVICE(s);
-    struct libusb_config_descriptor *conf;
+    g_autoptr(libusb_config_descriptor) conf = NULL;
     const struct libusb_interface_descriptor *intf;
     const struct libusb_endpoint_descriptor *endp;
 #ifdef HAVE_STREAMS
@@ -948,8 +952,6 @@ static void usb_host_ep_update(USBHostDevice *s)
 #endif
         }
     }
-
-    libusb_free_config_descriptor(conf);
 }

 static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
@@ -1343,7 +1345,7 @@ static void usb_host_attach_kernel(USBHostDevice *s)
 static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
 {
     USBDevice *udev = USB_DEVICE(s);
-    struct libusb_config_descriptor *conf;
+    g_autoptr(libusb_config_descriptor) conf = NULL;
     int rc, i, claimed;

     for (i = 0; i < USB_MAX_INTERFACES; i++) {
@@ -1381,7 +1383,6 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
     udev->ninterfaces   = conf->bNumInterfaces;
     udev->configuration = configuration;

-    libusb_free_config_descriptor(conf);
     return USB_RET_SUCCESS;
 }