summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2016-06-27 16:49:46 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2016-06-27 16:49:46 +0000
commit333b171011d1943d14fd9ca7664cbbd74eea7def (patch)
tree828cff80081e688824aacaa642d1c6fe21d79ea8 /sys
parent493d71866081135706fea08b11c73f6d6804aa3e (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.c3
-rw-r--r--sys/kern/kern_sig.c59
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 /* {