Index: sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.75
diff -u -r1.75 proc.h
--- sys/proc.h	2004/07/22 15:42:11	1.75
+++ sys/proc.h	2006/01/17 15:39:44
@@ -144,7 +144,8 @@
 	int	p_flag;			/* P_* flags. */
 	u_char	p_os;			/* OS tag */
 	char	p_stat;			/* S* process status. */
-	char	p_pad1[2];
+	char	p_pad1[1];
+	u_char	p_descfd;		/* if not 255, fdesc permits this fd */
 
 	pid_t	p_pid;			/* Process identifier. */
 	LIST_ENTRY(proc) p_hash;	/* Hash chain. */
Index: kern/kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.69
diff -u -r1.69 kern_descrip.c
--- kern/kern_descrip.c	2004/07/22 06:13:08	1.69
+++ kern/kern_descrip.c	2006/01/17 15:39:44
@@ -1222,6 +1222,17 @@
 	struct file *wfp;
 
 	/*
+	 * Assume that the filename was user-specified; applications do
+	 * not tend to opens of /dev/fd/# when they can just call dup()
+	 */
+	if ((curproc->p_flag & (P_SUGIDEXEC | P_SUGID))) {
+		if (curproc->p_descfd == 255)
+			return (EPERM);
+		if (curproc->p_descfd != curproc->p_dupfd)
+			return (EPERM);
+	}
+
+	/*
 	 * If the to-be-dup'd fd number is greater than the allowed number
 	 * of file descriptors, or the fd to be dup'd has already been
 	 * closed, reject. Note, there is no need to check for new == old
Index: kern/kern_exec.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.90
diff -u -r1.90 kern_exec.c
--- kern/kern_exec.c	2004/08/24 23:01:26	1.90
+++ kern/kern_exec.c	2006/01/17 15:39:44
@@ -635,6 +635,10 @@
 	    p->p_emul != pack.ep_emul)
 		(*p->p_emul->e_proc_exit)(p);
 
+	p->p_descfd = 255;
+	if ((pack.ep_flags & EXEC_HASFD) && pack.ep_fd < 255)
+		p->p_descfd = pack.ep_fd;
+
 	/*
 	 * Call exec hook. Emulation code may NOT store reference to anything
 	 * from &pack.
