linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
@ 2016-02-21 23:01 Stas Sergeev
  2016-02-25  8:25 ` Ingo Molnar
  0 siblings, 1 reply; 9+ messages in thread
From: Stas Sergeev @ 2016-02-21 23:01 UTC (permalink / raw)
  Cc: Stas Sergeev, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Borislav Petkov, Brian Gerst,
	Oleg Nesterov, Richard Weinberger, Stas Sergeev

Currently x86's get_sigframe() checks for "current->sas_ss_size"
to determine whether there is a need to switch to sigaltstack.
The common practice used by all other arches is to check for
sas_ss_flags(sp) == 0

This patch makes the code consistent with other arches.
The slight complexity of the patch is added by the optimization on
!sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
already implies that we are not on a sigstack, so the code is shuffled
to avoid the duplicate checking.

CC: linux-kernel@vger.kernel.org
CC: Andy Lutomirski <luto@amacapital.net>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
CC: "H. Peter Anvin" <hpa@zytor.com>
CC: x86@kernel.org
CC: Borislav Petkov <bp@suse.de>
CC: Brian Gerst <brgerst@gmail.com>
CC: Oleg Nesterov <oleg@redhat.com>
CC: Richard Weinberger <richard@nod.at>

Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
---
 arch/x86/kernel/signal.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index cb6282c..285183b 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -213,18 +213,17 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
 	if (config_enabled(CONFIG_X86_64))
 		sp -= 128;
 
-	if (!onsigstack) {
-		/* This is the X/Open sanctioned signal stack switching.  */
-		if (ka->sa.sa_flags & SA_ONSTACK) {
-			if (current->sas_ss_size)
-				sp = current->sas_ss_sp + current->sas_ss_size;
-		} else if (config_enabled(CONFIG_X86_32) &&
-			   (regs->ss & 0xffff) != __USER_DS &&
-			   !(ka->sa.sa_flags & SA_RESTORER) &&
-			   ka->sa.sa_restorer) {
-				/* This is the legacy signal stack switching. */
-				sp = (unsigned long) ka->sa.sa_restorer;
-		}
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (sas_ss_flags(sp) == 0)
+			sp = current->sas_ss_sp + current->sas_ss_size;
+	} else if (config_enabled(CONFIG_X86_32) &&
+		   !onsigstack &&
+		   (regs->ss & 0xffff) != __USER_DS &&
+		   !(ka->sa.sa_flags & SA_RESTORER) &&
+		   ka->sa.sa_restorer) {
+		/* This is the legacy signal stack switching. */
+		sp = (unsigned long) ka->sa.sa_restorer;
 	}
 
 	if (fpu->fpstate_active) {
-- 
2.5.0

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-02-21 23:01 [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches Stas Sergeev
@ 2016-02-25  8:25 ` Ingo Molnar
  2016-02-25 12:14   ` Stas Sergeev
  0 siblings, 1 reply; 9+ messages in thread
From: Ingo Molnar @ 2016-02-25  8:25 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev


* Stas Sergeev <stsp@list.ru> wrote:

> Currently x86's get_sigframe() checks for "current->sas_ss_size"
> to determine whether there is a need to switch to sigaltstack.
> The common practice used by all other arches is to check for
> sas_ss_flags(sp) == 0
> 
> This patch makes the code consistent with other arches.
> The slight complexity of the patch is added by the optimization on
> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
> already implies that we are not on a sigstack, so the code is shuffled
> to avoid the duplicate checking.

So this changelog is missing an analysis about what effect this change will have 
on applications. Can any type of user-space code see a change in behavior? If yes, 
what will happen and is that effect desirable?

Thanks,

	Ingo

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-02-25  8:25 ` Ingo Molnar
@ 2016-02-25 12:14   ` Stas Sergeev
  2016-03-08 16:20     ` Ingo Molnar
  0 siblings, 1 reply; 9+ messages in thread
From: Stas Sergeev @ 2016-02-25 12:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev

