diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-02 08:53:05 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-02 08:53:05 +0000 |
commit | 8d55b2b5e86caddbaa52430c868610b702845e50 (patch) | |
tree | 5cb36b789560ca1aab4f21016e0a686d59758d83 | |
parent | 6cb7bd865482408d42b831ca725fbf1980a6aa2f (diff) |
for sugid procs ensure that fd 0-2 are allocated slots (by pointing at
/dev/null -- future patch will use a dead vnode of some sort) to prevent
reuse (ie. new allocations) of these fd which libc makes many assumptions
about; problem noted by James Youngman
-rw-r--r-- | sys/kern/kern_exec.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 1c7ccd95528..f4d2dca6669 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.19 1998/06/27 07:32:12 deraadt Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.20 1998/07/02 08:53:04 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -456,6 +456,8 @@ sys_execve(p, v, retval) * MNT_NOEXEC and P_TRACED have already been used to disable s[ug]id. */ if ((attr.va_mode & (VSUID | VSGID))) { + int i; + #ifdef KTRACE /* * If process is being ktraced, turn off - unless @@ -474,6 +476,41 @@ sys_execve(p, v, retval) p->p_ucred->cr_gid = attr.va_gid; p->p_flag |= P_SUGID; p->p_flag |= P_SUGIDEXEC; + + /* + * XXX For setuid processes, attempt to ensure that + * stdin, stdout, and stderr are already allocated. + * We do not want userland to accidentally allocate + * descriptors in this range which has implied meaning + * to libc. + */ + for (i = 0; i < 3; i++) { + extern struct fileops vnops; + struct nameidata nd; + struct file *fp; + int indx; + + if (p->p_fd->fd_ofiles[i] == NULL) { + printf("need %d\n", i); + if ((error = falloc(p, &fp, &indx)) != 0) + continue; + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, + "/dev/null", p); + if ((error = vn_open(&nd, FREAD, 0)) != 0) { + printf("failed %d\n", i); + ffree(fp); + p->p_fd->fd_ofiles[indx] = NULL; + break; + } + printf("got %d\n", i); + fp->f_flag = FREAD; + fp->f_type = DTYPE_VNODE; + fp->f_ops = &vnops; + fp->f_data = (caddr_t)nd.ni_vp; + VOP_UNLOCK(nd.ni_vp, 0, p); + } + } + } else p->p_flag &= ~P_SUGID; p->p_cred->p_svuid = p->p_ucred->cr_uid; |