diff mbox series

[v2] soc: dpio: fix cleanup on error

Message ID 20211004115323.7454-1-laurentiu.tudor@nxp.com (mailing list archive)
State New, archived
Headers show
Series [v2] soc: dpio: fix cleanup on error | expand

Commit Message

Laurentiu Tudor Oct. 4, 2021, 11:53 a.m. UTC
dpaa2_io_service_register() adds an element to a linked list but
doesn't remove it on the error path, leading to the below kasan
use-after-free splat. Fix it.

==================================================================
BUG: KASAN: use-after-free in dpaa2_io_service_register+0xb8/0x1d4
Write of size 8 at addr ffff05d2b13af028 by task kworker/u32:2/151

CPU: 9 PID: 151 Comm: kworker/u32:2 Not tainted 5.14.0-rc1-00222
Hardware name: NXP NXP LX2160ARDB Platform, BIOS EDK II Apr 16 2021
Workqueue: events_unbound deferred_probe_work_func
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_store8+0xa8/0xd0
 dpaa2_io_service_register+0xb8/0x1d4
 dpaa2_eth_probe+0x93c/0x21cc
 fsl_mc_driver_probe+0x3c/0x80
 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+0xa4/0x72c
 kthread+0x1f8/0x210
 ret_from_fork+0x10/0x18

Allocated by task 1192:
 kasan_save_stack+0x2c/0x60
 __kasan_kmalloc+0x90/0xb4
 dpaa2_eth_probe+0x830/0x21cc
 fsl_mc_driver_probe+0x3c/0x80
 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
 device_add+0x570/0xca0
 fsl_mc_device_add+0x360/0x8f0
 fsl_mc_obj_device_add+0x140/0x16c
 dprc_scan_objects+0x2c4/0x480
 dprc_probe+0x48/0x17c
 fsl_mc_driver_probe+0x3c/0x80
 really_probe.part.0+0xec/0x480
 __driver_probe_device+0xd4/0x180
 device_driver_attach+0x70/0xf0
 bind_store+0xf8/0x160
 drv_attr_store+0x50/0x6c
 sysfs_kf_write+0x94/0xb0
 kernfs_fop_write_iter+0x19c/0x264
 new_sync_write+0x1c4/0x2bc
 vfs_write+0x30c/0x390
 ksys_write+0xc4/0x170
 __arm64_sys_write+0x48/0x60
 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

Freed by task 1192:
 kasan_save_stack+0x2c/0x60
 kasan_set_track+0x2c/0x40
 kasan_set_free_info+0x2c/0x50
 __kasan_slab_free+0xdc/0x140
 kfree+0xd4/0x360
 dpaa2_eth_probe+0x11b4/0x21cc
 fsl_mc_driver_probe+0x3c/0x80
 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
 device_add+0x570/0xca0
 fsl_mc_device_add+0x360/0x8f0
 fsl_mc_obj_device_add+0x140/0x16c
 dprc_scan_objects+0x2c4/0x480
 dprc_probe+0x48/0x17c
 fsl_mc_driver_probe+0x3c/0x80
 really_probe.part.0+0xec/0x480
 __driver_probe_device+0xd4/0x180
 device_driver_attach+0x70/0xf0
 bind_store+0xf8/0x160
 drv_attr_store+0x50/0x6c
 sysfs_kf_write+0x94/0xb0
 kernfs_fop_write_iter+0x19c/0x264
 new_sync_write+0x1c4/0x2bc
 vfs_write+0x30c/0x390
 ksys_write+0xc4/0x170
 __arm64_sys_write+0x48/0x60
 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 ffff05d2b13af000
 which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 40 bytes inside of
 1024-byte region [ffff05d2b13af000, ffff05d2b13af400)
The buggy address belongs to the page:
page:0000000091873dc7 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x22313a8
head:0000000091873dc7 order:3 compound_mapcount:0 compound_pincount:0
flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff)
raw: 0bfffc0000010200 0000000000000000 dead000000000122 ffff05d1000028c0
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff05d2b13aef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff05d2b13aef80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff05d2b13af000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                  ^
 ffff05d2b13af080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff05d2b13af100: 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>
---
Changes in v2:
 - corrected commit msg

 drivers/soc/fsl/dpio/dpio-service.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

Comments

