aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/ia32
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-06-23 03:08:37 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:13 -0400
commit0928d6ef7f204979749fb241a90a04a35dae133a (patch)
treef91a3a4725a2e59ed3cfce4cabd31f61798b9342 /arch/x86_64/ia32
parenta3a00751ad8970c13d0563c2e92ee68c655a8e6b (diff)
[PATCH] x86_64: never block forced SIGSEGV
This is the x86_64 version of the signal fix I just posted for i386. This problem was first noticed on PPC and has already been fixed there. But the exact same issue applies to other platforms in the same way. The signal blocking for sa_mask and the handled signal takes place after the handler setup. When the stack is bogus, the handler setup forces a SIGSEGV. But then this will be blocked, and returning to user mode will fault again and iterate. This patch fixes the problem by checking whether signal handler setup failed, and not doing the signal-blocking if so. This copies what was done in the ppc code. I think all architectures' signal handler setup code follows this pattern and needs the change. Signed-off-by: Roland McGrath <roland@redhat.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/ia32')
-rw-r--r--arch/x86_64/ia32/ia32_signal.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index fbd09b5126ce..66e2821533db 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -428,8 +428,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
428 return (void __user *)((rsp - frame_size) & -8UL); 428 return (void __user *)((rsp - frame_size) & -8UL);
429} 429}
430 430
431void ia32_setup_frame(int sig, struct k_sigaction *ka, 431int ia32_setup_frame(int sig, struct k_sigaction *ka,
432 compat_sigset_t *set, struct pt_regs * regs) 432 compat_sigset_t *set, struct pt_regs * regs)
433{ 433{
434 struct sigframe __user *frame; 434 struct sigframe __user *frame;
435 int err = 0; 435 int err = 0;
@@ -514,14 +514,15 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
514 current->comm, current->pid, frame, regs->rip, frame->pretcode); 514 current->comm, current->pid, frame, regs->rip, frame->pretcode);
515#endif 515#endif
516 516
517 return; 517 return 1;
518 518
519give_sigsegv: 519give_sigsegv:
520 force_sigsegv(sig, current); 520 force_sigsegv(sig, current);
521 return 0;
521} 522}
522 523
523void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 524int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
524 compat_sigset_t *set, struct pt_regs * regs) 525 compat_sigset_t *set, struct pt_regs * regs)
525{ 526{
526 struct rt_sigframe __user *frame; 527 struct rt_sigframe __user *frame;
527 int err = 0; 528 int err = 0;
@@ -613,9 +614,9 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
613 current->comm, current->pid, frame, regs->rip, frame->pretcode); 614 current->comm, current->pid, frame, regs->rip, frame->pretcode);
614#endif 615#endif
615 616
616 return; 617 return 1;
617 618
618give_sigsegv: 619give_sigsegv:
619 force_sigsegv(sig, current); 620 force_sigsegv(sig, current);
621 return 0;
620} 622}
621