From owner-freebsd-current@FreeBSD.ORG Wed Aug 27 21:36:59 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1028A16A4BF for ; Wed, 27 Aug 2003 21:36:59 -0700 (PDT) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id A054943FDF for ; Wed, 27 Aug 2003 21:36:57 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3p2/8.8.7) with ESMTP id OAA03936; Thu, 28 Aug 2003 14:33:26 +1000 Date: Thu, 28 Aug 2003 14:33:20 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Joe Greco In-Reply-To: <200308271408.h7RE8ghW073779@aurora.sol.net> Message-ID: <20030828140312.N2706@gamplex.bde.org> References: <200308271408.h7RE8ghW073779@aurora.sol.net> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-current@freebsd.org Subject: Re: Someone help me understand this...? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Aug 2003 04:36:59 -0000 On Wed, 27 Aug 2003, Joe Greco wrote: > I've got a weirdness with kill(2). > > This code is out of Diablo, the news package, and has been working fine for > some years. It apparently works fine on other OS's. > > In the Diablo model, the parent process may choose to tell its children to > update status via a signal. The loop basically consists of going through > and issuing a SIGALRM. > > This stopped working a while ago, don't know precisely when. I was in the > process of debugging it today and ran into this. > > The specific OS below is 5.1-RELEASE but apparently this happens on 4.8 as > well. Perhaps the children are setuid, the parent doesn't have appropriate privelege and you are mistaken about this happening under 4.8 as well. In 5.x since at least rev.1.80 of kern_prot.c, only certain signals not including SIGALRM can be sent from unprivileged processes to setuid processes. This is very UN-unixlike although it is permitted as an-implementation- defined restriction in at least POSIX.1-2001. It breaks^Wexposes bugs in some old POSIX test programs and I don't have many security concerns so I just disable it locally: %%% Index: kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.175 diff -u -2 -r1.175 kern_prot.c --- kern_prot.c 13 Jul 2003 01:22:20 -0000 1.175 +++ kern_prot.c 17 Aug 2003 04:26:00 -0000 @@ -1395,4 +1387,5 @@ return (error); +#if 0 /* * UNIX signal semantics depend on the status of the P_SUGID @@ -1425,4 +1418,5 @@ } } +#endif /* %%% > Wot? Why can't I send it a signal? > > I've read kill(2) rather carefully and cannot find the reason. It says, > > For a process to have permission to send a signal to a process designated > by pid, the real or effective user ID of the receiving process must match > that of the sending process or the user must have appropriate privileges > (such as given by a set-user-ID program or the user is the super-user). The implementation-defined restrictions are not documented, of course ;-). > Well, the sending and receiving processes both clearly have equal uid/euid. > > We're not running in a jail, so I don't expect any issues there. > > The parent process did actually start as root and then shed privilege with > > struct passwd *pw = getpwnam("news"); > struct group *gr = getgrnam("news"); > gid_t gid; > > if (pw == NULL) { > perror("getpwnam('news')"); > exit(1); > } > if (gr == NULL) { > perror("getgrnam('news')"); > exit(1); > } > gid = gr->gr_gid; > setgroups(1, &gid); > setgid(gr->gr_gid); > setuid(pw->pw_uid); > > so that looks all well and fine... so why can't it kill its own children, > and why can't I kill one of its children from a shell with equivalent > uid/euid? Changing the ids is one way to make the process setuid (setuid-on-exec is another but that doesn't seem to be the problem here). The relevant setuid bit (P_SUGID) is normally cleared on exec, but perhaps it isn't here, either because the children don't exec or the effective ids don't match the real ids at the time of the exec. > I know there's been some paranoia about signal delivery and all that, but > my searching hasn't turned up anything that would explain this. Certainly > the manual page ought to be updated if this is a new expected behaviour or > something... at least some clue as to why it might fail would be helpful. Certainly. It is incomplete even not counting complications for jails or other implementation-defined restrictions related to "appropriate privilege". Bruce