This is revision 4 of this patch.
Apply by doing
cd /usr/src/sys/kern
patch -p0 < kill.patch
Then rebuild the kernel you use.
Index: kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.26
retrieving revision 1.30
diff -u -r1.26 -r1.30
--- kern_sig.c 1998/02/20 14:46:18 1.26
+++ kern_sig.c 1998/06/07 20:17:25 1.30
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.26 1998/02/20 14:46:18 niklas Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.30 1998/06/07 20:17:25 deraadt Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -73,19 +73,64 @@
void stop __P((struct proc *p));
void killproc __P((struct proc *, char *));
+int cansignal __P((struct proc *, struct pcred *, struct proc *, int));
/*
* Can process p, with pcred pc, send the signal signum to process q?
*/
-#define CANSIGNAL(p, pc, q, signum) \
- ((pc)->pc_ucred->cr_uid == 0 || \
- (pc)->p_ruid == (q)->p_cred->p_ruid || \
- (pc)->p_ruid == (q)->p_cred->p_svuid || \
- (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
- (pc)->pc_ucred->cr_uid == (q)->p_cred->p_svuid || \
- (pc)->p_ruid == (q)->p_ucred->cr_uid || \
- (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
- ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
+int
+cansignal(p, pc, q, signum)
+ struct proc *p;
+ struct pcred *pc;
+ struct proc *q;
+ int signum;
+{
+ if (pc->pc_ucred->cr_uid == 0)
+ return (1); /* root can always signal */
+
+ if (signum == SIGCONT && q->p_session == p->p_session)
+ return (1); /* SIGCONT in session */
+
+ /*
+ * Using kill(), only certain signals can be sent to setugid
+ * child processes
+ */
+ if (q->p_flag & P_SUGID) {
+ switch (signum) {
+ case 0:
+ case SIGKILL:
+ case SIGINT:
+ case SIGTERM:
+ case SIGSTOP:
+ case SIGTTIN:
+ case SIGTTOU:
+ case SIGTSTP:
+ case SIGHUP:
+ case SIGUSR1:
+ case SIGUSR2:
+ if (pc->p_ruid == q->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
+ pc->p_ruid == q->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
+ return (1);
+ }
+ return (0);
+ }
+
+ /* XXX
+ * because the P_SUGID test exists, this has extra tests which
+ * could be removed.
+ */
+ if (pc->p_ruid == q->p_cred->p_ruid ||
+ pc->p_ruid == q->p_cred->p_svuid ||
+ pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == q->p_cred->p_svuid ||
+ pc->p_ruid == q->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
+ return (1);
+ return (0);
+}
+
/* ARGSUSED */
int
@@ -433,7 +478,7 @@
/* kill single process */
if ((p = pfind(SCARG(uap, pid))) == NULL)
return (ESRCH);
- if (!CANSIGNAL(cp, pc, p, SCARG(uap, signum)))
+ if (!cansignal(cp, pc, p, SCARG(uap, signum)))
return (EPERM);
if (SCARG(uap, signum))
psignal(p, SCARG(uap, signum));
@@ -470,7 +515,7 @@
*/
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
- p == cp || !CANSIGNAL(cp, pc, p, signum))
+ p == cp || !cansignal(cp, pc, p, signum))
continue;
nfound++;
if (signum)
@@ -489,7 +534,7 @@
}
for (p = pgrp->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
- !CANSIGNAL(cp, pc, p, signum))
+ !cansignal(cp, pc, p, signum))
continue;
nfound++;
if (signum)