25.02.2016 11:25, Ingo Molnar пишет:
> 
> * Stas Sergeev <stsp@list.ru> wrote:
> 
>> Currently x86's get_sigframe() checks for "current->sas_ss_size"
>> to determine whether there is a need to switch to sigaltstack.
>> The common practice used by all other arches is to check for
>> sas_ss_flags(sp) == 0
>>
>> This patch makes the code consistent with other arches.
>> The slight complexity of the patch is added by the optimization on
>> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
>> already implies that we are not on a sigstack, so the code is shuffled
>> to avoid the duplicate checking.
> 
> So this changelog is missing an analysis about what effect this change will have 
> on applications. Can any type of user-space code see a change in behavior? If yes, 
> what will happen and is that effect desirable?
This is a clean-up, and as such, there is no visible effect.
If there is - it is a bug.
The purpose of this patch is only to unify the x86 code with
what all the other arches do. It was initially the part of the
rejected series, but now it is just a clean-up.

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-02-25 12:14   ` Stas Sergeev
@ 2016-03-08 16:20     ` Ingo Molnar
  2016-03-08 16:55       ` Stas Sergeev
  2016-03-10  0:02       ` Andy Lutomirski
  0 siblings, 2 replies; 9+ messages in thread
From: Ingo Molnar @ 2016-03-08 16:20 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev


* Stas Sergeev <stsp@list.ru> wrote:

> 25.02.2016 11:25, Ingo Molnar пишет:
> > 
> > * Stas Sergeev <stsp@list.ru> wrote:
> > 
> >> Currently x86's get_sigframe() checks for "current->sas_ss_size"
> >> to determine whether there is a need to switch to sigaltstack.
> >> The common practice used by all other arches is to check for
> >> sas_ss_flags(sp) == 0
> >>
> >> This patch makes the code consistent with other arches.
> >> The slight complexity of the patch is added by the optimization on
> >> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
> >> already implies that we are not on a sigstack, so the code is shuffled
> >> to avoid the duplicate checking.
> > 
> > So this changelog is missing an analysis about what effect this change will have 
> > on applications. Can any type of user-space code see a change in behavior? If yes, 
> > what will happen and is that effect desirable?
> This is a clean-up, and as such, there is no visible effect.
> If there is - it is a bug.
> The purpose of this patch is only to unify the x86 code with
> what all the other arches do. It was initially the part of the
> rejected series, but now it is just a clean-up.

Ok, so AFAICS the relevant change is:

-               if (current->sas_ss_size)
-                       sp = current->sas_ss_sp + current->sas_ss_size;
+               if (sas_ss_flags(sp) == 0)
+                       sp = current->sas_ss_sp + current->sas_ss_size;

and since sas_ss_flags() is defined as:

static inline int sas_ss_flags(unsigned long sp)
{
        if (!current->sas_ss_size)
                return SS_DISABLE;

        return on_sig_stack(sp) ? SS_ONSTACK : 0;
}

sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().

But we already have on_sig_stack(sp) calculated. Why not write that as:

+               if (current->sas_ss_size && !onsigstack)
+                       sp = current->sas_ss_sp + current->sas_ss_size;

and since we check '!onsigstack' in both branches, we might as well factor it out 
into a single condition ... and arrive to the exact code that we began with.

So what happened is that every other arch has a non-optimal version of this 
function.

And if you look at the x86-32 defconfig build size difference:

   text    data     bss     dec     hex filename
   4155       0       0    4155    103b signal.o.before
   4299       0       0    4299    10cb signal.o.after

i.e. your patch increases the generated code size. So I don't see the upside.

If this is really duplicated across architectures then we should perhaps try to 
factor out this check into kernel/signal.c or so, and share it between 
architectures more seriously?

