In the not far future fd_getfile() will return the referenced file instance, so dupfdopen() should be modified for the same reasons that getsock() and getvnode().
The modified dupfdopen() receives a thread pointer instead of it's file descriptor table and of it's file descriptor for duplication. The thread pointer, passed to dupfdopen() and "current" thread pointer used within dupfdopen() are the same, so current was replaced by passed thread pointer. Thread struct has "p_dupfd" field which is descriptor for duplication, so it is used instead of removed "dfd" arg. Index: sys/kern/kern_descrip.c =================================================================== RCS file: /cvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.119 diff -u -p -r1.119 kern_descrip.c --- sys/kern/kern_descrip.c 30 Apr 2015 21:18:45 -0000 1.119 +++ sys/kern/kern_descrip.c 7 May 2015 23:22:23 -0000 @@ -1225,8 +1225,9 @@ filedescopen(dev_t dev, int mode, int ty * Duplicate the specified descriptor to a free descriptor. */ int -dupfdopen(struct filedesc *fdp, int indx, int dfd, int mode) +dupfdopen(struct proc *p, int indx, int mode) { + struct filedesc *fdp = p->p_fd; struct file *wfp; fdpassertlocked(fdp); @@ -1235,10 +1236,10 @@ dupfdopen(struct filedesc *fdp, int indx * Assume that the filename was user-specified; applications do * not tend to open /dev/fd/# when they can just call dup() */ - if ((curproc->p_p->ps_flags & (PS_SUGIDEXEC | PS_SUGID))) { - if (curproc->p_descfd == 255) + if ((p->p_p->ps_flags & (PS_SUGIDEXEC | PS_SUGID))) { + if (p->p_descfd == 255) return (EPERM); - if (curproc->p_descfd != curproc->p_dupfd) + if (p->p_descfd != p->p_dupfd) return (EPERM); } @@ -1249,7 +1250,7 @@ dupfdopen(struct filedesc *fdp, int indx * because fd_getfile will return NULL if the file at indx is * newly created by falloc (FIF_LARVAL). */ - if ((wfp = fd_getfile(fdp, dfd)) == NULL) + if ((wfp = fd_getfile(fdp, p->p_dupfd)) == NULL) return (EBADF); /* @@ -1263,7 +1264,7 @@ dupfdopen(struct filedesc *fdp, int indx fdp->fd_ofiles[indx] = wfp; fdp->fd_ofileflags[indx] = (fdp->fd_ofileflags[indx] & UF_EXCLOSE) | - (fdp->fd_ofileflags[dfd] & ~UF_EXCLOSE); + (fdp->fd_ofileflags[p->p_dupfd] & ~UF_EXCLOSE); wfp->f_count++; fd_used(fdp, indx); return (0); Index: sys/kern/vfs_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.220 diff -u -p -r1.220 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 7 May 2015 08:53:33 -0000 1.220 +++ sys/kern/vfs_syscalls.c 7 May 2015 23:22:23 -0000 @@ -862,8 +862,7 @@ doopenat(struct proc *p, int fd, const c if ((error = vn_open(&nd, flags, cmode)) != 0) { if (error == ENODEV && p->p_dupfd >= 0 && /* XXX from fdopen */ - (error = - dupfdopen(fdp, indx, p->p_dupfd, flags)) == 0) { + (error = dupfdopen(p, indx, flags)) == 0) { closef(fp, p); *retval = indx; goto out; Index: sys/sys/filedesc.h =================================================================== RCS file: /cvs/src/sys/sys/filedesc.h,v retrieving revision 1.30 diff -u -p -r1.30 filedesc.h --- sys/sys/filedesc.h 6 May 2015 08:52:17 -0000 1.30 +++ sys/sys/filedesc.h 7 May 2015 23:22:23 -0000 @@ -121,7 +121,7 @@ struct filedesc0 { * Kernel global variables and routines. */ void filedesc_init(void); -int dupfdopen(struct filedesc *, int, int, int); +int dupfdopen(struct proc *, int, int); int fdalloc(struct proc *p, int want, int *result); void fdexpand(struct proc *); int falloc(struct proc *p, struct file **resultfp, int *resultfd);