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

Reply via email to