Thanks,

	Ingo

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-03-08 16:20     ` Ingo Molnar
@ 2016-03-08 16:55       ` Stas Sergeev
  2016-03-10  0:02       ` Andy Lutomirski
  1 sibling, 0 replies; 9+ messages in thread
From: Stas Sergeev @ 2016-03-08 16:55 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev

08.03.2016 19:20, Ingo Molnar пишет:
> * Stas Sergeev <stsp@list.ru> wrote:
>
>> 25.02.2016 11:25, Ingo Molnar пишет:
>>> * Stas Sergeev <stsp@list.ru> wrote:
>>>
>>>> Currently x86's get_sigframe() checks for "current->sas_ss_size"
>>>> to determine whether there is a need to switch to sigaltstack.
>>>> The common practice used by all other arches is to check for
>>>> sas_ss_flags(sp) == 0
>>>>
>>>> This patch makes the code consistent with other arches.
>>>> The slight complexity of the patch is added by the optimization on
>>>> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
>>>> already implies that we are not on a sigstack, so the code is shuffled
>>>> to avoid the duplicate checking.
>>> So this changelog is missing an analysis about what effect this change will have
>>> on applications. Can any type of user-space code see a change in behavior? If yes,
>>> what will happen and is that effect desirable?
>> This is a clean-up, and as such, there is no visible effect.
>> If there is - it is a bug.
>> The purpose of this patch is only to unify the x86 code with
>> what all the other arches do. It was initially the part of the
>> rejected series, but now it is just a clean-up.
> Ok, so AFAICS the relevant change is:
>
> -               if (current->sas_ss_size)
> -                       sp = current->sas_ss_sp + current->sas_ss_size;
> +               if (sas_ss_flags(sp) == 0)
> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>
> and since sas_ss_flags() is defined as:
>
> static inline int sas_ss_flags(unsigned long sp)
> {
>          if (!current->sas_ss_size)
>                  return SS_DISABLE;
>
>          return on_sig_stack(sp) ? SS_ONSTACK : 0;
> }
>
> sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().
>
> But we already have on_sig_stack(sp) calculated. Why not write that as:
>
> +               if (current->sas_ss_size && !onsigstack)
> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>
> and since we check '!onsigstack' in both branches, we might as well factor it out
> into a single condition ... and arrive to the exact code that we began with.
>
> So what happened is that every other arch has a non-optimal version of this
> function.
>
> And if you look at the x86-32 defconfig build size difference:
>
>     text    data     bss     dec     hex filename
>     4155       0       0    4155    103b signal.o.before
>     4299       0       0    4299    10cb signal.o.after
>
> i.e. your patch increases the generated code size. So I don't see the upside.
144 bytes increase?
The upside is to use the common functions, shared across
the arches, rather than making an assumptions on what that
function does, and inlining it.

> If this is really duplicated across architectures then we should perhaps try to
> factor out this check into kernel/signal.c or so, and share it between
> architectures more seriously?
IMHO you are trying to do the gcc work here.
It should inline the functions without your help.
Since all the above functions are in the sched.h header
and are marked as "inline", I think gcc has enough
information to not re-evaluate on_sig_stack() twice.
If it hits the memory barrier and does not trust the
previous value of on_sig_stack(), then perhaps you can
simply move the line "onsigstack = on_sig_stack();" right
before the SA_ONSTACK check. In this case I hope gcc
will be able to emit "if (current->sas_ss_size && !onsigstack)".
And if we had the common "if (!onsigstack)" for both branches,
that Andy asked the remove, then gcc perhaps could reduce
the check to just "if (current->sas_ss_size)"as it knows that
on_sig_stack() returns 0 here. Though I don't see any problem
for gcc to move the onsigstack check back, so that it to
cover both branches again.
So just moving the "onsigstack = on_sig_stack();" a few
lines down, should do what you want and generate the
code similar to the old one.

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-03-08 16:20     ` Ingo Molnar
  2016-03-08 16:55       ` Stas Sergeev
@ 2016-03-10  0:02       ` Andy Lutomirski
  2016-03-10 10:26         ` Ingo Molnar
                           ` (2 more replies)
  1 sibling, 3 replies; 9+ messages in thread
From: Andy Lutomirski @ 2016-03-10  0:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Stas Sergeev, linux-kernel, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Borislav Petkov, Brian Gerst,
	Oleg Nesterov, Richard Weinberger, Stas Sergeev

