Commit d09042da7284a86ffbdd18695f517a71514ed598

Authored by Laurent MEYER
Committed by Linus Torvalds
1 parent 785d55708c

[PATCH] fix incorrect SA_ONSTACK behaviour for 64-bit processes

- When setting a sighandler using sigaction() call, if the flag
  SA_ONSTACK is set and no alternate stack is provided via sigaltstack(),
  the kernel still try to install the alternate stack.  This behavior is
  the opposite of the one which is documented in Single Unix Specifications
  V3.

- Also when setting an alternate stack using sigaltstack() with the flag
  SS_DISABLE, the kernel try to install the alternate stack on signal
  delivery.

These two use cases makes the process crash at signal delivery.

Signed-off-by: Laurent Meyer <meyerlau@fr.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Chris Zankel <chris@zankel.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 9 changed files with 9 additions and 9 deletions Side-by-side Diff

arch/alpha/kernel/signal.c
... ... @@ -375,7 +375,7 @@
375 375 static inline void __user *
376 376 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
377 377 {
378   - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
  378 + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
379 379 sp = current->sas_ss_sp + current->sas_ss_size;
380 380  
381 381 return (void __user *)((sp - frame_size) & -32ul);
arch/frv/kernel/signal.c
... ... @@ -233,7 +233,7 @@
233 233  
234 234 /* This is the X/Open sanctioned signal stack switching. */
235 235 if (ka->sa.sa_flags & SA_ONSTACK) {
236   - if (! on_sig_stack(sp))
  236 + if (! sas_ss_flags(sp))
237 237 sp = current->sas_ss_sp + current->sas_ss_size;
238 238 }
239 239  
arch/h8300/kernel/signal.c
... ... @@ -307,7 +307,7 @@
307 307  
308 308 /* This is the X/Open sanctioned signal stack switching. */
309 309 if (ka->sa.sa_flags & SA_ONSTACK) {
310   - if (!on_sig_stack(usp))
  310 + if (!sas_ss_flags(usp))
311 311 usp = current->sas_ss_sp + current->sas_ss_size;
312 312 }
313 313 return (void *)((usp - frame_size) & -8UL);
arch/m68k/kernel/signal.c
... ... @@ -763,7 +763,7 @@
763 763  
764 764 /* This is the X/Open sanctioned signal stack switching. */
765 765 if (ka->sa.sa_flags & SA_ONSTACK) {
766   - if (!on_sig_stack(usp))
  766 + if (!sas_ss_flags(usp))
767 767 usp = current->sas_ss_sp + current->sas_ss_size;
768 768 }
769 769 return (void __user *)((usp - frame_size) & -8UL);
arch/m68knommu/kernel/signal.c
... ... @@ -553,7 +553,7 @@
553 553  
554 554 /* This is the X/Open sanctioned signal stack switching. */
555 555 if (ka->sa.sa_flags & SA_ONSTACK) {
556   - if (!on_sig_stack(usp))
  556 + if (!sas_ss_flags(usp))
557 557 usp = current->sas_ss_sp + current->sas_ss_size;
558 558 }
559 559 return (void *)((usp - frame_size) & -8UL);
arch/parisc/kernel/signal.c
... ... @@ -248,7 +248,7 @@
248 248 DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
249 249 (unsigned long)ka, sp, frame_size);
250 250  
251   - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
  251 + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
252 252 sp = current->sas_ss_sp; /* Stacks grow up! */
253 253  
254 254 DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
arch/sh64/kernel/signal.c
... ... @@ -407,7 +407,7 @@
407 407 static inline void __user *
408 408 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
409 409 {
410   - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
  410 + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
411 411 sp = current->sas_ss_sp + current->sas_ss_size;
412 412  
413 413 return (void __user *)((sp - frame_size) & -8ul);
arch/v850/kernel/signal.c
... ... @@ -274,7 +274,7 @@
274 274 /* Default to using normal stack */
275 275 unsigned long sp = regs->gpr[GPR_SP];
276 276  
277   - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
  277 + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
278 278 sp = current->sas_ss_sp + current->sas_ss_size;
279 279  
280 280 return (void *)((sp - frame_size) & -8UL);
arch/xtensa/kernel/signal.c
... ... @@ -433,7 +433,7 @@
433 433 static inline void *
434 434 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
435 435 {
436   - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
  436 + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
437 437 sp = current->sas_ss_sp + current->sas_ss_size;
438 438  
439 439 return (void *)((sp - frame_size) & -16ul);