Linux USB
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Michael Grzeschik" <grzeschik@puzzle.ch>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH 1/2] usbip: stub: reference count struct stub_device
Date: Wed, 11 Nov 2026 12:07:27 +0000	[thread overview]
Message-ID: <sashiko-outbox-208935@kernel.org> (raw)
In-Reply-To: <20261111-usbip-v1-1-da5217ac71d7@puzzle.ch>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] usbip: stub: hung stub_tx, leaks, and URB UAF when shutdown is
  missed
- [Medium] usbip: use-after-free in event_handler() reading eh_ops.put
  after wake_up()
--

commit cd9a80911da15b88ceb306a5e8d623b311108647
Author: Michael Grzeschik <grzeschik@puzzle.ch>

usbip: stub: reference count struct stub_device

This commit adds kref reference counting to struct stub_device and holds
references across device binding, the rx/tx kthreads, and queued events so
that stub_device and its usb_device are not freed while still in use.

> diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
> index abfa11d6bde79..27d1e9c8db176 100644
> --- a/drivers/usb/usbip/stub_dev.c
> +++ b/drivers/usb/usbip/stub_dev.c
> @@ -11,6 +11,42 @@
>  #include "usbip_common.h"
>  #include "stub.h"
>  
> +/*
> + * A stub_device is referenced by its binding to the USB device (from probe
> + * until disconnect), by the rx and tx threads while they run, and by the
> + * event handler while an event for it is queued or being handled. It must
> + * not be freed before all of them are done with it: stopping the threads
> + * relies on the event handler, which can miss a shutdown request or still
> + * have an event queued when disconnect wants to free the device.
> + */
> +static void stub_device_release(struct kref *kref)
> +{
> +	struct stub_device *sdev = container_of(kref, struct stub_device, kref);
> +
> +	usb_put_dev(sdev->udev);
> +	kfree(sdev);
> +}

[Severity: High]
If the rx and tx threads outlive stub_disconnect() because
stub_shutdown_connection() was missed, does stub_tx_loop() hang forever on
sdev->tx_waitq, or does stub_device_release() free sdev while in-flight
URBs and connection resources are still active?

Once shutdown_busid() queues SDEV_EVENT_REMOVED during stub_disconnect(),
USBIP_EH_BYE is set in ud->event, which causes any later usbip_event_add()
call to return early without scheduling stub_shutdown_connection():

drivers/usb/usbip/usbip_event.c:usbip_event_add() {
	if (ud->event & USBIP_EH_BYE)
		return;
}

Without stub_shutdown_connection() calling kthread_stop_put(ud->tcp_tx),
stub_tx_loop() blocks indefinitely in wait_event_interruptible() on
sdev->tx_waitq because neither socket closure nor usbip_event_add() wakes
that queue.

Even if both threads exit on a socket error and drop their references,
stub_device_release() only drops sdev->udev and frees sdev without running
the cleanup from stub_shutdown_connection().  That leaks the ud->tcp_rx and
ud->tcp_tx task structs, ud->tcp_socket, and the sdev->unlink_tx and
sdev->unlink_free lists, and leaves in-flight URBs on sdev->priv_init to
dereference the freed sdev in stub_complete().  In addition, letting
stub_disconnect() return while threads or events are still running allows
usbip_host_exit() to destroy stub_priv_cache and finish unloading the
module while sdev is still in use.

[ ... ]

> diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c
> index 0e00c2d000f89..eea9a71f0eac2 100644
> --- a/drivers/usb/usbip/usbip_event.c
> +++ b/drivers/usb/usbip/usbip_event.c
> @@ -94,6 +94,10 @@ static void event_handler(struct work_struct *work)
>  		mutex_unlock(&ud->sysfs_lock);
>  
>  		wake_up(&ud->eh_waitq);
> +
> +		/* drop the reference taken by usbip_event_add() */
> +		if (ud->eh_ops.put)
> +			ud->eh_ops.put(ud);
>  	}
>  }

[Severity: Medium]
Can waking ud->eh_waitq before reading ud->eh_ops.put cause a
use-after-free on ud?

vhci and vudc do not set eh_ops.get or eh_ops.put, and their removal paths
free the enclosing device as soon as usbip_stop_eh() returns from waiting
on ud->eh_waitq:

CPU0 (event_handler)              CPU1 (vudc_remove)
unset_event(ud, ...)
wake_up(&ud->eh_waitq)
                                  usb_del_gadget_udc()
                                    vgadget_pullup()
                                      usbip_stop_eh(&udc->ud)  /* returns */
                                  kfree(udc)
if (ud->eh_ops.put)  <-- use-after-free

For stub_device, waking usbip_stop_eh() before ud->eh_ops.put(ud) runs (or
while a second event queued for the same ud is still on event_list) also
lets stub_disconnect() and usbip_host_exit() finish unloading usbip-host.ko
while event_handler() in usbip-core.ko is still about to call
stub_eh_put().

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261111-usbip-v1-0-da5217ac71d7@puzzle.ch?part=1

  reply	other threads:[~2026-11-11 12:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 11:34 [PATCH 0/2] usbip: stability changes Michael Grzeschik
2026-11-11 11:34 ` [PATCH 1/2] usbip: stub: reference count struct stub_device Michael Grzeschik
2026-11-11 12:07   ` sashiko-bot [this message]
2026-11-11 11:34 ` [PATCH 2/2] usbip: identify the event handler with current_work() Michael Grzeschik
2026-11-11 11:42   ` sashiko-bot
2026-11-11 15:35   ` John Ernberg
2026-11-11 21:58     ` Michael Grzeschik

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-208935@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=grzeschik@puzzle.ch \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox