The branch main has been updated by markj:

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

commit b84ed4e7f626de5475cf26bae6d7ff15ec9f9675
Author:     Mark Johnston <[email protected]>
AuthorDate: 2022-02-03 14:41:17 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2022-02-03 14:41:53 +0000

    filemon: Reject FILEMON_SET_FD commands when the fd is a kqueue
    
    When FILEMON_SET_FD is used, the filemon handle effectively wraps the
    passed file.  In particular, the handle may be inherited by a child
    process, or transferred over a unix domain socket, so we must verify
    that the backing file permits this.
    
    Reported by:    [email protected]
    Reviewed by:    emaste
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D34128
---
 sys/dev/filemon/filemon.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c
index cd48c68d8b04..4c3a23a53042 100644
--- a/sys/dev/filemon/filemon.c
+++ b/sys/dev/filemon/filemon.c
@@ -359,9 +359,10 @@ static int
 filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
     struct thread *td)
 {
-       int error = 0;
        struct filemon *filemon;
+       struct file *fp;
        struct proc *p;
+       int error;
 
        if ((error = devfs_get_cdevpriv((void **) &filemon)) != 0)
                return (error);
@@ -376,12 +377,21 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, 
int flag __unused,
                        break;
                }
 
-               error = fget_write(td, *(int *)data,
-                   &cap_pwrite_rights,
-                   &filemon->fp);
-               if (error == 0)
+               error = fget_write(td, *(int *)data, &cap_pwrite_rights, &fp);
+               if (error == 0) {
+                       /*
+                        * The filemon handle may be passed to another process,
+                        * so the underlying file handle must support this.
+                        */
+                       if ((fp->f_ops->fo_flags & DFLAG_PASSABLE) == 0) {
+                               fdrop(fp, curthread);
+                               error = EINVAL;
+                               break;
+                       }
+                       filemon->fp = fp;
                        /* Write the file header. */
                        filemon_write_header(filemon);
+               }
                break;
 
        /* Set the monitored process ID. */

Reply via email to