Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Dec 2019 15:33:19 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r355981 - in stable/12: lib/libc/sys sys/kern
Message-ID:  <201912211533.xBLFXJWo042539@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Dec 21 15:33:19 2019
New Revision: 355981
URL: https://svnweb.freebsd.org/changeset/base/355981

Log:
  MFC r355500:
  Only return EPERM from kill(-pid) when no process was signalled.

Modified:
  stable/12/lib/libc/sys/kill.2
  stable/12/sys/kern/kern_sig.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/lib/libc/sys/kill.2
==============================================================================
--- stable/12/lib/libc/sys/kill.2	Sat Dec 21 11:38:48 2019	(r355980)
+++ stable/12/lib/libc/sys/kill.2	Sat Dec 21 15:33:19 2019	(r355981)
@@ -28,7 +28,7 @@
 .\"     @(#)kill.2	8.3 (Berkeley) 4/19/94
 .\" $FreeBSD$
 .\"
-.Dd December 1, 2017
+.Dd December 1, 2019
 .Dt KILL 2
 .Os
 .Sh NAME
@@ -105,12 +105,11 @@ process with ID 1
 .Xr init 8 ) ,
 and the process sending the signal.
 If the user is not the super user, the signal is sent to all processes
-with the same uid as the user excluding the process sending the signal.
+which the caller has permissions to, excluding the process sending the signal.
 No error is returned if any process could be signaled.
 .El
 .Pp
-For compatibility with System V,
-if the process number is negative but not -1,
+If the process number is negative but not -1,
 the signal is sent to all processes whose process group ID
 is equal to the absolute value of the process number.
 This is a variant of
@@ -134,7 +133,7 @@ No process or process group can be found corresponding
 .It Bq Er EPERM
 The sending process does not have permission to send
 .Va sig
-to the receiving process.
+to any receiving process.
 .El
 .Sh SEE ALSO
 .Xr getpgrp 2 ,

Modified: stable/12/sys/kern/kern_sig.c
==============================================================================
--- stable/12/sys/kern/kern_sig.c	Sat Dec 21 11:38:48 2019	(r355980)
+++ stable/12/sys/kern/kern_sig.c	Sat Dec 21 15:33:19 2019	(r355981)
@@ -1679,6 +1679,36 @@ kern_sigaltstack(struct thread *td, stack_t *ss, stack
 	return (0);
 }
 
+struct killpg1_ctx {
+	struct thread *td;
+	ksiginfo_t *ksi;
+	int sig;
+	bool sent;
+	bool found;
+	int ret;
+};
+
+static void
+killpg1_sendsig(struct proc *p, bool notself, struct killpg1_ctx *arg)
+{
+	int err;
+
+	if (p->p_pid <= 1 || (p->p_flag & P_SYSTEM) != 0 ||
+	    (notself && p == arg->td->td_proc) || p->p_state == PRS_NEW)
+		return;
+	PROC_LOCK(p);
+	err = p_cansignal(arg->td, p, arg->sig);
+	if (err == 0 && arg->sig != 0)
+		pksignal(p, arg->sig, arg->ksi);
+	PROC_UNLOCK(p);
+	if (err != ESRCH)
+		arg->found = true;
+	if (err == 0)
+		arg->sent = true;
+	else if (arg->ret == 0 && err != ESRCH && err != EPERM)
+		arg->ret = err;
+}
+
 /*
  * Common code for kill process group/broadcast kill.
  * cp is calling process.
@@ -1688,30 +1718,21 @@ killpg1(struct thread *td, int sig, int pgid, int all,
 {
 	struct proc *p;
 	struct pgrp *pgrp;
-	int err;
-	int ret;
+	struct killpg1_ctx arg;
 
-	ret = ESRCH;
+	arg.td = td;
+	arg.ksi = ksi;
+	arg.sig = sig;
+	arg.sent = false;
+	arg.found = false;
+	arg.ret = 0;
 	if (all) {
 		/*
 		 * broadcast
 		 */
 		sx_slock(&allproc_lock);
 		FOREACH_PROC_IN_SYSTEM(p) {
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-			    p == td->td_proc || p->p_state == PRS_NEW) {
-				continue;
-			}
-			PROC_LOCK(p);
-			err = p_cansignal(td, p, sig);
-			if (err == 0) {
-				if (sig)
-					pksignal(p, sig, ksi);
-				ret = err;
-			}
-			else if (ret == ESRCH)
-				ret = err;
-			PROC_UNLOCK(p);
+			killpg1_sendsig(p, true, &arg);
 		}
 		sx_sunlock(&allproc_lock);
 	} else {
@@ -1731,25 +1752,14 @@ killpg1(struct thread *td, int sig, int pgid, int all,
 		}
 		sx_sunlock(&proctree_lock);
 		LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
-			PROC_LOCK(p);
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-			    p->p_state == PRS_NEW) {
-				PROC_UNLOCK(p);
-				continue;
-			}
-			err = p_cansignal(td, p, sig);
-			if (err == 0) {
-				if (sig)
-					pksignal(p, sig, ksi);
-				ret = err;
-			}
-			else if (ret == ESRCH)
-				ret = err;
-			PROC_UNLOCK(p);
+			killpg1_sendsig(p, false, &arg);
 		}
 		PGRP_UNLOCK(pgrp);
 	}
-	return (ret);
+	MPASS(arg.ret != 0 || arg.found || !arg.sent);
+	if (arg.ret == 0 && !arg.sent)
+		arg.ret = arg.found ? EPERM : ESRCH;
+	return (arg.ret);
 }
 
 #ifndef _SYS_SYSPROTO_H_



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912211533.xBLFXJWo042539>