Ioana Ciornei Oct. 7, 2021, 12:24 p.m. UTC | #1
On Mon, Oct 04, 2021 at 02:53:23PM +0300, Laurentiu Tudor wrote:
> dpaa2_io_service_register() adds an element to a linked list but
> doesn't remove it on the error path, leading to the below kasan
> use-after-free splat. Fix it.
> 
> ==================================================================
> BUG: KASAN: use-after-free in dpaa2_io_service_register+0xb8/0x1d4
> Write of size 8 at addr ffff05d2b13af028 by task kworker/u32:2/151
> 
> CPU: 9 PID: 151 Comm: kworker/u32:2 Not tainted 5.14.0-rc1-00222
> Hardware name: NXP NXP LX2160ARDB Platform, BIOS EDK II Apr 16 2021
> Workqueue: events_unbound deferred_probe_work_func
> 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_store8+0xa8/0xd0
>  dpaa2_io_service_register+0xb8/0x1d4
>  dpaa2_eth_probe+0x93c/0x21cc
>  fsl_mc_driver_probe+0x3c/0x80
>  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+0xa4/0x72c
>  kthread+0x1f8/0x210
>  ret_from_fork+0x10/0x18
> 
> Allocated by task 1192:
>  kasan_save_stack+0x2c/0x60
>  __kasan_kmalloc+0x90/0xb4
>  dpaa2_eth_probe+0x830/0x21cc
>  fsl_mc_driver_probe+0x3c/0x80
>  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
>  device_add+0x570/0xca0
>  fsl_mc_device_add+0x360/0x8f0
>  fsl_mc_obj_device_add+0x140/0x16c
>  dprc_scan_objects+0x2c4/0x480
>  dprc_probe+0x48/0x17c
>  fsl_mc_driver_probe+0x3c/0x80
>  really_probe.part.0+0xec/0x480
>  __driver_probe_device+0xd4/0x180
>  device_driver_attach+0x70/0xf0
>  bind_store+0xf8/0x160
>  drv_attr_store+0x50/0x6c
>  sysfs_kf_write+0x94/0xb0
>  kernfs_fop_write_iter+0x19c/0x264
>  new_sync_write+0x1c4/0x2bc
>  vfs_write+0x30c/0x390
>  ksys_write+0xc4/0x170
>  __arm64_sys_write+0x48/0x60
>  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
> 
> Freed by task 1192:
>  kasan_save_stack+0x2c/0x60
>  kasan_set_track+0x2c/0x40
>  kasan_set_free_info+0x2c/0x50
>  __kasan_slab_free+0xdc/0x140
>  kfree+0xd4/0x360
>  dpaa2_eth_probe+0x11b4/0x21cc
>  fsl_mc_driver_probe+0x3c/0x80
>  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
>  device_add+0x570/0xca0
>  fsl_mc_device_add+0x360/0x8f0
>  fsl_mc_obj_device_add+0x140/0x16c
>  dprc_scan_objects+0x2c4/0x480
>  dprc_probe+0x48/0x17c
>  fsl_mc_driver_probe+0x3c/0x80
>  really_probe.part.0+0xec/0x480
>  __driver_probe_device+0xd4/0x180
>  device_driver_attach+0x70/0xf0
>  bind_store+0xf8/0x160
>  drv_attr_store+0x50/0x6c
>  sysfs_kf_write+0x94/0xb0
>  kernfs_fop_write_iter+0x19c/0x264
>  new_sync_write+0x1c4/0x2bc
>  vfs_write+0x30c/0x390
>  ksys_write+0xc4/0x170
>  __arm64_sys_write+0x48/0x60
>  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 ffff05d2b13af000
>  which belongs to the cache kmalloc-1k of size 1024
> The buggy address is located 40 bytes inside of
>  1024-byte region [ffff05d2b13af000, ffff05d2b13af400)
> The buggy address belongs to the page:
> page:0000000091873dc7 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x22313a8
> head:0000000091873dc7 order:3 compound_mapcount:0 compound_pincount:0
> flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff)
> raw: 0bfffc0000010200 0000000000000000 dead000000000122 ffff05d1000028c0
> raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
> 
> Memory state around the buggy address:
>  ffff05d2b13aef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  ffff05d2b13aef80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >ffff05d2b13af000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                   ^
>  ffff05d2b13af080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff05d2b13af100: 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>

Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Laurentiu Tudor Feb. 2, 2022, 12:37 p.m. UTC | #2
Hi Leo,

Kind reminder.

---
Best Regards, Laurentiu