On Tue, Mar 8, 2016 at 8:20 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
> * Stas Sergeev <stsp@list.ru> wrote:
>
>> 25.02.2016 11:25, Ingo Molnar пишет:
>> >
>> > * Stas Sergeev <stsp@list.ru> wrote:
>> >
>> >> Currently x86's get_sigframe() checks for "current->sas_ss_size"
>> >> to determine whether there is a need to switch to sigaltstack.
>> >> The common practice used by all other arches is to check for
>> >> sas_ss_flags(sp) == 0
>> >>
>> >> This patch makes the code consistent with other arches.
>> >> The slight complexity of the patch is added by the optimization on
>> >> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
>> >> already implies that we are not on a sigstack, so the code is shuffled
>> >> to avoid the duplicate checking.
>> >
>> > So this changelog is missing an analysis about what effect this change will have
>> > on applications. Can any type of user-space code see a change in behavior? If yes,
>> > what will happen and is that effect desirable?
>> This is a clean-up, and as such, there is no visible effect.
>> If there is - it is a bug.
>> The purpose of this patch is only to unify the x86 code with
>> what all the other arches do. It was initially the part of the
>> rejected series, but now it is just a clean-up.
>
> Ok, so AFAICS the relevant change is:
>
> -               if (current->sas_ss_size)
> -                       sp = current->sas_ss_sp + current->sas_ss_size;
> +               if (sas_ss_flags(sp) == 0)
> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>
> and since sas_ss_flags() is defined as:
>
> static inline int sas_ss_flags(unsigned long sp)
> {
>         if (!current->sas_ss_size)
>                 return SS_DISABLE;
>
>         return on_sig_stack(sp) ? SS_ONSTACK : 0;
> }
>
> sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().
>
> But we already have on_sig_stack(sp) calculated. Why not write that as:
>
> +               if (current->sas_ss_size && !onsigstack)
> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>
> and since we check '!onsigstack' in both branches, we might as well factor it out
> into a single condition ... and arrive to the exact code that we began with.

ISTM it's silly for us to be unconditionally computing onsigstack.
We're doing it because we need it later for this:

        /*
         * If we are on the alternate signal stack and would overflow it, don't.
         * Return an always-bogus address instead so we will die with SIGSEGV.
         */
        if (onsigstack && !likely(on_sig_stack(sp)))
                return (void __user *)-1L;

This seems basically useless to me.  Sure, it's nice to send SIGSEGV
if we overflow due to signal delivery.  But we're almost as likely to
overflow in the signal handler as we are to overflow during delivery,
and we don't even try to catch that.

Anyway, I think we should make two changes to the sig_on_stack thing:

1. If SS_AUTODISARM, then we're not on the stack, regardless of what sp says.

2. If !user_64bit_mode(regs) && (regs->ss & 0x4), then we're not on
the signal stack.  This will happen if we're running on an LDT stack
and we coincidentally have the ESP part of SS:ESP matching the signal
stack.

In general, the existing design is crap and it should always have
worked the way that Stas is proposing with SS_AUTODISARM.

--Andy

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-03-10  0:02       ` Andy Lutomirski
@ 2016-03-10 10:26         ` Ingo Molnar
  2016-03-10 12:08         ` Stas Sergeev
  2016-04-13 22:11         ` Stas Sergeev
  2 siblings, 0 replies; 9+ messages in thread
From: Ingo Molnar @ 2016-03-10 10:26 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Stas Sergeev, linux-kernel, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Borislav Petkov, Brian Gerst,
	Oleg Nesterov, Richard Weinberger, Stas Sergeev


* Andy Lutomirski <luto@amacapital.net> wrote:

