Some time ago someone reported a wird behavior in the shells/zsh ports.

  http://marc.info/?l=openbsd-misc&m=146101806918986&w=2

The latter relies on kill(zombie, 0) to succeed, instead we return -1.
This is because zombie processes aren't looked up in sys_kill().

A potential fix was suggested, which involved stopping using a reaper
process and let processes clean up after themselves.  However such
a change doesn't look trivial, especially late in this development
cycle.

So here's a bit of band-aid.  Worth it?


Index: kern/kern_proc.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.66
diff -u -p -r1.66 kern_proc.c
--- kern/kern_proc.c    4 Mar 2016 14:09:37 -0000       1.66
+++ kern/kern_proc.c    27 Jun 2016 18:02:01 -0000
@@ -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.
Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.199
diff -u -p -r1.199 kern_sig.c
--- kern/kern_sig.c     27 Jun 2016 16:49:45 -0000      1.199
+++ kern/kern_sig.c     27 Jun 2016 18:02:01 -0000
@@ -627,19 +627,24 @@ sys_kill(struct proc *cp, void *v, regis
        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);
        }
Index: sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.223
diff -u -p -r1.223 proc.h
--- sys/proc.h  30 May 2016 21:31:27 -0000      1.223
+++ sys/proc.h  27 Jun 2016 18:02:01 -0000
@@ -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,


-- 
jca | PGP: 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to