fusefs: correctly return EROFS from VOP_ACCESS
Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
46c37cd0d7
commit
140bb4927a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=345950
@ -137,7 +137,7 @@ fuse_internal_access(struct vnode *vp,
|
|||||||
dataflags = data->dataflags;
|
dataflags = data->dataflags;
|
||||||
|
|
||||||
if ((mode & VWRITE) && vfs_isrdonly(mp)) {
|
if ((mode & VWRITE) && vfs_isrdonly(mp)) {
|
||||||
return EACCES;
|
return EROFS;
|
||||||
}
|
}
|
||||||
/* Unless explicitly permitted, deny everyone except the fs owner. */
|
/* Unless explicitly permitted, deny everyone except the fs owner. */
|
||||||
if (vnode_isvroot(vp) && !(facp->facc_flags & FACCESS_NOCHECKSPY)) {
|
if (vnode_isvroot(vp) && !(facp->facc_flags & FACCESS_NOCHECKSPY)) {
|
||||||
|
@ -46,6 +46,14 @@ void expect_lookup(const char *relpath, uint64_t ino)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RofsAccess: public Access {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
m_ro = true;
|
||||||
|
Access::SetUp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* The error case of FUSE_ACCESS. */
|
/* The error case of FUSE_ACCESS. */
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236291 */
|
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236291 */
|
||||||
TEST_F(Access, DISABLED_eaccess)
|
TEST_F(Access, DISABLED_eaccess)
|
||||||
@ -83,6 +91,19 @@ TEST_F(Access, DISABLED_enosys)
|
|||||||
ASSERT_EQ(0, access(FULLPATH, access_mode)) << strerror(errno);
|
ASSERT_EQ(0, access(FULLPATH, access_mode)) << strerror(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(RofsAccess, erofs)
|
||||||
|
{
|
||||||
|
const char FULLPATH[] = "mountpoint/some_file.txt";
|
||||||
|
const char RELPATH[] = "some_file.txt";
|
||||||
|
uint64_t ino = 42;
|
||||||
|
mode_t access_mode = W_OK;
|
||||||
|
|
||||||
|
expect_lookup(RELPATH, ino);
|
||||||
|
|
||||||
|
ASSERT_NE(0, access(FULLPATH, access_mode));
|
||||||
|
ASSERT_EQ(EROFS, errno);
|
||||||
|
}
|
||||||
|
|
||||||
/* The successful case of FUSE_ACCESS. */
|
/* The successful case of FUSE_ACCESS. */
|
||||||
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236291 */
|
/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236291 */
|
||||||
TEST_F(Access, DISABLED_ok)
|
TEST_F(Access, DISABLED_ok)
|
||||||
|
@ -258,7 +258,7 @@ void debug_fuseop(const mockfs_buf_in *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
|
MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
|
||||||
bool push_symlinks_in, uint32_t flags)
|
bool push_symlinks_in, bool ro, uint32_t flags)
|
||||||
{
|
{
|
||||||
struct iovec *iov = NULL;
|
struct iovec *iov = NULL;
|
||||||
int iovlen = 0;
|
int iovlen = 0;
|
||||||
@ -307,6 +307,10 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
|
|||||||
build_iovec(&iov, &iovlen, "push_symlinks_in",
|
build_iovec(&iov, &iovlen, "push_symlinks_in",
|
||||||
__DECONST(void*, &trueval), sizeof(bool));
|
__DECONST(void*, &trueval), sizeof(bool));
|
||||||
}
|
}
|
||||||
|
if (ro) {
|
||||||
|
build_iovec(&iov, &iovlen, "ro",
|
||||||
|
__DECONST(void*, &trueval), sizeof(bool));
|
||||||
|
}
|
||||||
if (nmount(iov, iovlen, 0))
|
if (nmount(iov, iovlen, 0))
|
||||||
throw(std::system_error(errno, std::system_category(),
|
throw(std::system_error(errno, std::system_category(),
|
||||||
"Couldn't mount filesystem"));
|
"Couldn't mount filesystem"));
|
||||||
|
@ -216,7 +216,7 @@ class MockFS {
|
|||||||
|
|
||||||
/* Create a new mockfs and mount it to a tempdir */
|
/* Create a new mockfs and mount it to a tempdir */
|
||||||
MockFS(int max_readahead, bool allow_other,
|
MockFS(int max_readahead, bool allow_other,
|
||||||
bool default_permissions, bool push_symlinks_in,
|
bool default_permissions, bool push_symlinks_in, bool ro,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
virtual ~MockFS();
|
virtual ~MockFS();
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void FuseTest::SetUp() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
m_mock = new MockFS(m_maxreadahead, m_allow_other,
|
m_mock = new MockFS(m_maxreadahead, m_allow_other,
|
||||||
m_default_permissions, m_push_symlinks_in,
|
m_default_permissions, m_push_symlinks_in, m_ro,
|
||||||
m_init_flags);
|
m_init_flags);
|
||||||
} catch (std::system_error err) {
|
} catch (std::system_error err) {
|
||||||
FAIL() << err.what();
|
FAIL() << err.what();
|
||||||
|
@ -44,6 +44,7 @@ class FuseTest : public ::testing::Test {
|
|||||||
bool m_allow_other;
|
bool m_allow_other;
|
||||||
bool m_default_permissions;
|
bool m_default_permissions;
|
||||||
bool m_push_symlinks_in;
|
bool m_push_symlinks_in;
|
||||||
|
bool m_ro;
|
||||||
MockFS *m_mock = NULL;
|
MockFS *m_mock = NULL;
|
||||||
const static uint64_t FH = 0xdeadbeef1a7ebabe;
|
const static uint64_t FH = 0xdeadbeef1a7ebabe;
|
||||||
|
|
||||||
@ -59,7 +60,8 @@ class FuseTest : public ::testing::Test {
|
|||||||
m_init_flags(0),
|
m_init_flags(0),
|
||||||
m_allow_other(false),
|
m_allow_other(false),
|
||||||
m_default_permissions(false),
|
m_default_permissions(false),
|
||||||
m_push_symlinks_in(false)
|
m_push_symlinks_in(false),
|
||||||
|
m_ro(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void SetUp();
|
virtual void SetUp();
|
||||||
|
Loading…
Reference in New Issue
Block a user