[prev in list] [next in list] [prev in thread] [next in thread] 

List:       user-mode-linux-devel
Subject:    [uml-devel] Signal handling: deliver segfault immediately
From:       "Stroesser, Bodo" <Bodo.Stroesser () fujitsu-siemens ! com>
Date:       2004-09-30 15:29:06
Message-ID: 8B6FF516CBA0194AB0996705076B02520F7C3F () ABGEX01E ! abg ! fsc ! net
[Download RAW message or body]

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.

As a further consequence of the patch the first instruction of a signal
handler will be checked for a system call, if the process should be
singlestepped (not a big risk, but better close the hole, I think). If
you don't want this, replace the "break" by "return 1".

Bodo


--- arch/um/kernel/signal_kern.c.orig	2004-09-30 16:34:07.610109219
+0200
+++ arch/um/kernel/signal_kern.c	2004-09-30 16:51:51.743255023
+0200
@@ -38,7 +38,7 @@
 /*
  * OK, we're invoking a handler
  */	
-static void handle_signal(struct pt_regs *regs, unsigned long signr, 
+static int  handle_signal(struct pt_regs *regs, unsigned long signr, 
 			  struct k_sigaction *ka, siginfo_t *info, 
 			  sigset_t *oldset)
 {
@@ -103,23 +103,25 @@
 		recalc_sigpending();
 		spin_unlock_irq(&current->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)) ) {
+		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 ||
@@ -143,7 +145,8 @@
 	if((current->ptrace & PT_DTRACE) && 
 	   is_syscall(PT_REGS_IP(&current->thread.regs)))
  		(void)
CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
-	return(0);
+
+	return( handled_sig);
 }
 
 int do_signal(void)


-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic