pidfd: clone: allow CLONE_THREAD | CLONE_PIDFD together

copy_process() just needs to pass PIDFD_THREAD to __pidfd_prepare()
if clone_flags & CLONE_THREAD.

We can also add another CLONE_ flag (or perhaps reuse CLONE_DETACHED)
to enforce PIDFD_THREAD without CLONE_THREAD.

Originally-from: Tycho Andersen <tycho@tycho.pizza>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/20240205145532.GA28823@redhat.com
Reviewed-by: Tycho Andersen <tandersen@netflix.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Oleg Nesterov 2024-02-05 15:55:32 +01:00 committed by Christian Brauner
parent e2e8a142fb
commit 83b290c9e3
1 changed files with 4 additions and 3 deletions

View File

@ -2311,9 +2311,8 @@ __latent_entropy struct task_struct *copy_process(
/*
* - CLONE_DETACHED is blocked so that we can potentially
* reuse it later for CLONE_PIDFD.
* - CLONE_THREAD is blocked until someone really needs it.
*/
if (clone_flags & (CLONE_DETACHED | CLONE_THREAD))
if (clone_flags & CLONE_DETACHED)
return ERR_PTR(-EINVAL);
}
@ -2536,8 +2535,10 @@ __latent_entropy struct task_struct *copy_process(
* if the fd table isn't shared).
*/
if (clone_flags & CLONE_PIDFD) {
int flags = (clone_flags & CLONE_THREAD) ? PIDFD_THREAD : 0;
/* Note that no task has been attached to @pid yet. */
retval = __pidfd_prepare(pid, 0, &pidfile);
retval = __pidfd_prepare(pid, flags, &pidfile);
if (retval < 0)
goto bad_fork_free_pid;
pidfd = retval;