Messages in this thread Patch in this message | | | From | Alois Wohlschlager <> | Subject | [PATCH] pid: Allow creation of pidfds to threads | Date | Thu, 31 Mar 2022 21:02:32 +0200 |
| |
The pidfd_open() syscall now allows retrieving pidfds to processes which are not thread group leaders. Like standard pidfds so far, these may be used to retrieve file descriptors from the target thread using pidfd_getfd(), as well as for killing the target thread group using pidfd_send_signal(). However, unlike pidfds referencing thread group leaders, they do not support polling for process exit. Attempts to do so signal an error condition instead of blocking indefinitely.
Since the semantics of pidfd_getfd() and pidfd_send_signal() are not very useful within a thread group, these thread pidfds can only be created using pidfd_open(), not via clone().
Signed-off-by: Alois Wohlschlager <alois1@gmx-topmail.de> --- kernel/fork.c | 3 +++ kernel/pid.c | 15 +++------------ 2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c index f1e89007f228..f98230630a57 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1836,6 +1836,9 @@ static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts) struct pid *pid = file->private_data; __poll_t poll_flags = 0;
+ if (!pid_has_task(pid, PIDTYPE_TGID)) + return EPOLLERR; + poll_wait(file, &pid->wait_pidfd, pts);
/* diff --git a/kernel/pid.c b/kernel/pid.c index 2fc0a16ec77b..6be745c7399c 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -548,11 +548,6 @@ struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags) * Return the task associated with @pidfd. The function takes a reference on * the returned task. The caller is responsible for releasing that reference. * - * Currently, the process identified by @pidfd is always a thread-group leader. - * This restriction currently exists for all aspects of pidfds including pidfd - * creation (CLONE_PIDFD cannot be used with CLONE_THREAD) and pidfd polling - * (only supports thread group leaders). - * * Return: On success, the task_struct associated with the pidfd. * On error, a negative errno number will be returned. */ @@ -566,7 +561,7 @@ struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags) if (IS_ERR(pid)) return ERR_CAST(pid);
- task = get_pid_task(pid, PIDTYPE_TGID); + task = get_pid_task(pid, PIDTYPE_PID); put_pid(pid); if (!task) return ERR_PTR(-ESRCH); @@ -595,7 +590,7 @@ int pidfd_create(struct pid *pid, unsigned int flags) { int fd;
- if (!pid || !pid_has_task(pid, PIDTYPE_TGID)) + if (!pid) return -EINVAL;
if (flags & ~(O_NONBLOCK | O_RDWR | O_CLOEXEC)) @@ -616,11 +611,7 @@ int pidfd_create(struct pid *pid, unsigned int flags) * @flags: flags to pass * * This creates a new pid file descriptor with the O_CLOEXEC flag set for - * the process identified by @pid. Currently, the process identified by - * @pid must be a thread-group leader. This restriction currently exists - * for all aspects of pidfds including pidfd creation (CLONE_PIDFD cannot - * be used with CLONE_THREAD) and pidfd polling (only supports thread group - * leaders). + * the process identified by @pid. * * Return: On success, a cloexec pidfd is returned. * On error, a negative errno number will be returned. -- 2.35.1[unhandled content-type:application/pgp-signature] | |