svn commit: r347077 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs

Alan Somers asomers at FreeBSD.org
Sat May 4 02:11:30 UTC 2019


Author: asomers
Date: Sat May  4 02:11:28 2019
New Revision: 347077
URL: https://svnweb.freebsd.org/changeset/base/347077

Log:
  fusefs: use effective gid, not real gid, for FUSE operations
  
  This is the gid used for stuff like setting the group of a newly created
  file.
  
  Reported by:	pjdfstest
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_ipc.c
  projects/fuse2/tests/sys/fs/fusefs/allow_other.cc
  projects/fuse2/tests/sys/fs/fusefs/utils.cc
  projects/fuse2/tests/sys/fs/fusefs/utils.hh

Modified: projects/fuse2/sys/fs/fuse/fuse_ipc.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_ipc.c	Sat May  4 02:10:47 2019	(r347076)
+++ projects/fuse2/sys/fs/fuse/fuse_ipc.c	Sat May  4 02:11:28 2019	(r347077)
@@ -191,6 +191,7 @@ fuse_interrupt_send(struct fuse_ticket *otick, int err
 	struct fuse_data *data = otick->tk_data;
 	struct fuse_ticket *tick, *xtick;
 	struct ucred reused_creds;
+	gid_t reused_groups[1];
 
 	if (otick->irq_unique == 0) {
 		/* 
@@ -233,7 +234,8 @@ fuse_interrupt_send(struct fuse_ticket *otick, int err
 		 */
 		ftick_hdr = fticket_in_header(otick);
 		reused_creds.cr_uid = ftick_hdr->uid;
-		reused_creds.cr_rgid = ftick_hdr->gid;
+		reused_groups[0] = ftick_hdr->gid;
+		reused_creds.cr_groups = reused_groups;
 		fdisp_init(&fdi, sizeof(*fii));
 		fdisp_make_pid(&fdi, FUSE_INTERRUPT, data, ftick_hdr->nodeid,
 			ftick_hdr->pid, &reused_creds);
@@ -878,7 +880,7 @@ fuse_setup_ihead(struct fuse_in_header *ihead, struct 
 
 	ihead->pid = pid;
 	ihead->uid = cred->cr_uid;
-	ihead->gid = cred->cr_rgid;
+	ihead->gid = cred->cr_groups[0];
 }
 
 /*

Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Sat May  4 02:10:47 2019	(r347076)
+++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc	Sat May  4 02:11:28 2019	(r347077)
@@ -98,6 +98,31 @@ TEST_F(AllowOther, allowed)
 	ASSERT_EQ(0, WEXITSTATUS(status));
 }
 
+/* Check that fusefs uses the correct credentials for FUSE operations */
+TEST_F(AllowOther, creds)
+{
+	int status;
+	uid_t uid;
+	gid_t gid;
+
+	get_unprivileged_id(&uid, &gid);
+	fork(true, &status, [=] {
+			EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) {
+				return (in->header.opcode == FUSE_LOOKUP &&
+					in->header.uid == uid &&
+					in->header.gid == gid);
+				}, Eq(true)),
+				_)
+			).Times(1)
+			.WillOnce(Invoke(ReturnErrno(ENOENT)));
+		}, []() {
+			eaccess(FULLPATH, F_OK);
+			return 0;
+		}
+	);
+	ASSERT_EQ(0, WEXITSTATUS(status));
+}
+
 /*
  * A variation of the Open.multiple_creds test showing how the bug can lead to a
  * privilege elevation.  The first process is privileged and opens a file only

Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/utils.cc	Sat May  4 02:10:47 2019	(r347076)
+++ projects/fuse2/tests/sys/fs/fusefs/utils.cc	Sat May  4 02:11:28 2019	(r347077)
@@ -35,6 +35,7 @@ extern "C" {
 #include <sys/sysctl.h>
 #include <sys/wait.h>
 
+#include <grp.h>
 #include <pwd.h>
 #include <semaphore.h>
 #include <unistd.h>
@@ -317,10 +318,11 @@ void FuseTest::expect_write(uint64_t ino, uint64_t off
 	})));
 }
 
-static void
-get_unprivileged_uid(uid_t *uid)
+void
+get_unprivileged_id(uid_t *uid, gid_t *gid)
 {
 	struct passwd *pw;
+	struct group *gr;
 
 	/* 
 	 * First try "tests", Kyua's default unprivileged user.  XXX after
@@ -333,7 +335,12 @@ get_unprivileged_uid(uid_t *uid)
 	}
 	if (pw == NULL)
 		GTEST_SKIP() << "Test requires an unprivileged user";
+	/* Use group "nobody", which is Kyua's default unprivileged group */
+	gr = getgrnam("nobody");
+	if (gr == NULL)
+		GTEST_SKIP() << "Test requires an unprivileged group";
 	*uid = pw->pw_uid;
+	*gid = gr->gr_gid;
 }
 
 void
@@ -346,9 +353,10 @@ FuseTest::fork(bool drop_privs, int *child_status,
 	int mflags = MAP_ANON | MAP_SHARED;
 	pid_t child;
 	uid_t uid;
+	gid_t gid;
 	
 	if (drop_privs) {
-		get_unprivileged_uid(&uid);
+		get_unprivileged_id(&uid, &gid);
 		if (IsSkipped())
 			return;
 	}
@@ -367,6 +375,11 @@ FuseTest::fork(bool drop_privs, int *child_status,
 			goto out;
 		}
 
+		if (drop_privs && 0 != setegid(gid)) {
+			perror("setegid");
+			err = 1;
+			goto out;
+		}
 		if (drop_privs && 0 != setreuid(-1, uid)) {
 			perror("setreuid");
 			err = 1;

Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/utils.hh	Sat May  4 02:10:47 2019	(r347076)
+++ projects/fuse2/tests/sys/fs/fusefs/utils.hh	Sat May  4 02:11:28 2019	(r347077)
@@ -37,6 +37,8 @@
 #define FUSE_WRITE_CACHE 1
 #endif
 
+void get_unprivileged_id(uid_t *uid, gid_t *gid);
+
 class FuseTest : public ::testing::Test {
 	protected:
 	uint32_t m_maxreadahead;


More information about the svn-src-projects mailing list