]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Oct 2025 10:23:51 +0000 (12:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Oct 2025 10:23:51 +0000 (12:23 +0200)
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

queue-5.15/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch [new file with mode: 0644]
queue-5.15/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch [new file with mode: 0644]
queue-5.15/media-tunner-xc5000-refactor-firmware-load.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch b/queue-5.15/media-i2c-tc358743-fix-use-after-free-bugs-caused-by-orphan-timer-in-probe.patch
new file mode 100644 (file)
index 0000000..ffb9061
--- /dev/null
@@ -0,0 +1,149 @@
+From stable+bounces-183317-greg=kroah.com@vger.kernel.org Fri Oct  3 21:03:05 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  3 Oct 2025 15:02:57 -0400
+Subject: media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe
+To: stable@vger.kernel.org
+Cc: Duoming Zhou <duoming@zju.edu.cn>, Hans Verkuil <hverkuil+cisco@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20251003190257.3301728-1-sashal@kernel.org>
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ 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:
+ <IRQ>
+ 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
+ </IRQ>
+...
+
+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 <duoming@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+[ replaced del_timer() instead of timer_delete() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch b/queue-5.15/media-tuner-xc5000-fix-use-after-free-in-xc5000_release.patch
new file mode 100644 (file)
index 0000000..72e22b3
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-183331-greg=kroah.com@vger.kernel.org Fri Oct  3 22:55:00 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  3 Oct 2025 16:54:47 -0400
+Subject: media: tuner: xc5000: Fix use-after-free in xc5000_release
+To: stable@vger.kernel.org
+Cc: Duoming Zhou <duoming@zju.edu.cn>, Hans Verkuil <hverkuil+cisco@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20251003205447.3385896-2-sashal@kernel.org>
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ 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 <duoming@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+[hverkuil: fix typo in Subject: tunner -> tuner]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/media-tunner-xc5000-refactor-firmware-load.patch b/queue-5.15/media-tunner-xc5000-refactor-firmware-load.patch
new file mode 100644 (file)
index 0000000..422ec9e
--- /dev/null
@@ -0,0 +1,113 @@
+From stable+bounces-183330-greg=kroah.com@vger.kernel.org Fri Oct  3 22:54:57 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  3 Oct 2025 16:54:46 -0400
+Subject: media: tunner: xc5000: Refactor firmware load
+To: stable@vger.kernel.org
+Cc: Ricardo Ribalda <ribalda@chromium.org>, Shuah Khan <shuah.kh@samsung.com>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20251003205447.3385896-1-sashal@kernel.org>
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ 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 <shuah.kh@samsung.com>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: 40b7a19f321e ("media: tuner: xc5000: Fix use-after-free in xc5000_release")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+       }
index 1be5384e07b0654e037597ccc6194bfb3aca7926..83ca5b939877b5320d316646684c2a7824c09d10 100644 (file)
@@ -5,3 +5,6 @@ media-rc-fix-races-with-imon_disconnect.patch
 media-uvcvideo-mark-invalid-entities-with-id-uvc_invalid_entity_id.patch
 kvm-arm64-fix-softirq-masking-in-fpsimd-register-saving-sequence.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