+#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