mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
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
This commit is contained in:
parent
7027e4dac4
commit
28a7f60741
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238220
@ -2340,11 +2340,11 @@ _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) || ((fp->f_flag & FWRITE) != 0)))) {
|
||||
fdrop(fp, td);
|
||||
return (EBADF);
|
||||
}
|
||||
@ -2444,6 +2444,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,
|
||||
|
@ -443,8 +443,10 @@ do_execve(td, args, mac_p)
|
||||
/*
|
||||
* 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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user