diff options
author | 2008-11-01 05:59:20 +0000 | |
---|---|---|
committer | 2008-11-01 05:59:20 +0000 | |
commit | c160d3550429e6a7312e295de8e9baa4ea8a0c06 (patch) | |
tree | 064399e5403eb7342d2aebdbff570f19b48cfd18 | |
parent | sprinkle ARGSUSED on dispatch handlers (diff) | |
download | wireguard-openbsd-c160d3550429e6a7312e295de8e9baa4ea8a0c06.tar.xz wireguard-openbsd-c160d3550429e6a7312e295de8e9baa4ea8a0c06.zip |
change all callers of enterpgrp() to pre-allocate a pgrp or session if
it might be needed later -- before calling pfind(), so that enterpgrp()
can operate without sleeping
ok tedu
-rw-r--r-- | sys/compat/hpux/hpux_compat.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 47 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 52 | ||||
-rw-r--r-- | sys/sys/proc.h | 6 |
4 files changed, 77 insertions, 36 deletions
diff --git a/sys/compat/hpux/hpux_compat.c b/sys/compat/hpux/hpux_compat.c index a1c2e0f65b9..73193038c6f 100644 --- a/sys/compat/hpux/hpux_compat.c +++ b/sys/compat/hpux/hpux_compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hpux_compat.c,v 1.29 2007/09/22 09:57:40 martin Exp $ */ +/* $OpenBSD: hpux_compat.c,v 1.30 2008/11/01 05:59:21 deraadt Exp $ */ /* $NetBSD: hpux_compat.c,v 1.35 1997/05/08 16:19:48 mycroft Exp $ */ /* @@ -63,6 +63,7 @@ #include <sys/stat.h> #include <sys/syslog.h> #include <sys/malloc.h> +#include <sys/pool.h> #include <sys/mount.h> #include <sys/ipc.h> #include <sys/user.h> @@ -1163,9 +1164,12 @@ hpux_sys_setpgrp_6x(p, v, retval) void *v; register_t *retval; { + struct pgrp *npgrp; + + npgrp = pool_get(&pgrp_pool, PR_WAITOK); if (p->p_pid != p->p_pgid) - enterpgrp(p, p->p_pid, 0); + enterpgrp(p, p->p_pid, npgrp, NULL); *retval = p->p_pgid; return (0); } diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index e97e929255d..9bbe506f971 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_proc.c,v 1.38 2008/10/31 17:17:03 deraadt Exp $ */ +/* $OpenBSD: kern_proc.c,v 1.39 2008/11/01 05:59:21 deraadt Exp $ */ /* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */ /* @@ -193,20 +193,22 @@ pgfind(pid_t pgid) /* * 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. */ int -enterpgrp(struct proc *p, pid_t pgid, int mksess) +enterpgrp(struct proc *p, pid_t pgid, struct pgrp *newpgrp, + struct session *newsess) { struct pgrp *pgrp = pgfind(pgid); #ifdef DIAGNOSTIC - if (pgrp != NULL && mksess) /* firewalls */ + if (pgrp != NULL && newsess) /* firewalls */ panic("enterpgrp: setsid into non-empty pgrp"); if (SESS_LEADER(p)) panic("enterpgrp: session leader attempted setpgrp"); #endif if (pgrp == NULL) { - pid_t savepid = p->p_pid; struct proc *np; /* * new process group @@ -215,24 +217,27 @@ enterpgrp(struct proc *p, pid_t pgid, int mksess) if (p->p_pid != pgid) panic("enterpgrp: new pgrp and pid != pgid"); #endif - if ((np = pfind(savepid)) == NULL || np != p) + + if ((np = pfind(p->p_pid)) == NULL || np != p) { + pool_put(&pgrp_pool, newpgrp); + if (newsess) + pool_put(&session_pool, newsess); return (ESRCH); - pgrp = pool_get(&pgrp_pool, PR_WAITOK); - if (mksess) { - struct session *sess; + } + pgrp = newpgrp; + if (newsess) { /* * new session */ - sess = pool_get(&session_pool, PR_WAITOK); - sess->s_leader = p; - sess->s_count = 1; - sess->s_ttyvp = NULL; - sess->s_ttyp = NULL; - bcopy(p->p_session->s_login, sess->s_login, - sizeof(sess->s_login)); + newsess->s_leader = p; + newsess->s_count = 1; + newsess->s_ttyvp = NULL; + newsess->s_ttyp = NULL; + bcopy(p->p_session->s_login, newsess->s_login, + sizeof(newsess->s_login)); atomic_clearbits_int(&p->p_flag, P_CONTROLT); - pgrp->pg_session = sess; + pgrp->pg_session = newsess; #ifdef DIAGNOSTIC if (p != curproc) panic("enterpgrp: mksession and p != curproc"); @@ -245,8 +250,16 @@ enterpgrp(struct proc *p, pid_t pgid, int mksess) LIST_INIT(&pgrp->pg_members); LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); pgrp->pg_jobc = 0; - } else if (pgrp == p->p_pgrp) + } else if (pgrp == p->p_pgrp) { + if (newsess) + pool_put(&session_pool, newsess); + pool_put(&pgrp_pool, newpgrp); return (0); + } else { + if (newsess) + pool_put(&session_pool, newsess); + pool_put(&pgrp_pool, newpgrp); + } /* * Adjust eligibility of affected pgrps to participate in job control. diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 7379a924540..4b0185952e2 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_prot.c,v 1.36 2008/10/31 17:17:04 deraadt Exp $ */ +/* $OpenBSD: kern_prot.c,v 1.37 2008/11/01 05:59:21 deraadt Exp $ */ /* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */ /* @@ -233,11 +233,18 @@ sys_getgroups(struct proc *p, void *v, register_t *retval) int sys_setsid(struct proc *p, void *v, register_t *retval) { + struct session *newsess; + struct pgrp *newpgrp; + + newsess = pool_get(&session_pool, PR_WAITOK); + newpgrp = pool_get(&pgrp_pool, PR_WAITOK); if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { + pool_put(&pgrp_pool, newpgrp); + pool_put(&session_pool, newsess); return (EPERM); } else { - (void)enterpgrp(p, p->p_pid, 1); + (void) enterpgrp(p, p->p_pid, newpgrp, newsess); *retval = p->p_pid; return (0); } @@ -265,9 +272,9 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval) syscallarg(int) pgid; } */ *uap = v; struct proc *targp; /* target process */ - struct pgrp *pgrp; /* target pgrp */ + struct pgrp *pgrp, *newpgrp; /* target pgrp */ pid_t pid; - int pgid; + int pgid, error; pid = SCARG(uap, pid); pgid = SCARG(uap, pgid); @@ -275,24 +282,39 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval) if (pgid < 0) return (EINVAL); + newpgrp = pool_get(&pgrp_pool, PR_WAITOK); + if (pid != 0 && pid != curp->p_pid) { - if ((targp = pfind(pid)) == 0 || !inferior(targp)) - return (ESRCH); - if (targp->p_session != curp->p_session) - return (EPERM); - if (targp->p_flag & P_EXEC) - return (EACCES); + if ((targp = pfind(pid)) == 0 || !inferior(targp)) { + error = ESRCH; + goto out; + } + if (targp->p_session != curp->p_session) { + error = EPERM; + goto out; + } + if (targp->p_flag & P_EXEC) { + error = EACCES; + goto out; + } } else targp = curp; - if (SESS_LEADER(targp)) - return (EPERM); + if (SESS_LEADER(targp)) { + error = EPERM; + goto out; + } if (pgid == 0) pgid = targp->p_pid; else if (pgid != targp->p_pid) if ((pgrp = pgfind(pgid)) == 0 || - pgrp->pg_session != curp->p_session) - return (EPERM); - return (enterpgrp(targp, pgid, 0)); + pgrp->pg_session != curp->p_session) { + error = EPERM; + goto out; + } + return (enterpgrp(targp, pgid, newpgrp, NULL)); +out: + pool_put(&pgrp_pool, newpgrp); + return (error); } /* ARGSUSED */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a52b35b528f..cbea6649d1c 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.108 2008/10/14 18:27:29 guenther Exp $ */ +/* $OpenBSD: proc.h,v 1.109 2008/11/01 05:59:20 deraadt Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -400,6 +400,7 @@ extern struct pool proc_pool; /* memory pool for procs */ extern struct pool rusage_pool; /* memory pool for zombies */ extern struct pool ucred_pool; /* memory pool for ucreds */ extern struct pool session_pool; /* memory pool for sessions */ +extern struct pool pgrp_pool; /* memory pool for pgrps */ extern struct pool pcred_pool; /* memory pool for pcreds */ struct simplelock; @@ -410,7 +411,8 @@ void proc_printit(struct proc *p, const char *modif, int (*pr)(const char *, ...)); int chgproccnt(uid_t uid, int diff); -int enterpgrp(struct proc *p, pid_t pgid, int mksess); +int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *newpgrp, + struct session *newsess); void fixjobc(struct proc *p, struct pgrp *pgrp, int entering); int inferior(struct proc *p); int leavepgrp(struct proc *p); |