linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Joel Fernandes <joel@joelfernandes.org>
To: Daniel Colascione <dancol@google.com>
Cc: linux-kernel@vger.kernel.org, timmurray@google.com,
	joelaf@google.com, surenb@google.com, cyphar@cyphar.com,
	christian.brauner@canonical.com, ebiederm@xmission.com,
	keescook@chromium.org, oleg@redhat.com
Subject: Re: [PATCH v2] Implement /proc/pid/kill
Date: Wed, 31 Oct 2018 08:05:48 -0700	[thread overview]
Message-ID: <20181031150548.GA103404@joelaf.mtv.corp.google.com> (raw)
In-Reply-To: <20181031143744.77677-1-dancol@google.com>

On Wed, Oct 31, 2018 at 02:37:44PM +0000, Daniel Colascione wrote:
> Add a simple proc-based kill interface. To use /proc/pid/kill, just
> write the signal number in base-10 ASCII to the kill file of the
> process to be killed: for example, 'echo 9 > /proc/$$/kill'.
> 
> Semantically, /proc/pid/kill works like kill(2), except that the
> process ID comes from the proc filesystem context instead of from an
> explicit system call parameter. This way, it's possible to avoid races
> between inspecting some aspect of a process and that process's PID
> being reused for some other process.
> 
> Note that only the real user ID that opened a /proc/pid/kill file can
> write to it; other users get EPERM.  This check prevents confused
> deputy attacks via, e.g., standard output of setuid programs.
> 
> With /proc/pid/kill, it's possible to write a proper race-free and
> safe pkill(1). An approximation follows. A real program might use
> openat(2), having opened a process's /proc/pid directory explicitly,
> with the directory file descriptor serving as a sort of "process
> handle".
> 
>     #!/bin/bash
>     set -euo pipefail
>     pat=$1
>     for proc_status in /proc/*/status; do (
>         cd $(dirname $proc_status)
>         readarray proc_argv -d'' < cmdline
>         if ((${#proc_argv[@]} > 0)) &&
>                [[ ${proc_argv[0]} = *$pat* ]];
>         then
>             echo 15 > kill
>         fi
>     ) || true; done
> 
> Signed-off-by: Daniel Colascione <dancol@google.com>
> ---
> 
> Added a real-user-ID check to prevent confused deputy attacks.
> 
>  fs/proc/base.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 7e9f07bf260d..74e494f24b28 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -205,6 +205,56 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
>  	return result;
>  }
>  
> +static ssize_t proc_pid_kill_write(struct file *file,
> +				   const char __user *buf,
> +				   size_t count, loff_t *ppos)
> +{
> +	ssize_t res;
> +	int sig;
> +	char buffer[4];
> +
> +	/* This check prevents a confused deputy attack in which an
> +	 * unprivileged process opens /proc/victim/kill and convinces
> +	 * a privileged process to write to that kill FD, effectively
> +	 * performing a kill with the privileges of the unwitting
> +	 * privileged process.  Here, we just fail the kill operation
> +	 * if someone calls write(2) with a real user ID that differs
> +	 * from the one used to open the kill FD.
> +	 */
> +	res = -EPERM;
> +	if (file->f_cred->user != current_user())
> +		goto out;

nit: You could get rid of the out label and just do direct returns. Will save
a few lines and is more readable.

> +
> +	res = -EINVAL;
> +	if (*ppos != 0)
> +		goto out;
> +
> +	res = -EINVAL;
> +	if (count > sizeof(buffer) - 1)
> +		goto out;
> +
> +	res = -EFAULT;
> +	if (copy_from_user(buffer, buf, count))
> +		goto out;
> +
> +	buffer[count] = '\0';

I think you can just zero-initialize buffer with "= {};" and get rid of this line.

> +	res = kstrtoint(strstrip(buffer), 10, &sig);
> +	if (res)
> +		goto out;


> +
> +	res = kill_pid(proc_pid(file_inode(file)), sig, 0);
> +	if (res)
> +		goto out;

