From: Huang, Tao Date: Fri, 28 Apr 2017 10:28:23 +0000 (+0800) Subject: drivers: switch: clear drvdata before device_destroy X-Git-Tag: release-20171130_firefly~4^2~699 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=92ee5ce90bfb7d94c90a0b24dad489a3495fb7f7;p=firefly-linux-kernel-4.4.55.git drivers: switch: clear drvdata before device_destroy Otherwise, we see write after free. ============================================================================= BUG kmalloc-1024 (Not tainted): Poison overwritten ----------------------------------------------------------------------------- INFO: 0xc599bcc4-0xc599bcc7. First byte 0x0 instead of 0x6b INFO: Allocated in device_create_groups_vargs+0x34/0xcc age=43 cpu=3 pid=1 kmem_cache_alloc_trace+0xd8/0x378 device_create_groups_vargs+0x34/0xcc device_create_vargs+0x20/0x28 device_create+0x28/0x48 switch_dev_register+0x80/0x108 dw_hdmi_bind+0x38c/0x9e4 dw_hdmi_rockchip_bind+0x248/0x38c component_bind_all+0x78/0x1e4 rockchip_drm_bind+0x1bc/0xbc0 try_to_bring_up_master.part.0+0xa8/0x138 component_master_add_with_match+0xb8/0x100 rockchip_drm_platform_probe+0x188/0x1d0 platform_drv_probe+0x50/0xa0 driver_probe_device+0x110/0x2c0 __driver_attach+0x70/0x94 bus_for_each_dev+0x94/0xc0 INFO: Freed in device_release+0x5c/0x90 age=42 cpu=3 pid=1 device_release+0x5c/0x90 kobject_release+0xd4/0x11c device_destroy+0x2c/0x38 switch_dev_unregister+0x30/0x5c dw_hdmi_unbind+0x48/0xc8 component_bind_all+0x1a4/0x1e4 rockchip_drm_bind+0x1bc/0xbc0 try_to_bring_up_master.part.0+0xa8/0x138 component_master_add_with_match+0xb8/0x100 rockchip_drm_platform_probe+0x188/0x1d0 platform_drv_probe+0x50/0xa0 driver_probe_device+0x110/0x2c0 __driver_attach+0x70/0x94 bus_for_each_dev+0x94/0xc0 bus_add_driver+0xcc/0x1e8 driver_register+0x9c/0xe0 Change-Id: Ied903eed40212e9666e123dd3f69a2a2966b6bb5 Signed-off-by: Huang, Tao --- diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c index e373b625806e..a008699463a3 100644 --- a/drivers/switch/switch_class.c +++ b/drivers/switch/switch_class.c @@ -151,8 +151,8 @@ void switch_dev_unregister(struct switch_dev *sdev) { device_remove_file(sdev->dev, &dev_attr_name); device_remove_file(sdev->dev, &dev_attr_state); - device_destroy(switch_class, MKDEV(0, sdev->index)); dev_set_drvdata(sdev->dev, NULL); + device_destroy(switch_class, MKDEV(0, sdev->index)); } EXPORT_SYMBOL_GPL(switch_dev_unregister);