summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2008-11-01 05:59:20 +0000
committerderaadt <deraadt@openbsd.org>2008-11-01 05:59:20 +0000
commitc160d3550429e6a7312e295de8e9baa4ea8a0c06 (patch)
tree064399e5403eb7342d2aebdbff570f19b48cfd18
parentsprinkle ARGSUSED on dispatch handlers (diff)
downloadwireguard-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.c8
-rw-r--r--sys/kern/kern_proc.c47
-rw-r--r--sys/kern/kern_prot.c52
-rw-r--r--sys/sys/proc.h6
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);