Apply by doing: cd /usr/src patch -p0 < 008_fd.patch Rebuild your kernel. And then rebuild and install authpf: cd usr.sbin/authpf make obj make make install Index: sys/sys/proc.h =================================================================== RCS file: /cvs/src/sys/sys/proc.h,v retrieving revision 1.77 retrieving revision 1.77.2.1 diff -u -p -r1.77 -r1.77.2.1 --- sys/sys/proc.h 10 Mar 2005 17:26:10 -0000 1.77 +++ sys/sys/proc.h 30 Dec 2005 01:28:02 -0000 1.77.2.1 @@ -144,7 +144,8 @@ struct proc { 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: sys/kern/kern_descrip.c =================================================================== RCS file: /cvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.69 retrieving revision 1.69.4.1 diff -u -p -r1.69 -r1.69.4.1 --- sys/kern/kern_descrip.c 22 Jul 2004 06:13:08 -0000 1.69 +++ sys/kern/kern_descrip.c 30 Dec 2005 01:28:02 -0000 1.69.4.1 @@ -1220,6 +1220,17 @@ dupfdopen(fdp, indx, dfd, mode, error) int error; { 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 Index: sys/kern/kern_exec.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exec.c,v retrieving revision 1.91 retrieving revision 1.91.2.1 diff -u -p -r1.91 -r1.91.2.1 --- sys/kern/kern_exec.c 9 Mar 2005 17:41:29 -0000 1.91 +++ sys/kern/kern_exec.c 30 Dec 2005 01:28:02 -0000 1.91.2.1 @@ -634,6 +634,10 @@ sys_execve(p, v, retval) if (p->p_emul && p->p_emul->e_proc_exit && 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 Index: usr.sbin/authpf/authpf.c =================================================================== RCS file: /cvs/src/usr.sbin/authpf/authpf.c,v retrieving revision 1.89 retrieving revision 1.89.2.1 diff -u -p -r1.89 -r1.89.2.1 --- usr.sbin/authpf/authpf.c 10 Feb 2005 04:24:15 -0000 1.89 +++ usr.sbin/authpf/authpf.c 18 Dec 2005 04:18:25 -0000 1.89.2.1 @@ -92,6 +92,7 @@ main(int argc, char *argv[]) struct in6_addr ina; struct passwd *pw; char *cp; + gid_t gid; uid_t uid; char *shell; login_cap_t *lc; @@ -257,10 +258,16 @@ main(int argc, char *argv[]) fclose(pidfp); } while (1); + /* whack the group list */ + gid = getegid(); + if (setgroups(1, &gid) == -1) { + syslog(LOG_INFO, "setgroups: %s", strerror(errno)); + do_death(0); + } + /* revoke privs */ seteuid(getuid()); setuid(getuid()); - openlog("authpf", LOG_PID | LOG_NDELAY, LOG_DAEMON); if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(luser)) { @@ -633,6 +640,7 @@ change_filter(int add, const char *luser char *fdpath = NULL, *userstr = NULL, *ipstr = NULL; char *rsn = NULL, *fn = NULL; pid_t pid; + gid_t gid; int s; if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) { @@ -674,6 +682,11 @@ change_filter(int add, const char *luser case -1: err(1, "fork failed"); case 0: + /* revoke group privs before exec */ + gid = getgid(); + if (setregid(gid, gid) == -1) { + err(1, "setregid"); + } execvp(PATH_PFCTL, pargv); warn("exec of %s failed", PATH_PFCTL); _exit(1);