]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
io_uring/fdinfo: translate SqThread PID through caller's pid_ns
authorMaoyi Xie <maoyixie.tju@gmail.com>
Sun, 10 May 2026 08:41:19 +0000 (16:41 +0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 11 May 2026 13:44:09 +0000 (07:44 -0600)
SQPOLL stores current->pid (init_pid_ns view) in sqd->task_pid
at thread creation. fdinfo prints it raw via
seq_printf("SqThread:\t%d\n", sq_pid). A reader inside a
non-initial pid_ns sees the host PID, not the kthread's PID in
the reader's own pid_ns.

The SQPOLL kthread is created with CLONE_THREAD and no
CLONE_NEW*, so it lives in the submitter's pid_ns. An
unprivileged user_ns + pid_ns submitter can read fdinfo and
learn the host PID of a kthread whose in-namespace PID is
different.

Reproducer (mainline 7.0, KASAN): unshare CLONE_NEWUSER |
CLONE_NEWPID | CLONE_NEWNS, mount a private /proc, then have a
grandchild that is pid 1 in the new pid_ns open an io_uring
ring with IORING_SETUP_SQPOLL. /proc/self/task lists {1, 2};
the SQPOLL kthread is pid 2. Before: fdinfo prints
SqThread = <host pid>. After: SqThread = 2.

Use task_pid_nr_ns() against the proc inode's pid_ns to compute
sq_pid, instead of reading the stored sq->task_pid (which holds
the init_pid_ns view). pidfd_show_fdinfo() in kernel/pid.c
follows the same pattern.

Signed-off-by: Maoyi Xie <maoyi.xie@ntu.edu.sg>
Link: https://patch.msgid.link/20260510084119.457578-1-maoyi.xie@ntu.edu.sg
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/fdinfo.c

index c2d3e45544bb4ef4e6a3a6cda4393d9563382bc1..001fb542dc11a8a35e78670287f7387d2d744818 100644 (file)
@@ -190,8 +190,9 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
                        get_task_struct(tsk);
                        rcu_read_unlock();
                        usec = io_sq_cpu_usec(tsk);
+                       sq_pid = task_pid_nr_ns(tsk,
+                                               proc_pid_ns(file_inode(m->file)->i_sb));
                        put_task_struct(tsk);
-                       sq_pid = sq->task_pid;
                        sq_cpu = sq->sq_cpu;
                        sq_total_time = usec;
                        sq_work_time = sq->work_time;