usb: gadget: composite: fix double freeing of freed memory
authorWilliam Wu <wulf@rock-chips.com>
Fri, 16 Dec 2016 08:39:47 +0000 (16:39 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 19 Dec 2016 06:39:06 +0000 (14:39 +0800)
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:
[<ffffff9008088490>] dump_backtrace+0x0/0x1c8
[<ffffff900808866c>] show_stack+0x14/0x1c
[<ffffff900835cbe4>] dump_stack+0x8c/0xac
[<ffffff900819f840>] print_trailer+0x188/0x198
[<ffffff900819f9bc>] object_err+0x3c/0x4c
[<ffffff90081a1fb8>] free_debug_processing+0x27c/0x36c
[<ffffff90081a2108>] __slab_free+0x60/0x388
[<ffffff90081a2c88>] kfree+0x210/0x27c
[<ffffff9008645a58>] composite_dev_cleanup+0x74/0xfc
[<ffffff900864789c>] configfs_composite_bind+0x2b8/0x2d8
[<ffffff900864953c>] udc_bind_to_driver+0x38/0xcc
[<ffffff9008649650>] usb_udc_attach_driver+0x80/0xa8
[<ffffff900864835c>] gadget_dev_desc_UDC_store+0xa0/0xe4
[<ffffff9008218144>] configfs_write_file+0xfc/0x14c
[<ffffff90081ac958>] __vfs_write+0x38/0xfc
[<ffffff90081ad290>] vfs_write+0xac/0x174
[<ffffff90081adc4c>] SyS_write+0x54/0xa4
[<ffffff90080826f0>] 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 <wulf@rock-chips.com>
drivers/usb/gadget/composite.c

index 53499a7ddf4557f2a6b6118c1356ac18d52bb396..eb88b8bfcb11369586dc290926ff4695ac9abb85 100644 (file)
@@ -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);