summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-06-27 19:55:03 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-06-27 19:55:03 +0000
commitcdeae92b34145c12a75af3e9593500f212cfc129 (patch)
treeb2f6bac1c02b6d66c0660a6c36f2c54aea473737 /sys
parent71e4495190aa39a98f8f101bd2adfd5efdcd90fe (diff)
Repair kill(2) on zombie processes.
kill(2) is supposed to find zombie processes, this probably got broken when the process reaper was introduced. As a temporary(tm) workaround, walk the list of zombie processes if we can't find the target pid in the main process list. Problem with zsh initially reported by Geoff Wozniak on misc@, analysis done by naddy@. ok kettenis@ tedu@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_proc.c16
-rw-r--r--sys/kern/kern_sig.c13
-rw-r--r--sys/sys/proc.h3
3 files changed, 26 insertions, 6 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index b1d474c8cf0..bb18000ac04 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.66 2016/03/04 14:09:37 deraadt Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.67 2016/06/27 19:55:02 jca Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -205,6 +205,20 @@ pgfind(pid_t pgid)
}
/*
+ * Locate a zombie process
+ */
+struct process *
+zombiefind(pid_t pid)
+{
+ struct process *pr;
+
+ LIST_FOREACH(pr, &zombprocess, ps_list)
+ if (pr->ps_mainproc->p_pid == pid)
+ return (pr);
+ return (NULL);
+}
+
+/*
* Move p to a new or existing process group (and session)
* Caller provides a pre-allocated pgrp and session that should
* be freed if they are not used.
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index db92fb2d715..ad89f681555 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.199 2016/06/27 16:49:45 jsing Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.200 2016/06/27 19:55:02 jca Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -627,19 +627,24 @@ sys_kill(struct proc *cp, void *v, register_t *retval)
int pid = SCARG(uap, pid);
int signum = SCARG(uap, signum);
int error;
+ int zombie = 0;
if ((error = pledge_kill(cp, pid)) != 0)
return (error);
if (((u_int)signum) >= NSIG)
return (EINVAL);
if (pid > 0) {
- if ((pr = prfind(pid)) == NULL)
- return (ESRCH);
+ if ((pr = prfind(pid)) == NULL) {
+ if ((pr = zombiefind(pid)) == NULL)
+ return (ESRCH);
+ else
+ zombie = 1;
+ }
if (!cansignal(cp, pr, signum))
return (EPERM);
/* kill single process */
- if (signum)
+ if (signum && !zombie)
prsignal(pr, signum);
return (0);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 9b5263ec889..7c3b7f056b9 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.223 2016/05/30 21:31:27 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.224 2016/06/27 19:55:02 jca Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -482,6 +482,7 @@ pid_t allocpid(void);
void freepid(pid_t);
struct process *prfind(pid_t); /* Find process by id. */
+struct process *zombiefind(pid_t); /* Find zombie process by id. */
struct proc *pfind(pid_t); /* Find thread by id. */
struct pgrp *pgfind(pid_t); /* Find process group by id. */
void proc_printit(struct proc *p, const char *modif,