Author: mjg
Date: Sun Jul  8 00:51:38 2012
New Revision: 238220
URL: http://svn.freebsd.org/changeset/base/238220

Log:
  Unbreak handling of descriptors opened with O_EXEC by fexecve(2).
  
  While here return EBADF for descriptors opened for writing (previously it was 
ETXTBSY).
  
  Add fgetvp_exec function which performs appropriate checks.
  
  PR:           kern/169651
  In collaboration with:        kib
  Approved by:  trasz (mentor)
  MFC after:    1 week

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/kern/kern_exec.c
  head/sys/sys/file.h

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Sat Jul  7 22:22:13 2012        
(r238219)
+++ head/sys/kern/kern_descrip.c        Sun Jul  8 00:51:38 2012        
(r238220)
@@ -2340,11 +2340,11 @@ _fget(struct thread *td, int fd, struct 
 
        /*
         * FREAD and FWRITE failure return EBADF as per POSIX.
-        *
-        * Only one flag, or 0, may be specified.
         */
        if ((flags == FREAD && (fp->f_flag & FREAD) == 0) ||
-           (flags == FWRITE && (fp->f_flag & FWRITE) == 0)) {
+           (flags == FWRITE && (fp->f_flag & FWRITE) == 0) ||
+           (flags == (FREAD | FEXEC) &&
+           (((fp->f_flag & flags) == 0) || ((fp->f_flag & FWRITE) != 0)))) {
                fdrop(fp, td);
                return (EBADF);
        }
@@ -2444,6 +2444,13 @@ fgetvp_read(struct thread *td, int fd, c
        return (_fgetvp(td, fd, FREAD, rights, NULL, vpp));
 }
 
+int
+fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp)
+{
+
+       return (_fgetvp(td, fd, FREAD | FEXEC, rights, NULL, vpp));
+}
+
 #ifdef notyet
 int
 fgetvp_write(struct thread *td, int fd, cap_rights_t rights,

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c   Sat Jul  7 22:22:13 2012        (r238219)
+++ head/sys/kern/kern_exec.c   Sun Jul  8 00:51:38 2012        (r238220)
@@ -443,8 +443,10 @@ interpret:
                /*
                 * Some might argue that CAP_READ and/or CAP_MMAP should also
                 * be required here; such arguments will be entertained.
+                *
+                * Descriptors opened only with O_EXEC or O_RDONLY are allowed.
                 */
-               error = fgetvp_read(td, args->fd, CAP_FEXECVE, &binvp);
+               error = fgetvp_exec(td, args->fd, CAP_FEXECVE, &binvp);
                if (error)
                        goto exec_fail;
                vfslocked = VFS_LOCK_GIANT(binvp->v_mount);

Modified: head/sys/sys/file.h
==============================================================================
--- head/sys/sys/file.h Sat Jul  7 22:22:13 2012        (r238219)
+++ head/sys/sys/file.h Sun Jul  8 00:51:38 2012        (r238220)
@@ -238,6 +238,8 @@ fo_chown_t  invfo_chown;
 
 void finit(struct file *, u_int, short, void *, struct fileops *);
 int fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp);
+int fgetvp_exec(struct thread *td, int fd, cap_rights_t rights,
+    struct vnode **vpp);
 int fgetvp_rights(struct thread *td, int fd, cap_rights_t need,
     cap_rights_t *have, struct vnode **vpp);
 int fgetvp_read(struct thread *td, int fd, cap_rights_t rights,
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to