Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:06:18 -0000
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r345958 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Message-ID:  <201904051721.x35HLNIX020006@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Fri Apr  5 17:21:23 2019
New Revision: 345958
URL: https://svnweb.freebsd.org/changeset/base/345958

Log:
  fusefs: enforce -onoallow_other even beneath the mountpoint
  
  When -o allow_other is not in use, fusefs is supposed to prevent access to
  the filesystem by any user other than the one who owns the daemon.  Our
  fusefs implementation was only enforcing that restriction at the mountpoint
  itself.  That was usually good enough because lookup usually descends from
  the mountpoint.  However, there are cases when it doesn't, such as when
  using openat relative to a file beneath the mountpoint.
  
  PR:		237052
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_internal.c
  projects/fuse2/tests/sys/fs/fusefs/allow_other.cc

Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.c	Fri Apr  5 16:54:20 2019	(r345957)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.c	Fri Apr  5 17:21:23 2019	(r345958)
@@ -140,7 +140,7 @@ fuse_internal_access(struct vnode *vp,
 		return EROFS;
 	}
 	/* Unless explicitly permitted, deny everyone except the fs owner. */
-	    if (vnode_isvroot(vp) && !(facp->facc_flags & FACCESS_NOCHECKSPY)) {
+	if (!(facp->facc_flags & FACCESS_NOCHECKSPY)) {
 		if (!(dataflags & FSESS_DAEMON_CAN_SPY)) {
 			int denied = fuse_match_cred(data->daemoncred,
 			    cred);
@@ -149,6 +149,10 @@ fuse_internal_access(struct vnode *vp,
 				return EPERM;
 			}
 		}
+		/* 
+		 * Set the "skip cred check" flag so future callers that share
+		 * facp can skip fuse_match_cred.
+		 */
 		facp->facc_flags |= FACCESS_NOCHECKSPY;
 	}
 	if (!(facp->facc_flags & FACCESS_DO_ACCESS)) {

Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Fri Apr  5 16:54:20 2019	(r345957)
+++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Fri Apr  5 17:21:23 2019	(r345958)
@@ -179,3 +179,48 @@ TEST_F(NoAllowOther, disallowed)
 		}
 	);
 }
+
+/* 
+ * When -o allow_other is not used, users other than the owner aren't allowed
+ * to open anything inside of the mount point, not just the mountpoint itself
+ * This is a regression test for bug 237052
+ */
+TEST_F(NoAllowOther, disallowed_beneath_root)
+{
+	const static char FULLPATH[] = "mountpoint/some_dir";
+	const static char RELPATH[] = "some_dir";
+	const static char RELPATH2[] = "other_dir";
+	const static uint64_t ino = 42;
+	const static uint64_t ino2 = 43;
+	int dfd;
+
+	expect_lookup(RELPATH, ino, S_IFDIR | 0755, 0, 1);
+	EXPECT_LOOKUP(ino, RELPATH2)
+	.WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
+		SET_OUT_HEADER_LEN(out, entry);
+		out->body.entry.attr.mode = S_IFREG | 0644;
+		out->body.entry.nodeid = ino2;
+		out->body.entry.attr.nlink = 1;
+		out->body.entry.attr_valid = UINT64_MAX;
+	})));
+	expect_opendir(ino);
+	dfd = open(FULLPATH, O_DIRECTORY);
+	ASSERT_LE(0, dfd) << strerror(errno);
+
+	fork(true, [] {
+		}, [&]() {
+			int fd;
+
+			fd = openat(dfd, RELPATH2, O_RDONLY);
+			if (fd >= 0) {
+				fprintf(stderr, "openat should've failed\n");
+				return(1);
+			} else if (errno != EPERM) {
+				fprintf(stderr, "Unexpected error: %s\n",
+					strerror(errno));
+				return(1);
+			}
+			return 0;
+		}
+	);
+}





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904051721.x35HLNIX020006>