From ebfcd1a2b0cee83e6ed1e4b83f050129ca022e8c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 6 Oct 2025 12:23:40 +0200 Subject: [PATCH] 5.10-stable patches added patches: media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch media-tunner-xc5000-refactor-firmware-load.patch --- ...bugs-caused-by-orphan-timer-in-probe.patch | 149 ++++++++++++++++++ ...fix-use-after-free-in-xc5000_release.patch | 59 +++++++ ...tunner-xc5000-refactor-firmware-load.patch | 113 +++++++++++++ queue-5.10/series | 3 + 4 files changed, 324 insertions(+) create mode 100644 queue-5.10/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch create mode 100644 queue-5.10/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch create mode 100644 queue-5.10/media-tunner-xc5000-refactor-firmware-load.patch diff --git a/queue-5.10/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch b/queue-5.10/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch new file mode 100644 index 0000000000..f2786a2409 --- /dev/null +++ b/queue-5.10/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch @@ -0,0 +1,149 @@ +From stable+bounces-183321-greg=kroah.com@vger.kernel.org Fri Oct 3 21:32:46 2025 +From: Sasha Levin +Date: Fri, 3 Oct 2025 15:32:38 -0400 +Subject: media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe +To: stable@vger.kernel.org +Cc: Duoming Zhou , Hans Verkuil , Sasha Levin +Message-ID: <20251003193238.3340101-1-sashal@kernel.org> + +From: Duoming Zhou + +[ Upstream commit 79d10f4f21a92e459b2276a77be62c59c1502c9d ] + +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. + +BUG: KASAN: slab-use-after-free in __run_timer_base.part.0+0x7d7/0x8c0 +Write of size 8 at addr ffff88800ded83c8 by task swapper/1/0 +... +Call Trace: + + dump_stack_lvl+0x55/0x70 + print_report+0xcf/0x610 + ? __pfx_sched_balance_find_src_group+0x10/0x10 + ? __run_timer_base.part.0+0x7d7/0x8c0 + kasan_report+0xb8/0xf0 + ? __run_timer_base.part.0+0x7d7/0x8c0 + __run_timer_base.part.0+0x7d7/0x8c0 + ? rcu_sched_clock_irq+0xb06/0x27d0 + ? __pfx___run_timer_base.part.0+0x10/0x10 + ? try_to_wake_up+0xb15/0x1960 + ? tmigr_update_events+0x280/0x740 + ? _raw_spin_lock_irq+0x80/0xe0 + ? __pfx__raw_spin_lock_irq+0x10/0x10 + tmigr_handle_remote_up+0x603/0x7e0 + ? __pfx_tmigr_handle_remote_up+0x10/0x10 + ? sched_balance_trigger+0x98/0x9f0 + ? sched_tick+0x221/0x5a0 + ? _raw_spin_lock_irq+0x80/0xe0 + ? __pfx__raw_spin_lock_irq+0x10/0x10 + ? tick_nohz_handler+0x339/0x440 + ? __pfx_tmigr_handle_remote_up+0x10/0x10 + __walk_groups.isra.0+0x42/0x150 + tmigr_handle_remote+0x1f4/0x2e0 + ? __pfx_tmigr_handle_remote+0x10/0x10 + ? ktime_get+0x60/0x140 + ? lapic_next_event+0x11/0x20 + ? clockevents_program_event+0x1d4/0x2a0 + ? hrtimer_interrupt+0x322/0x780 + handle_softirqs+0x16a/0x550 + irq_exit_rcu+0xaf/0xe0 + sysvec_apic_timer_interrupt+0x70/0x80 + +... + +Allocated by task 141: + kasan_save_stack+0x24/0x50 + kasan_save_track+0x14/0x30 + __kasan_kmalloc+0x7f/0x90 + __kmalloc_node_track_caller_noprof+0x198/0x430 + devm_kmalloc+0x7b/0x1e0 + tc358743_probe+0xb7/0x610 i2c_device_probe+0x51d/0x880 + really_probe+0x1ca/0x5c0 + __driver_probe_device+0x248/0x310 + driver_probe_device+0x44/0x120 + __device_attach_driver+0x174/0x220 + bus_for_each_drv+0x100/0x190 + __device_attach+0x206/0x370 + bus_probe_device+0x123/0x170 + device_add+0xd25/0x1470 + i2c_new_client_device+0x7a0/0xcd0 + do_one_initcall+0x89/0x300 + do_init_module+0x29d/0x7f0 + load_module+0x4f48/0x69e0 + init_module_from_file+0xe4/0x150 + idempotent_init_module+0x320/0x670 + __x64_sys_finit_module+0xbd/0x120 + do_syscall_64+0xac/0x280 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Freed by task 141: + kasan_save_stack+0x24/0x50 + kasan_save_track+0x14/0x30 + kasan_save_free_info+0x3a/0x60 + __kasan_slab_free+0x3f/0x50 + kfree+0x137/0x370 + release_nodes+0xa4/0x100 + devres_release_group+0x1b2/0x380 + i2c_device_probe+0x694/0x880 + really_probe+0x1ca/0x5c0 + __driver_probe_device+0x248/0x310 + driver_probe_device+0x44/0x120 + __device_attach_driver+0x174/0x220 + bus_for_each_drv+0x100/0x190 + __device_attach+0x206/0x370 + bus_probe_device+0x123/0x170 + device_add+0xd25/0x1470 + i2c_new_client_device+0x7a0/0xcd0 + do_one_initcall+0x89/0x300 + do_init_module+0x29d/0x7f0 + load_module+0x4f48/0x69e0 + init_module_from_file+0xe4/0x150 + idempotent_init_module+0x320/0x670 + __x64_sys_finit_module+0xbd/0x120 + do_syscall_64+0xac/0x280 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +... + +Replace timer_delete() with timer_delete_sync() and cancel_delayed_work() +with cancel_delayed_work_sync() to ensure proper termination of timer and +work items before resource cleanup. + +This bug was initially identified through static analysis. For reproduction +and testing, I created a functional emulation of the tc358743 device via a +kernel module and introduced faults through the debugfs interface. + +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") +Cc: stable@vger.kernel.org +Signed-off-by: Duoming Zhou +Signed-off-by: Hans Verkuil +[ replaced del_timer() instead of timer_delete() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/i2c/tc358743.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/i2c/tc358743.c ++++ b/drivers/media/i2c/tc358743.c +@@ -2201,10 +2201,10 @@ static int tc358743_probe(struct i2c_cli + err_work_queues: + cec_unregister_adapter(state->cec_adap); + if (!state->i2c_client->irq) { +- del_timer(&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); diff --git a/queue-5.10/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch b/queue-5.10/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch new file mode 100644 index 0000000000..c8151fcce3 --- /dev/null +++ b/queue-5.10/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch @@ -0,0 +1,59 @@ +From stable+bounces-183343-greg=kroah.com@vger.kernel.org Sat Oct 4 02:22:08 2025 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:21:57 -0400 +Subject: media: tuner: xc5000: Fix use-after-free in xc5000_release +To: stable@vger.kernel.org +Cc: Duoming Zhou , Hans Verkuil , Sasha Levin +Message-ID: <20251004002158.4023173-2-sashal@kernel.org> + +From: Duoming Zhou + +[ Upstream commit 40b7a19f321e65789612ebaca966472055dab48c ] + +The original code uses cancel_delayed_work() in xc5000_release(), which +does not guarantee that the delayed work item timer_sleep has fully +completed if it was already running. This leads to use-after-free scenarios +where xc5000_release() may free the xc5000_priv while timer_sleep is still +active and attempts to dereference the xc5000_priv. + +A typical race condition is illustrated below: + +CPU 0 (release thread) | CPU 1 (delayed work callback) +xc5000_release() | xc5000_do_timer_sleep() + cancel_delayed_work() | + hybrid_tuner_release_state(priv) | + kfree(priv) | + | priv = container_of() // UAF + +Replace cancel_delayed_work() with cancel_delayed_work_sync() to ensure +that the timer_sleep is properly canceled before the xc5000_priv memory +is deallocated. + +A deadlock concern was considered: xc5000_release() is called in a process +context and is not holding any locks that the timer_sleep work item might +also need. Therefore, the use of the _sync() variant is safe here. + +This bug was initially identified through static analysis. + +Fixes: f7a27ff1fb77 ("[media] xc5000: delay tuner sleep to 5 seconds") +Cc: stable@vger.kernel.org +Signed-off-by: Duoming Zhou +Signed-off-by: Hans Verkuil +[hverkuil: fix typo in Subject: tunner -> tuner] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/tuners/xc5000.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/tuners/xc5000.c ++++ b/drivers/media/tuners/xc5000.c +@@ -1304,7 +1304,7 @@ static void xc5000_release(struct dvb_fr + mutex_lock(&xc5000_list_mutex); + + if (priv) { +- cancel_delayed_work(&priv->timer_sleep); ++ cancel_delayed_work_sync(&priv->timer_sleep); + hybrid_tuner_release_state(priv); + } + diff --git a/queue-5.10/media-tunner-xc5000-refactor-firmware-load.patch b/queue-5.10/media-tunner-xc5000-refactor-firmware-load.patch new file mode 100644 index 0000000000..702c1c2801 --- /dev/null +++ b/queue-5.10/media-tunner-xc5000-refactor-firmware-load.patch @@ -0,0 +1,113 @@ +From stable+bounces-183342-greg=kroah.com@vger.kernel.org Sat Oct 4 02:22:07 2025 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:21:56 -0400 +Subject: media: tunner: xc5000: Refactor firmware load +To: stable@vger.kernel.org +Cc: Ricardo Ribalda , Shuah Khan , Hans Verkuil , Sasha Levin +Message-ID: <20251004002158.4023173-1-sashal@kernel.org> + +From: Ricardo Ribalda + +[ Upstream commit 8e1f5da59dd4a1966f859639860b803a7e8b8bfb ] + +Make sure the firmware is released when we leave +xc_load_fw_and_init_tuner() + +This change makes smatch happy: +drivers/media/tuners/xc5000.c:1213 xc_load_fw_and_init_tuner() warn: 'fw' from request_firmware() not released on lines: 1213. + +Cc: Shuah Khan +Signed-off-by: Ricardo Ribalda +Signed-off-by: Hans Verkuil +Stable-dep-of: 40b7a19f321e ("media: tuner: xc5000: Fix use-after-free in xc5000_release") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/tuners/xc5000.c | 41 ++++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 23 deletions(-) + +--- a/drivers/media/tuners/xc5000.c ++++ b/drivers/media/tuners/xc5000.c +@@ -58,7 +58,7 @@ struct xc5000_priv { + struct dvb_frontend *fe; + struct delayed_work timer_sleep; + +- const struct firmware *firmware; ++ bool inited; + }; + + /* Misc Defines */ +@@ -1110,23 +1110,19 @@ static int xc_load_fw_and_init_tuner(str + if (!force && xc5000_is_firmware_loaded(fe) == 0) + return 0; + +- if (!priv->firmware) { +- ret = request_firmware(&fw, desired_fw->name, +- priv->i2c_props.adap->dev.parent); +- if (ret) { +- pr_err("xc5000: Upload failed. rc %d\n", ret); +- return ret; +- } +- dprintk(1, "firmware read %zu bytes.\n", fw->size); +- +- if (fw->size != desired_fw->size) { +- pr_err("xc5000: Firmware file with incorrect size\n"); +- release_firmware(fw); +- return -EINVAL; +- } +- priv->firmware = fw; +- } else +- fw = priv->firmware; ++ ret = request_firmware(&fw, desired_fw->name, ++ priv->i2c_props.adap->dev.parent); ++ if (ret) { ++ pr_err("xc5000: Upload failed. rc %d\n", ret); ++ return ret; ++ } ++ dprintk(1, "firmware read %zu bytes.\n", fw->size); ++ ++ if (fw->size != desired_fw->size) { ++ pr_err("xc5000: Firmware file with incorrect size\n"); ++ release_firmware(fw); ++ return -EINVAL; ++ } + + /* Try up to 5 times to load firmware */ + for (i = 0; i < 5; i++) { +@@ -1204,6 +1200,7 @@ static int xc_load_fw_and_init_tuner(str + } + + err: ++ release_firmware(fw); + if (!ret) + printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n", + desired_fw->name); +@@ -1274,7 +1271,7 @@ static int xc5000_resume(struct dvb_fron + + /* suspended before firmware is loaded. + Avoid firmware load in resume path. */ +- if (!priv->firmware) ++ if (!priv->inited) + return 0; + + return xc5000_set_params(fe); +@@ -1293,6 +1290,8 @@ static int xc5000_init(struct dvb_fronte + if (debug) + xc_debug_dump(priv); + ++ priv->inited = true; ++ + return 0; + } + +@@ -1306,10 +1305,6 @@ static void xc5000_release(struct dvb_fr + + if (priv) { + cancel_delayed_work(&priv->timer_sleep); +- if (priv->firmware) { +- release_firmware(priv->firmware); +- priv->firmware = NULL; +- } + hybrid_tuner_release_state(priv); + } + diff --git a/queue-5.10/series b/queue-5.10/series index 248123de2b..4a860ef07d 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -2,3 +2,6 @@ scsi-target-target_core_configfs-add-length-check-to-avoid-buffer-overflow.patch media-b2c2-fix-use-after-free-causing-by-irq_check_work-in-flexcop_pci_remove.patch media-rc-fix-races-with-imon_disconnect.patch udp-fix-memory-accounting-leak.patch +media-tunner-xc5000-refactor-firmware-load.patch +media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch +media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch -- 2.47.3