All of lore.kernel.org
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Christoph Hellwig <hch@lst.de>
Cc: akpm@linux-foundation.org, mcgrof@kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] kernel: add a kernel_wait helper
Date: Tue, 21 Jul 2020 08:35:00 -0500	[thread overview]
Message-ID: <87eep5ng8r.fsf@x220.int.ebiederm.org> (raw)
In-Reply-To: <20200721130449.5008-1-hch@lst.de> (Christoph Hellwig's message of "Tue, 21 Jul 2020 15:04:49 +0200")

Christoph Hellwig <hch@lst.de> writes:

> Add a helper that waits for a pid and stores the status in the passed
> in kernel pointer.  Use it to fix the usage of kernel_wait4 in
> call_usermodehelper_exec_sync that only happens to work due to the
> implicit set_fs(KERNEL_DS) for kernel threads.

Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  include/linux/sched/task.h |  1 +
>  kernel/exit.c              | 16 ++++++++++++++++
>  kernel/umh.c               | 29 ++++-------------------------
>  3 files changed, 21 insertions(+), 25 deletions(-)
>
> diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
> index 38359071236ad7..a80007df396e95 100644
> --- a/include/linux/sched/task.h
> +++ b/include/linux/sched/task.h
> @@ -102,6 +102,7 @@ struct task_struct *fork_idle(int);
>  struct mm_struct *copy_init_mm(void);
>  extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
>  extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
> +int kernel_wait(pid_t pid, int *stat);
>  
>  extern void free_task(struct task_struct *tsk);
>  
> diff --git a/kernel/exit.c b/kernel/exit.c
> index 727150f2810338..fd598846df0b17 100644
> --- a/kernel/exit.c
> +++ b/kernel/exit.c
> @@ -1626,6 +1626,22 @@ long kernel_wait4(pid_t upid, int __user *stat_addr, int options,
>  	return ret;
>  }
>  
> +int kernel_wait(pid_t pid, int *stat)
> +{
> +	struct wait_opts wo = {
> +		.wo_type	= PIDTYPE_PID,
> +		.wo_pid		= find_get_pid(pid),
> +		.wo_flags	= WEXITED,
> +	};
> +	int ret;
> +
> +	ret = do_wait(&wo);
> +	if (ret > 0 && wo.wo_stat)
> +		*stat = wo.wo_stat;
> +	put_pid(wo.wo_pid);
> +	return ret;
> +}
> +
>  SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
>  		int, options, struct rusage __user *, ru)
>  {
> diff --git a/kernel/umh.c b/kernel/umh.c
> index 79f139a7ca03c6..733430921f47d7 100644
> --- a/kernel/umh.c
> +++ b/kernel/umh.c
> @@ -130,37 +130,16 @@ static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info)
>  {
>  	pid_t pid;
>  
> -	/* If SIGCLD is ignored kernel_wait4 won't populate the status. */
> +	/* If SIGCLD is ignored do_wait won't populate the status. */
>  	kernel_sigaction(SIGCHLD, SIG_DFL);
>  	pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD);
> -	if (pid < 0) {
> +	if (pid < 0)
>  		sub_info->retval = pid;
> -	} else {
> -		int ret = -ECHILD;
> -		/*
> -		 * Normally it is bogus to call wait4() from in-kernel because
> -		 * wait4() wants to write the exit code to a userspace address.
> -		 * But call_usermodehelper_exec_sync() always runs as kernel
> -		 * thread (workqueue) and put_user() to a kernel address works
> -		 * OK for kernel threads, due to their having an mm_segment_t
> -		 * which spans the entire address space.
> -		 *
> -		 * Thus the __user pointer cast is valid here.
> -		 */
> -		kernel_wait4(pid, (int __user *)&ret, 0, NULL);
> -
> -		/*
> -		 * If ret is 0, either call_usermodehelper_exec_async failed and
> -		 * the real error code is already in sub_info->retval or
> -		 * sub_info->retval is 0 anyway, so don't mess with it then.
> -		 */
> -		if (ret)
> -			sub_info->retval = ret;
> -	}
> +	else
> +		kernel_wait(pid, &sub_info->retval);
>  
>  	/* Restore default kernel sig handler */
>  	kernel_sigaction(SIGCHLD, SIG_IGN);
> -
>  	umh_complete(sub_info);
>  }

  reply	other threads:[~2020-07-21 13:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-21 13:04 [PATCH] kernel: add a kernel_wait helper Christoph Hellwig
2020-07-21 13:35 ` Eric W. Biederman [this message]
2020-07-21 21:18 ` Andrew Morton
2020-07-22  6:10   ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87eep5ng8r.fsf@x220.int.ebiederm.org \
    --to=ebiederm@xmission.com \
    --cc=akpm@linux-foundation.org \
    --cc=hch@lst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mcgrof@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.