Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107069004
D42081.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D42081.diff
View Options
diff --git a/sys/fs/fuse/fuse_ipc.h b/sys/fs/fuse/fuse_ipc.h
--- a/sys/fs/fuse/fuse_ipc.h
+++ b/sys/fs/fuse/fuse_ipc.h
@@ -239,6 +239,7 @@
#define FSESS_WARN_CACHE_INCOHERENT 0x200000 /* Read cache incoherent */
#define FSESS_WARN_WB_CACHE_INCOHERENT 0x400000 /* WB cache incoherent */
#define FSESS_WARN_ILLEGAL_INODE 0x800000 /* Illegal inode for new file */
+#define FSESS_WARN_READLINK_EMBEDDED_NUL 0x1000000 /* corrupt READLINK output */
#define FSESS_MNTOPTS_MASK ( \
FSESS_DAEMON_CAN_SPY | FSESS_PUSH_SYMLINKS_IN | \
FSESS_DEFAULT_PERMISSIONS | FSESS_INTR)
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -2007,6 +2007,13 @@
if (err) {
goto out;
}
+ if (strnlen(fdi.answ, fdi.iosize) + 1 < fdi.iosize) {
+ struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp));
+ fuse_warn(data, FSESS_WARN_READLINK_EMBEDDED_NUL,
+ "Returned an embedded NUL from FUSE_READLINK.");
+ err = EIO;
+ goto out;
+ }
if (((char *)fdi.answ)[0] == '/' &&
fuse_get_mpdata(vnode_mount(vp))->dataflags & FSESS_PUSH_SYMLINKS_IN) {
char *mpth = vnode_mount(vp)->mnt_stat.f_mntonname;
diff --git a/tests/sys/fs/fusefs/readlink.cc b/tests/sys/fs/fusefs/readlink.cc
--- a/tests/sys/fs/fusefs/readlink.cc
+++ b/tests/sys/fs/fusefs/readlink.cc
@@ -79,6 +79,45 @@
EXPECT_EQ(ELOOP, errno);
}
+/*
+ * If a malicious or buggy server returns a NUL in the FUSE_READLINK result, it
+ * should be handled gracefully.
+ * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274268
+ */
+TEST_F(Readlink, embedded_nul)
+{
+ const char FULLPATH[] = "mountpoint/src";
+ const char RELPATH[] = "src";
+ const char dst[] = "dst\0stuff";
+ char buf[80];
+ const uint64_t ino = 42;
+
+ EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH)
+ .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
+ SET_OUT_HEADER_LEN(out, entry);
+ out.body.entry.attr.mode = S_IFLNK | 0777;
+ out.body.entry.nodeid = ino;
+ out.body.entry.attr_valid = UINT64_MAX;
+ out.body.entry.entry_valid = UINT64_MAX;
+ })));
+
+ EXPECT_CALL(*m_mock, process(
+ ResultOf([=](auto in) {
+ return (in.header.opcode == FUSE_READLINK &&
+ in.header.nodeid == ino);
+ }, Eq(true)),
+ _)
+ ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) {
+ memcpy(out.body.str, dst, sizeof(dst));
+ out.header.len = sizeof(out.header) + sizeof(dst) + 1;
+ })));
+
+ EXPECT_EQ(-1, readlink(FULLPATH, buf, sizeof(buf)));
+ EXPECT_EQ(EIO, errno);
+ EXPECT_EQ(-1, access(FULLPATH, R_OK));
+ EXPECT_EQ(EIO, errno);
+}
+
TEST_F(Readlink, ok)
{
const char FULLPATH[] = "mountpoint/src";
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 3:14 PM (14 h, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15743659
Default Alt Text
D42081.diff (2 KB)
Attached To
Mode
D42081: Don't panic in vfs_lookup due to paths with embedded NULs
Attached
Detach File
Event Timeline
Log In to Comment