summaryrefslogtreecommitdiff
path: root/sys/kern/kern_prot.c
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2010-07-26 01:56:28 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2010-07-26 01:56:28 +0000
commit12738501a521de949783a0ef772f333a85a28079 (patch)
treea8d79b5579bc5fb4f0fe053219d7da149a912112 /sys/kern/kern_prot.c
parent58397ea88d58979fc9e046dc9c64692785b924ae (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.c78
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);