svn commit: r238220 - in head/sys: kern sys
Mateusz Guzik
mjg at FreeBSD.org
Sun Jul 8 00:51:39 UTC 2012
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,
More information about the svn-src-all
mailing list