[PATCH] media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe

Duoming Zhou posted 1 patch 2 days, 1 hour ago
drivers/media/i2c/tc358743.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe
Posted by Duoming Zhou 2 days, 1 hour ago
The state->timer is a cyclic timer that schedules work_i2c_poll and
delayed_work_enable_hotplug, while rearming itself. Using timer_delete()
fails to guarantee the timer isn't still running when destroyed, similarly
cancel_delayed_work() cannot ensure delayed_work_enable_hotplug has
terminated if already executing. During probe failure after timer
initialization, these may continue running as orphans and reference the
already-freed tc358743_state object through tc358743_irq_poll_timer.

The following is the trace captured by KASAN.

[   34.674318] BUG: KASAN: slab-use-after-free in __run_timer_base.part.0+0x7d7/0x8c0
[   34.674949] Write of size 8 at addr ffff88800ded83c8 by task swapper/1/0
......
[   34.677259] Call Trace:
[   34.677336]  <IRQ>
[   34.677447]  dump_stack_lvl+0x55/0x70
[   34.677532]  print_report+0xcf/0x610
[   34.677562]  ? __pfx_sched_balance_find_src_group+0x10/0x10
[   34.677586]  ? __run_timer_base.part.0+0x7d7/0x8c0
[   34.677603]  kasan_report+0xb8/0xf0
[   34.677622]  ? __run_timer_base.part.0+0x7d7/0x8c0
[   34.677642]  __run_timer_base.part.0+0x7d7/0x8c0
[   34.677665]  ? rcu_sched_clock_irq+0xb06/0x27d0
[   34.677683]  ? __pfx___run_timer_base.part.0+0x10/0x10
[   34.677698]  ? try_to_wake_up+0xb15/0x1960
[   34.677717]  ? tmigr_update_events+0x280/0x740
[   34.677737]  ? _raw_spin_lock_irq+0x80/0xe0
[   34.677756]  ? __pfx__raw_spin_lock_irq+0x10/0x10
[   34.677775]  tmigr_handle_remote_up+0x603/0x7e0
[   34.677800]  ? __pfx_tmigr_handle_remote_up+0x10/0x10
[   34.677817]  ? sched_balance_trigger+0x98/0x9f0
[   34.677834]  ? sched_tick+0x221/0x5a0
[   34.677851]  ? _raw_spin_lock_irq+0x80/0xe0
[   34.677866]  ? __pfx__raw_spin_lock_irq+0x10/0x10
[   34.677883]  ? tick_nohz_handler+0x339/0x440
[   34.677901]  ? __pfx_tmigr_handle_remote_up+0x10/0x10
[   34.677918]  __walk_groups.isra.0+0x42/0x150
[   34.677938]  tmigr_handle_remote+0x1f4/0x2e0
[   34.677955]  ? __pfx_tmigr_handle_remote+0x10/0x10
[   34.677973]  ? ktime_get+0x60/0x140
[   34.677990]  ? lapic_next_event+0x11/0x20
[   34.678008]  ? clockevents_program_event+0x1d4/0x2a0
[   34.678023]  ? hrtimer_interrupt+0x322/0x780
[   34.678042]  handle_softirqs+0x16a/0x550
[   34.678069]  irq_exit_rcu+0xaf/0xe0
[   34.678086]  sysvec_apic_timer_interrupt+0x70/0x80
[   34.678117]  </IRQ>
[   34.678129]  <TASK>
[   34.678137]  asm_sysvec_apic_timer_interrupt+0x1a/0x20
[   34.678213] RIP: 0010:pv_native_safe_halt+0xf/0x20
[   34.678290] Code: 67 ec 00 c3 cc cc cc cc 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f0
[   34.678346] RSP: 0018:ffff8880089afe60 EFLAGS: 00000216
[   34.678431] RAX: ffff8880e59c4000 RBX: 0000000000000001 RCX: ffffffff84aa9571
[   34.678469] RDX: 0000000000000001 RSI: 0000000000000004 RDI: 000000000001a7dc
[   34.678501] RBP: dffffc0000000000 R08: ffff88806d0a7ae0 R09: ffffed100da1613b
[   34.678535] R10: ffffed100da1613a R11: ffff88806d0b09d3 R12: ffffffff8666be50
[   34.678567] R13: 1ffff11001135fd2 R14: 0000000000000000 R15: 0000000000000000
[   34.678607]  ? ct_kernel_exit.constprop.0+0xa1/0xc0
[   34.678633]  default_idle+0x9/0x10
[   34.678651]  default_idle_call+0x3a/0x60
[   34.678667]  do_idle+0x2e5/0x3a0
[   34.678687]  ? __pfx_do_idle+0x10/0x10
[   34.678703]  ? swake_up_locked.part.0+0x5f/0x170
[   34.678719]  ? __kthread_bind_mask+0x44/0x90
[   34.678739]  cpu_startup_entry+0x4f/0x60
[   34.678755]  start_secondary+0x1b3/0x210
[   34.678774]  common_startup_64+0x13e/0x148
[   34.678811]  </TASK>
[   34.678863]
[   34.685702] Allocated by task 141:
[   34.686070]  kasan_save_stack+0x24/0x50
[   34.686382]  kasan_save_track+0x14/0x30
[   34.686597]  __kasan_kmalloc+0x7f/0x90
[   34.686827]  __kmalloc_node_track_caller_noprof+0x198/0x430
[   34.687085]  devm_kmalloc+0x7b/0x1e0
[   34.687341]  tc358743_probe+0xb7/0x610 [tc358743]
[   34.688028]  i2c_device_probe+0x51d/0x880
[   34.688141]  really_probe+0x1ca/0x5c0
[   34.688248]  __driver_probe_device+0x248/0x310
[   34.688489]  driver_probe_device+0x44/0x120
[   34.688639]  __device_attach_driver+0x174/0x220
[   34.688827]  bus_for_each_drv+0x100/0x190
[   34.689035]  __device_attach+0x206/0x370
[   34.689272]  bus_probe_device+0x123/0x170
[   34.689473]  device_add+0xd25/0x1470
[   34.689694]  i2c_new_client_device+0x7a0/0xcd0
[   34.690193]  do_one_initcall+0x89/0x300
[   34.690389]  do_init_module+0x29d/0x7f0
[   34.690608]  load_module+0x4f48/0x69e0
[   34.690782]  init_module_from_file+0xe4/0x150
[   34.691113]  idempotent_init_module+0x320/0x670
[   34.691291]  __x64_sys_finit_module+0xbd/0x120
[   34.691429]  do_syscall_64+0xac/0x280
[   34.691684]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   34.692042]
[   34.692240] Freed by task 141:
[   34.692436]  kasan_save_stack+0x24/0x50
[   34.692743]  kasan_save_track+0x14/0x30
[   34.692968]  kasan_save_free_info+0x3a/0x60
[   34.693263]  __kasan_slab_free+0x3f/0x50
[   34.693485]  kfree+0x137/0x370
[   34.693653]  release_nodes+0xa4/0x100
[   34.693849]  devres_release_group+0x1b2/0x380
[   34.694009]  i2c_device_probe+0x694/0x880
[   34.694307]  really_probe+0x1ca/0x5c0
[   34.694526]  __driver_probe_device+0x248/0x310
[   34.694829]  driver_probe_device+0x44/0x120
[   34.695076]  __device_attach_driver+0x174/0x220
[   34.695366]  bus_for_each_drv+0x100/0x190
[   34.695629]  __device_attach+0x206/0x370
[   34.695731]  bus_probe_device+0x123/0x170
[   34.695971]  device_add+0xd25/0x1470
[   34.696173]  i2c_new_client_device+0x7a0/0xcd0
[   34.696491]  do_one_initcall+0x89/0x300
[   34.696664]  do_init_module+0x29d/0x7f0
[   34.696856]  load_module+0x4f48/0x69e0
[   34.697047]  init_module_from_file+0xe4/0x150
[   34.697345]  idempotent_init_module+0x320/0x670
[   34.697681]  __x64_sys_finit_module+0xbd/0x120
[   34.697972]  do_syscall_64+0xac/0x280
[   34.698123]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   34.698421]
[   34.698666] The buggy address belongs to the object at ffff88800ded8000
[   34.698666]  which belongs to the cache kmalloc-2k of size 2048
[   34.699248] The buggy address is located 968 bytes inside of
[   34.699248]  freed 2048-byte region [ffff88800ded8000, ffff88800ded8800)
[   34.699780]
[   34.700099] The buggy address belongs to the physical page:
[   34.700794] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xded8
[   34.701253] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[   34.701674] flags: 0x100000000000040(head|node=0|zone=1)
[   34.702298] page_type: f5(slab)
[   34.702973] raw: 0100000000000040 ffff888008042f00 dead000000000122 0000000000000000
[   34.703395] raw: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
[   34.704087] head: 0100000000000040 ffff888008042f00 dead000000000122 0000000000000000
[   34.704372] head: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
[   34.704495] head: 0100000000000003 ffffea000037b601 00000000ffffffff 00000000ffffffff
[   34.704599] head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   34.704739] page dumped because: kasan: bad access detected
[   34.704823]
[   34.704862] Memory state around the buggy address:
[   34.705390]  ffff88800ded8280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   34.705718]  ffff88800ded8300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   34.706286] >ffff88800ded8380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   34.706706]                                               ^
[   34.707255]  ffff88800ded8400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   34.707573]  ffff88800ded8480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   34.707937] ==================================================================

Replace timer_delete() with del_timer_sync() and cancel_delayed_work() with
cancel_delayed_work_sync() to ensure proper termination of timer and work
items before resource cleanup.

Fixes: 869f38ae07f7 ("media: i2c: tc358743: Fix crash in the probe error path when using polling")
Fixes: d32d98642de6 ("[media] Driver for Toshiba TC358743 HDMI to CSI-2 bridge")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
---
 drivers/media/i2c/tc358743.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 1cc7636e446d..5042cf612d21 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -2245,10 +2245,10 @@ static int tc358743_probe(struct i2c_client *client)
 err_work_queues:
 	cec_unregister_adapter(state->cec_adap);
 	if (!state->i2c_client->irq) {
-		timer_delete(&state->timer);
+		timer_delete_sync(&state->timer);
 		flush_work(&state->work_i2c_poll);
 	}
-	cancel_delayed_work(&state->delayed_work_enable_hotplug);
+	cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
 	mutex_destroy(&state->confctl_mutex);
 err_hdl:
 	media_entity_cleanup(&sd->entity);
-- 
2.34.1