Thread (42 messages) 42 messages, 6 authors, 19d ago

Re: [PATCH RFC v3 03/13] rcu-tasks: Add a Tasks RCU implementation for reader-marked trampolines

flat view

From: sashiko-bot@kernel.org
Date: 2026-09-15 13:29:20
Also in: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] rcu-tasks: Use-after-free in trampolines executed by the idle task
--

commit 4dc15eb660eecbf1c68e4f2d97dcdde7b8456c35
Author: Josef Bacik [off-list ref]

    rcu-tasks: Add a Tasks RCU implementation for reader-marked trampolines

    Tasks RCU waits for every task to pass through a voluntary context switch,
    usermode or idle, because a preempted task might be sitting in a trampoline
    that is about to be freed and nothing marks it as such. This adds a new
    Tasks RCU implementation for architectures that make their trampolines Tasks
    Trace RCU readers.
quoted hunk ↗ jump to hunk
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index e4acd50bd81a1..94318519998c8 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -141,8 +142,13 @@ void raw_irqentry_exit_cond_resched(struct pt_regs *regs)
 		rcu_irq_exit_check_preempt();
 		if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
 			WARN_ON_ONCE(!on_thread_stack());
-		if (need_resched() && arch_irqentry_exit_need_resched())
+		if (need_resched() && arch_irqentry_exit_need_resched()) {
+			if (IS_ENABLED(CONFIG_TASKS_RCU_TRAMPOLINE_READERS))
+				rcu_tasks_irq_resched_enter(instruction_pointer(regs));
[Severity: High]
Does this logic leave the idle task off the holdout list if it is
interrupted while executing trampoline text?

If an IRQ interrupts the idle task (for example, while executing a traced
function before entering an RCU extended quiescent state) and enters the
trampoline's unmarked preamble, but does not wake any new tasks,
need_resched() will be false.

Because need_resched() is false, raw_irqentry_exit_cond_resched() will not
call rcu_tasks_irq_resched_enter(), meaning the idle task is never added to
the holdout list.
quoted hunk ↗ jump to hunk
 			preempt_schedule_irq();
+			if (IS_ENABLED(CONFIG_TASKS_RCU_TRAMPOLINE_READERS))
+				rcu_tasks_irq_resched_exit();
+		}
 	}
 }
[ ... ]
quoted hunk ↗ jump to hunk
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
index 627295396cd91..3a7c092361a66 100644
--- a/kernel/rcu/tasks.h
+++ b/kernel/rcu/tasks.h
[ ... ]
quoted hunk ↗ jump to hunk
+/* Has @cpu passed a quiescent event since the snapshot, or need it not? */
+static bool rcu_tasks_cpu_quiescent(int cpu)
+{
+	if (!cpu_online(cpu))
+		return true;
+	/* Pairs with the release in rcu_tasks_qs_event(). */
+	if (smp_load_acquire(per_cpu_ptr(&rcu_tasks_qs_seq, cpu)) !=
+	    per_cpu(rcu_tasks_qs_snap, cpu))
+		return true;
+	/*
+	 * Idle or nohz_full userspace (an RCU extended quiescent state): no
+	 * task-level kernel frames there, and whatever ran before has switched
+	 * out.  As with the classic flavor, the idle task itself is not waited
+	 * for.
+	 */
+	if (!(ct_rcu_watching_cpu(cpu) & CT_RCU_WATCHING))
+		return true;
+	return idle_cpu(cpu);
+}
[Severity: High]
Could the unconditional return of idle_cpu() lead to a use-after-free crash
if the idle task was interrupted in trampoline code?

Since the idle task wasn't added to the holdout list during IRQ exit
(because need_resched() was false in raw_irqentry_exit_cond_resched()), the
grace period thread relies entirely on rcu_tasks_cpu_quiescent().

Because idle_cpu(cpu) returns true, the QS sequence check for the idle task
is bypassed. The GP thread will assume the CPU has passed a quiescent state,
complete the grace period, and free the trampoline memory.

When the IRQ returns, the idle task will resume execution in the now-freed
trampoline memory, which can lead to a kernel panic.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260915-b4-rcu-tasks-preempt-qs-v3-0-0ad30c4c5ee7@toxicpanda.com?part=3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help