public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
@ 2019-03-30  2:12 Jann Horn
  2019-03-30  2:17 ` Christian Brauner
  2019-04-08 13:13 ` Oleg Nesterov
  0 siblings, 2 replies; 8+ messages in thread
From: Jann Horn @ 2019-03-30  2:12 UTC (permalink / raw)
  To: Christian Brauner, jannh
  Cc: Oleg Nesterov, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

The current sys_pidfd_send_signal() silently turns signals with explicit
SI_USER context that are sent to non-current tasks into signals with
kernel-generated siginfo.
This is unlike do_rt_sigqueueinfo(), which returns -EPERM in this case.
If a user actually wants to send a signal with kernel-provided siginfo,
they can do that with pidfd_send_signal(pidfd, sig, NULL, 0); so allowing
this case is unnecessary.

Instead of silently replacing the siginfo, just bail out with an error;
this is consistent with other interfaces and avoids special-casing behavior
based on security checks.

Fixes: 3eb39f47934f ("signal: add pidfd_send_signal() syscall")
Signed-off-by: Jann Horn <jannh@google.com>
---
 kernel/signal.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index b7953934aa99..f98448cf2def 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3605,16 +3605,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
 		if (unlikely(sig != kinfo.si_signo))
 			goto err;
 
+		/* Only allow sending arbitrary signals to yourself. */
+		ret = -EPERM;
 		if ((task_pid(current) != pid) &&
-		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) {
-			/* Only allow sending arbitrary signals to yourself. */
-			ret = -EPERM;
-			if (kinfo.si_code != SI_USER)
-				goto err;
-
-			/* Turn this into a regular kill signal. */
-			prepare_kill_siginfo(sig, &kinfo);
-		}
+		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
+			goto err;
 	} else {
 		prepare_kill_siginfo(sig, &kinfo);
 	}
