diff options
author | Andrei Vagin <avagin@google.com> | 2021-01-05 09:45:27 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-05 09:47:30 -0800 |
commit | 2a200811d4c95e1c84d2bdd56068f02d46ebc524 (patch) | |
tree | 7b9de79aadc2173717747e40c9022737bc00d4d4 /test | |
parent | 807a080d9574e42dae83bb8bd0863b110b98a858 (diff) |
fs/fuse: check that a task has a specified file descriptor
Reported-by: syzbot+814105309d2ae8651084@syzkaller.appspotmail.com
PiperOrigin-RevId: 350159452
Diffstat (limited to 'test')
-rw-r--r-- | test/fuse/linux/BUILD | 1 | ||||
-rw-r--r-- | test/fuse/linux/mount_test.cc | 42 | ||||
-rw-r--r-- | test/syscalls/linux/mount.cc | 36 |
3 files changed, 43 insertions, 36 deletions
diff --git a/test/fuse/linux/BUILD b/test/fuse/linux/BUILD index d1fb178e8..2f745bd47 100644 --- a/test/fuse/linux/BUILD +++ b/test/fuse/linux/BUILD @@ -235,6 +235,7 @@ cc_binary( srcs = ["mount_test.cc"], deps = [ gtest, + "//test/util:mount_util", "//test/util:temp_path", "//test/util:test_main", "//test/util:test_util", diff --git a/test/fuse/linux/mount_test.cc b/test/fuse/linux/mount_test.cc index a5c2fbb01..8a5478116 100644 --- a/test/fuse/linux/mount_test.cc +++ b/test/fuse/linux/mount_test.cc @@ -17,6 +17,7 @@ #include <sys/mount.h> #include "gtest/gtest.h" +#include "test/util/mount_util.h" #include "test/util/temp_path.h" #include "test/util/test_util.h" @@ -25,6 +26,17 @@ namespace testing { namespace { +TEST(FuseMount, Success) { + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_WRONLY)); + std::string mopts = absl::StrCat("fd=", std::to_string(fd.get())); + + const auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + + const auto mount = + ASSERT_NO_ERRNO_AND_VALUE(Mount("", dir.path(), "fuse", 0, mopts, 0)); +} + TEST(FuseMount, FDNotParsable) { int devfd; EXPECT_THAT(devfd = open("/dev/fuse", O_RDWR), SyscallSucceeds()); @@ -35,6 +47,36 @@ TEST(FuseMount, FDNotParsable) { SyscallFailsWithErrno(EINVAL)); } +TEST(FuseMount, NoDevice) { + const auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + + EXPECT_THAT(mount("", dir.path().c_str(), "fuse", 0, ""), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(FuseMount, ClosedFD) { + FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_WRONLY)); + int fd = f.release(); + close(fd); + std::string mopts = absl::StrCat("fd=", std::to_string(fd)); + + const auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + + EXPECT_THAT(mount("", dir.path().c_str(), "fuse", 0, mopts.c_str()), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(FuseMount, BadFD) { + const auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + std::string mopts = absl::StrCat("fd=", std::to_string(fd.get())); + + EXPECT_THAT(mount("", dir.path().c_str(), "fuse", 0, mopts.c_str()), + SyscallFailsWithErrno(EINVAL)); +} + } // namespace } // namespace testing diff --git a/test/syscalls/linux/mount.cc b/test/syscalls/linux/mount.cc index d65b7d031..15b645fb7 100644 --- a/test/syscalls/linux/mount.cc +++ b/test/syscalls/linux/mount.cc @@ -345,42 +345,6 @@ TEST(MountTest, RenameRemoveMountPoint) { ASSERT_THAT(rmdir(dir.path().c_str()), SyscallFailsWithErrno(EBUSY)); } -TEST(MountTest, MountFuseFilesystemNoDevice) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))); - SKIP_IF(IsRunningOnGvisor() && !IsFUSEEnabled()); - - auto const dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); - - // Before kernel version 4.16-rc6, FUSE mount is protected by - // capable(CAP_SYS_ADMIN). After this version, it uses - // ns_capable(CAP_SYS_ADMIN) to protect. Before the 4.16 kernel, it was not - // allowed to mount fuse file systems without the global CAP_SYS_ADMIN. - int res = mount("", dir.path().c_str(), "fuse", 0, ""); - SKIP_IF(!IsRunningOnGvisor() && res == -1 && errno == EPERM); - - EXPECT_THAT(mount("", dir.path().c_str(), "fuse", 0, ""), - SyscallFailsWithErrno(EINVAL)); -} - -TEST(MountTest, MountFuseFilesystem) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))); - SKIP_IF(IsRunningOnGvisor() && !IsFUSEEnabled()); - - const FileDescriptor fd = - ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_WRONLY)); - std::string mopts = "fd=" + std::to_string(fd.get()); - - auto const dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); - - // See comments in MountFuseFilesystemNoDevice for the reason why we skip - // EPERM when running on Linux. - int res = mount("", dir.path().c_str(), "fuse", 0, ""); - SKIP_IF(!IsRunningOnGvisor() && res == -1 && errno == EPERM); - - auto const mount = - ASSERT_NO_ERRNO_AND_VALUE(Mount("", dir.path(), "fuse", 0, mopts, 0)); -} - } // namespace } // namespace testing |