diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2008-11-01 05:59:22 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2008-11-01 05:59:22 +0000 |
commit | aa813f454ea87b333effafe597d250f4340b3432 (patch) | |
tree | 228067666e617b0710c893c00beabe232089090d /sys/kern/kern_prot.c | |
parent | 4970aa6bbe2ea68e5cfcb70b07f73ae27f5702c1 (diff) |
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
Diffstat (limited to 'sys/kern/kern_prot.c')
-rw-r--r-- | sys/kern/kern_prot.c | 52 |
1 files changed, 37 insertions, 15 deletions
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 */ |