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