On Wed, 16 Aug 2017, Alexey Khoroshilov wrote: > Hello, > > usb_add_gadget_udc_release() gets release() argument that allows to > release user resources. > > As far as I can see, the release() is called on error paths > of usb_add_gadget_udc_release() as a result of > put_device(&gadget->dev); > except for the only path going via err1. > > As a result a caller of the usb_add_gadget_udc_release() have no chance > to know if the release() was invoked or not. > > It may lead to memory leaks (drivers/usb/gadget/udc/snps_udc_core.c) > or to double free (drivers/usb/gadget/udc/fsl_udc_core.c). > > Is my reading correct? If so, should we always call release() on error paths? How about this (untested)? Alan Stern Index: usb-4.x/drivers/usb/gadget/udc/core.c =================================================================== --- usb-4.x.orig/drivers/usb/gadget/udc/core.c +++ usb-4.x/drivers/usb/gadget/udc/core.c @@ -1137,10 +1137,6 @@ int usb_add_gadget_udc_release(struct de struct usb_udc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); - if (!udc) - goto err1; - dev_set_name(&gadget->dev, "gadget"); INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; @@ -1150,7 +1146,13 @@ int usb_add_gadget_udc_release(struct de else gadget->dev.release = usb_udc_nop_release; - ret = device_register(&gadget->dev); + device_initialize(&gadget->dev); + + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (!udc) + goto err1; + + ret = device_add(&gadget->dev); if (ret) goto err2; @@ -1197,10 +1199,10 @@ err3: device_del(&gadget->dev); err2: - put_device(&gadget->dev); kfree(udc); err1: + put_device(&gadget->dev); return ret; } EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html