summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2014-07-13 16:41:23 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2014-07-13 16:41:23 +0000
commit0a62e3699149faa5ecee87ff710c406eb40e9d64 (patch)
treede62b925dcff0be23d142e4d7a167b7d745e6886
parentebff1c1914c0660343592efe09fb9ad4994a9316 (diff)
Introduce PS_NOBROADCASTKILL a process flag that excludes processes from
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@
-rw-r--r--sys/kern/kern_sig.c5
-rw-r--r--sys/kern/kern_sysctl.c49
-rw-r--r--sys/sys/proc.h5
-rw-r--r--sys/sys/sysctl.h6
4 files changed, 58 insertions, 7 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 970507f28b6..88a8865d1a9 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -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++;
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index c0a9d02cc43..d89199df16a 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -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
/*
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index d7c3224701e..6f25f2c0e52 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -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 {
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index b9e38a95369..889e997e0f3 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -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 }, \
}
/*