The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=bbf7a4e878ed6828d13c7029c128a7e60dc25391

commit bbf7a4e878ed6828d13c7029c128a7e60dc25391
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-04-07 18:31:48 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-04-15 09:49:18 +0000

    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
---
 lib/libc/sys/open.2     |  3 +++
 sys/kern/kern_descrip.c |  2 +-
 sys/kern/vfs_syscalls.c |  3 ++-
 sys/kern/vfs_vnops.c    | 14 +++++++++++++-
 sys/sys/fcntl.h         |  2 ++
 sys/sys/file.h          |  1 +
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index 06a877e34460..a7806df69daf 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -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 ,
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index a28e94634326..30ac40ffe296 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -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,
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9130843f6761..43104a472b5b 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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 {
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index bb9ee2cceb79..9da35721def4 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -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.
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
index c328abaa02af..58d46ae26338 100644
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -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)
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 9237ee5ceb9d..b16e23bdfbcf 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -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 *);
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to