In the Linux kernel, the following vulnerability has been resolved:
usb: dwc3: gadget: Free gadget structure only after freeing endpoints
As part of commit e81a7018d93a ("usb: dwc3: allocate gadget structure dynamically") the dwc3gadgetrelease() was added which will free the dwc->gadget structure upon the device's removal when usbdelgadgetudc() is called in dwc3gadget_exit().
However, simply freeing the gadget results a dangling pointer situation: the endpoints created in dwc3gadgetinitendpoints() have their dep->endpoint.eplist members chained off the listhead anchored at dwc->gadget->eplist. Thus when dwc->gadget is freed, the first dwc3ep in the list now has a dangling prev pointer and likewise for the next pointer of the dwc3ep at the tail of the list. The dwc3gadgetfreeendpoints() that follows will result in a use-after-free when it calls listdel().
This was caught by enabling KASAN and performing a driver unbind. The recent commit 568262bf5492 ("usb: dwc3: core: Add shutdown callback for dwc3") also exposes this as a panic during shutdown.
There are a few possibilities to fix this. One could be to perform a listdel() of the gadget->eplist itself which removes it from the rest of the dwc3_ep chain.
Another approach is what this patch does, by splitting up the usbdelgadgetudc() call into its separate "del" and "put" components. This allows dwc3gadgetfreeendpoints() to be called before the gadget is finally freed with usbputgadget().