> On Tue, Mar 8, 2016 at 8:20 AM, Ingo Molnar <mingo@kernel.org> wrote:
> >
> > * Stas Sergeev <stsp@list.ru> wrote:
> >
> >> 25.02.2016 11:25, Ingo Molnar пишет:
> >> >
> >> > * Stas Sergeev <stsp@list.ru> wrote:
> >> >
> >> >> Currently x86's get_sigframe() checks for "current->sas_ss_size"
> >> >> to determine whether there is a need to switch to sigaltstack.
> >> >> The common practice used by all other arches is to check for
> >> >> sas_ss_flags(sp) == 0
> >> >>
> >> >> This patch makes the code consistent with other arches.
> >> >> The slight complexity of the patch is added by the optimization on
> >> >> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
> >> >> already implies that we are not on a sigstack, so the code is shuffled
> >> >> to avoid the duplicate checking.
> >> >
> >> > So this changelog is missing an analysis about what effect this change will have
> >> > on applications. Can any type of user-space code see a change in behavior? If yes,
> >> > what will happen and is that effect desirable?
> >> This is a clean-up, and as such, there is no visible effect.
> >> If there is - it is a bug.
> >> The purpose of this patch is only to unify the x86 code with
> >> what all the other arches do. It was initially the part of the
> >> rejected series, but now it is just a clean-up.
> >
> > Ok, so AFAICS the relevant change is:
> >
> > -               if (current->sas_ss_size)
> > -                       sp = current->sas_ss_sp + current->sas_ss_size;
> > +               if (sas_ss_flags(sp) == 0)
> > +                       sp = current->sas_ss_sp + current->sas_ss_size;
> >
> > and since sas_ss_flags() is defined as:
> >
> > static inline int sas_ss_flags(unsigned long sp)
> > {
> >         if (!current->sas_ss_size)
> >                 return SS_DISABLE;
> >
> >         return on_sig_stack(sp) ? SS_ONSTACK : 0;
> > }
> >
> > sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().
> >
> > But we already have on_sig_stack(sp) calculated. Why not write that as:
> >
> > +               if (current->sas_ss_size && !onsigstack)
> > +                       sp = current->sas_ss_sp + current->sas_ss_size;
> >
> > and since we check '!onsigstack' in both branches, we might as well factor it out
> > into a single condition ... and arrive to the exact code that we began with.
> 
> ISTM it's silly for us to be unconditionally computing onsigstack.
> We're doing it because we need it later for this:
> 
>         /*
>          * If we are on the alternate signal stack and would overflow it, don't.
>          * Return an always-bogus address instead so we will die with SIGSEGV.
>          */
>         if (onsigstack && !likely(on_sig_stack(sp)))
>                 return (void __user *)-1L;
> 
> This seems basically useless to me.  Sure, it's nice to send SIGSEGV
> if we overflow due to signal delivery.  But we're almost as likely to
> overflow in the signal handler as we are to overflow during delivery,
> and we don't even try to catch that.

Ok, I was just put off by the code size difference - but no strong opinion from 
me, I'd certainly be fine with (as a first step) harmonizing the implementation 
with other architectures. I withdraw my objection.

> Anyway, I think we should make two changes to the sig_on_stack thing:
> 
> 1. If SS_AUTODISARM, then we're not on the stack, regardless of what sp says.
> 
> 2. If !user_64bit_mode(regs) && (regs->ss & 0x4), then we're not on
> the signal stack.  This will happen if we're running on an LDT stack
> and we coincidentally have the ESP part of SS:ESP matching the signal
> stack.
> 
> In general, the existing design is crap and it should always have
> worked the way that Stas is proposing with SS_AUTODISARM.

Ok, no objections here either.

Thanks,

	Ingo

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-03-10  0:02       ` Andy Lutomirski
  2016-03-10 10:26         ` Ingo Molnar
@ 2016-03-10 12:08         ` Stas Sergeev
  2016-04-13 22:11         ` Stas Sergeev
  2 siblings, 0 replies; 9+ messages in thread
From: Stas Sergeev @ 2016-03-10 12:08 UTC (permalink / raw)
  To: Andy Lutomirski, Ingo Molnar
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	X86 ML, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev

