diff --git a/sys/vfs/fuse/fuse_vnops.c b/sys/vfs/fuse/fuse_vnops.c --- a/sys/vfs/fuse/fuse_vnops.c +++ b/sys/vfs/fuse/fuse_vnops.c @@ -1071,6 +1071,22 @@ freclen = FUSE_DIRENT_SIZE(fde); /* + * DF-0781: a malicious/buggy daemon may claim a name length that + * exceeds the remaining reply buffer (or is absurdly large). + * Without these checks, vop_write_dirent()'s bcopy(d_name, + * dp->d_name, d_namlen) reads past the daemon's reply buffer into + * adjacent kernel heap (info leak) and the subsequent + * `len -= freclen` underflows, advancing `buf` to a wild pointer + * (panic). Reject the entry instead. + */ + if (fde->namelen > NAME_MAX || + FUSE_NAME_OFFSET + fde->namelen > len || + freclen > len) { + error = EINVAL; + break; + } + + /* * Also see * getdirentries(2) in sys/kern/vfs_syscalls.c * readdir(3) in lib/libc/gen/readdir.c