diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2016-06-27 16:49:46 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2016-06-27 16:49:46 +0000 |
commit | 333b171011d1943d14fd9ca7664cbbd74eea7def (patch) | |
tree | 828cff80081e688824aacaa642d1c6fe21d79ea8 /sys | |
parent | 493d71866081135706fea08b11c73f6d6804aa3e (diff) |
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@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_pledge.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 59 |
2 files changed, 60 insertions, 2 deletions
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 <nicm@openbsd.org> @@ -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 $ */ /* @@ -560,6 +560,63 @@ sys_sigaltstack(struct proc *p, void *v, register_t *retval) } 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) { struct sys_kill_args /* { |