[tip: sched/core] sched/debug: Protect p->mm access in sched_show_numa()

From: tip-bot2 for Aaron Tomlin

Date: Mon Nov 09 2026 - 04:35:38 EST


The following commit has been merged into the sched/core branch of tip:

Commit-ID: 5bb5768ef4680edf119dc7ced1d1faf7fbd0bcc6
Gitweb: https://git.kernel.org/tip/5bb5768ef4680edf119dc7ced1d1faf7fbd0bcc6
Author: Aaron Tomlin <atomlin@xxxxxxxxxxx>
AuthorDate: Fri, 30 Oct 2026 11:13:05 -04:00
Committer: Ingo Molnar <mingo@xxxxxxxxxx>
CommitterDate: Mon, 09 Nov 2026 10:23:57 +01:00

sched/debug: Protect p->mm access in sched_show_numa()

In sched_show_numa(), p->mm is checked locklessly and then passed to the
P(mm->numa_scan_seq) macro. This presents both a time-of-change to
time-of-use race and a potential use-after-free vulnerability.

If a task exits concurrently via exit_mm(p), another CPU can set p->mm
to NULL and call mmput(mm) to free the struct mm_struct. Dereferencing
mm->numa_scan_seq without holding task_lock(p) can access freed memory if
mmput() runs immediately after the check.

Fix this by wrapping the p->mm check and macro dereference in
task_lock(p) and task_unlock(p). In exit_mm(), current->mm is set to
NULL under task_lock(p) before mmput() is called, guaranteeing that
p->mm cannot be set to NULL or freed while task_lock(p) is held.

Fixes: b32e86b4301e ("sched/numa: Add debugging")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxxx>
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
Link: https://patch.msgid.link/20261030151307.768523-5-atomlin@xxxxxxxxxxx
---
kernel/sched/debug.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index be886ed..a22d646 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -1389,8 +1389,10 @@ void print_numa_stats(struct seq_file *m, int node, unsigned long tsf,
static void sched_show_numa(struct task_struct *p, struct seq_file *m)
{
#ifdef CONFIG_NUMA_BALANCING
+ task_lock(p);
if (p->mm)
P(mm->numa_scan_seq);
+ task_unlock(p);

P(numa_pages_migrated);
P(numa_preferred_nid);