On 10/7/2021 3:24 PM, Ioana Ciornei wrote:
> On Mon, Oct 04, 2021 at 02:53:23PM +0300, Laurentiu Tudor wrote:
>> dpaa2_io_service_register() adds an element to a linked list but
>> doesn't remove it on the error path, leading to the below kasan
>> use-after-free splat. Fix it.
>>
>> ==================================================================
>> BUG: KASAN: use-after-free in dpaa2_io_service_register+0xb8/0x1d4
>> Write of size 8 at addr ffff05d2b13af028 by task kworker/u32:2/151
>>
>> CPU: 9 PID: 151 Comm: kworker/u32:2 Not tainted 5.14.0-rc1-00222
>> Hardware name: NXP NXP LX2160ARDB Platform, BIOS EDK II Apr 16 2021
>> Workqueue: events_unbound deferred_probe_work_func
>> 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_store8+0xa8/0xd0
>>   dpaa2_io_service_register+0xb8/0x1d4
>>   dpaa2_eth_probe+0x93c/0x21cc
>>   fsl_mc_driver_probe+0x3c/0x80
>>   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+0xa4/0x72c
>>   kthread+0x1f8/0x210
>>   ret_from_fork+0x10/0x18
>>
>> Allocated by task 1192:
>>   kasan_save_stack+0x2c/0x60
>>   __kasan_kmalloc+0x90/0xb4
>>   dpaa2_eth_probe+0x830/0x21cc
>>   fsl_mc_driver_probe+0x3c/0x80
>>   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
>>   device_add+0x570/0xca0
>>   fsl_mc_device_add+0x360/0x8f0
>>   fsl_mc_obj_device_add+0x140/0x16c
>>   dprc_scan_objects+0x2c4/0x480
>>   dprc_probe+0x48/0x17c
>>   fsl_mc_driver_probe+0x3c/0x80
>>   really_probe.part.0+0xec/0x480
>>   __driver_probe_device+0xd4/0x180
>>   device_driver_attach+0x70/0xf0
>>   bind_store+0xf8/0x160
>>   drv_attr_store+0x50/0x6c
>>   sysfs_kf_write+0x94/0xb0
>>   kernfs_fop_write_iter+0x19c/0x264
>>   new_sync_write+0x1c4/0x2bc
>>   vfs_write+0x30c/0x390
>>   ksys_write+0xc4/0x170
>>   __arm64_sys_write+0x48/0x60
>>   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
>>
>> Freed by task 1192:
>>   kasan_save_stack+0x2c/0x60
>>   kasan_set_track+0x2c/0x40
>>   kasan_set_free_info+0x2c/0x50
>>   __kasan_slab_free+0xdc/0x140
>>   kfree+0xd4/0x360
>>   dpaa2_eth_probe+0x11b4/0x21cc
>>   fsl_mc_driver_probe+0x3c/0x80
>>   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
>>   device_add+0x570/0xca0
>>   fsl_mc_device_add+0x360/0x8f0
>>   fsl_mc_obj_device_add+0x140/0x16c
>>   dprc_scan_objects+0x2c4/0x480
>>   dprc_probe+0x48/0x17c
>>   fsl_mc_driver_probe+0x3c/0x80
>>   really_probe.part.0+0xec/0x480
>>   __driver_probe_device+0xd4/0x180
>>   device_driver_attach+0x70/0xf0
>>   bind_store+0xf8/0x160
>>   drv_attr_store+0x50/0x6c
>>   sysfs_kf_write+0x94/0xb0
>>   kernfs_fop_write_iter+0x19c/0x264
>>   new_sync_write+0x1c4/0x2bc
>>   vfs_write+0x30c/0x390
>>   ksys_write+0xc4/0x170
>>   __arm64_sys_write+0x48/0x60
>>   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 ffff05d2b13af000
>>   which belongs to the cache kmalloc-1k of size 1024
>> The buggy address is located 40 bytes inside of
>>   1024-byte region [ffff05d2b13af000, ffff05d2b13af400)
>> The buggy address belongs to the page:
>> page:0000000091873dc7 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x22313a8
>> head:0000000091873dc7 order:3 compound_mapcount:0 compound_pincount:0
>> flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff)
>> raw: 0bfffc0000010200 0000000000000000 dead000000000122 ffff05d1000028c0
>> raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
>> page dumped because: kasan: bad access detected
>>
>> Memory state around the buggy address:
>>   ffff05d2b13aef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>   ffff05d2b13aef80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>> ffff05d2b13af000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>                                    ^
>>   ffff05d2b13af080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>   ffff05d2b13af100: 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>
> 
> Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
diff mbox series

Patch

diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
index 7351f3030550..b42367eb1653 100644
--- a/drivers/soc/fsl/dpio/dpio-service.c
+++ b/drivers/soc/fsl/dpio/dpio-service.c
@@ -278,10 +278,20 @@  int dpaa2_io_service_register(struct dpaa2_io *d,
 	spin_unlock_irqrestore(&d->lock_notifications, irqflags);
 
 	/* Enable the generation of CDAN notifications */
-	if (ctx->is_cdan)
-		return qbman_swp_CDAN_set_context_enable(d->swp,
-							 (u16)ctx->id,
-							 ctx->qman64);
+	if (ctx->is_cdan) {
+		int ret;
+
+		ret = qbman_swp_CDAN_set_context_enable(d->swp, (u16)ctx->id,
+							ctx->qman64);
+		if (ret) {
+			spin_lock_irqsave(&d->lock_notifications, irqflags);
+			list_del(&ctx->node);
+			spin_unlock_irqrestore(&d->lock_notifications,
+					       irqflags);
+
+			return ret;
+		}
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(dpaa2_io_service_register);