All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junjie Cao <junjie.cao@linux.dev>
To: dongwon.kim@intel.com
Cc: liang1.yang@intel.com, qemu-devel@nongnu.org, thuth@redhat.com,
	marcandre.lureau@redhat.com, junjie.cao@linux.dev
Subject: Re: [PATCH] hw/usb/host-libusb: Avoid assertion on invalid altsetting
Date: Wed, 28 Oct 2026 00:37:17 -0500	[thread overview]
Message-ID: <20261028053717.525008-1-junjie.cao@linux.dev> (raw)
In-Reply-To: <20260812092403.37511-1-dongwon.kim@intel.com>

On Wed, 12 Aug 2026 02:24:03 -0700, dongwon.kim@intel.com wrote:
> 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.

Hi Dongwon, Liang,

The out-of-range alt does not come from libusb. It is QEMU's own
udev->altsetting[], written by usb_host_set_interface() when the guest
selects an alternate setting and only cleared in
usb_host_claim_interfaces() on SET_CONFIGURATION. usb_host_open() runs
usb_host_ep_update() before either of those, so when a different device
shows up on the same usb-host instance, the values left behind by the
previous device are checked against the new device's descriptors.

Reproduced on master with -device usb-host,hostbus=3,hostport=4 and a
Debian 12 guest on qemu-xhci: an Arkmicro 18ec:3399 UVC camera, guest
selects interface 1 alt 11 through usbfs, camera unplugged, a Jieli
4c4a:4155 UAC device (interface 1 has two alternate settings) plugged
into the same port. QEMU aborts at host-libusb.c:910 while opening the
second device.

Skipping the interface hides the assert but keeps the stale value, and a
stale value that happens to be in range is not caught at all: it picks
the endpoints of the wrong alternate setting. Clearing udev->altsetting[]
in usb_host_open() before usb_host_ep_update(), the way
usb_host_claim_interfaces() does, removes the cause. The guest has not
selected anything on the new device yet, so zero is the right content,
and the array is written again only after
libusb_set_interface_alt_setting() succeeds, so the assert can stay.
udev->ninterfaces and udev->configuration go stale the same way; nothing
in usb-host reads them, but moving the three resets from
usb_host_claim_interfaces() into a helper called from both places keeps
them together. With udev->altsetting[] cleared the sequence above
enumerates the second device, snd-usb-audio and usbhid bind to it and
its own SET_INTERFACE round trips go through.

> +                warn_report("usb-host: ignoring out-of-bounds altsetting=%d "
> +                            "for interface %d (index %d) on %s (bus=%03d, addr=%03d)",
> +                            alt, intf->bInterfaceNumber, i,
> +                            udev->product_desc, s->bus_num, s->addr);

usb_host_open() fills udev->product_desc after usb_host_ep_update(), so
this names the previous device. With the patch rebased onto master the
sequence above prints

  usb-host: ignoring out-of-bounds altsetting=11 for interface 1 (index 1)
  on USB2.0 PC CAMERA (bus=003, addr=014)

for the audio device.

> +    /* Log and skip if configuration is NULL or has no interfaces */
> +    if (!conf || conf->bNumInterfaces == 0) {

libusb_get_active_config_descriptor() sets *config whenever it returns
0, so !conf cannot happen, and bNumInterfaces == 0 already falls through
the loop.

The patch also no longer applies on master: e1b7f5e2a6 ("usb-host:
validate interface number before indexing altsetting") changed the same
loop, and conf is a g_autoptr there since 322894eed3, so the explicit
libusb_free_config_descriptor() in the new early return would be a
double free. A v2 should carry
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3189 and
Cc: qemu-stable@nongnu.org, the assert is reachable from 9.1.0 as
reported there.

Thanks,
Junjie


      reply	other threads:[~2026-10-28  5:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12  9:24 [PATCH] hw/usb/host-libusb: Avoid assertion on invalid altsetting dongwon.kim
2026-10-28  5:37 ` Junjie Cao [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028053717.525008-1-junjie.cao@linux.dev \
    --to=junjie.cao@linux.dev \
    --cc=dongwon.kim@intel.com \
    --cc=liang1.yang@intel.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.