mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jamie Iles <jamie.iles@oracle.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Jamie Iles <jamie.iles@oracle.com>,
	linux-kernel@vger.kernel.org,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH] signal: protect SIGNAL_UNKILLABLE from unintentional clearing.
Date: Tue, 29 Nov 2016 14:23:53 +0000	[thread overview]
Message-ID: <20161129142353.ew2l4yn66ehdfupd@cedar> (raw)
In-Reply-To: <20161129140600.GB9654@redhat.com>

Hi Oleg,

On Tue, Nov 29, 2016 at 03:06:00PM +0100, Oleg Nesterov wrote:
> Jamie,
> 
> I am really sorry for the huge delay.

No problem!

> On 11/16, Jamie Iles wrote:
> >
> > Since 00cd5c37af (ptrace: permit ptracing of /sbin/init) we can now
> > trace init processes.  init is initially protected with
> > SIGNAL_UNKILLABLE which will prevent fatal signals such as SIGSTOP, but
> > there are a number of paths during tracing where SIGNAL_UNKILLABLE can
> > be implicitly cleared.
> 
> Yes, old problem which nobody bothered to fix ;) Thanks for doing this.
> To remind, there are more problems with SIGNAL_UNKILLABLE, but this
> patch looks like a good start to me.
> 
> However, I would like to ask you to make V2, see below.
> 
> > +static inline void signal_set_flags(struct signal_struct *sig,
> > +				    unsigned int flags)
> > +{
> > +	sig->flags = (sig->flags & SIGNAL_PROTECTED_MASK) | flags;
> > +}
> 
> OK, agreed, probably the helper makes sense, but I think it is overused
> in this patch, please see below. In short, I'd suggest to use it only in
> the jctl code, at least for now.
> 
> > +static inline void signal_clear_flags(struct signal_struct *sig,
> > +				      unsigned int flags)
> > +{
> > +	sig->flags &= (~flags | SIGNAL_PROTECTED_MASK);
> > +}
> 
> But this one looks pointless.

Well the intent was to have set/clear helpers and *always* use those so 
that it's clear when SIGNAL_UNKILLABLE is being intentionally cleared.  
At the moment there are sites where it is cleared intentionally, and 
others as a consequence of direct assignment.

> > --- a/kernel/exit.c
> > +++ b/kernel/exit.c
> > @@ -922,7 +922,7 @@ do_group_exit(int exit_code)
> >  			exit_code = sig->group_exit_code;
> >  		else {
> >  			sig->group_exit_code = exit_code;
> > -			sig->flags = SIGNAL_GROUP_EXIT;
> > +			signal_set_flags(sig, SIGNAL_GROUP_EXIT);
> 
> Well. I am not sure about this change. SIGNAL_GROUP_EXIT is the terminal
> state, it is fine to clear UNKILLABLE.
> 
> Yes, perhaps this actually makes sense, and we want to make UNKILLABLE
> immutable, but then we need to change force_sig_info() too, at least.
> And btw it should be changed anyway, in particular UNKILLABLE can be
> wrongly cleared if the task is traced. But I'd prefer to do this later.
> 
> The same for the similar changes in zap_process(), coredump_finish(),
> and complete_signal().

Okay.

> > @@ -922,7 +922,7 @@ static void complete_signal(int sig, struct 
> > task_struct *p, int group)
> >  			 * running and doing things after a slower
> >  			 * thread has the fatal signal pending.
> >  			 */
> > -			signal->flags = SIGNAL_GROUP_EXIT;
> > +			signal_set_flags(signal, SIGNAL_GROUP_EXIT);
> 
> Again, I'd prefer to just set SIGNAL_GROUP_EXIT, like in do_group_exit().
> Note also that SIGNAL_UNKILLABLE can't be set in this case, see the check
> above, so this change has no effect. And at the same time this code needs
> the changes too, this SIGNAL_UNKILLABLE check is not 100% correct, but this
> is off-topic.
> 
> So I think it would be better to start with the minimal change which fixes
> task_participate_group_stop() and prepare_signal() only. And while I won't
> insist, perhaps we should add
> 
> 	#define SIGNAL_STOP_MASK (SIGNAL_CLD_MASK | SIGNAL_STOP_STOPPED | SIGNAL_STOP_CONTINUED)
> 
> 	signal_set_stop_flags(signal, flags)
> 	{
> 		signal->flags = (signal->flags & ~SIGNAL_STOP_MASK) | flags;
> 	}
> 
> instead of signal_set_flags(). This way we can, say, add
> WARN_ON(signal->flags & (SIGNAL_GROUP_EXIT|SIGNAL_GROUP_COREDUMP)) into this helper.
> Then later we can add signal_set_exit_flags() which manipulates
> GROUP_EXIT/COREDUMP/UNKILLABLE.
> 
> Not sure, up to you.

Right, so part of the challenge was figuring out where SIGNAL_UNKILLABLE 
should be cleared, and where it shouldn't.  So is making it an explicit 
boolean in a bitfield a better approach?  That way we can continue to 
manipulate flags as required and then explicitly clear SIGNAL_UNKILLABLE 
when it needs to be cleared?  SIGNAL_UKILLABLE feels like enough of a 
corner case that it has easy potential for regression in the future if 
signal_struct::flags is assigned to.

Thanks,

Jamie

  reply	other threads:[~2016-11-29 14:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-16 12:57 Jamie Iles
2016-11-17 19:04 ` Oleg Nesterov
2016-11-28 12:14   ` Jamie Iles
2016-11-29 14:06 ` Oleg Nesterov
2016-11-29 14:23   ` Jamie Iles [this message]
2016-12-01 17:45     ` Oleg Nesterov

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=20161129142353.ew2l4yn66ehdfupd@cedar \
    --to=jamie.iles@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=viro@zeniv.linux.org.uk \
    /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

Powered by JetHome