10.03.2016 03:02, Andy Lutomirski пишет:
> On Tue, Mar 8, 2016 at 8:20 AM, Ingo Molnar <mingo@kernel.org> wrote:
>>
>> * Stas Sergeev <stsp@list.ru> wrote:
>>
>>> 25.02.2016 11:25, Ingo Molnar пишет:
>>>>
>>>> * Stas Sergeev <stsp@list.ru> wrote:
>>>>
>>>>> Currently x86's get_sigframe() checks for "current->sas_ss_size"
>>>>> to determine whether there is a need to switch to sigaltstack.
>>>>> The common practice used by all other arches is to check for
>>>>> sas_ss_flags(sp) == 0
>>>>>
>>>>> This patch makes the code consistent with other arches.
>>>>> The slight complexity of the patch is added by the optimization on
>>>>> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
>>>>> already implies that we are not on a sigstack, so the code is shuffled
>>>>> to avoid the duplicate checking.
>>>>
>>>> So this changelog is missing an analysis about what effect this change will have
>>>> on applications. Can any type of user-space code see a change in behavior? If yes,
>>>> what will happen and is that effect desirable?
>>> This is a clean-up, and as such, there is no visible effect.
>>> If there is - it is a bug.
>>> The purpose of this patch is only to unify the x86 code with
>>> what all the other arches do. It was initially the part of the
>>> rejected series, but now it is just a clean-up.
>>
>> Ok, so AFAICS the relevant change is:
>>
>> -               if (current->sas_ss_size)
>> -                       sp = current->sas_ss_sp + current->sas_ss_size;
>> +               if (sas_ss_flags(sp) == 0)
>> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>>
>> and since sas_ss_flags() is defined as:
>>
>> static inline int sas_ss_flags(unsigned long sp)
>> {
>>         if (!current->sas_ss_size)
>>                 return SS_DISABLE;
>>
>>         return on_sig_stack(sp) ? SS_ONSTACK : 0;
>> }
>>
>> sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().
>>
>> But we already have on_sig_stack(sp) calculated. Why not write that as:
>>
>> +               if (current->sas_ss_size && !onsigstack)
>> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>>
>> and since we check '!onsigstack' in both branches, we might as well factor it out
>> into a single condition ... and arrive to the exact code that we began with.
> 
> ISTM it's silly for us to be unconditionally computing onsigstack.
> We're doing it because we need it later for this:
> 
>         /*
>          * If we are on the alternate signal stack and would overflow it, don't.
>          * Return an always-bogus address instead so we will die with SIGSEGV.
>          */
>         if (onsigstack && !likely(on_sig_stack(sp)))
>                 return (void __user *)-1L;
But there is also the SA_RESTORER check that needs this as well:

} else if (config_enabled(CONFIG_X86_32) &&
   !onsigstack &&
   (regs->ss & 0xffff) != __USER_DS &&
   !(ka->sa.sa_flags & SA_RESTORER) &&
   ka->sa.sa_restorer) {
		/* This is the legacy signal stack switching. */
		sp = (unsigned long) ka->sa.sa_restorer;

So I don't think you can that easily get rid of calling
on_sig_stack(), but definitely we can structure the code
so that gcc can better optimize it.

> Anyway, I think we should make two changes to the sig_on_stack thing:
> 
> 1. If SS_AUTODISARM, then we're not on the stack, regardless of what sp says.
I think Ingo replied to the stand-alone cleanup I sent a month
ago. Now I have also included it in an SS_AUTODISARM series, and
that led to confusion... Sorry about that.
But I think the above is not correct: if SS_AUTODISARM is used,
we should still look into sp, or sa_restorer will not work.
And in fact, someone could even call sigaltstack(SS_ONSTACK|SS_AUTODISARM)
inside the sighandler itself! In this case we still have to look
into sp as we did before.
So I don't think the optimization you suggest above, can work.

> 2. If !user_64bit_mode(regs) && (regs->ss & 0x4), then we're not on
> the signal stack.  This will happen if we're running on an LDT stack
> and we coincidentally have the ESP part of SS:ESP matching the signal
> stack.
Yes, but let me please do that later. :)
If I start merging also that into an existing series, we'll never
get any progress. So can we just get applied at least something? :)

> In general, the existing design is crap and it should always have
> worked the way that Stas is proposing with SS_AUTODISARM.
But how would you then return oss->ss_flags to user?
I think returning oss->ss_flags to user requires the current
design, and by specifying SS_AUTODISARM, the user accepts the
fact that oss->ss_flags is no longer reliable (never returns SS_ONSTACK).

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

