Re: [PATCH] usb: gadget: udc: Fix overwriting the gadget driver of occupied udc
From: Alan Stern
Date: Mon Apr 20 2026 - 11:04:11 EST
How did you find this "problem"? By encountering a crash? By code
review? Some other way?
On Mon, Apr 20, 2026 at 12:02:23PM +0800, Huisong Li wrote:
> In gadget_match_driver(), the core only validates whether the gadget
> driver is already bound, but it doesn't check the current state of
> the UDC. This leads to gadget_bind_driver() (the probe stage) being
> invoked for an already occupied UDC.
No it doesn't. It is not possible for gadget_bind_driver() to be called
if the UDC is already bound to a driver. That's because this routine is
a .probe() callback, and the device core only probes devices that aren't
already bound to a driver.
It's true that gadget_bind_driver() is a probe routine for the gadget
bus, not whatever bus the UDC was registered on, but that doesn't matter
because the UDC's driver is always assigned and cleared along with the
gadget's driver.
> In gadget_bind_driver(), the code proceeds to overwrite 'udc->driver'
> and forcibly modify the UDC speed without checking if the UDC is
> currently in use. This results in state inconsistency and disruption
> of the existing connection.
>
> Fix this by adding a check for 'udc->driver' in
> gadget_bind_driver().
This change is not necessary.
Alan Stern
> Fixes: fc274c1e9973 ("USB: gadget: Add a new bus for gadgets")
> Signed-off-by: Huisong Li <lihuisong@xxxxxxxxxx>
> ---
> drivers/usb/gadget/udc/core.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
> index e8861eaad907..47e50fe1b75b 100644
> --- a/drivers/usb/gadget/udc/core.c
> +++ b/drivers/usb/gadget/udc/core.c
> @@ -1615,6 +1615,13 @@ static int gadget_bind_driver(struct device *dev)
> int ret = 0;
>
> mutex_lock(&udc_lock);
> + if (udc->driver) {
> + dev_err(&udc->dev, "UDC (%s) is already in use.\n",
> + dev_name(&udc->dev));
> + mutex_unlock(&udc_lock);
> + return -EBUSY;
> + }
> +
> if (driver->is_bound) {
> mutex_unlock(&udc_lock);
> return -ENXIO; /* Driver binds to only one gadget */
> --
> 2.33.0
>
>