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);