Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Mar 2019 03:30:04 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r345626 - projects/fuse2/tests/sys/fs/fusefs
Message-ID:  <201903280330.x2S3U4Fa037940@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Thu Mar 28 03:30:04 2019
New Revision: 345626
URL: https://svnweb.freebsd.org/changeset/base/345626

Log:
  fusefs: add a regression test for bug 236844
  
  fusefs should send a FUSE_OPEN for every open(2) so the daemon can validate
  accesses.
  
  PR:		236844
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/tests/sys/fs/fusefs/allow_other.cc
  projects/fuse2/tests/sys/fs/fusefs/fsync.cc
  projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
  projects/fuse2/tests/sys/fs/fusefs/open.cc
  projects/fuse2/tests/sys/fs/fusefs/utils.cc
  projects/fuse2/tests/sys/fs/fusefs/utils.hh

Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Thu Mar 28 03:30:04 2019	(r345626)
@@ -78,7 +78,7 @@ TEST_F(AllowOther, allowed)
 
 			expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1);
 			expect_open(ino, 0, 1);
-			expect_release(ino);
+			expect_release(ino, FH);
 			expect_getattr(ino, 0);
 		}, []() {
 			int fd;

Modified: projects/fuse2/tests/sys/fs/fusefs/fsync.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/fsync.cc	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/fsync.cc	Thu Mar 28 03:30:04 2019	(r345626)
@@ -139,7 +139,7 @@ TEST_F(Fsync, close)
 		}, Eq(true)),
 		_)
 	).Times(0);
-	expect_release(ino);
+	expect_release(ino, FH);
 
 	fd = open(FULLPATH, O_RDWR);
 	ASSERT_LE(0, fd) << strerror(errno);

Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc	Thu Mar 28 03:30:04 2019	(r345626)
@@ -204,7 +204,8 @@ void debug_fuseop(const mockfs_buf_in *in)
 				in->body.readdir.size);
 			break;
 		case FUSE_RELEASE:
-			printf(" flags=%#x lock_owner=%lu",
+			printf(" fh=%#lx flags=%#x lock_owner=%lu",
+				in->body.release.fh,
 				in->body.release.flags,
 				in->body.release.lock_owner);
 			break;

Modified: projects/fuse2/tests/sys/fs/fusefs/open.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/open.cc	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/open.cc	Thu Mar 28 03:30:04 2019	(r345626)
@@ -62,17 +62,7 @@ void test_ok(int os_flags, int fuse_flags) {
 	})));
 
 	/* Until the attr cache is working, we may send an additional GETATTR */
-	EXPECT_CALL(*m_mock, process(
-		ResultOf([=](auto in) {
-			return (in->header.opcode == FUSE_GETATTR &&
-				in->header.nodeid == ino);
-		}, Eq(true)),
-		_)
-	).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) {
-		SET_OUT_HEADER_LEN(out, attr);
-		out->body.attr.attr.ino = ino;	// Must match nodeid
-		out->body.attr.attr.mode = S_IFREG | 0644;
-	})));
+	expect_getattr(ino, 0);
 
 	fd = open(FULLPATH, os_flags);
 	EXPECT_LE(0, fd) << strerror(errno);
@@ -168,6 +158,72 @@ TEST_F(Open, fifo)
 
 	ASSERT_EQ(-1, open(FULLPATH, O_RDONLY));
 	EXPECT_EQ(EOPNOTSUPP, errno);
+}
+
+/* 
+ * fusefs must issue multiple FUSE_OPEN operations if clients with different
+ * credentials open the same file, even if they use the same mode.  This is
+ * necessary so that the daemon can validate each set of credentials.
+ */
+/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236844 */
+TEST_F(Open, DISABLED_multiple_creds)
+{
+	const static char FULLPATH[] = "mountpoint/some_file.txt";
+	const static char RELPATH[] = "some_file.txt";
+	int fd1;
+	const static uint64_t ino = 42;
+	const static uint64_t fh0 = 100, fh1 = 200;
+
+	/* Fork a child to open the file with different credentials */
+	fork(false, [&] {
+
+		expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2);
+		EXPECT_CALL(*m_mock, process(
+			ResultOf([=](auto in) {
+				return (in->header.opcode == FUSE_OPEN &&
+					in->header.pid == (uint32_t)getpid() &&
+					in->header.nodeid == ino);
+			}, Eq(true)),
+			_)
+		).WillOnce(Invoke(
+			ReturnImmediate([](auto in __unused, auto out) {
+			out->body.open.fh = fh0;
+			out->header.len = sizeof(out->header);
+			SET_OUT_HEADER_LEN(out, open);
+		})));
+
+		EXPECT_CALL(*m_mock, process(
+			ResultOf([=](auto in) {
+				return (in->header.opcode == FUSE_OPEN &&
+					in->header.pid != (uint32_t)getpid() &&
+					in->header.nodeid == ino);
+			}, Eq(true)),
+			_)
+		).WillOnce(Invoke(
+			ReturnImmediate([](auto in __unused, auto out) {
+			out->body.open.fh = fh1;
+			out->header.len = sizeof(out->header);
+			SET_OUT_HEADER_LEN(out, open);
+		})));
+		expect_getattr(ino, 0);
+		expect_release(ino, fh0);
+		expect_release(ino, fh1);
+
+		fd1 = open(FULLPATH, O_RDONLY);
+		EXPECT_LE(0, fd1) << strerror(errno);
+	}, [] {
+		int fd0;
+
+		fd0 = open(FULLPATH, O_RDONLY);
+		if (fd0 < 0) {
+			perror("open");
+			return(1);
+		}
+		return 0;
+	}
+	);
+
+	close(fd1);
 }
 
 /* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236340 */

Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/utils.cc	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/utils.cc	Thu Mar 28 03:30:04 2019	(r345626)
@@ -206,13 +206,13 @@ void FuseTest::expect_read(uint64_t ino, uint64_t offs
 	}))).RetiresOnSaturation();
 }
 
-void FuseTest::expect_release(uint64_t ino)
+void FuseTest::expect_release(uint64_t ino, uint64_t fh)
 {
 	EXPECT_CALL(*m_mock, process(
 		ResultOf([=](auto in) {
 			return (in->header.opcode == FUSE_RELEASE &&
 				in->header.nodeid == ino &&
-				in->body.release.fh == FH);
+				in->body.release.fh == fh);
 		}, Eq(true)),
 		_)
 	).WillOnce(Invoke(ReturnErrno(0)));

Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/utils.hh	Thu Mar 28 02:12:32 2019	(r345625)
+++ projects/fuse2/tests/sys/fs/fusefs/utils.hh	Thu Mar 28 03:30:04 2019	(r345626)
@@ -113,9 +113,9 @@ class FuseTest : public ::testing::Test {
 
 	/* 
 	 * Create an expectation that FUSE_RELEASE will be called exactly once
-	 * for the given inode, returning success
+	 * for the given inode and filehandle, returning success
 	 */
-	void expect_release(uint64_t ino);
+	void expect_release(uint64_t ino, uint64_t fh);
 
 	/*
 	 * Create an expectation that FUSE_WRITE will be called exactly once



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