USB: UDC core: fix double-free in usb_add_gadget_udc_release

The error-handling pathways in usb_add_gadget_udc_release() are messed
up. Aside from the uninformative statement labels, they can deallocate
the udc structure after calling put_device(), which is a double-free.
This was observed by KASAN in automatic testing.

This patch cleans up the routine. It preserves the requirement that
when any failure occurs, we call put_device(&gadget->dev).

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
CC: <stable@vger.kernel.org>
Reviewed-by: Peter Chen <peter.chen@nxp.com>
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Alan Stern and committed by Greg Kroah-Hartman 7ae2c3c2 46eb14a6

+13 -15
+13 -15
drivers/usb/gadget/udc/core.c
··· 1147 1147 1148 1148 udc = kzalloc(sizeof(*udc), GFP_KERNEL); 1149 1149 if (!udc) 1150 - goto err1; 1151 - 1152 - ret = device_add(&gadget->dev); 1153 - if (ret) 1154 - goto err2; 1150 + goto err_put_gadget; 1155 1151 1156 1152 device_initialize(&udc->dev); 1157 1153 udc->dev.release = usb_udc_release; ··· 1156 1160 udc->dev.parent = parent; 1157 1161 ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); 1158 1162 if (ret) 1159 - goto err3; 1163 + goto err_put_udc; 1164 + 1165 + ret = device_add(&gadget->dev); 1166 + if (ret) 1167 + goto err_put_udc; 1160 1168 1161 1169 udc->gadget = gadget; 1162 1170 gadget->udc = udc; ··· 1170 1170 1171 1171 ret = device_add(&udc->dev); 1172 1172 if (ret) 1173 - goto err4; 1173 + goto err_unlist_udc; 1174 1174 1175 1175 usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); 1176 1176 udc->vbus = true; ··· 1178 1178 /* pick up one of pending gadget drivers */ 1179 1179 ret = check_pending_gadget_drivers(udc); 1180 1180 if (ret) 1181 - goto err5; 1181 + goto err_del_udc; 1182 1182 1183 1183 mutex_unlock(&udc_lock); 1184 1184 1185 1185 return 0; 1186 1186 1187 - err5: 1187 + err_del_udc: 1188 1188 device_del(&udc->dev); 1189 1189 1190 - err4: 1190 + err_unlist_udc: 1191 1191 list_del(&udc->list); 1192 1192 mutex_unlock(&udc_lock); 1193 1193 1194 - err3: 1195 - put_device(&udc->dev); 1196 1194 device_del(&gadget->dev); 1197 1195 1198 - err2: 1199 - kfree(udc); 1196 + err_put_udc: 1197 + put_device(&udc->dev); 1200 1198 1201 - err1: 1199 + err_put_gadget: 1202 1200 put_device(&gadget->dev); 1203 1201 return ret; 1204 1202 }