aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuah Khan (Samsung OSG) <shuah@kernel.org>2018-10-18 12:19:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-18 13:44:39 -0400
commite28fd56ad5273be67d0fae5bedc7e1680e729952 (patch)
tree76d02d9e61603277f2ef1ac3d421f1b1166b0fa3
parente325808c0051b16729ffd472ff887c6cae5c6317 (diff)
usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten
In rmmod path, usbip_vudc does platform_device_put() twice once from platform_device_unregister() and then from put_vudc_device(). The second put results in: BUG kmalloc-2048 (Not tainted): Poison overwritten error or BUG: KASAN: use-after-free in kobject_put+0x1e/0x230 if KASAN is enabled. [ 169.042156] calling init+0x0/0x1000 [usbip_vudc] @ 1697 [ 169.042396] ============================================================================= [ 169.043678] probe of usbip-vudc.0 returned 1 after 350 usecs [ 169.044508] BUG kmalloc-2048 (Not tainted): Poison overwritten [ 169.044509] ----------------------------------------------------------------------------- ... [ 169.057849] INFO: Freed in device_release+0x2b/0x80 age=4223 cpu=3 pid=1693 [ 169.057852] kobject_put+0x86/0x1b0 [ 169.057853] 0xffffffffc0c30a96 [ 169.057855] __x64_sys_delete_module+0x157/0x240 Fix it to call platform_device_del() instead and let put_vudc_device() do the platform_device_put(). Reported-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/usbip/vudc_main.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/usb/usbip/vudc_main.c b/drivers/usb/usbip/vudc_main.c
index 3fc22037a82f..390733e6937e 100644
--- a/drivers/usb/usbip/vudc_main.c
+++ b/drivers/usb/usbip/vudc_main.c
@@ -73,6 +73,10 @@ static int __init init(void)
73cleanup: 73cleanup:
74 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) { 74 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
75 list_del(&udc_dev->dev_entry); 75 list_del(&udc_dev->dev_entry);
76 /*
77 * Just do platform_device_del() here, put_vudc_device()
78 * calls the platform_device_put()
79 */
76 platform_device_del(udc_dev->pdev); 80 platform_device_del(udc_dev->pdev);
77 put_vudc_device(udc_dev); 81 put_vudc_device(udc_dev);
78 } 82 }
@@ -89,7 +93,11 @@ static void __exit cleanup(void)
89 93
90 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) { 94 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
91 list_del(&udc_dev->dev_entry); 95 list_del(&udc_dev->dev_entry);
92 platform_device_unregister(udc_dev->pdev); 96 /*
97 * Just do platform_device_del() here, put_vudc_device()
98 * calls the platform_device_put()
99 */
100 platform_device_del(udc_dev->pdev);
93 put_vudc_device(udc_dev); 101 put_vudc_device(udc_dev);
94 } 102 }
95 platform_driver_unregister(&vudc_driver); 103 platform_driver_unregister(&vudc_driver);