Skip to content

Commit

Permalink
fork: don't check parent_tidptr with CLONE_PIDFD
Browse files Browse the repository at this point in the history
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 b3e5838 ("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: b3e5838 ("clone: add CLONE_PIDFD")
Signed-off-by: Dmitry V. Levin <[email protected]>
Signed-off-by: Christian Brauner <[email protected]>
  • Loading branch information
ldv-alt authored and brauner committed Jun 24, 2019
1 parent 4b972a0 commit 9014143
Showing 1 changed file with 0 additions and 12 deletions.
12 changes: 0 additions & 12 deletions kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -1822,8 +1822,6 @@ static __latent_entropy struct task_struct *copy_process(
}

if (clone_flags & CLONE_PIDFD) {
int reserved;

/*
* - CLONE_PARENT_SETTID is useless for pidfds and also
* parent_tidptr is used to return pidfds.
Expand All @@ -1834,16 +1832,6 @@ static __latent_entropy struct task_struct *copy_process(
if (clone_flags &
(CLONE_DETACHED | CLONE_PARENT_SETTID | CLONE_THREAD))
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);
}

/*
Expand Down

0 comments on commit 9014143

Please sign in to comment.