From 2c7778ecca7e896f692c7bd0b59fca1bf574a963 Mon Sep 17 00:00:00 2001 From: Jing Chen Date: Fri, 25 Aug 2023 15:14:44 -0700 Subject: [PATCH] Support MS_STRICTATIME flag for the syscall mount. PiperOrigin-RevId: 560207305 --- pkg/sentry/syscalls/linux/sys_mount.go | 5 ++--- test/syscalls/linux/mount.cc | 29 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go index c3212c071..f5576641f 100644 --- a/pkg/sentry/syscalls/linux/sys_mount.go +++ b/pkg/sentry/syscalls/linux/sys_mount.go @@ -46,8 +46,7 @@ func Mount(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, // Silently allow MS_NOSUID, since we don't implement set-id bits anyway. const unsupported = linux.MS_REMOUNT | linux.MS_SLAVE | - linux.MS_UNBINDABLE | linux.MS_MOVE | linux.MS_REC | linux.MS_NODIRATIME | - linux.MS_STRICTATIME + linux.MS_UNBINDABLE | linux.MS_MOVE | linux.MS_REC | linux.MS_NODIRATIME // Linux just allows passing any flags to mount(2) - it won't fail when // unknown or unsupported flags are passed. Since we don't implement @@ -109,7 +108,7 @@ func Mount(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, } } var opts vfs.MountOptions - if flags&linux.MS_NOATIME == linux.MS_NOATIME { + if flags&(linux.MS_NOATIME|linux.MS_STRICTATIME) == linux.MS_NOATIME { opts.Flags.NoATime = true } if flags&linux.MS_NOEXEC == linux.MS_NOEXEC { diff --git a/test/syscalls/linux/mount.cc b/test/syscalls/linux/mount.cc index d989ef675..c95a5f521 100644 --- a/test/syscalls/linux/mount.cc +++ b/test/syscalls/linux/mount.cc @@ -45,6 +45,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" +#include "absl/time/clock.h" #include "absl/time/time.h" #include "test/util/capability_util.h" #include "test/util/file_descriptor.h" @@ -389,6 +390,34 @@ TEST(MountTest, MountNoAtime) { EXPECT_EQ(before, after); } +TEST(MountTest, MountWithStrictAtime) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN))); + + auto const dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + auto const mount = ASSERT_NO_ERRNO_AND_VALUE(Mount( + "", dir.path(), "tmpfs", MS_NOATIME | MS_STRICTATIME, "mode=0777", 0)); + + std::string const contents = "No no no, don't follow the instructions!"; + auto const file = ASSERT_NO_ERRNO_AND_VALUE( + TempPath::CreateFileWith(dir.path(), contents, 0777)); + + absl::Time const before = ASSERT_NO_ERRNO_AND_VALUE(ATime(file.path())); + + absl::SleepFor(absl::Milliseconds(100)); + + // MS_STRICTATIME should override MS_NOATIME and update the file's atime. + auto const fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + char buf[100]; + int read_n; + ASSERT_THAT(read_n = read(fd.get(), buf, sizeof(buf)), SyscallSucceeds()); + EXPECT_EQ(std::string(buf, read_n), contents); + + absl::Time const after = ASSERT_NO_ERRNO_AND_VALUE(ATime(file.path())); + + // The after atime is expected to be larger than the before atime. + EXPECT_LT(before, after); +} + TEST(MountTest, MountNoExec) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));