From: William Wu Date: Fri, 16 Dec 2016 08:39:47 +0000 (+0800) Subject: usb: gadget: composite: fix double freeing of freed memory X-Git-Tag: firefly_0821_release~1057 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a586e51a4551681203bf5076ecf0a84780b9f219;p=firefly-linux-kernel-4.4.55.git usb: gadget: composite: fix double freeing of freed memory The following message can be observed on rk3399 nougat board when switch MTP/charge mode with KASan backported : ============================================================================= BUG kmalloc-192 (Not tainted): Object already free ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in dwc3_gadget_ep_alloc_request+0x2c/0xf4 age=977 cpu=4 pid=1 alloc_debug_processing+0x128/0x17c ___slab_alloc.constprop.56+0x520/0x604 __slab_alloc.isra.53.constprop.55+0x24/0x34 kmem_cache_alloc_trace+0xa4/0x210 dwc3_gadget_ep_alloc_request+0x2c/0xf4 __ffs_func_bind_do_descs+0x15c/0x1b0 ffs_do_descs+0x50/0x180 ffs_func_bind+0x3e4/0x634 usb_add_function+0x78/0xe8 configfs_composite_bind+0x240/0x2d8 udc_bind_to_driver+0x38/0xcc usb_udc_attach_driver+0x80/0xa8 gadget_dev_desc_UDC_store+0xa0/0xe4 configfs_write_file+0xfc/0x14c __vfs_write+0x38/0xfc vfs_write+0xac/0x174 INFO: Freed in dwc3_gadget_ep_free_request+0x84/0xbc age=4 cpu=4 pid=1 free_debug_processing+0x29c/0x36c __slab_free+0x60/0x388 kfree+0x210/0x27c dwc3_gadget_ep_free_request+0x84/0xbc ffs_func_unbind+0x88/0xe4 purge_configs_funcs+0xa8/0x100 configfs_composite_unbind+0x34/0x5c usb_gadget_remove_driver+0x74/0xa0 usb_gadget_unregister_driver+0x60/0xa4 unregister_gadget+0x24/0x48 gadget_dev_desc_UDC_store+0x7c/0xe4 configfs_write_file+0xfc/0x14c __vfs_write+0x38/0xfc vfs_write+0xac/0x174 SyS_write+0x54/0xa4 el0_svc_naked+0x24/0x28 Hardware name: Rockchip RK3399 Evaluation Board v3 edp (Android) (DT) Call trace: [] dump_backtrace+0x0/0x1c8 [] show_stack+0x14/0x1c [] dump_stack+0x8c/0xac [] print_trailer+0x188/0x198 [] object_err+0x3c/0x4c [] free_debug_processing+0x27c/0x36c [] __slab_free+0x60/0x388 [] kfree+0x210/0x27c [] composite_dev_cleanup+0x74/0xfc [] configfs_composite_bind+0x2b8/0x2d8 [] udc_bind_to_driver+0x38/0xcc [] usb_udc_attach_driver+0x80/0xa8 [] gadget_dev_desc_UDC_store+0xa0/0xe4 [] configfs_write_file+0xfc/0x14c [] __vfs_write+0x38/0xfc [] vfs_write+0xac/0x174 [] SyS_write+0x54/0xa4 [] el0_svc_naked+0x24/0x28 This patch sets the usb_request pointer to NULL after the free the usb_request buf. And the composite_dev_cleanup() will check if the usb_request pointer is NULL before do kfree and avoid double freeing freed menory. Change-Id: I69df57553cb14d046b8b8206becd342a5e5fb7ba Signed-off-by: William Wu --- diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 53499a7ddf45..eb88b8bfcb11 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2059,6 +2059,7 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) kfree(cdev->os_desc_req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); + cdev->os_desc_req = NULL; } if (cdev->req) { if (cdev->setup_pending) @@ -2066,6 +2067,7 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) kfree(cdev->req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->req); + cdev->req = NULL; } cdev->next_string_id = 0; device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);