-- 
2.21.0.392.gf8f6787159e-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-03-30  2:12 [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd Jann Horn
@ 2019-03-30  2:17 ` Christian Brauner
  2019-04-08 13:13 ` Oleg Nesterov
  1 sibling, 0 replies; 8+ messages in thread
From: Christian Brauner @ 2019-03-30  2:17 UTC (permalink / raw)
  To: Jann Horn
  Cc: Oleg Nesterov, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On Sat, Mar 30, 2019 at 03:12:32AM +0100, Jann Horn wrote:
> The current sys_pidfd_send_signal() silently turns signals with explicit
> SI_USER context that are sent to non-current tasks into signals with
> kernel-generated siginfo.
> This is unlike do_rt_sigqueueinfo(), which returns -EPERM in this case.
> If a user actually wants to send a signal with kernel-provided siginfo,
> they can do that with pidfd_send_signal(pidfd, sig, NULL, 0); so allowing
> this case is unnecessary.
> 
> Instead of silently replacing the siginfo, just bail out with an error;
> this is consistent with other interfaces and avoids special-casing behavior
> based on security checks.
> 
> Fixes: 3eb39f47934f ("signal: add pidfd_send_signal() syscall")
> Signed-off-by: Jann Horn <jannh@google.com>

Reviewed-by: Christian Brauner <christian@brauner.io>

As discussed in
https://lore.kernel.org/lkml/20190330012229.yt3hecmgaj2r6vp7@brauner.io
targeting this for a 5.1 rc.

> ---
>  kernel/signal.c | 13 ++++---------
>  1 file changed, 4 insertions(+), 9 deletions(-)
> 
> diff --git a/kernel/signal.c b/kernel/signal.c
> index b7953934aa99..f98448cf2def 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -3605,16 +3605,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
>  		if (unlikely(sig != kinfo.si_signo))
>  			goto err;
>  
> +		/* Only allow sending arbitrary signals to yourself. */
> +		ret = -EPERM;
>  		if ((task_pid(current) != pid) &&
> -		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) {
> -			/* Only allow sending arbitrary signals to yourself. */
> -			ret = -EPERM;
> -			if (kinfo.si_code != SI_USER)
> -				goto err;
> -
> -			/* Turn this into a regular kill signal. */
> -			prepare_kill_siginfo(sig, &kinfo);
> -		}
> +		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
> +			goto err;
>  	} else {
>  		prepare_kill_siginfo(sig, &kinfo);
>  	}
> -- 
> 2.21.0.392.gf8f6787159e-goog
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-03-30  2:12 [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd Jann Horn
  2019-03-30  2:17 ` Christian Brauner
@ 2019-04-08 13:13 ` Oleg Nesterov
  2019-04-17 13:03   ` Christian Brauner
  1 sibling, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2019-04-08 13:13 UTC (permalink / raw)
  To: Jann Horn
  Cc: Christian Brauner, Eric W. Biederman, Arnd Bergmann,
	Thomas Gleixner, linux-kernel

On 03/30, Jann Horn wrote:
>
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -3605,16 +3605,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
>  		if (unlikely(sig != kinfo.si_signo))
>  			goto err;
>
> +		/* Only allow sending arbitrary signals to yourself. */
> +		ret = -EPERM;
>  		if ((task_pid(current) != pid) &&
> -		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) {
> -			/* Only allow sending arbitrary signals to yourself. */
> -			ret = -EPERM;
> -			if (kinfo.si_code != SI_USER)
> -				goto err;
> -
> -			/* Turn this into a regular kill signal. */
> -			prepare_kill_siginfo(sig, &kinfo);
> -		}
> +		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
> +			goto err;

ACK.


but perhaps it should always fail, even if task_pid(current) == pid.

sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
for checkpoint/restart.

Oleg.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-04-08 13:13 ` Oleg Nesterov
@ 2019-04-17 13:03   ` Christian Brauner
  2019-04-17 13:16     ` Oleg Nesterov
  0 siblings, 1 reply; 8+ messages in thread
From: Christian Brauner @ 2019-04-17 13:03 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Jann Horn, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On Mon, Apr 08, 2019 at 03:13:16PM +0200, Oleg Nesterov wrote:
> On 03/30, Jann Horn wrote:
> >
> > --- a/kernel/signal.c
> > +++ b/kernel/signal.c
> > @@ -3605,16 +3605,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
> >  		if (unlikely(sig != kinfo.si_signo))
> >  			goto err;
> >
> > +		/* Only allow sending arbitrary signals to yourself. */
> > +		ret = -EPERM;
> >  		if ((task_pid(current) != pid) &&
> > -		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) {
> > -			/* Only allow sending arbitrary signals to yourself. */
> > -			ret = -EPERM;
> > -			if (kinfo.si_code != SI_USER)
> > -				goto err;
> > -
> > -			/* Turn this into a regular kill signal. */
> > -			prepare_kill_siginfo(sig, &kinfo);
> > -		}
> > +		    (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
> > +			goto err;
> 
> ACK.
> 

Sorry Oleg. I missed that message somehow.
> 
> but perhaps it should always fail, even if task_pid(current) == pid.
> 
> sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
> for checkpoint/restart.

Yes, that's why this was added. I would leave it in exactly because of
checkpoint/restart. I have sympathies for "this [...] project by various
mad Russians" [1] and it doesn't really hurt us. :)

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=099469502f62fbe0d7e4f0b83a2f22538367f734

Christian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-04-17 13:03   ` Christian Brauner
@ 2019-04-17 13:16     ` Oleg Nesterov
  2019-04-17 13:19       ` Christian Brauner
  0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2019-04-17 13:16 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Jann Horn, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On 04/17, Christian Brauner wrote:
>
> On Mon, Apr 08, 2019 at 03:13:16PM +0200, Oleg Nesterov wrote:
> >
> > but perhaps it should always fail, even if task_pid(current) == pid.
> >
> > sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
> > for checkpoint/restart.
>
> Yes, that's why this was added. I would leave it in exactly because of
> checkpoint/restart.

I don't understand...

c/r doesn't need this "feature" in pidfd_send_signal(), so it can be removed.
But,

> I have sympathies for "this [...] project by various
> mad Russians" [1] and it doesn't really hurt us. :)

I won't argue, I agree it doesn't hurt and looks consistent with sys_rt_sigqueueinfo.

Oleg.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-04-17 13:16     ` Oleg Nesterov
@ 2019-04-17 13:19       ` Christian Brauner
  2019-04-17 13:50         ` Oleg Nesterov
  0 siblings, 1 reply; 8+ messages in thread
From: Christian Brauner @ 2019-04-17 13:19 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Jann Horn, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On Wed, Apr 17, 2019 at 03:16:03PM +0200, Oleg Nesterov wrote:
> On 04/17, Christian Brauner wrote:
> >
> > On Mon, Apr 08, 2019 at 03:13:16PM +0200, Oleg Nesterov wrote:
> > >
> > > but perhaps it should always fail, even if task_pid(current) == pid.
> > >
> > > sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
> > > for checkpoint/restart.
> >
> > Yes, that's why this was added. I would leave it in exactly because of
> > checkpoint/restart.
> 
> I don't understand...
> 
> c/r doesn't need this "feature" in pidfd_send_signal(), so it can be removed.
> But,

Just out of curiosity: in what sense? They don't need it since they have
other ways of doing this or they *can't* use it for some other reason
I'm not seeing?

Christian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-04-17 13:19       ` Christian Brauner
@ 2019-04-17 13:50         ` Oleg Nesterov
  2019-04-17 14:13           ` Christian Brauner
  0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2019-04-17 13:50 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Jann Horn, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On 04/17, Christian Brauner wrote:
>
> On Wed, Apr 17, 2019 at 03:16:03PM +0200, Oleg Nesterov wrote:
> > On 04/17, Christian Brauner wrote:
> > >
> > > On Mon, Apr 08, 2019 at 03:13:16PM +0200, Oleg Nesterov wrote:
> > > >
> > > > but perhaps it should always fail, even if task_pid(current) == pid.
> > > >
> > > > sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
> > > > for checkpoint/restart.
> > >
> > > Yes, that's why this was added. I would leave it in exactly because of
> > > checkpoint/restart.
> >
> > I don't understand...
> >
> > c/r doesn't need this "feature" in pidfd_send_signal(), so it can be removed.
> > But,
>
> Just out of curiosity: in what sense? They don't need it since they have
> other ways of doing this

Yes. The restarting process needs to "restore" the pending signals, including the
signals with si_code >= 0. It does this using tgsigqueueinfo() and that is why we
allow this if the signal sent to itself.

So criu simply doesn't need pidfd_send_signal() to do this. And at the same time,

> or they *can't* use it for some other reason

Yes again. pidfd_send_signal() does kill_pid_info(), so it can't be used to restore
the "per-thread" task->pending signals.

Oleg.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd
  2019-04-17 13:50         ` Oleg Nesterov
@ 2019-04-17 14:13           ` Christian Brauner
  0 siblings, 0 replies; 8+ messages in thread
From: Christian Brauner @ 2019-04-17 14:13 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Jann Horn, Eric W. Biederman, Arnd Bergmann, Thomas Gleixner,
	linux-kernel

On Wed, Apr 17, 2019 at 03:50:03PM +0200, Oleg Nesterov wrote:
> On 04/17, Christian Brauner wrote:
> >
> > On Wed, Apr 17, 2019 at 03:16:03PM +0200, Oleg Nesterov wrote:
> > > On 04/17, Christian Brauner wrote:
> > > >
> > > > On Mon, Apr 08, 2019 at 03:13:16PM +0200, Oleg Nesterov wrote:
> > > > >
> > > > > but perhaps it should always fail, even if task_pid(current) == pid.
> > > > >
> > > > > sys_rt_sigqueueinfo() allows to send any siginfo to yourself, but this is only needed
> > > > > for checkpoint/restart.
> > > >
> > > > Yes, that's why this was added. I would leave it in exactly because of
> > > > checkpoint/restart.
> > >
> > > I don't understand...
> > >
> > > c/r doesn't need this "feature" in pidfd_send_signal(), so it can be removed.
> > > But,
> >
> > Just out of curiosity: in what sense? They don't need it since they have
> > other ways of doing this
> 
> Yes. The restarting process needs to "restore" the pending signals, including the
> signals with si_code >= 0. It does this using tgsigqueueinfo() and that is why we
> allow this if the signal sent to itself.
> 
> So criu simply doesn't need pidfd_send_signal() to do this. And at the same time,
> 
> > or they *can't* use it for some other reason
> 
> Yes again. pidfd_send_signal() does kill_pid_info(), so it can't be used to restore
> the "per-thread" task->pending signals.

In the future pidfd_send_signal() will gain the flag
PIDFD_SIGNAL_THREAD. Jann and I already have a patch for this but we're
holding off until the need arises.

Christian

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-04-17 14:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-03-30  2:12 [PATCH] signal: don't silently convert SI_USER signals to non-current pidfd Jann Horn
2019-03-30  2:17 ` Christian Brauner
2019-04-08 13:13 ` Oleg Nesterov
2019-04-17 13:03   ` Christian Brauner
2019-04-17 13:16     ` Oleg Nesterov
2019-04-17 13:19       ` Christian Brauner
2019-04-17 13:50         ` Oleg Nesterov
2019-04-17 14:13           ` Christian Brauner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox