public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs
@ 2007-10-04 13:08 Mikael Pettersson
  2007-10-05  0:55 ` Shi Weihua
  0 siblings, 1 reply; 20+ messages in thread
From: Mikael Pettersson @ 2007-10-04 13:08 UTC (permalink / raw)
  To: kamezawa.hiroyu, shiwh; +Cc: linux-kernel, mikpe

On Thu, 4 Oct 2007 21:47:30 +0900, KAMEZAWA Hiroyuki wrote:
> On Thu, 04 Oct 2007 21:33:12 +0900
> Shi Weihua <shiwh@cn.fujitsu.com> wrote:
> 
> > KAMEZAWA Hiroyuki wrote::
> > > On Thu, 04 Oct 2007 20:56:14 +0900
> > > Shi Weihua <shiwh@cn.fujitsu.com> wrote:
> > > 
> > >> 	stack.ss_sp = addr + pagesize;
> > >> 	stack.ss_flags = 0;
> > >> 	stack.ss_size = pagesize;
> > > Here is bad. 
> > > stack,ss_sp = addr;
> > > stack.ss_flags = 0;
> > > stack.ss_size = pagesize * 2;
> > [What the test code want to do]
> > addr+pagesize*2 - addr+pagesize	 -> sigaltstack
> > addr+pagesize	- addr		 -> protected region
> > The code want to catch overflow when esp enter the protected region.
> > 
> You have to protect the top of *registered* sigaltstack.
> The reason of wraparound is %esp will be set to the bottom of sigaltstack
> if it is not on sigaltstack area when signaled.
> What you have to do is protect the top of registerd sigaltstack.
> If %esp is in the range of registerd sigaltstack at SEGV, wraparound
> will stop.

Exactly right. You mprotect or munmap the end of the altstack,
not the area beyond it.

/Mikael

^ permalink raw reply	[flat|nested] 20+ messages in thread
[parent not found: <474CF7D5.6010702@cn.fujitsu.com>]
[parent not found: <20071126143317.dd884128.akpm@linux-foundation.org>]
* Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs
@ 2007-10-03 13:46 Mikael Pettersson
  2007-10-03 14:25 ` KAMEZAWA Hiroyuki
  0 siblings, 1 reply; 20+ messages in thread
From: Mikael Pettersson @ 2007-10-03 13:46 UTC (permalink / raw)
  To: kamezawa.hiroyu; +Cc: linux-kernel, mikpe, shiwh

