Commit 9014143b authored by Dmitry V. Levin's avatar Dmitry V. Levin Committed by Christian Brauner

fork: don't check parent_tidptr with CLONE_PIDFD

Give userspace a cheap and reliable way to tell whether CLONE_PIDFD is
supported by the kernel or not. The easiest way is to pass an invalid
file descriptor value in parent_tidptr, perform the syscall and verify
that parent_tidptr has been changed to a valid file descriptor value.

CLONE_PIDFD uses parent_tidptr to return pidfds. CLONE_PARENT_SETTID
will use parent_tidptr to return the tid of the parent. The two flags
cannot be used together. Old kernels that only support
CLONE_PARENT_SETTID will not verify the value pointed to by
parent_tidptr. This behavior is unchanged even with the introduction of
CLONE_PIDFD.
However, if CLONE_PIDFD is specified the kernel will currently check the
value pointed to by parent_tidptr before placing the pidfd in the memory
pointed to. EINVAL will be returned if the value in parent_tidptr is not
0.

If CLONE_PIDFD is supported and fd 0 is closed, then the returned pidfd
can and likely will be 0 and parent_tidptr will be unchanged. This means
userspace must either check CLONE_PIDFD support beforehand or check that
fd 0 is not closed when invoking CLONE_PIDFD.

The check for pidfd == 0 was introduced during the v5.2 merge window by
commit b3e58382 ("clone: add CLONE_PIDFD") to ensure that
CLONE_PIDFD could be potentially extended by passing in flags through
the return argument.

However, that extension would look horrible, and with the upcoming
introduction of the clone3 syscall in v5.3 there is no need to extend
legacy clone syscall this way. (Even if it would need to be extended,
CLONE_DETACHED can be reused with CLONE_PIDFD.)

So remove the pidfd == 0 check. Userspace that needs to be portable to
kernels without CLONE_PIDFD support can then be advised to initialize
pidfd to -1 and check the pidfd value returned by CLONE_PIDFD.

Fixes: b3e58382 ("clone: add CLONE_PIDFD")
Signed-off-by: default avatarDmitry V. Levin <ldv@altlinux.org>
Signed-off-by: default avatarChristian Brauner <christian@brauner.io>
parent 4b972a01
...@@ -1822,8 +1822,6 @@ static __latent_entropy struct task_struct *copy_process( ...@@ -1822,8 +1822,6 @@ static __latent_entropy struct task_struct *copy_process(
} }
if (clone_flags & CLONE_PIDFD) { if (clone_flags & CLONE_PIDFD) {
int reserved;
/* /*
* - CLONE_PARENT_SETTID is useless for pidfds and also * - CLONE_PARENT_SETTID is useless for pidfds and also
* parent_tidptr is used to return pidfds. * parent_tidptr is used to return pidfds.
...@@ -1834,16 +1832,6 @@ static __latent_entropy struct task_struct *copy_process( ...@@ -1834,16 +1832,6 @@ static __latent_entropy struct task_struct *copy_process(
if (clone_flags & if (clone_flags &
(CLONE_DETACHED | CLONE_PARENT_SETTID | CLONE_THREAD)) (CLONE_DETACHED | CLONE_PARENT_SETTID | CLONE_THREAD))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/*
* Verify that parent_tidptr is sane so we can potentially
* reuse it later.
*/
if (get_user(reserved, parent_tidptr))
return ERR_PTR(-EFAULT);
if (reserved != 0)
return ERR_PTR(-EINVAL);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment