From ed557a3682b90c9d79cd694303ca27156c5408c7 Mon Sep 17 00:00:00 2001 From: guenther Date: Sun, 4 May 2014 05:03:26 +0000 Subject: [PATCH] Add PS_SYSTEM, the process-level mirror of the thread-level P_SYSTEM, and FORK_SYSTEM as a flag to set them. This eliminates needing to peek into other processes threads in various places. Inspired by NetBSD ok miod@ matthew@ --- sys/kern/init_main.c | 3 ++- sys/kern/kern_fork.c | 8 ++++++-- sys/kern/kern_kthread.c | 9 ++------- sys/kern/kern_sched.c | 9 ++------- sys/kern/kern_sig.c | 15 ++++++--------- sys/kern/kern_sysctl.c | 24 +++++++++--------------- sys/kern/sys_process.c | 4 ++-- sys/sys/proc.h | 6 ++++-- 8 files changed, 33 insertions(+), 45 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index eaea6e4d2ab..92481c3308f 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.211 2014/04/18 11:51:17 guenther Exp $ */ +/* $OpenBSD: init_main.c,v 1.212 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -266,6 +266,7 @@ main(void *framep) process0.ps_refcnt = 1; p->p_p = pr = &process0; LIST_INSERT_HEAD(&allprocess, pr, ps_list); + atomic_setbits_int(&pr->ps_flags, PS_SYSTEM); /* Set the default routing table/domain. */ process0.ps_rtableid = 0; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index da052e891ff..b2ff5552d91 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.164 2014/05/03 22:44:36 guenther Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.165 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -208,6 +208,8 @@ process_new(struct proc *p, struct process *parent, int flags) atomic_setbits_int(&pr->ps_flags, PS_TRACED); if (flags & FORK_NOZOMBIE) atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE); + if (flags & FORK_SYSTEM) + atomic_setbits_int(&pr->ps_flags, PS_SYSTEM); /* it's sufficiently inited to be globally visible */ LIST_INSERT_HEAD(&allprocess, pr, ps_list); @@ -236,7 +238,7 @@ fork1(struct proc *curp, int flags, void *stack, pid_t *tidptr, /* sanity check some flag combinations */ if (flags & FORK_THREAD) { - if ((flags & FORK_SIGHAND) == 0) + if ((flags & FORK_SIGHAND) == 0 || (flags & FORK_SYSTEM) != 0) return (EINVAL); } if (flags & FORK_SIGHAND && (flags & FORK_SHAREVM) == 0) @@ -331,6 +333,8 @@ fork1(struct proc *curp, int flags, void *stack, pid_t *tidptr, process_new(p, curpr, flags); pr = p->p_p; } + if (pr->ps_flags & PS_SYSTEM) + atomic_setbits_int(&p->p_flag, P_SYSTEM); /* * Duplicate sub-structures as needed. diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 39b7689edb0..8733f82cdb2 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_kthread.c,v 1.34 2014/02/12 05:47:36 guenther Exp $ */ +/* $OpenBSD: kern_kthread.c,v 1.35 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */ /*- @@ -67,15 +67,10 @@ kthread_create(void (*func)(void *), void *arg, * parent to wait for. */ error = fork1(&proc0, FORK_SHAREVM|FORK_SHAREFILES|FORK_NOZOMBIE| - FORK_SIGHAND, NULL, 0, func, arg, NULL, &p); + FORK_SYSTEM|FORK_SIGHAND, NULL, 0, func, arg, NULL, &p); if (error) return (error); - /* - * Mark it as a system process. - */ - atomic_setbits_int(&p->p_flag, P_SYSTEM); - /* Name it as specified. */ strlcpy(p->p_comm, name, sizeof p->p_comm); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 1482a3117fa..32e8527d3d0 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.31 2014/02/12 05:47:36 guenther Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.32 2014/05/04 05:03:26 guenther Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski * @@ -106,15 +106,10 @@ sched_kthreads_create(void *v) static int num; if (fork1(&proc0, FORK_SHAREVM|FORK_SHAREFILES|FORK_NOZOMBIE| - FORK_SIGHAND|FORK_IDLE, NULL, 0, sched_idle, ci, NULL, + FORK_SYSTEM|FORK_SIGHAND|FORK_IDLE, NULL, 0, sched_idle, ci, NULL, &spc->spc_idleproc)) panic("fork idle"); - /* - * Mark it as a system process. - */ - atomic_setbits_int(&spc->spc_idleproc->p_flag, P_SYSTEM); - /* Name it as specified. */ snprintf(spc->spc_idleproc->p_comm, sizeof(spc->spc_idleproc->p_comm), "idle%d", num); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index dd42647a2e6..0c15c8e1477 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.165 2014/05/04 03:53:37 deraadt Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.166 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -618,7 +618,6 @@ sys_kill(struct proc *cp, void *v, register_t *retval) int killpg1(struct proc *cp, int signum, int pgid, int all) { - struct proc *p; struct process *pr; struct pgrp *pgrp; int nfound = 0; @@ -628,13 +627,12 @@ killpg1(struct proc *cp, int signum, int pgid, int all) * broadcast */ LIST_FOREACH(pr, &allprocess, ps_list) { - p = pr->ps_mainproc; - if (pr->ps_pid <= 1 || p->p_flag & P_SYSTEM || + if (pr->ps_pid <= 1 || pr->ps_flags & PS_SYSTEM || pr == cp->p_p || !cansignal(cp, pr, signum)) continue; nfound++; if (signum) - psignal(p, signum); + prsignal(pr, signum); } else { if (pgid == 0) @@ -648,13 +646,12 @@ killpg1(struct proc *cp, int signum, int pgid, int all) return (ESRCH); } LIST_FOREACH(pr, &pgrp->pg_members, ps_pglist) { - p = pr->ps_mainproc; - if (pr->ps_pid <= 1 || p->p_flag & P_SYSTEM || + if (pr->ps_pid <= 1 || pr->ps_flags & PS_SYSTEM || !cansignal(cp, pr, signum)) continue; nfound++; - if (signum && P_ZOMBIE(p) == 0) - psignal(p, signum); + if (signum) + prsignal(pr, signum); } } return (nfound ? 0 : ESRCH); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 2d07834f844..e1950f3d766 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.247 2014/05/03 23:30:04 guenther Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.248 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -1252,7 +1252,7 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, * processes */ pp = pr->ps_mainproc; - if ((pp->p_flag & P_SYSTEM) || (pr->ps_flags & PS_EXITING) + if ((pr->ps_flags & (PS_SYSTEM | PS_EXITING)) || pp->p_stat == SIDL || pp->p_stat == SZOMB) continue; if (arg > 0 && pp->p_pid != (pid_t)arg) { @@ -1284,7 +1284,7 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, * skip system, exiting, embryonic and undead * processes */ - if ((pp->p_flag & P_SYSTEM) || (pr->ps_flags & PS_EXITING) + if ((pr->ps_flags & (PS_SYSTEM | PS_EXITING)) || pp->p_stat == SIDL || pp->p_stat == SZOMB) continue; if (arg >= 0 && pp->p_ucred->cr_uid != (uid_t)arg) { @@ -1418,7 +1418,7 @@ again: break; case KERN_PROC_ALL: - if (p->p_flag & P_SYSTEM) + if (pr->ps_flags & PS_SYSTEM) continue; break; @@ -1584,11 +1584,8 @@ sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp, return (0); } - if (vp->p_flag & P_SYSTEM) - return (EINVAL); - - /* Exiting - don't bother, it will be gone soon anyway */ - if (vp->p_p->ps_flags & PS_EXITING) + /* Either system process or exiting/zombie */ + if (vp->p_p->ps_flags & (PS_SYSTEM | PS_EXITING)) return (EINVAL); /* Execing - danger. */ @@ -1774,15 +1771,12 @@ sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, return (0); } - if (findp->p_flag & P_SYSTEM) - return (EINVAL); - - /* Exiting - don't bother, it will be gone soon anyway */ - if (findp->p_p->ps_flags & PS_EXITING) + /* Either system process or exiting/zombie */ + if (findp->p_p->ps_flags & (PS_SYSTEM | PS_EXITING)) return (EINVAL); /* Only owner or root can get cwd */ - if (findp->p_ucred->cr_uid != cp->p_ucred->cr_uid && + if (findp->p_p->ps_ucred->cr_uid != cp->p_ucred->cr_uid && (error = suser(cp, 0)) != 0) return (error); diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 2500fef5ae7..088d4f35fff 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_process.c,v 1.60 2014/03/30 21:54:48 guenther Exp $ */ +/* $OpenBSD: sys_process.c,v 1.61 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */ /*- @@ -185,7 +185,7 @@ sys_ptrace(struct proc *p, void *v, register_t *retval) /* * (2) it's a system process */ - if (ISSET(t->p_flag, P_SYSTEM)) + if (ISSET(tr->ps_flags, PS_SYSTEM)) return (EPERM); /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 33ec6d82e2b..cf4170ad2a8 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.184 2014/04/18 11:51:17 guenther Exp $ */ +/* $OpenBSD: proc.h,v 1.185 2014/05/04 05:03:26 guenther Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -242,12 +242,13 @@ struct process { #define PS_SINGLEUNWIND 0x00002000 /* Other threads must unwind. */ #define PS_NOZOMBIE 0x00004000 /* No signal or zombie at exit. */ #define PS_STOPPED 0x00008000 /* Just stopped, need sig to parent. */ +#define PS_SYSTEM 0x00010000 /* No sigs, stats or swapping. */ #define PS_BITS \ ("\20\01CONTROLT\02EXEC\03INEXEC\04EXITING\05SUGID" \ "\06SUGIDEXEC\07PPWAIT\010ISPWAIT\011PROFIL\012TRACED" \ "\013WAITED\014COREDUMP\015SINGLEEXIT\016SINGLEUNWIND" \ - "\017NOZOMBIE\020STOPPED") + "\017NOZOMBIE\020STOPPED\021SYSTEM") struct proc { @@ -415,6 +416,7 @@ struct uidinfo *uid_find(uid_t); #define FORK_IDLE 0x00000004 #define FORK_PPWAIT 0x00000008 #define FORK_SHAREFILES 0x00000010 +#define FORK_SYSTEM 0x00000020 #define FORK_NOZOMBIE 0x00000040 #define FORK_SHAREVM 0x00000080 #define FORK_TFORK 0x00000100 -- 2.20.1