CVE-2026-89739: usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition
In the Linux kernel, the following vulnerability has been resolved:
usb: dwc3: gadget: Fix use-after-free in dwc3gadgetfreeendpoints due to race condition
In dwc3gadgetinitendpoint, &dep->nostreamwork is bound with dwc3nostreamwork, and dwc3gadgetendpointstreamevent can queue this delayed work on systempercpuwq when a DEPEVTSTREAMNOSTREAM event is received.
If we remove the gadget, dwc3gadgetfreeendpoints makes cleanup and the memory allocated for dep with kzalloc() is released by kfree(dep), while the delayed work mentioned above may still be pending or running. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| dwc3threadinterrupt | dwc3endpointinterrupt | dwc3gadgetendpointstreamevent | queuedelayedwork(systempercpuwq, | &dep->nostreamwork) dwc3gadgetfreeendpoints | dwc3freetrbpool(dep) | listdel(&dep->endpoint.eplist) | dwc3debugfsremoveendpointdir(dep) | kfree(dep) | // dep is freed | | dwc3nostreamwork | // use dep (use-after-free)
Fix it by canceling the delayed work before kfree(dep) in dwc3gadgetfreeendpoints.
Affected Software
Event History
Frequently Asked Questions
What conditions are required for the use-after-free to occur?
The DWC3 gadget must receive a DEPEVT_STREAM_NOSTREAM event, which queues nostream_work on system_percpu_wq. The gadget must then be removed while that delayed work is still pending or executing, allowing the work handler to access an endpoint structure after it has been freed.
Which systems are exposed?
Systems using the Linux kernel's DWC3 USB gadget functionality are exposed when the affected endpoint stream-event path can run. The provided information does not identify specific kernel versions, hardware platforms, or default configurations.
What should be done if the fix cannot be applied immediately?
No mitigation is provided in the available data. The described race is associated with removing a DWC3 gadget while delayed nostream work may be pending, so avoiding that condition may reduce exposure, but this is not documented as a complete workaround.
How can I determine whether a kernel includes the fix?
Check whether dwc3_gadget_free_endpoints cancels each endpoint's nostream_work before freeing the endpoint structure with kfree(dep). The listed kernel stable references contain the corresponding fixes.