* Re: [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches
  2016-03-10  0:02       ` Andy Lutomirski
  2016-03-10 10:26         ` Ingo Molnar
  2016-03-10 12:08         ` Stas Sergeev
@ 2016-04-13 22:11         ` Stas Sergeev
  2 siblings, 0 replies; 9+ messages in thread
From: Stas Sergeev @ 2016-04-13 22:11 UTC (permalink / raw)
  To: Andy Lutomirski, Ingo Molnar
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	X86 ML, Borislav Petkov, Brian Gerst, Oleg Nesterov,
	Richard Weinberger, Stas Sergeev

10.03.2016 03:02, Andy Lutomirski пишет:
> On Tue, Mar 8, 2016 at 8:20 AM, Ingo Molnar <mingo@kernel.org> wrote:
>> * Stas Sergeev <stsp@list.ru> wrote:
>>
>>> 25.02.2016 11:25, Ingo Molnar пишет:
>>>> * Stas Sergeev <stsp@list.ru> wrote:
>>>>
>>>>> Currently x86's get_sigframe() checks for "current->sas_ss_size"
>>>>> to determine whether there is a need to switch to sigaltstack.
>>>>> The common practice used by all other arches is to check for
>>>>> sas_ss_flags(sp) == 0
>>>>>
>>>>> This patch makes the code consistent with other arches.
>>>>> The slight complexity of the patch is added by the optimization on
>>>>> !sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
>>>>> already implies that we are not on a sigstack, so the code is shuffled
>>>>> to avoid the duplicate checking.
>>>> So this changelog is missing an analysis about what effect this change will have
>>>> on applications. Can any type of user-space code see a change in behavior? If yes,
>>>> what will happen and is that effect desirable?
>>> This is a clean-up, and as such, there is no visible effect.
>>> If there is - it is a bug.
>>> The purpose of this patch is only to unify the x86 code with
>>> what all the other arches do. It was initially the part of the
>>> rejected series, but now it is just a clean-up.
>> Ok, so AFAICS the relevant change is:
>>
>> -               if (current->sas_ss_size)
>> -                       sp = current->sas_ss_sp + current->sas_ss_size;
>> +               if (sas_ss_flags(sp) == 0)
>> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>>
>> and since sas_ss_flags() is defined as:
>>
>> static inline int sas_ss_flags(unsigned long sp)
>> {
>>          if (!current->sas_ss_size)
>>                  return SS_DISABLE;
>>
>>          return on_sig_stack(sp) ? SS_ONSTACK : 0;
>> }
>>
>> sas_ss_flags() returns 0 iff current->sas_ss_size && !on_sig_stack().
>>
>> But we already have on_sig_stack(sp) calculated. Why not write that as:
>>
>> +               if (current->sas_ss_size && !onsigstack)
>> +                       sp = current->sas_ss_sp + current->sas_ss_size;
>>
>> and since we check '!onsigstack' in both branches, we might as well factor it out
>> into a single condition ... and arrive to the exact code that we began with.
> ISTM it's silly for us to be unconditionally computing onsigstack.
> We're doing it because we need it later for this:
>
>          /*
>           * If we are on the alternate signal stack and would overflow it, don't.
>           * Return an always-bogus address instead so we will die with SIGSEGV.
>           */
>          if (onsigstack && !likely(on_sig_stack(sp)))
>                  return (void __user *)-1L;
>
> This seems basically useless to me.  Sure, it's nice to send SIGSEGV
> if we overflow due to signal delivery.  But we're almost as likely to
> overflow in the signal handler as we are to overflow during delivery,
> and we don't even try to catch that.
>
> Anyway, I think we should make two changes to the sig_on_stack thing:
>
> 1. If SS_AUTODISARM, then we're not on the stack, regardless of what sp says.
>
> 2. If !user_64bit_mode(regs) && (regs->ss & 0x4), then we're not on
> the signal stack.  This will happen if we're running on an LDT stack
> and we coincidentally have the ESP part of SS:ESP matching the signal
> stack.
>
> In general, the existing design is crap and it should always have
> worked the way that Stas is proposing with SS_AUTODISARM.
Andy, so can I use your Acked-by to this patch?
I think 2 is an entirely separate problem and can be implemented
later. Do you have any objections to the patch in its current form?
Do you think that 1 should be implemented, or can we agree that
it is not possible/unsafe? Please, state your optinion explicitly, because
I am completely puzzled with why this patch cannot be applied.

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

end of thread, other threads:[~2016-04-13 21:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-21 23:01 [PATCH] [Cleanup] x86: signal: unify the sigaltstack check with other arches Stas Sergeev
2016-02-25  8:25 ` Ingo Molnar
2016-02-25 12:14   ` Stas Sergeev
2016-03-08 16:20     ` Ingo Molnar
2016-03-08 16:55       ` Stas Sergeev
2016-03-10  0:02       ` Andy Lutomirski
2016-03-10 10:26         ` Ingo Molnar
2016-03-10 12:08         ` Stas Sergeev
2016-04-13 22:11         ` Stas Sergeev

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).