On Wed, 3 Oct 2007 22:20:46 +0900, KAMEZAWA Hiroyuki wrote:
> On Wed, 3 Oct 2007 21:40:29 +0900
> KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
> 
> > On Wed, 3 Oct 2007 14:20:07 +0200 (MEST)
> > Mikael Pettersson <mikpe@it.uu.se> wrote:
> > 
> > > What I don't agree with is the logic itself:
> > > - You only catch altstack overflow caused by the kernel pushing
> > >   a sigframe. You don't catch overflow caused by the user-space
> > >   signal handler pushing its own stack frame after the sigframe.
> > > - SUSv3 specifies the effect of altstack overflow as "undefined".
> > > - The overflow problem can be solved in user-space: allocate the
> > >   altstack with mmap(), then mprotect() the lowest page to prevent
> > >   accesses to it. Any overflow into it, by the kernel's signal
> > >   delivery code or by the user-space signal handler, will be caught.
> > > 
> > > So this patch gets a NAK from me.
> > > 
> > 
> > I can understand what you say, but a program which meets this problem
> > cannot be debugged ;(
> > 
> > gdb just shows infinit loop of function frames and origignal signal frame
> > which includes the most important information is overwritten.
> > 
> there is a difference among user's stack overflow and kernel's.
>  - user's stack overflow just breaks memory next to stack frame.
>  - kernel's altstack overflow, which this patch tries to fix, breaks
>    the bottom of altstack  bacause %esp goes back to the bottom
>    of ths altstack when it exceeds altstack range.
>    This behavior overwrite orignail stack frame and shows  infinit loop
>    of function call to gdb and never stop with 100% cpu usage.

The proposed kernel signal delivery patch only handles the case
where the /sigframe/ ends up overlapping the end of the altstack.
If the sigframe remains within the altstack boundaries but the
user-space signal handler adds an /ordinary stack frame/ that
moves SP beyond the altstack limit, then the kernel patch solves
nothing and recursive signals will cause altstack wraparound.

On the other hand, the user-space technique of making the lowest
page(s) in the altstack inaccessible handles both cases of overflow.

/Mikael

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs
@ 2007-10-03 12:20 Mikael Pettersson
  2007-10-03 12:40 ` KAMEZAWA Hiroyuki
  2007-10-04 11:02 ` Shi Weihua
  0 siblings, 2 replies; 20+ messages in thread
From: Mikael Pettersson @ 2007-10-03 12:20 UTC (permalink / raw)
  To: linux-kernel, shiwh

On Wed, 03 Oct 2007 17:06:24 +0900, Shi Weihua wrote:
> Fixing alternative signal stack wraparound.
> 
> If a process uses alternative signal stack by using sigaltstack()
> and that stack overflow, stack wraparound occurs.
> This patch checks whether the signal frame is on the alternative
> stack. If the frame is not on there, kill a signal SIGSEGV to the process forcedly
> then the process will be terminated.
> 
> This patch is for i386,version is 2.6.23-rc8.
> 
> Signed-off-by: Shi Weihua <shiwh@cn.fujitsu.com>
> 
> diff -pur linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c linux-2.6.23-rc8/arch/i386/kernel/signal.c
> --- linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c	2007-09-26 09:44:08.000000000 +0900
> +++ linux-2.6.23-rc8/arch/i386/kernel/signal.c	2007-09-26 13:14:25.000000000 +0900
> @@ -332,6 +332,10 @@ static int setup_frame(int sig, struct k
> 
>   	frame = get_sigframe(ka, regs, sizeof(*frame));
> 
> +	if ((ka->sa.sa_flags & SA_ONSTACK) &&
> +		!sas_ss_flags((unsigned long)frame))
> +		goto give_sigsegv;
> +
>   	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
>   		goto give_sigsegv;
> 
> @@ -425,6 +429,10 @@ static int setup_rt_frame(int sig, struc
> 
>   	frame = get_sigframe(ka, regs, sizeof(*frame));
> 
> +	if ((ka->sa.sa_flags & SA_ONSTACK) &&
> +		!sas_ss_flags((unsigned long)frame))
> +		goto give_sigsegv;
> +
>   	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
>   		goto give_sigsegv;

Your patch description is a little terse. What you do is that
after the kernel has decided where to put the signal frame,
you add a check that the base of the frame still lies in the
altstack range if altstack delivery is requested for the signal,
and if it doesn't a hard error is forced.

The coding of that logic is fine.

What I don't agree with is the logic itself:
- You only catch altstack overflow caused by the kernel pushing
  a sigframe. You don't catch overflow caused by the user-space
  signal handler pushing its own stack frame after the sigframe.
- SUSv3 specifies the effect of altstack overflow as "undefined".
- The overflow problem can be solved in user-space: allocate the
  altstack with mmap(), then mprotect() the lowest page to prevent
  accesses to it. Any overflow into it, by the kernel's signal
  delivery code or by the user-space signal handler, will be caught.

So this patch gets a NAK from me.

/Mikael

^ permalink raw reply	[flat|nested] 20+ messages in thread
* [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs
@ 2007-10-03  8:06 Shi Weihua
  2007-11-19  2:15 ` Shi Weihua
  0 siblings, 1 reply; 20+ messages in thread
From: Shi Weihua @ 2007-10-03  8:06 UTC (permalink / raw)
  To: linux-kernel

Fixing alternative signal stack wraparound.

If a process uses alternative signal stack by using sigaltstack()
and that stack overflow, stack wraparound occurs.
This patch checks whether the signal frame is on the alternative
stack. If the frame is not on there, kill a signal SIGSEGV to the process forcedly
then the process will be terminated.

This patch is for i386,version is 2.6.23-rc8.

Signed-off-by: Shi Weihua <shiwh@cn.fujitsu.com>

diff -pur linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c linux-2.6.23-rc8/arch/i386/kernel/signal.c
--- linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c	2007-09-26 09:44:08.000000000 +0900
+++ linux-2.6.23-rc8/arch/i386/kernel/signal.c	2007-09-26 13:14:25.000000000 +0900
@@ -332,6 +332,10 @@ static int setup_frame(int sig, struct k

  	frame = get_sigframe(ka, regs, sizeof(*frame));

+	if ((ka->sa.sa_flags & SA_ONSTACK) &&
+		!sas_ss_flags((unsigned long)frame))
+		goto give_sigsegv;
+
  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  		goto give_sigsegv;

@@ -425,6 +429,10 @@ static int setup_rt_frame(int sig, struc

  	frame = get_sigframe(ka, regs, sizeof(*frame));

+	if ((ka->sa.sa_flags & SA_ONSTACK) &&
+		!sas_ss_flags((unsigned long)frame))
+		goto give_sigsegv;
+
  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  		goto give_sigsegv;



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

end of thread, other threads:[~2007-12-05  5:36 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-04 13:08 [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs Mikael Pettersson
2007-10-05  0:55 ` Shi Weihua
     [not found] <474CF7D5.6010702@cn.fujitsu.com>
2007-11-28  6:07 ` Fw: " Shi Weihua
2007-12-04 13:02   ` Ingo Molnar
2007-12-04 21:52     ` Roland McGrath
2007-12-04 21:57       ` Ingo Molnar
2007-12-05  5:22       ` Shi Weihua
2007-12-05  5:36         ` Roland McGrath
     [not found] <20071126143317.dd884128.akpm@linux-foundation.org>
     [not found] ` <20071126230242.GA9623@elte.hu>
2007-11-27  3:02   ` Fw: " Roland McGrath
2007-11-27 22:57     ` Arjan van de Ven
  -- strict thread matches above, loose matches on Subject: below --
2007-10-03 13:46 Mikael Pettersson
2007-10-03 14:25 ` KAMEZAWA Hiroyuki
2007-10-04 11:56   ` Shi Weihua
2007-10-04 12:17     ` KAMEZAWA Hiroyuki
2007-10-04 12:33       ` Shi Weihua
2007-10-04 12:47         ` KAMEZAWA Hiroyuki
2007-10-03 12:20 Mikael Pettersson
2007-10-03 12:40 ` KAMEZAWA Hiroyuki
2007-10-03 13:20   ` KAMEZAWA Hiroyuki
2007-10-04 11:02 ` Shi Weihua
2007-10-03  8:06 Shi Weihua
2007-11-19  2:15 ` Shi Weihua

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