Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pidfd: improve uapi when task isn't found

We currently report EINVAL whenever a struct pid has no tasked attached
anymore thereby conflating two concepts:

(1) The task has already been reaped.
(2) The caller requested a pidfd for a thread-group leader but the pid
actually references a struct pid that isn't used as a thread-group
leader.

This is causing issues for non-threaded workloads as in [1].

This patch tries to allow userspace to distinguish between (1) and (2).
This is racy of course but that shouldn't matter.

Link: https://github.com/systemd/systemd/pull/36982 [1]
Link: https://lore.kernel.org/r/20250403-work-pidfd-fixes-v1-3-a123b6ed6716@kernel.org
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

+20 -3
+20 -3
kernel/fork.c
··· 2108 2108 */ 2109 2109 int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret) 2110 2110 { 2111 - bool thread = flags & PIDFD_THREAD; 2111 + int err = 0; 2112 2112 2113 - if (!pid_has_task(pid, thread ? PIDTYPE_PID : PIDTYPE_TGID)) 2114 - return -EINVAL; 2113 + if (!(flags & PIDFD_THREAD)) { 2114 + /* 2115 + * If this is struct pid isn't used as a thread-group 2116 + * leader pid but the caller requested to create a 2117 + * thread-group leader pidfd then report ENOENT to the 2118 + * caller as a hint. 2119 + */ 2120 + if (!pid_has_task(pid, PIDTYPE_TGID)) 2121 + err = -ENOENT; 2122 + } 2123 + 2124 + /* 2125 + * If this wasn't a thread-group leader struct pid or the task 2126 + * got reaped in the meantime report -ESRCH to userspace. 2127 + */ 2128 + if (!pid_has_task(pid, PIDTYPE_PID)) 2129 + err = -ESRCH; 2130 + if (err) 2131 + return err; 2115 2132 2116 2133 return __pidfd_prepare(pid, flags, ret); 2117 2134 }