summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2010-01-28 19:23:07 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2010-01-28 19:23:07 +0000
commitc8c4525ddb2c026993ac0bce3ef1651951330f8c (patch)
treeb9bf01fbf1cb0cf30f5efa759c63602a982fec30 /sys
parent2349c69070600289d40ea08fb6b49fa982532d83 (diff)
Make sure the process tree is is loop-free by forbidding ptrace()
of a direct ancestor, closing a localhost DoS. As an exception, do permit ptrace() of pid 1 and have inferiors() stop climbing if it hits that. ok tedu@ hpux_compat suggestion from miod@
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/hpux/hpux_compat.c20
-rw-r--r--sys/kern/kern_proc.c10
-rw-r--r--sys/kern/kern_prot.c4
-rw-r--r--sys/kern/sys_process.c10
-rw-r--r--sys/sys/proc.h4
5 files changed, 31 insertions, 17 deletions
diff --git a/sys/compat/hpux/hpux_compat.c b/sys/compat/hpux/hpux_compat.c
index 73193038c6f..f8baad27585 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.30 2008/11/01 05:59:21 deraadt Exp $ */
+/* $OpenBSD: hpux_compat.c,v 1.31 2010/01/28 19:23:06 guenther Exp $ */
/* $NetBSD: hpux_compat.c,v 1.35 1997/05/08 16:19:48 mycroft Exp $ */
/*
@@ -949,7 +949,7 @@ out:
/*
* This is the equivalent of BSD getpgrp but with more restrictions.
- * Note we do not check the real uid or "saved" uid.
+ * XXX Need to verify the differences between this and sys_getpgid()
*/
int
hpux_sys_getpgrp2(cp, v, retval)
@@ -960,13 +960,19 @@ hpux_sys_getpgrp2(cp, v, retval)
struct hpux_sys_getpgrp2_args *uap = v;
struct proc *p;
+ /* If zero, the call applies to the calling process */
if (SCARG(uap, pid) == 0)
- SCARG(uap, pid) = cp->p_pid;
- p = pfind(SCARG(uap, pid));
- if (p == 0)
+ p = cp;
+ else
+ p = pfind(SCARG(uap, pid));
+ if (p == NULL)
+ return (ESRCH);
+ /* Skip exiting processes. */
+ if (p->p_pgrp->pg_session->s_leader == NULL)
return (ESRCH);
- if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
- !inferior(p))
+ /* Both processes need to be in the same session. */
+ if (cp != p && cp->p_pgrp->pg_session->s_leader->p_pid !=
+ p->p_pgrp->pg_session->s_leader->p_pid)
return (EPERM);
*retval = p->p_pgid;
return (0);
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index ff2854c0dda..8c2eb86af41 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.40 2009/04/15 10:47:46 art Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.41 2010/01/28 19:23:06 guenther Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -151,14 +151,14 @@ chgproccnt(uid_t uid, int diff)
}
/*
- * Is p an inferior of the current process?
+ * Is p an inferior of parent?
*/
int
-inferior(struct proc *p)
+inferior(struct proc *p, struct proc *parent)
{
- for (; p != curproc; p = p->p_pptr)
- if (p->p_pid == 0)
+ for (; p != parent; p = p->p_pptr)
+ if (p->p_pid == 0 || p->p_pid == 1)
return (0);
return (1);
}
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 882a083656a..e707c68e0da 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_prot.c,v 1.40 2010/01/14 23:12:11 schwarze Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.41 2010/01/28 19:23:06 guenther Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
@@ -282,7 +282,7 @@ 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)) {
+ if ((targp = pfind(pid)) == 0 || !inferior(targp, curp)) {
error = ESRCH;
goto out;
}
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index cd58c064ddf..72a65276cff 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.43 2008/10/31 17:29:51 deraadt Exp $ */
+/* $OpenBSD: sys_process.c,v 1.44 2010/01/28 19:23:06 guenther Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -167,6 +167,14 @@ sys_ptrace(struct proc *p, void *v, register_t *retval)
*/
if ((t->p_pid == 1) && (securelevel > -1))
return (EPERM);
+
+ /*
+ * (6) it's an ancestor of the current process and
+ * not init (because that would create a loop in
+ * the process graph).
+ */
+ if (t->p_pid != 1 && inferior(p, t))
+ return (EINVAL);
break;
case PT_READ_I:
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 0c3b8d8413a..47548df5aee 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.122 2009/12/23 07:40:31 guenther Exp $ */
+/* $OpenBSD: proc.h,v 1.123 2010/01/28 19:23:06 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -419,7 +419,7 @@ int chgproccnt(uid_t uid, int diff);
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 inferior(struct proc *, struct proc *);
int leavepgrp(struct proc *p);
void yield(void);
void preempt(struct proc *);