bug in signals and setuid in 4.2 bsd.

matt at oddjob.UUCP matt at oddjob.UUCP
Mon Apr 30 09:06:08 AEST 1984


While checking out nmtvax!fred's report, I found another...

Subject: sending SIGCONT to child proc not *always* allowed
Index:	sys/kern_sig.c 4.2BSD

Description:
	The manual for kill(2) states "...the signal SIGCONT ...
     may always	be sent	to any child or	grandchild of the current
     process.", but this is true only if the signal is sent to the
     entire process group via kill(0, SIGCONT) or killpg().

Repeat-By:
	Compile the following programs and make "child" suid to some
	other user than "parent", then run parent (not as root).
------------parent.c-----------
#include <stdio.h>
#include <errno.h>
#include <signal.h>

main()
{
	int	pid;
	
	if ( pid = fork() ) {
		sleep(5);
		if ( kill(pid, SIGCONT) )
		        perror("CONT");
		fprintf(stderr, "Parent exitting.\n");
	}
	else {
		execv("child", 0);
		fprintf(stderr, "Can't exec.\n");
	}
}
------------child.c-----------
#include <stdio.h>
#include <signal.h>

main()
{
	fprintf(stderr, "Child started.\n");
	kill(getpid(), SIGSTOP);
	fprintf(stderr, "Continued OK.\n");
}
-------------------------------

Fix:
	This could be intended to allow suid processes to protect
	themselves from SIGCONT by using setpgrp(0, getpid()), but I
	don't see why...
	If this is not a "feature" then the following >>untested<<
	change to kill1() in sys/kern_sig.c should fix it.  Change:
----------------------
	if (who > 0 && !ispgrp) {
		p = pfind(who);
		if (p == 0)
			return (ESRCH);
*		if (u.u_uid && u.u_uid != p->p_uid)
			return (EPERM);
----------------------
	to:
**********************
	if (who > 0 && !ispgrp) {
		p = pfind(who);
		if (p == 0)
			return (ESRCH);
*		if (u.u_uid && u.u_uid != p->p_uid &&
*		    (signo != SIGCONT || !inferior(p)))
			return (EPERM);
*********************************



More information about the Comp.unix.wizards mailing list