[PATCH v4 3/5] sched/debug: Protect lockless p->mm access in sched_show_numa()
From: Aaron Tomlin
Date: Sun Aug 09 2026 - 21:59:46 EST
In sched_show_numa(), p->mm is checked locklessly and then passed to the
P(mm->numa_scan_seq) macro. This results in a double-evaluation of p->mm.
If the task exits concurrently via exit_mm(p) between the check and the
macro expansion, p->mm can be set to NULL on another CPU. The second
evaluation then dereferences a NULL pointer.
Fix this TOCTOU race by reading p->mm once into a local variable using
READ_ONCE(p->mm) before checking and dereferencing its numa_scan_seq
field.
Fixes: b32e86b4301e ("sched/numa: Add debugging")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxxx>
---
kernel/sched/debug.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index c3409166a288..f5494e02f600 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -1317,8 +1317,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
- if (p->mm)
- P(mm->numa_scan_seq);
+ struct mm_struct *mm = READ_ONCE(p->mm);
+
+ if (mm)
+ __PS("mm->numa_scan_seq", mm->numa_scan_seq);
P(numa_pages_migrated);
P(numa_preferred_nid);
--
2.55.0