if (res)
	return res;

Other than the security issues which I still think you're discussing, since
we need this, I suggest to maintainers we take this in as an intermediate
solution since we don't have anything close to it and this is a real issue,
and the fix proposed is simple.  So FWIW feel free to add my reviewed-by
(with the above nits and security issues taken care off) on any future
respins:

Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>

thanks,

- Joel


  reply	other threads:[~2018-10-31 15:05 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-29 22:10 [RFC PATCH] Implement /proc/pid/kill Daniel Colascione
2018-10-30  3:21 ` Joel Fernandes
2018-10-30  8:50   ` Daniel Colascione
2018-10-30 10:39     ` Christian Brauner
2018-10-30 10:40       ` Christian Brauner
2018-10-30 10:48         ` Daniel Colascione
2018-10-30 11:04           ` Christian Brauner
2018-10-30 11:12             ` Daniel Colascione
2018-10-30 11:19               ` Christian Brauner
2018-10-31  5:00                 ` Eric W. Biederman
2018-10-30 17:01     ` Joel Fernandes
2018-10-30  5:00 ` Aleksa Sarai
2018-10-30  9:05   ` Daniel Colascione
2018-10-30 20:45     ` Aleksa Sarai
2018-10-30 21:42       ` Joel Fernandes
2018-10-30 22:23         ` Aleksa Sarai
2018-10-30 22:33           ` Joel Fernandes
2018-10-30 22:49             ` Aleksa Sarai
2018-10-31  0:42               ` Joel Fernandes
2018-10-31  1:59                 ` Daniel Colascione
2018-10-30 23:10             ` Daniel Colascione
2018-10-30 23:23               ` Christian Brauner
2018-10-30 23:55                 ` Daniel Colascione
2018-10-31  2:56                 ` Aleksa Sarai
2018-10-31  4:24                   ` Joel Fernandes
2018-11-01 20:40                     ` Joel Fernandes
2018-11-02  9:46                       ` Christian Brauner
2018-11-02 14:34                         ` Serge E. Hallyn
2018-10-31  0:57               ` Joel Fernandes
2018-10-31  1:56                 ` Daniel Colascione
2018-10-31  4:47   ` Eric W. Biederman
2018-10-31  4:44 ` Eric W. Biederman
2018-10-31 12:44   ` Oleg Nesterov
2018-10-31 13:27     ` Daniel Colascione
2018-10-31 15:10       ` Oleg Nesterov
2018-10-31 15:16         ` Daniel Colascione
2018-10-31 15:49           ` Oleg Nesterov
2018-11-01 11:53       ` David Laight
2018-11-01 15:50         ` Daniel Colascione
2018-10-31 14:37 ` [PATCH v2] " Daniel Colascione
2018-10-31 15:05   ` Joel Fernandes [this message]
2018-10-31 17:33     ` Aleksa Sarai
2018-10-31 21:47       ` Joel Fernandes
2018-10-31 15:59 ` [PATCH v3] " Daniel Colascione
2018-10-31 17:54   ` Tycho Andersen
2018-10-31 18:00     ` Daniel Colascione
2018-10-31 18:17       ` Tycho Andersen
2018-10-31 19:33         ` Daniel Colascione
2018-10-31 20:06           ` Tycho Andersen
2018-11-01 11:33           ` David Laight
2018-11-12  1:19             ` Eric W. Biederman
2018-10-31 16:22 ` [RFC PATCH] " Jann Horn
2018-11-01  4:53   ` Andy Lutomirski
2018-11-12 23:13 ` Pavel Machek

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=20181031150548.GA103404@joelaf.mtv.corp.google.com \
    --to=joel@joelfernandes.org \
    --cc=christian.brauner@canonical.com \
    --cc=cyphar@cyphar.com \
    --cc=dancol@google.com \
    --cc=ebiederm@xmission.com \
    --cc=joelaf@google.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=surenb@google.com \
    --cc=timmurray@google.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).