Re: [PATCH] usb: gadget: udc: Fix overwriting the gadget driver of occupied udc
From: lihuisong (C)
Date: Tue Apr 21 2026 - 03:35:53 EST
On 4/20/2026 10:10 PM, Alan Stern wrote:
How did you find this "problem"? By encountering a crash? By codeYes, you are right.
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 gadgetNo it doesn't. It is not possible for gadget_bind_driver() to be called
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.
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.
The device core ensure that one device just allows to bind one driver.
The __driver_probe_device() will return -EBUSY if dev->driver is not NULL. Then this device will be ignored to probe.
I forgot that the udc gadget itself is used as a device.
It's true that gadget_bind_driver() is a probe routine for the gadgetSorry for the noise.
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'This change is not necessary.
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().
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