diff options
author | Dean Deng <deandeng@google.com> | 2019-10-24 01:44:03 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-10-24 01:45:25 -0700 |
commit | d9fd5363409facbc5cf04b85b3b0e7dade085dd9 (patch) | |
tree | c1deb0abdc6aae4ab44b9b5459eaa7a542b1d5b9 /test/syscalls/linux | |
parent | 7ca50236c42ad1b1aa19951815d03b62c0c722ed (diff) |
Handle AT_SYMLINK_NOFOLLOW flag for execveat.
PiperOrigin-RevId: 276441249
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r-- | test/syscalls/linux/exec.cc | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/test/syscalls/linux/exec.cc b/test/syscalls/linux/exec.cc index 03ec9f75f..21a5ffd40 100644 --- a/test/syscalls/linux/exec.cc +++ b/test/syscalls/linux/exec.cc @@ -542,23 +542,23 @@ TEST(ExecveatTest, BasicWithFDCWD) { TEST(ExecveatTest, Basic) { std::string absolute_path = WorkloadPath(kBasicWorkload); std::string parent_dir = std::string(Dirname(absolute_path)); - std::string relative_path = std::string(Basename(absolute_path)); + std::string base = std::string(Basename(absolute_path)); const FileDescriptor dirfd = ASSERT_NO_ERRNO_AND_VALUE(Open(parent_dir, O_DIRECTORY)); - CheckExecveat(dirfd.get(), relative_path, {absolute_path}, {}, /*flags=*/0, + CheckExecveat(dirfd.get(), base, {absolute_path}, {}, /*flags=*/0, ArgEnvExitStatus(0, 0), absl::StrCat(absolute_path, "\n")); } TEST(ExecveatTest, FDNotADirectory) { std::string absolute_path = WorkloadPath(kBasicWorkload); - std::string relative_path = std::string(Basename(absolute_path)); + std::string base = std::string(Basename(absolute_path)); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(absolute_path, 0)); int execve_errno; - ASSERT_NO_ERRNO_AND_VALUE(ForkAndExecveat(fd.get(), relative_path, - {absolute_path}, {}, /*flags=*/0, - /*child=*/nullptr, &execve_errno)); + ASSERT_NO_ERRNO_AND_VALUE(ForkAndExecveat(fd.get(), base, {absolute_path}, {}, + /*flags=*/0, /*child=*/nullptr, + &execve_errno)); EXPECT_EQ(execve_errno, ENOTDIR); } @@ -618,14 +618,77 @@ TEST(ExecveatTest, AbsolutePathWithEmptyPathFlag) { TEST(ExecveatTest, RelativePathWithEmptyPathFlag) { std::string absolute_path = WorkloadPath(kBasicWorkload); std::string parent_dir = std::string(Dirname(absolute_path)); - std::string relative_path = std::string(Basename(absolute_path)); + std::string base = std::string(Basename(absolute_path)); const FileDescriptor dirfd = ASSERT_NO_ERRNO_AND_VALUE(Open(parent_dir, O_DIRECTORY)); - CheckExecveat(dirfd.get(), relative_path, {absolute_path}, {}, AT_EMPTY_PATH, + CheckExecveat(dirfd.get(), base, {absolute_path}, {}, AT_EMPTY_PATH, ArgEnvExitStatus(0, 0), absl::StrCat(absolute_path, "\n")); } +TEST(ExecveatTest, SymlinkNoFollowWithRelativePath) { + std::string parent_dir = "/tmp"; + TempPath link = ASSERT_NO_ERRNO_AND_VALUE( + TempPath::CreateSymlinkTo(parent_dir, WorkloadPath(kBasicWorkload))); + const FileDescriptor dirfd = + ASSERT_NO_ERRNO_AND_VALUE(Open(parent_dir, O_DIRECTORY)); + std::string base = std::string(Basename(link.path())); + + int execve_errno; + ASSERT_NO_ERRNO_AND_VALUE(ForkAndExecveat(dirfd.get(), base, {base}, {}, + AT_SYMLINK_NOFOLLOW, + /*child=*/nullptr, &execve_errno)); + EXPECT_EQ(execve_errno, ELOOP); +} + +TEST(ExecveatTest, SymlinkNoFollowWithAbsolutePath) { + std::string parent_dir = "/tmp"; + TempPath link = ASSERT_NO_ERRNO_AND_VALUE( + TempPath::CreateSymlinkTo(parent_dir, WorkloadPath(kBasicWorkload))); + std::string path = link.path(); + + int execve_errno; + ASSERT_NO_ERRNO_AND_VALUE(ForkAndExecveat(AT_FDCWD, path, {path}, {}, + AT_SYMLINK_NOFOLLOW, + /*child=*/nullptr, &execve_errno)); + EXPECT_EQ(execve_errno, ELOOP); +} + +TEST(ExecveatTest, SymlinkNoFollowAndEmptyPath) { + TempPath link = ASSERT_NO_ERRNO_AND_VALUE( + TempPath::CreateSymlinkTo("/tmp", WorkloadPath(kBasicWorkload))); + std::string path = link.path(); + const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path, 0)); + + CheckExecveat(fd.get(), "", {path}, {}, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, + ArgEnvExitStatus(0, 0), absl::StrCat(path, "\n")); +} + +TEST(ExecveatTest, SymlinkNoFollowIgnoreSymlinkAncestor) { + TempPath parent_link = + ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateSymlinkTo("/tmp", "/bin")); + std::string path_with_symlink = JoinPath(parent_link.path(), "echo"); + + CheckExecveat(AT_FDCWD, path_with_symlink, {path_with_symlink}, {}, + AT_SYMLINK_NOFOLLOW, ArgEnvExitStatus(0, 0), ""); +} + +TEST(ExecveatTest, SymlinkNoFollowWithNormalFile) { + const FileDescriptor dirfd = + ASSERT_NO_ERRNO_AND_VALUE(Open("/bin", O_DIRECTORY)); + + CheckExecveat(dirfd.get(), "echo", {"echo"}, {}, AT_SYMLINK_NOFOLLOW, + ArgEnvExitStatus(0, 0), ""); +} + +TEST(ExecveatTest, InvalidFlags) { + int execve_errno; + ASSERT_NO_ERRNO_AND_VALUE(ForkAndExecveat( + /*dirfd=*/-1, "", {}, {}, /*flags=*/0xFFFF, /*child=*/nullptr, + &execve_errno)); + EXPECT_EQ(execve_errno, EINVAL); +} + // Priority consistent across calls to execve() TEST(GetpriorityTest, ExecveMaintainsPriority) { int prio = 16; |