mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
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
This commit is contained in:
parent
72f03b7ccd
commit
61b0a927cb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=347077
@ -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 fuse_ticket *ftick,
|
||||
|
||||
ihead->pid = pid;
|
||||
ihead->uid = cred->cr_uid;
|
||||
ihead->gid = cred->cr_rgid;
|
||||
ihead->gid = cred->cr_groups[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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 offset, uint64_t isize,
|
||||
})));
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user