From: Greg Kroah-Hartman Date: Mon, 18 Aug 2025 12:15:35 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.12.43~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f91418d002a1eb2c607dd90dda9392273278fc62;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: md-fix-create-on-open-mddev-lifetime-regression.patch rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch --- diff --git a/queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch new file mode 100644 index 0000000000..fc2bb441aa --- /dev/null +++ b/queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch @@ -0,0 +1,79 @@ +From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Wed, 30 Jul 2025 15:33:21 +0800 +Subject: md: fix create on open mddev lifetime regression + +From: Yu Kuai + +commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream. + +Commit 9e59d609763f ("md: call del_gendisk in control path") moves +setting MD_DELETED from __mddev_put() to do_md_stop(), however, for the +case create on open, mddev can be freed without do_md_stop(): + +1) open + +md_probe + md_alloc_and_put + md_alloc + mddev_alloc + atomic_set(&mddev->active, 1); + mddev->hold_active = UNTIL_IOCTL + mddev_put + atomic_dec_and_test(&mddev->active) + if (mddev->hold_active) + -> active is 0, hold_active is set +md_open + mddev_get + atomic_inc(&mddev->active); + +2) ioctl that is not STOP_ARRAY, for example, GET_ARRAY_INFO: + +md_ioctl + mddev->hold_active = 0 + +3) close + +md_release + mddev_put(mddev); + atomic_dec_and_lock(&mddev->active, &all_mddevs_lock) + __mddev_put + -> hold_active is cleared, mddev will be freed + queue_work(md_misc_wq, &mddev->del_work) + +Now that MD_DELETED is not set, before mddev is freed by +mddev_delayed_delete(), md_open can still succeed and break mddev +lifetime, causing mddev->kobj refcount underflow or mddev uaf +problem. + +Fix this problem by setting MD_DELETED before queuing del_work. + +Reported-by: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/ +Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/ +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com +Signed-off-by: Yu Kuai +Reviewed-by: Paul Menzel +Reviewed-by: Xiao Ni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/md.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -640,6 +640,12 @@ static void __mddev_put(struct mddev *md + return; + + /* ++ * If array is freed by stopping array, MD_DELETED is set by ++ * do_md_stop(), MD_DELETED is still set here in case mddev is freed ++ * directly by closing a mddev that is created by create_on_open. ++ */ ++ set_bit(MD_DELETED, &mddev->flags); ++ /* + * Call queue_work inside the spinlock so that flush_workqueue() after + * mddev_find will succeed in waiting for the work to be done. + */ diff --git a/queue-6.6/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch b/queue-6.6/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch new file mode 100644 index 0000000000..9bd2d7dd9e --- /dev/null +++ b/queue-6.6/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch @@ -0,0 +1,104 @@ +From 61399e0c5410567ef60cb1cda34cca42903842e3 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Fri, 8 Aug 2025 19:03:22 +0200 +Subject: rcu: Fix racy re-initialization of irq_work causing hangs + +From: Frederic Weisbecker + +commit 61399e0c5410567ef60cb1cda34cca42903842e3 upstream. + +RCU re-initializes the deferred QS irq work everytime before attempting +to queue it. However there are situations where the irq work is +attempted to be queued even though it is already queued. In that case +re-initializing messes-up with the irq work queue that is about to be +handled. + +The chances for that to happen are higher when the architecture doesn't +support self-IPIs and irq work are then all lazy, such as with the +following sequence: + +1) rcu_read_unlock() is called when IRQs are disabled and there is a + grace period involving blocked tasks on the node. The irq work + is then initialized and queued. + +2) The related tasks are unblocked and the CPU quiescent state + is reported. rdp->defer_qs_iw_pending is reset to DEFER_QS_IDLE, + allowing the irq work to be requeued in the future (note the previous + one hasn't fired yet). + +3) A new grace period starts and the node has blocked tasks. + +4) rcu_read_unlock() is called when IRQs are disabled again. The irq work + is re-initialized (but it's queued! and its node is cleared) and + requeued. Which means it's requeued to itself. + +5) The irq work finally fires with the tick. But since it was requeued + to itself, it loops and hangs. + +Fix this with initializing the irq work only once before the CPU boots. + +Fixes: b41642c87716 ("rcu: Fix rcu_read_unlock() deadloop due to IRQ work") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202508071303.c1134cce-lkp@intel.com +Signed-off-by: Frederic Weisbecker +Reviewed-by: Joel Fernandes +Signed-off-by: Neeraj Upadhyay (AMD) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/rcu/tree.c | 2 ++ + kernel/rcu/tree.h | 1 + + kernel/rcu/tree_plugin.h | 8 ++++++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -4427,6 +4427,8 @@ int rcutree_prepare_cpu(unsigned int cpu + rdp->rcu_iw_gp_seq = rdp->gp_seq - 1; + trace_rcu_grace_period(rcu_state.name, rdp->gp_seq, TPS("cpuonl")); + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); ++ ++ rcu_preempt_deferred_qs_init(rdp); + rcu_spawn_one_boost_kthread(rnp); + rcu_spawn_cpu_nocb_kthread(cpu); + WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus + 1); +--- a/kernel/rcu/tree.h ++++ b/kernel/rcu/tree.h +@@ -463,6 +463,7 @@ static int rcu_print_task_exp_stall(stru + static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); + static void rcu_flavor_sched_clock_irq(int user); + static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck); ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp); + static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); + static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); + static bool rcu_is_callbacks_kthread(struct rcu_data *rdp); +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -687,8 +687,6 @@ static void rcu_read_unlock_special(stru + cpu_online(rdp->cpu)) { + // Get scheduler to re-evaluate and call hooks. + // If !IRQ_WORK, FQS scan will eventually IPI. +- rdp->defer_qs_iw = +- IRQ_WORK_INIT_HARD(rcu_preempt_deferred_qs_handler); + rdp->defer_qs_iw_pending = DEFER_QS_PENDING; + irq_work_queue_on(&rdp->defer_qs_iw, rdp->cpu); + } +@@ -828,6 +826,10 @@ dump_blkd_tasks(struct rcu_node *rnp, in + } + } + ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp) ++{ ++ rdp->defer_qs_iw = IRQ_WORK_INIT_HARD(rcu_preempt_deferred_qs_handler); ++} + #else /* #ifdef CONFIG_PREEMPT_RCU */ + + /* +@@ -1027,6 +1029,8 @@ dump_blkd_tasks(struct rcu_node *rnp, in + WARN_ON_ONCE(!list_empty(&rnp->blkd_tasks)); + } + ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp) { } ++ + #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ + + /* diff --git a/queue-6.6/series b/queue-6.6/series index c492e2e164..b4f04d03e9 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -329,3 +329,5 @@ tools-nolibc-fix-spelling-of-fd_setbitmask-in-fd_-macros.patch rdma-siw-fix-the-sendmsg-byte-count-in-siw_tcp_sendpages.patch hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch +md-fix-create-on-open-mddev-lifetime-regression.patch +rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch