Messages in this thread Patch in this message | | | Subject | [PATCH 10/11] - UML - Don't delay segfaults | Date | Fri, 12 Nov 2004 21:01:01 -0500 | From | Jeff Dike <> |
| |
From Bodo Stroesser - This one covers the fact, that the SIGSEGV signal, which is created by force_sigsegv() in case of an error in handle_signal(), is not delivered to the user immediately. In the worst case it even could be masked if a sigprocmask() systemcall follows immediately after return from kernel. The patch is relevant for other architectures, too.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Index: 2.6.9/arch/um/kernel/signal_kern.c =================================================================== --- 2.6.9.orig/arch/um/kernel/signal_kern.c 2004-11-12 16:24:20.000000000 -0500 +++ 2.6.9/arch/um/kernel/signal_kern.c 2004-11-12 16:24:21.000000000 -0500 @@ -38,9 +38,9 @@ /* * OK, we're invoking a handler */ -static void handle_signal(struct pt_regs *regs, unsigned long signr, - struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset) +static int handle_signal(struct pt_regs *regs, unsigned long signr, + struct k_sigaction *ka, siginfo_t *info, + sigset_t *oldset) { unsigned long sp; int err; @@ -94,23 +94,25 @@ recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } + + return err; } static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka_copy; siginfo_t info; - int sig; + int sig, handled_sig = 0; - sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL); - if(sig > 0){ + while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ + handled_sig = 1; /* Whee! Actually deliver the signal. */ - handle_signal(regs, sig, &ka_copy, &info, oldset); - return(1); + if(!handle_signal(regs, sig, &ka_copy, &info, oldset)) + break; } /* Did we come from a system call? */ - if(PT_REGS_SYSCALL_NR(regs) >= 0){ + if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ /* Restart the system call - no handlers present */ if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || @@ -134,7 +136,7 @@ if(current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); - return(0); + return(handled_sig); } int do_signal(void) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |