Re: Fw: Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

Previous thread: [PATCH][for -mm] per-zone and reclaim enhancements for memory controller take 3 [0/10] introduction by KAMEZAWA Hiroyuki on Monday, November 26, 2007 - 10:55 pm. (20 messages)

Next thread: Dynticks Causing High Context Switch Rate in ksoftirqd by bdupree on Monday, November 26, 2007 - 10:36 pm. (3 messages)
To: Ingo Molnar <mingo@...>
Cc: Andrew Morton <akpm@...>, Thomas Gleixner <tglx@...>, Ulrich Drepper <drepper@...>, <linux-kernel@...>
Date: Monday, November 26, 2007 - 11:02 pm

cf http://lkml.org/lkml/2007/10/3/41

To summarize: on Linux, SA_ONSTACK decides whether you are already on the
signal stack based on the value of the SP at the time of a signal. If
you are not already inside the range, you are not "on the signal stack"
and so the new signal handler frame starts over at the base of the signal
stack.

sigaltstack (and sigstack before it) was invented in BSD. There, the
SA_ONSTACK behavior has always been different. It uses a kernel state
flag to decide, rather than the SP value. When you first take an
SA_ONSTACK signal and switch to the alternate signal stack, it sets the
SS_ONSTACK flag in the thread's sigaltstack state in the kernel.
Thereafter you are "on the signal stack" and don't switch SP before
pushing a handler frame no matter what the SP value is. Only when you
sigreturn from the original handler context do you clear the SS_ONSTACK
flag so that a new handler frame will start over at the base of the
alternate signal stack.

The undesireable effect of the Linux behavior is that an overflow of the
alternate signal stack can not only go undetected, but lead to a ring
buffer effect of clobbering the original handler frame at the base of the
signal stack for each successive signal that comes just after the
overflow. This is what Shi Weihua's test case demonstrates. Normally
this does not come up because of the signal mask, but the test case uses
SA_NODEFER for its SIGSEGV handler.

The other subtle part of the existing Linux semantics is that a simple
longjmp out of a signal handler serves to take you off the signal stack
in a safe and reliable fashion without having used sigreturn (nor having
just returned from the handler normally, which means the same). After
the longjmp (or even informal stack switching not via any proper libc or
kernel interface), the alternate signal stack stands ready to be used
again.

A paranoid program would allocate a PROT_NONE red zone around its
alternate signal stack. Then a small overflow would trigge...

To: Roland McGrath <roland@...>
Cc: Ingo Molnar <mingo@...>, Andrew Morton <akpm@...>, Thomas Gleixner <tglx@...>, Ulrich Drepper <drepper@...>, <linux-kernel@...>
Date: Tuesday, November 27, 2007 - 6:57 pm

On Mon, 26 Nov 2007 19:02:22 -0800 (PST)

we probably should also make sure userspace has at least a little bit
of stack space for itself, say 2Kb or 4Kb, not just "the kernel puts
you right at the edge"....

--
If you want to reach me at my work email, use arjan@linux.intel.com
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
-

To: Roland McGrath <roland@...>
Cc: Andrew Morton <akpm@...>, Thomas Gleixner <tglx@...>, Ulrich Drepper <drepper@...>, <linux-kernel@...>
Date: Tuesday, November 27, 2007 - 6:50 am

* Roland McGrath <roland@redhat.com> wrote:

thanks Roland for the detailed analysis. I've queued up the patch below
in the x86 tree. I suspect we can wait with this for v2.6.25, due to
this being long-standing behavior of Linux? Thus we could observe the
effects of this patch for a longer time.

I'm wondering how widespread sigaltstack use is in general. Googling
around gives:

http://google.com/codesearch?q=sigaltstack

~400 matches. A more common signal API in comparison:

http://google.com/codesearch?q=sigaction

gives ~139,000 matches. So i guess the right approach would be to also
extend LTP's sigaltstack tests to cover whatever new desired behavior -
so that we at least have a minimal chance of catching obvious breakages
here.

Ingo

--------------->
Subject: x86: protect against sigaltstack wraparound
From: Roland McGrath <roland@redhat.com>

cf http://lkml.org/lkml/2007/10/3/41

To summarize: on Linux, SA_ONSTACK decides whether you are already on the
signal stack based on the value of the SP at the time of a signal. If
you are not already inside the range, you are not "on the signal stack"
and so the new signal handler frame starts over at the base of the signal
stack.

sigaltstack (and sigstack before it) was invented in BSD. There, the
SA_ONSTACK behavior has always been different. It uses a kernel state
flag to decide, rather than the SP value. When you first take an
SA_ONSTACK signal and switch to the alternate signal stack, it sets the
SS_ONSTACK flag in the thread's sigaltstack state in the kernel.
Thereafter you are "on the signal stack" and don't switch SP before
pushing a handler frame no matter what the SP value is. Only when you
sigreturn from the original handler context do you clear the SS_ONSTACK
flag so that a new handler frame will start over at the base of the
alternate signal stack.

The undesireable effect of the Linux behavior is that an overflow of the
alternate signal stack can not only go undetected...

To: Ingo Molnar <mingo@...>
Cc: Andrew Morton <akpm@...>, Thomas Gleixner <tglx@...>, Ulrich Drepper <drepper@...>, <linux-kernel@...>
Date: Tuesday, November 27, 2007 - 7:07 pm

It's certainly nothing new. The failure mode of concern is only for a
buggy program to fail to crash as quickly and gracefully as it might.

Thanks,
Roland
-

Previous thread: [PATCH][for -mm] per-zone and reclaim enhancements for memory controller take 3 [0/10] introduction by KAMEZAWA Hiroyuki on Monday, November 26, 2007 - 10:55 pm. (20 messages)

Next thread: Dynticks Causing High Context Switch Rate in ksoftirqd by bdupree on Monday, November 26, 2007 - 10:36 pm. (3 messages)