Apply by doing: cd /usr/src patch -p0 < 018_procfs.patch And then rebuild your kernel. For free, you also get the fix for a possible NULL dereference in execve(2). Index: sys/kern/kern_exec.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exec.c,v retrieving revision 1.33 retrieving revision 1.36 diff -u -r1.33 -r1.36 --- sys/kern/kern_exec.c 1999/08/09 12:19:07 1.33 +++ sys/kern/kern_exec.c 2000/01/20 01:16:50 1.36 @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.33 1999/08/09 12:19:07 millert Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.36 2000/01/20 01:16:50 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -425,7 +425,11 @@ arginfo.ps_nargvstr = argc; arginfo.ps_nenvstr = envc; +#ifdef MACHINE_STACK_GROWS_UP + stack = (char *)USRSTACK; +#else stack = (char *)(USRSTACK - len); +#endif /* Now copy argc, args & environ to new stack */ if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack, argp)) goto exec_abort; @@ -434,10 +438,16 @@ if (copyout(&arginfo, (char *)PS_STRINGS, sizeof(arginfo))) goto exec_abort; - /* copy out the process's signal trapoline code */ + /* copy out the process's signal trampoline code */ +#ifdef MACHINE_STACK_GROWS_UP if (szsigcode && copyout((char *)pack.ep_emul->e_sigcode, + ((char *)PS_STRINGS) + sizeof(struct ps_strings), szsigcode)) + goto exec_abort; +#else + if (szsigcode && copyout((char *)pack.ep_emul->e_sigcode, ((char *)PS_STRINGS) - szsigcode, szsigcode)) goto exec_abort; +#endif stopprofclock(p); /* stop profiling */ fdcloseexec(p); /* handle close on exec */ @@ -496,22 +506,39 @@ 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 setuid processes, a few caveats apply to stdin, stdout, + * and stderr. */ for (i = 0; i < 3; i++) { - extern struct fileops vnops; - struct nameidata nd; - struct file *fp; - int indx; - short flags; + struct file *fp = NULL; - flags = FREAD | (i == 0 ? 0 : FWRITE); + if (i < p->p_fd->fd_nfiles) + fp = p->p_fd->fd_ofiles[i]; - if (p->p_fd->fd_ofiles[i] == NULL) { +#ifdef PROCFS + /* + * Close descriptors that are writing to procfs. + */ + if (fp && fp->f_type == DTYPE_VNODE && + ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS && + (fp->f_flag & FWRITE)) { + fdrelease(p, i); + fp = NULL; + } +#endif + + /* + * 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. + */ + if (fp == NULL) { + short flags = FREAD | (i == 0 ? 0 : FWRITE); + extern struct fileops vnops; + struct nameidata nd; + int indx; + if ((error = falloc(p, &fp, &indx)) != 0) continue; NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, @@ -528,7 +555,6 @@ VOP_UNLOCK(nd.ni_vp, 0, p); } } - } else p->p_flag &= ~P_SUGID; p->p_cred->p_svuid = p->p_ucred->cr_uid; @@ -563,7 +589,11 @@ if((*pack.ep_emul->e_fixup)(p, &pack) != 0) goto free_pack_abort; } +#ifdef MACHINE_STACK_GROWS_UP + (*pack.ep_emul->e_setregs)(p, &pack, (u_long)stack + len, retval); +#else (*pack.ep_emul->e_setregs)(p, &pack, (u_long)stack, retval); +#endif if (p->p_flag & P_TRACED) psignal(p, SIGTRAP);