From: jsing Date: Mon, 27 Jun 2016 16:49:45 +0000 (+0000) Subject: Restore the sys_o58_kill system call. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e1aaead3d75ae8b17a6a6b45a07a76faf1c35fbc;p=openbsd Restore the sys_o58_kill system call. By keeping both the new (sys_kill/sys_thrkill) and old (sys_o58_kill) system calls for the OpenBSD 6.0 release, code that uses either of these mechanisms will work on both of the supported OpenBSD releases. This provides a clean transition for runtimes that make direct system calls (namely the Go programming language). This requires a minimal amount of non-intrusive code and does not block development progress within OpenBSD. ok deraadt@ guenther@ --- diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 1a3a9e51395..047225c0933 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.171 2016/06/27 16:33:48 jca Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.172 2016/06/27 16:49:45 jsing Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -230,6 +230,7 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { * Can kill self with "stdio". Killing another pid * requires "proc" */ + [SYS_o58_kill] = PLEDGE_STDIO, [SYS_kill] = PLEDGE_STDIO, /* diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 7b9cba2cf9a..db92fb2d715 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.198 2016/06/11 21:41:50 tedu Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.199 2016/06/27 16:49:45 jsing Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -559,6 +559,63 @@ sys_sigaltstack(struct proc *p, void *v, register_t *retval) return (0); } +int +sys_o58_kill(struct proc *cp, void *v, register_t *retval) +{ + struct sys_o58_kill_args /* { + syscallarg(int) pid; + syscallarg(int) signum; + } */ *uap = v; + struct proc *p; + int pid = SCARG(uap, pid); + int signum = SCARG(uap, signum); + int error; + + if (pid <= THREAD_PID_OFFSET && (error = pledge_kill(cp, pid)) != 0) + return (error); + if (((u_int)signum) >= NSIG) + return (EINVAL); + if (pid > 0) { + enum signal_type type = SPROCESS; + + /* + * If the target pid is > THREAD_PID_OFFSET then this + * must be a kill of another thread in the same process. + * Otherwise, this is a process kill and the target must + * be a main thread. + */ + if (pid > THREAD_PID_OFFSET) { + if ((p = pfind(pid - THREAD_PID_OFFSET)) == NULL) + return (ESRCH); + if (p->p_p != cp->p_p) + return (ESRCH); + type = STHREAD; + } else { + /* XXX use prfind() */ + if ((p = pfind(pid)) == NULL) + return (ESRCH); + if (p->p_flag & P_THREAD) + return (ESRCH); + if (!cansignal(cp, p->p_p, signum)) + return (EPERM); + } + + /* kill single process or thread */ + if (signum) + ptsignal(p, signum, type); + return (0); + } + switch (pid) { + case -1: /* broadcast signal */ + return (killpg1(cp, signum, 0, 1)); + case 0: /* signal own process group */ + return (killpg1(cp, signum, 0, 0)); + default: /* negative explicit process group */ + return (killpg1(cp, signum, -pid, 0)); + } + /* NOTREACHED */ +} + int sys_kill(struct proc *cp, void *v, register_t *retval) {