From 4971756d8d9b7b9f1954a1357348f3dd2b9d4a68 Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Mon, 2 Dec 2024 20:19:02 -0800 Subject: [PATCH] Internal change. PiperOrigin-RevId: 702177156 --- pkg/sentry/syscalls/linux/sys_file.go | 8 ++++---- test/syscalls/linux/BUILD | 1 + test/syscalls/linux/access.cc | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 3d8665726..e78a01acc 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -127,7 +127,7 @@ func openat(t *kernel.Task, dirfd int32, pathAddr hostarch.Addr, flags uint32, m // Access implements Linux syscall access(2). func Access(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { addr := args[0].Pointer() - mode := args[1].ModeT() + mode := args[1].Uint() return 0, nil, accessAt(t, linux.AT_FDCWD, addr, mode, 0 /* flags */) } @@ -136,7 +136,7 @@ func Access(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, func Faccessat(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { dirfd := args[0].Int() addr := args[1].Pointer() - mode := args[2].ModeT() + mode := args[2].Uint() return 0, nil, accessAt(t, dirfd, addr, mode, 0 /* flags */) } @@ -145,13 +145,13 @@ func Faccessat(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintp func Faccessat2(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { dirfd := args[0].Int() addr := args[1].Pointer() - mode := args[2].ModeT() + mode := args[2].Uint() flags := args[3].Int() return 0, nil, accessAt(t, dirfd, addr, mode, flags) } -func accessAt(t *kernel.Task, dirfd int32, pathAddr hostarch.Addr, mode uint, flags int32) error { +func accessAt(t *kernel.Task, dirfd int32, pathAddr hostarch.Addr, mode uint32, flags int32) error { const rOK = 4 const wOK = 2 const xOK = 1 diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 771b590ce..7ad68bd79 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -253,6 +253,7 @@ cc_binary( "//test/util:temp_path", "//test/util:test_main", "//test/util:test_util", + "@com_google_absl//absl/strings:str_format", ], ) diff --git a/test/syscalls/linux/access.cc b/test/syscalls/linux/access.cc index fef94d64e..dc98327e5 100644 --- a/test/syscalls/linux/access.cc +++ b/test/syscalls/linux/access.cc @@ -20,7 +20,10 @@ #include #include +#include + #include "gtest/gtest.h" +#include "absl/strings/str_format.h" #include "test/util/capability_util.h" #include "test/util/fs_util.h" #include "test/util/temp_path.h" @@ -113,6 +116,29 @@ TEST_F(AccessTest, InvalidMode) { SyscallFailsWithErrno(EINVAL)); } +TEST_F(AccessTest, InvalidModeRoot) { + EXPECT_THAT(access("/", R_OK | 0x8000'0000), SyscallFailsWithErrno(EINVAL)); +} + +TEST_F(AccessTest, InvalidModes) { + // The only valid modes are: + // * F_OK + // * bitwise or combinations of R_OK, W_OK, and X_OK + std::set valid_modes = { + F_OK, R_OK, W_OK, X_OK, + R_OK | W_OK, R_OK | X_OK, W_OK | X_OK, R_OK | W_OK | X_OK}; + for (size_t i = 0; i < 32; i++) { + int mode_bit = 1 << i; + for (int valid_mode : valid_modes) { + int mode = valid_mode | mode_bit; + if (valid_modes.find(mode) != valid_modes.end()) continue; + SCOPED_TRACE(absl::StrFormat("mode=%08x", mode)); + EXPECT_THAT(access(relfile_.c_str(), mode), + SyscallFailsWithErrno(EINVAL)); + } + } +} + TEST_F(AccessTest, NoPerms) { // Drop capabilities that allow us to override permissions. We must drop // PERMITTED because access() checks those instead of EFFECTIVE.