diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-04-17 01:45:57 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-04-17 01:46:56 -0400 |
commit | de553438eb6c487f72d46019eb3821f6687ce011 (patch) | |
tree | 690fc48f89768c07dc0e338853ff7a93bac25a26 /arch | |
parent | 08a8a0c59e54f7eb80897c1e77efa4a541d11008 (diff) |
[S390] Protect against sigaltstack wraparound.
This is just a port of 83bd01024b1fdfc41d9b758e5669e80fca72df66
"x86: protect against sigaltstack wraparound".
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 10 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 10 |
2 files changed, 20 insertions, 0 deletions
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a5692c460bad..ae2f2d313930 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -428,6 +428,10 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
428 | /* Default to using normal stack */ | 428 | /* Default to using normal stack */ |
429 | sp = (unsigned long) A(regs->gprs[15]); | 429 | sp = (unsigned long) A(regs->gprs[15]); |
430 | 430 | ||
431 | /* Overflow on alternate signal stack gives SIGSEGV. */ | ||
432 | if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) | ||
433 | return (void __user *) -1UL; | ||
434 | |||
431 | /* This is the X/Open sanctioned signal stack switching. */ | 435 | /* This is the X/Open sanctioned signal stack switching. */ |
432 | if (ka->sa.sa_flags & SA_ONSTACK) { | 436 | if (ka->sa.sa_flags & SA_ONSTACK) { |
433 | if (! sas_ss_flags(sp)) | 437 | if (! sas_ss_flags(sp)) |
@@ -461,6 +465,9 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
461 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) | 465 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) |
462 | goto give_sigsegv; | 466 | goto give_sigsegv; |
463 | 467 | ||
468 | if (frame == (void __user *) -1UL) | ||
469 | goto give_sigsegv; | ||
470 | |||
464 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) | 471 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) |
465 | goto give_sigsegv; | 472 | goto give_sigsegv; |
466 | 473 | ||
@@ -514,6 +521,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))) | 521 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) |
515 | goto give_sigsegv; | 522 | goto give_sigsegv; |
516 | 523 | ||
524 | if (frame == (void __user *) -1UL) | ||
525 | goto give_sigsegv; | ||
526 | |||
517 | if (copy_siginfo_to_user32(&frame->info, info)) | 527 | if (copy_siginfo_to_user32(&frame->info, info)) |
518 | goto give_sigsegv; | 528 | goto give_sigsegv; |
519 | 529 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 4449bf32cbf1..8c92191949c2 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -235,6 +235,10 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
235 | /* Default to using normal stack */ | 235 | /* Default to using normal stack */ |
236 | sp = regs->gprs[15]; | 236 | sp = regs->gprs[15]; |
237 | 237 | ||
238 | /* Overflow on alternate signal stack gives SIGSEGV. */ | ||
239 | if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) | ||
240 | return (void __user *) -1UL; | ||
241 | |||
238 | /* This is the X/Open sanctioned signal stack switching. */ | 242 | /* This is the X/Open sanctioned signal stack switching. */ |
239 | if (ka->sa.sa_flags & SA_ONSTACK) { | 243 | if (ka->sa.sa_flags & SA_ONSTACK) { |
240 | if (! sas_ss_flags(sp)) | 244 | if (! sas_ss_flags(sp)) |
@@ -270,6 +274,9 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
270 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe))) | 274 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe))) |
271 | goto give_sigsegv; | 275 | goto give_sigsegv; |
272 | 276 | ||
277 | if (frame == (void __user *) -1UL) | ||
278 | goto give_sigsegv; | ||
279 | |||
273 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE)) | 280 | if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE)) |
274 | goto give_sigsegv; | 281 | goto give_sigsegv; |
275 | 282 | ||
@@ -327,6 +334,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
327 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe))) | 334 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe))) |
328 | goto give_sigsegv; | 335 | goto give_sigsegv; |
329 | 336 | ||
337 | if (frame == (void __user *) -1UL) | ||
338 | goto give_sigsegv; | ||
339 | |||
330 | if (copy_siginfo_to_user(&frame->info, info)) | 340 | if (copy_siginfo_to_user(&frame->info, info)) |
331 | goto give_sigsegv; | 341 | goto give_sigsegv; |
332 | 342 | ||