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
This commit is contained in:
parent
09c01e67de
commit
42d50d16e2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=345626
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
@ -170,6 +160,72 @@ TEST_F(Open, fifo)
|
||||
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 */
|
||||
TEST_F(Open, DISABLED_o_append)
|
||||
{
|
||||
|
@ -206,13 +206,13 @@ void FuseTest::expect_read(uint64_t ino, uint64_t offset, uint64_t isize,
|
||||
}))).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)));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user