diff mbox series

[2/2] usb: gadget: udc: Update USB gadget state during soft disconnect

Message ID 20250301003452.2675360-3-quic_wcheng@quicinc.com (mailing list archive)
State New
Headers show
Series Fix use after freed situation in UDC core | expand

Commit Message

Wesley Cheng March 1, 2025, 12:34 a.m. UTC
In the soft disconnect scenarios, the USB connection will be lost
momentarily, so the proper gadget state should be reflected during the time
the connection is unavailable.  Add a flush_work() call, to ensure that
gadget->work is completed before continuing with the UDC unbind sequence.
Since usb_gadget_set_state() queues work to a workqueue, depending on when
the queue is scheduled, this avoids a possible use after freed scenario as
the USB gadget will most likely be freed shortly after the UDC driver is
unbounded.

Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
 drivers/usb/gadget/udc/core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 4b3d5075621a..7e401cb5a265 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -775,8 +775,10 @@  static int usb_gadget_disconnect_locked(struct usb_gadget *gadget)
 	}
 
 	ret = gadget->ops->pullup(gadget, 0);
-	if (!ret)
+	if (!ret) {
 		gadget->connected = 0;
+		usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
+	}
 
 	mutex_lock(&udc_lock);
 	if (gadget->udc->driver)
@@ -1669,6 +1671,7 @@  static void gadget_unbind_driver(struct device *dev)
 		synchronize_irq(gadget->irq);
 	mutex_unlock(&udc->connect_lock);
 
+	flush_work(&gadget->work);
 	udc->driver->unbind(gadget);
 
 	mutex_lock(&udc->connect_lock);