All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anfernee Cao" <anferneemelokc5@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH] usb: xhci: fix EP0 context leak on virt device allocation failure
Date: Sat, 17 Oct 2026 11:20:54 +0000	[thread overview]
Message-ID: <sashiko-outbox-175494@kernel.org> (raw)
In-Reply-To: <20261017111114.1135-1-anferneemelokc5@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] usb: xhci: wrong slot ID passed on error in xhci_alloc_dev()
--

commit 19636b8ccf2f4295bbc8eb2a4bffefe6e79d41d3
Author: Anfernee Cao <anferneemelokc5@gmail.com>

usb: xhci: fix EP0 context leak on virt device allocation failure

This commit decrements xhci->num_active_eps when xhci_alloc_virt_device()
fails in xhci_alloc_dev() and XHCI_EP_LIMIT_QUIRK is set, since no virt
device is installed for the Disable Slot completion handler to clean up.

> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 30ac1bc4559b7..ea6f5c413d152 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -4278,6 +4278,15 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
>  	 */
>  	if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) {
>  		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
> +		/*
> +		 * The virt device was not installed, so the Disable Slot
> +		 * completion handler cannot drop the EP0 context reservation.
> +		 */
> +		if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) {
> +			spin_lock_irqsave(&xhci->lock, flags);
> +			xhci->num_active_eps--;
> +			spin_unlock_irqrestore(&xhci->lock, flags);
> +		}
>  		goto disable_slot;
>  	}
>  	vdev = xhci->devs[slot_id];

[Severity: High]
Does jumping to disable_slot here actually disable the newly enabled
slot_id?

In drivers/usb/host/xhci.c:xhci_alloc_dev(), the newly enabled hardware
slot is stored in the local variable slot_id, while udev->slot_id is only
updated after xhci_alloc_virt_device() succeeds:

	slot_id = command->slot_id;
	...
	if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) {
		...
		goto disable_slot;
	}
	vdev = xhci->devs[slot_id];
	slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
	trace_xhci_alloc_dev(slot_ctx);

	udev->slot_id = slot_id;
	...
disable_slot:
	xhci_disable_and_free_slot(xhci, udev->slot_id);

When either xhci_reserve_host_control_ep_resources() or
xhci_alloc_virt_device() fails and jumps to disable_slot, udev->slot_id has
not been set to slot_id yet.

During normal enumeration, udev->slot_id is 0, so
xhci_disable_and_free_slot(xhci, udev->slot_id) queues TRB_DISABLE_SLOT for
slot 0 and leaks the newly enabled hardware slot in slot_id.

Even worse, if xhci_alloc_dev() is called from
xhci_discover_or_reset_device() when virt_dev->udev != udev:

	if (virt_dev->udev != udev) {
		xhci_dbg(xhci, "The device to be reset with slot ID %u does "
				"not match the udev. Re-allocate the device\n",
				slot_id);
		ret = xhci_alloc_dev(hcd, udev);

udev->slot_id still holds an active slot ID belonging to another usb_device.
Jumping to disable_slot will disable and free that other device's active
slot and xhci_virt_device (and xhci_handle_cmd_disable_slot() will also
call xhci_free_device_endpoint_resources() on that other device's non-NULL
virt_dev, decrementing xhci->num_active_eps for its endpoints in addition
to the decrement added here), while still leaking the newly enabled
slot_id.

Should the disable_slot label pass slot_id instead of udev->slot_id to
xhci_disable_and_free_slot()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261017111114.1135-1-anferneemelokc5@gmail.com?part=1

  reply	other threads:[~2026-10-17 11:20 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-17 11:11 [PATCH] usb: xhci: fix EP0 context leak on virt device allocation failure Anfernee Cao
2026-10-17 11:20 ` sashiko-bot [this message]
2026-10-17 11:36   ` Anfernee Cao

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=sashiko-outbox-175494@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anferneemelokc5@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.