diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d16746a..b4c966d 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2340,11 +2340,10 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, /* * 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)) { fdrop(fp, td); return (EBADF); } @@ -2444,6 +2443,13 @@ fgetvp_read(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) 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, diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 414a826..6494e6e 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -444,7 +444,7 @@ interpret: * Some might argue that CAP_READ and/or CAP_MMAP should also * be required here; such arguments will be entertained. */ - 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); diff --git a/sys/sys/file.h b/sys/sys/file.h index c4c6dbf..dc49895 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -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,