diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2010-07-26 01:56:28 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2010-07-26 01:56:28 +0000 |
commit | 12738501a521de949783a0ef772f333a85a28079 (patch) | |
tree | a8d79b5579bc5fb4f0fe053219d7da149a912112 /sys/kern/kern_prot.c | |
parent | 58397ea88d58979fc9e046dc9c64692785b924ae (diff) |
Correct the links between threads, processes, pgrps, and sessions,
so that the process-level stuff is to/from struct process and not
struct proc. This fixes a bunch of problem cases in rthreads.
Based on earlier work by blambert and myself, but mostly written
at c2k10.
Tested by many: deraadt, sthen, krw, ray, and in snapshots
Diffstat (limited to 'sys/kern/kern_prot.c')
-rw-r--r-- | sys/kern/kern_prot.c | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 3f49186d5c2..a34714c4ba5 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_prot.c,v 1.45 2010/07/01 02:41:12 guenther Exp $ */ +/* $OpenBSD: kern_prot.c,v 1.46 2010/07/26 01:56:27 guenther Exp $ */ /* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */ /* @@ -59,8 +59,8 @@ int sys_getpid(struct proc *p, void *v, register_t *retval) { - retval[0] = p->p_p->ps_mainproc->p_pid; - retval[1] = p->p_p->ps_mainproc->p_pptr->p_pid; + retval[0] = p->p_p->ps_pid; + retval[1] = p->p_p->ps_pptr->ps_pid; return (0); } @@ -80,7 +80,7 @@ int sys_getppid(struct proc *p, void *v, register_t *retval) { - *retval = p->p_p->ps_mainproc->p_pptr->p_pid; + *retval = p->p_p->ps_pptr->ps_pid; return (0); } @@ -89,7 +89,7 @@ int sys_getpgrp(struct proc *p, void *v, register_t *retval) { - *retval = p->p_pgrp->pg_id; + *retval = p->p_p->ps_pgrp->pg_id; return (0); } @@ -102,16 +102,16 @@ sys_getpgid(struct proc *curp, void *v, register_t *retval) struct sys_getpgid_args /* { syscallarg(pid_t) pid; } */ *uap = v; - struct proc *targp = curp; + struct process *targpr = curp->p_p; - if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid) + if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == targpr->ps_pid) goto found; - if ((targp = pfind(SCARG(uap, pid))) == NULL) + if ((targpr = prfind(SCARG(uap, pid))) == NULL) return (ESRCH); - if (targp->p_session != curp->p_session) + if (targpr->ps_session != curp->p_p->ps_session) return (EPERM); found: - *retval = targp->p_pgid; + *retval = targpr->ps_pgid; return (0); } @@ -121,19 +121,19 @@ sys_getsid(struct proc *curp, void *v, register_t *retval) struct sys_getsid_args /* { syscallarg(pid_t) pid; } */ *uap = v; - struct proc *targp = curp; + struct process *targpr = curp->p_p; - if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid) + if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == targpr->ps_pid) goto found; - if ((targp = pfind(SCARG(uap, pid))) == NULL) + if ((targpr = prfind(SCARG(uap, pid))) == NULL) return (ESRCH); - if (targp->p_session != curp->p_session) + if (targpr->ps_session != curp->p_p->ps_session) return (EPERM); found: /* Skip exiting processes */ - if (targp->p_pgrp->pg_session->s_leader == NULL) + if (targpr->ps_pgrp->pg_session->s_leader == NULL) return (ESRCH); - *retval = targp->p_pgrp->pg_session->s_leader->p_pid; + *retval = targpr->ps_pgrp->pg_session->s_leader->ps_pid; return (0); } @@ -223,17 +223,19 @@ sys_setsid(struct proc *p, void *v, register_t *retval) { struct session *newsess; struct pgrp *newpgrp; + struct process *pr = p->p_p; + pid_t pid = pr->ps_pid; 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)) { + if (pr->ps_pgid == pid || pgfind(pid)) { pool_put(&pgrp_pool, newpgrp); pool_put(&session_pool, newsess); return (EPERM); } else { - (void) enterpgrp(p, p->p_pid, newpgrp, newsess); - *retval = p->p_pid; + (void) enterpgrp(pr, pid, newpgrp, newsess); + *retval = pid; return (0); } } @@ -259,7 +261,8 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval) syscallarg(pid_t) pid; syscallarg(int) pgid; } */ *uap = v; - struct proc *targp; /* target process */ + struct process *curpr = curp->p_p; + struct process *targpr; /* target process */ struct pgrp *pgrp, *newpgrp; /* target pgrp */ pid_t pid; int pgid, error; @@ -272,34 +275,34 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval) newpgrp = pool_get(&pgrp_pool, PR_WAITOK); - if (pid != 0 && pid != curp->p_pid) { - if ((targp = pfind(pid)) == 0 || !inferior(targp, curp)) { + if (pid != 0 && pid != curpr->ps_pid) { + if ((targpr = prfind(pid)) == 0 || !inferior(targpr, curpr)) { error = ESRCH; goto out; } - if (targp->p_session != curp->p_session) { + if (targpr->ps_session != curpr->ps_session) { error = EPERM; goto out; } - if (targp->p_flag & P_EXEC) { + if (targpr->ps_mainproc->p_flag & P_EXEC) { error = EACCES; goto out; } } else - targp = curp; - if (SESS_LEADER(targp)) { + targpr = curpr; + if (SESS_LEADER(targpr)) { error = EPERM; goto out; } if (pgid == 0) - pgid = targp->p_pid; - else if (pgid != targp->p_pid) + pgid = targpr->ps_pid; + else if (pgid != targpr->ps_pid) if ((pgrp = pgfind(pgid)) == 0 || - pgrp->pg_session != curp->p_session) { + pgrp->pg_session != curpr->ps_session) { error = EPERM; goto out; } - return (enterpgrp(targp, pgid, newpgrp, NULL)); + return (enterpgrp(targpr, pgid, newpgrp, NULL)); out: pool_put(&pgrp_pool, newpgrp); return (error); @@ -843,11 +846,12 @@ sys_getlogin(struct proc *p, void *v, register_t *retval) syscallarg(char *) namebuf; syscallarg(u_int) namelen; } */ *uap = v; + struct session *s = p->p_p->ps_pgrp->pg_session; - if (SCARG(uap, namelen) > sizeof (p->p_pgrp->pg_session->s_login)) - SCARG(uap, namelen) = sizeof (p->p_pgrp->pg_session->s_login); - return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, - (caddr_t) SCARG(uap, namebuf), SCARG(uap, namelen))); + if (SCARG(uap, namelen) > sizeof(s->s_login)) + SCARG(uap, namelen) = sizeof(s->s_login); + return (copyout((caddr_t)s->s_login, + (caddr_t)SCARG(uap, namebuf), SCARG(uap, namelen))); } /* @@ -860,13 +864,13 @@ sys_setlogin(struct proc *p, void *v, register_t *retval) struct sys_setlogin_args /* { syscallarg(const char *) namebuf; } */ *uap = v; + struct session *s = p->p_p->ps_pgrp->pg_session; int error; if ((error = suser(p, 0)) != 0) return (error); - error = copyinstr((caddr_t) SCARG(uap, namebuf), - (caddr_t) p->p_pgrp->pg_session->s_login, - sizeof (p->p_pgrp->pg_session->s_login), (size_t *)0); + error = copyinstr((caddr_t)SCARG(uap, namebuf), (caddr_t)s->s_login, + sizeof(s->s_login), NULL); if (error == ENAMETOOLONG) error = EINVAL; return (error); |