Bug 13293

Summary: You can catch SIGKILL and SIGSTOP in 4.0.
Product: Base System Reporter: dwmalone <dwmalone>
Component: kernAssignee: Martin Cracauer <cracauer>
Status: Closed FIXED    
Severity: Affects Only Me CC: cracauer
Priority: Normal    
Version: 4.0-CURRENT   
Hardware: Any   
OS: Any   

Description dwmalone 1999-08-21 17:50:00 UTC
Sigaction is supposed to check if you change the handler of SIGKILL
or SIGSTOP to anything but SIG_DFL.  In revision 1.57 one instance
too many of sa->sa_handler got replaced by ps->ps_sigact[signum].
Resultingly it checks if the current handler is SIG_DFL instead of
the new handler being SIG_DFL. This means you can create un-killable
un-stoppable processes.

Fix: 

--- kern_sig.c	1999/08/16 18:13:38	1.60
+++ kern_sig.c	1999/08/21 16:06:30
@@ -155,11 +155,11 @@
 	if (uap->nsa) {
 		if ((error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
 		    sizeof (vec))))
 			return (error);
 		if ((signum == SIGKILL || signum == SIGSTOP) &&
-		    ps->ps_sigact[signum] != SIG_DFL)
+		    sa->sa_handler != SIG_DFL)
 			return (EINVAL);
 		setsigvec(p, signum, sa);
 	}
 	return (0);
 }
How-To-Repeat: 
The following program is unkillable.

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>

void sighand(int sig)
{
        printf("Caught signal %d\n",sig);
}

int main(int argc,char **argv)
{
        int i;

        for( i = 0 ; i < 32 ; i++ )
                signal(i,sighand);

        while(1);

        exit(0);
}
Comment 1 Sheldon Hearn freebsd_committer freebsd_triage 1999-08-23 14:17:53 UTC
Responsible Changed
From-To: freebsd-bugs->cracauer

Rev 1.57 was martin's baby. 
Comment 2 Martin Cracauer freebsd_committer freebsd_triage 1999-08-23 14:53:47 UTC
State Changed
From-To: open->closed

The suggested fix has been reviewed and committed in version 1.61 of 
kern_sig.c. 

No releases shipped with that bug. Other branches than 4.0-current 
were not affected. 

Thanks for the detailed bug report.