diff options
Diffstat (limited to 'arch/s390/kernel/compat_signal.c')
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a5692c460bad..c7f02e777af2 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/lowcore.h> | 29 | #include <asm/lowcore.h> |
30 | #include "compat_linux.h" | 30 | #include "compat_linux.h" |
31 | #include "compat_ptrace.h" | 31 | #include "compat_ptrace.h" |
32 | #include "entry.h" | ||
32 | 33 | ||
33 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 34 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
34 | 35 | ||
@@ -428,6 +429,10 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
428 | /* Default to using normal stack */ | 429 | /* Default to using normal stack */ |
429 | sp = (unsigned long) A(regs->gprs[15]); | 430 | sp = (unsigned long) A(regs->gprs[15]); |
430 | 431 | ||
432 | /* Overflow on alternate signal stack gives SIGSEGV. */ | ||
433 | if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) | ||
434 | return (void __user *) -1UL; | ||
435 | |||
431 | /* This is the X/Open sanctioned signal stack switching. */ | 436 | /* This is the X/Open sanctioned signal stack switching. */ |
432 | if (ka->sa.sa_flags & SA_ONSTACK) { | 437 | if (ka->sa.sa_flags & SA_ONSTACK) { |
433 | if (! sas_ss_flags(sp)) | 438 | if (! sas_ss_flags(sp)) |
@@ -461,6 +466,9 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
461 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) | 466 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) |
462 | goto give_sigsegv; | 467 | goto give_sigsegv; |
463 | 468 | ||
469 | if (frame == (void __user *) -1UL) | ||
470 | goto give_sigsegv; | ||
471 | |||
464 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) | 472 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) |
465 | goto give_sigsegv; | 473 | goto give_sigsegv; |
466 | 474 | ||
@@ -514,6 +522,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
514 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) | 522 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) |
515 | goto give_sigsegv; | 523 | goto give_sigsegv; |
516 | 524 | ||
525 | if (frame == (void __user *) -1UL) | ||
526 | goto give_sigsegv; | ||
527 | |||
517 | if (copy_siginfo_to_user32(&frame->info, info)) | 528 | if (copy_siginfo_to_user32(&frame->info, info)) |
518 | goto give_sigsegv; | 529 | goto give_sigsegv; |
519 | 530 | ||