git: b84ed4e7f626 - main - filemon: Reject FILEMON_SET_FD commands when the fd is a kqueue
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Feb 2022 14:47:06 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=b84ed4e7f626de5475cf26bae6d7ff15ec9f9675
commit b84ed4e7f626de5475cf26bae6d7ff15ec9f9675
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-02-03 14:41:17 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
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: syzbot+36e6be9e02735fe66ca8@syzkaller.appspotmail.com
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. */