Introduce PS_NOBROADCASTKILL a process flag that excludes processes from
authorclaudio <claudio@openbsd.org>
Sun, 13 Jul 2014 16:41:21 +0000 (16:41 +0000)
committerclaudio <claudio@openbsd.org>
Sun, 13 Jul 2014 16:41:21 +0000 (16:41 +0000)
receiving broadcast signals (kill -1). The flag can be set via a new
sysctl KERN_PROC_NOBROADCASTKILL. This will be used by iscsid to survive
the mass killing by init(8) when terminating multi-user operations.
With and OK guenther@

sys/kern/kern_sig.c
sys/kern/kern_sysctl.c
sys/sys/proc.h
sys/sys/sysctl.h

index 970507f..88a8865 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sig.c,v 1.172 2014/07/13 15:46:21 uebayasi Exp $ */
+/*     $OpenBSD: kern_sig.c,v 1.173 2014/07/13 16:41:21 claudio Exp $  */
 /*     $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
 
 /*
@@ -629,7 +629,8 @@ killpg1(struct proc *cp, int signum, int pgid, int all)
                 * broadcast
                 */
                LIST_FOREACH(pr, &allprocess, ps_list) {
-                       if (pr->ps_pid <= 1 || pr->ps_flags & PS_SYSTEM ||
+                       if (pr->ps_pid <= 1 ||
+                           pr->ps_flags & (PS_SYSTEM | PS_NOBROADCASTKILL) ||
                            pr == cp->p_p || !cansignal(cp, pr, signum))
                                continue;
                        nfound++;
index c0a9d02..d89199d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sysctl.c,v 1.257 2014/07/13 15:29:04 tedu Exp $  */
+/*     $OpenBSD: kern_sysctl.c,v 1.258 2014/07/13 16:41:21 claudio Exp $       */
 /*     $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $     */
 
 /*-
@@ -116,6 +116,8 @@ extern void nmbclust_update(void);
 int sysctl_diskinit(int, struct proc *);
 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *);
+int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *,
+       struct proc *);
 int sysctl_intrcnt(int *, u_int, void *, size_t *);
 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
 int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
@@ -284,6 +286,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                case KERN_POOL:
                case KERN_PROC_ARGS:
                case KERN_PROC_CWD:
+               case KERN_PROC_NOBROADCASTKILL:
                case KERN_SYSVIPC_INFO:
                case KERN_SEMINFO:
                case KERN_SHMINFO:
@@ -372,6 +375,9 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
        case KERN_PROC_CWD:
                return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp,
                     p));
+       case KERN_PROC_NOBROADCASTKILL:
+               return (sysctl_proc_nobroadcastkill(name + 1, namelen - 1,
+                    newp, newlen, oldp, oldlenp, p));
        case KERN_FILE:
                return (sysctl_file(name + 1, namelen - 1, oldp, oldlenp, p));
 #endif
@@ -1820,6 +1826,47 @@ sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 
        return (error);
 }
+
+int
+sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen,
+    void *oldp, size_t *oldlenp, struct proc *cp)
+{
+       struct process *findpr;
+       pid_t pid;
+       int error, flag;
+
+       if (namelen > 1)
+               return (ENOTDIR);
+       if (namelen < 1)
+               return (EINVAL);
+
+       pid = name[0];
+       if ((findpr = prfind(pid)) == NULL)
+               return (ESRCH);
+
+       /* Either system process or exiting/zombie */
+       if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
+               return (EINVAL);
+
+       /* Only root can change PS_NOBROADCASTKILL */
+       if (newp != 0 && (error = suser(cp, 0)) != 0)
+               return (error);
+
+       /* get the PS_NOBROADCASTKILL flag */
+       flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0;
+
+       error = sysctl_int(oldp, oldlenp, newp, newlen, &flag);
+       if (error == 0 && newp) {
+               if (flag)
+                       atomic_setbits_int(&findpr->ps_flags,
+                           PS_NOBROADCASTKILL);
+               else
+                       atomic_clearbits_int(&findpr->ps_flags,
+                           PS_NOBROADCASTKILL);
+       }
+
+       return (error);
+}
 #endif
 
 /*
index d7c3224..6f25f2c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.189 2014/07/12 21:21:19 matthew Exp $      */
+/*     $OpenBSD: proc.h,v 1.190 2014/07/13 16:41:21 claudio Exp $      */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -247,12 +247,13 @@ struct process {
 #define        PS_SYSTEM       0x00010000      /* No sigs, stats or swapping. */
 #define        PS_EMBRYO       0x00020000      /* New process, not yet fledged */
 #define        PS_ZOMBIE       0x00040000      /* Dead and ready to be waited for */
+#define        PS_NOBROADCASTKILL 0x00080000   /* Process excluded from kill -1. */
 
 #define        PS_BITS \
     ("\20\01CONTROLT\02EXEC\03INEXEC\04EXITING\05SUGID" \
      "\06SUGIDEXEC\07PPWAIT\010ISPWAIT\011PROFIL\012TRACED" \
      "\013WAITED\014COREDUMP\015SINGLEEXIT\016SINGLEUNWIND" \
-     "\017NOZOMBIE\020STOPPED\021SYSTEM\022EMBRYO\023ZOMBIE")
+     "\017NOZOMBIE\020STOPPED\021SYSTEM\022EMBRYO\023ZOMBIE\024NOBROADCASTKILL")
 
 
 struct proc {
index b9e38a9..889e997 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysctl.h,v 1.147 2014/07/08 17:19:26 deraadt Exp $    */
+/*     $OpenBSD: sysctl.h,v 1.148 2014/07/13 16:41:22 claudio Exp $    */
 /*     $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $  */
 
 /*
@@ -179,7 +179,8 @@ struct ctlname {
 #define        KERN_NETLIVELOCKS       76      /* int: number of network livelocks */
 #define        KERN_POOL_DEBUG         77      /* int: enable pool_debug */
 #define        KERN_PROC_CWD           78      /* node: proc cwd */
-#define        KERN_MAXID              79      /* number of valid kern ids */
+#define        KERN_PROC_NOBROADCASTKILL 79    /* node: proc no broadcast kill */
+#define        KERN_MAXID              80      /* number of valid kern ids */
 
 #define        CTL_KERN_NAMES { \
        { 0, 0 }, \
@@ -261,6 +262,7 @@ struct ctlname {
        { "netlivelocks", CTLTYPE_INT }, \
        { "pool_debug", CTLTYPE_INT }, \
        { "proc_cwd", CTLTYPE_NODE }, \
+       { "proc_nobroadcastkill", CTLTYPE_NODE }, \
 }
 
 /*