O_PATH: allow vnode kevent filter on such files

if VREAD access is checked as allowed during open

Requested by:	wulf
Reviewed by:	markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29323
This commit is contained in:
Konstantin Belousov 2021-04-07 21:31:48 +03:00
parent f9b923af34
commit bbf7a4e878
6 changed files with 22 additions and 3 deletions

View File

@ -342,6 +342,9 @@ can be passed over a
socket using a
.Dv SCM_RIGHTS
message
.It Xr kqueue 2
using for
.Dv EVFILT_VNODE
.El
But operations like
.Xr read 2 ,

View File

@ -4988,7 +4988,7 @@ struct fileops path_fileops = {
.fo_truncate = badfo_truncate,
.fo_ioctl = badfo_ioctl,
.fo_poll = path_poll,
.fo_kqfilter = badfo_kqfilter,
.fo_kqfilter = vn_kqfilter_opath,
.fo_stat = vn_statfile,
.fo_close = path_close,
.fo_chmod = badfo_chmod,

View File

@ -1192,7 +1192,8 @@ kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
KASSERT(vp->v_type != VFIFO || (flags & O_PATH) != 0,
("Unexpected fifo fp %p vp %p", fp, vp));
if ((flags & O_PATH) != 0) {
finit_vnode(fp, flags, NULL, &path_fileops);
finit(fp, (flags & FMASK) | (fp->f_flag & FKQALLOWED),
DTYPE_VNODE, NULL, &path_fileops);
vhold(vp);
vunref(vp);
} else {

View File

@ -426,8 +426,12 @@ vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred,
if (error != 0)
return (error);
}
if ((fmode & O_PATH) != 0)
if ((fmode & O_PATH) != 0) {
error = VOP_ACCESS(vp, VREAD, cred, td);
if (error == 0)
fp->f_flag |= FKQALLOWED;
return (0);
}
if (vp->v_type == VFIFO && VOP_ISLOCKED(vp) != LK_EXCLUSIVE)
vn_lock(vp, LK_UPGRADE | LK_RETRY);
@ -2139,6 +2143,14 @@ vn_kqfilter(struct file *fp, struct knote *kn)
return (VOP_KQFILTER(fp->f_vnode, kn));
}
int
vn_kqfilter_opath(struct file *fp, struct knote *kn)
{
if ((fp->f_flag & FKQALLOWED) == 0)
return (EBADF);
return (vn_kqfilter(fp, kn));
}
/*
* Simplified in-kernel wrapper calls for extended attribute access.
* Both calls pass in a NULL credential, authorizing as "kernel" access.

View File

@ -153,6 +153,8 @@ typedef __pid_t pid_t;
#define FREVOKE O_VERIFY
/* Only for fo_close() from half-succeeded open */
#define FOPENFAILED O_TTY_INIT
/* Only for O_PATH files which passed ACCESS FREAD check on open */
#define FKQALLOWED O_RESOLVE_BENEATH
/* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
#define FFLAGS(oflags) ((oflags) & O_EXEC ? (oflags) : (oflags) + 1)

View File

@ -267,6 +267,7 @@ fo_stat_t vn_statfile;
fo_sendfile_t vn_sendfile;
fo_seek_t vn_seek;
fo_fill_kinfo_t vn_fill_kinfo;
fo_kqfilter_t vn_kqfilter_opath;
int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
void finit(struct file *, u_int, short, void *, struct fileops *);