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>