Date: Fri, 29 Nov 2019 19:45:09 +0300 From: Dmitry Marakasov <amdmi3@amdmi3.ru> To: freebsd-stable@freebsd.org Subject: Re: How can kill(-1, 0) return EPERM? Message-ID: <20191129164509.GE4071@hades.panopticon> In-Reply-To: <20191129151606.GD4071@hades.panopticon> References: <20191129151606.GD4071@hades.panopticon>
next in thread | previous in thread | raw e-mail | index | archive | help
* Dmitry Marakasov (amdmi3@amdmi3.ru) wrote: > I'm helping to investigate some userspace issue [1], where kill(-1, SIGKILL) > fails with EPERM. I've managed to isolate this case in a small program: > > > ``` > #include <err.h> > #include <errno.h> > #include <signal.h> > #include <stdio.h> > #include <string.h> > #include <unistd.h> > > int main() { > if (setuid(66) == -1) // uucp, just for the test > err(1, "setuid"); > > int res = kill(-1, 0); // <- fails with EPERM > fprintf(stderr, "kill(-1, 0) result=%d, errno=%s\n", res, strerror(errno)); > > return 0; > } > ``` > > when run from root on 12.1 kill call fails with EPERM. However I cannot > comprehend what it is caused by and how it's even possible: kill(2) manpage > says that with pid=-1 kill should only send (and in this case of sig=0, > /not/ send) signals to the processes belonging to the current uid, so there > should be no permission problems. I've also looked into the kernel code > (sys_kill, killpg1), and it matches to what manpage says, I see no way > for it to return EPERM: sys_kill() should fall through to the switch, call > killpg1() with all=1 and killpg1() if(all) branch may only set `ret` to > either 0 or ESRCH. Am I missing something, or is there a problem somewhere? It looks like I have misread the `else if' path of this core. 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); } sx_sunlock(&allproc_lock); } ... so it's clear now where EPERM comes from. However it looks like the behavior contradicts the manpage - there are no signs of check that the signalled process has the same uid as the caller. -- Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D amdmi3@amdmi3.ru ..: https://github.com/AMDmi3
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191129164509.GE4071>