diff mbox series

[2/6] bus: fsl-mc: fix a use-after-free issue

Message ID 20220208145928.12468-3-laurentiu.tudor@nxp.com (mailing list archive)
State New, archived
Headers show
Series bus: fsl-mc: fixes and .shutdown() op for dprc driver | expand

Commit Message

Laurentiu Tudor Feb. 8, 2022, 2:59 p.m. UTC
From: Laurentiu Tudor <laurentiu.tudor@nxp.com>

Lets keep a reference to the MC IO object before deleting the
containing device structure, so that we can safely free it.
This fixes the below use-after-free kasan warning:

==================================================================
BUG: KASAN: use-after-free in fsl_mc_bus_remove+0xb8/0x198
Read of size 8 at addr ffff00203a304300 by task reboot/1362

CPU: 8 PID: 1362 Comm: reboot Not tainted 5.14.0-rc1-00218-g23d67ae4b6d7-dirty #111
Hardware name: NXP NXP LX2160ARDB Platform, BIOS EDK II Apr 16 2021
Call trace:
 dump_backtrace+0x0/0x2a4
 show_stack+0x1c/0x30
 dump_stack_lvl+0x68/0x84
 print_address_description.constprop.0+0x74/0x2b8
 kasan_report+0x1e0/0x24c
 __asan_load8+0xa4/0xd0
 fsl_mc_bus_remove+0xb8/0x198
 fsl_mc_bus_shutdown+0x14/0x24
 platform_shutdown+0x44/0x54
 device_shutdown+0x1f0/0x430
 __do_sys_reboot+0x290/0x31c
 __arm64_sys_reboot+0x58/0x70
 invoke_syscall+0x60/0x190
 el0_svc_common+0x84/0x130
 do_el0_svc+0x88/0xa4
 el0_svc+0x24/0x34
 el0t_64_sync_handler+0xa8/0x130
 el0t_64_sync+0x198/0x19c

Allocated by task 7:
 kasan_save_stack+0x2c/0x60
 __kasan_kmalloc+0x90/0xb4
 fsl_mc_device_add+0x104/0x8f0
 fsl_mc_bus_probe+0x400/0x650
 platform_probe+0x90/0x110
 really_probe.part.0+0xec/0x480
 __driver_probe_device+0xd4/0x180
 driver_probe_device+0xf8/0x1e0
 __device_attach_driver+0x120/0x190
 bus_for_each_drv+0xec/0x15c
 __device_attach+0x168/0x250
 device_initial_probe+0x18/0x24
 bus_probe_device+0xec/0x100
 deferred_probe_work_func+0xe8/0x130
 process_one_work+0x3b8/0x650
 worker_thread+0x3cc/0x72c
 kthread+0x1f8/0x210
 ret_from_fork+0x10/0x18

Freed by task 1362:
 kasan_save_stack+0x2c/0x60
 kasan_set_track+0x2c/0x40
 kasan_set_free_info+0x2c/0x50
 __kasan_slab_free+0xdc/0x140
 kfree+0xd4/0x360
 fsl_mc_device_release+0x30/0x40
 device_release+0x54/0x110
 kobject_put+0xac/0x180
 put_device+0x18/0x30
 fsl_mc_device_remove+0x48/0x5c
 fsl_mc_bus_remove+0x84/0x198
 fsl_mc_bus_shutdown+0x14/0x24
 platform_shutdown+0x44/0x54
 device_shutdown+0x1f0/0x430
 __do_sys_reboot+0x290/0x31c
 __arm64_sys_reboot+0x58/0x70
 invoke_syscall+0x60/0x190
 el0_svc_common+0x84/0x130
 do_el0_svc+0x88/0xa4
 el0_svc+0x24/0x34
 el0t_64_sync_handler+0xa8/0x130
 el0t_64_sync+0x198/0x19c

The buggy address belongs to the object at ffff00203a304000
 which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 768 bytes inside of
 2048-byte region [ffff00203a304000, ffff00203a304800)
The buggy address belongs to the page:
page:00000000c0d8f504 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x20ba300
head:00000000c0d8f504 order:3 compound_mapcount:0 compound_pincount:0
flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff)
raw: 0bfffc0000010200 0000000000000000 dead000000000122 ffff002000002a00
raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff00203a304200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff00203a304280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff00203a304300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                   ^
 ffff00203a304380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff00203a304400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 8fd4a356a86e..8cbac1b4b60e 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -1236,14 +1236,16 @@  static int fsl_mc_bus_probe(struct platform_device *pdev)
 static int fsl_mc_bus_remove(struct platform_device *pdev)
 {
 	struct fsl_mc *mc = platform_get_drvdata(pdev);
+	struct fsl_mc_io *mc_io;
 
 	if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))
 		return -EINVAL;
 
+	mc_io = mc->root_mc_bus_dev->mc_io;
+
 	fsl_mc_device_remove(mc->root_mc_bus_dev);
 
-	fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
-	mc->root_mc_bus_dev->mc_io = NULL;
+	fsl_destroy_mc_io(mc_io);
 
 	bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb);