Deflake exec test.
- Only use MAXSYMLINKS/2+1 symlinks for each of the interpreter and script paths in SymlinkLimitRefreshedForInterpreter to tolerate cases where the original paths (/tmp, /bin, or /bin/echo) themselves contain symlinks. - Ensure that UnshareFiles performs execve immediately after clone(CLONE_VFORK) (no heap allocation for ExecveArray/RunfilesPath). - Use lstat() rather than stat() for the existence check in fs_util's Exists; the latter will fail if the symlink target does not exist, even if the symlink does. PiperOrigin-RevId: 320110156
This commit is contained in:
parent
76c7bc51b7
commit
5e05950c1c
|
@ -553,7 +553,12 @@ TEST(ExecTest, SymlinkLimitRefreshedForInterpreter) {
|
|||
// Hold onto TempPath objects so they are not destructed prematurely.
|
||||
std::vector<TempPath> interpreter_symlinks;
|
||||
std::vector<TempPath> script_symlinks;
|
||||
for (int i = 0; i < kLinuxMaxSymlinks; i++) {
|
||||
// Replace both the interpreter and script paths with symlink chains of just
|
||||
// over half the symlink limit each; this is the minimum required to test that
|
||||
// the symlink limit applies separately to each traversal, while tolerating
|
||||
// some symlinks in the resolution of (the original) interpreter_path and
|
||||
// script_path.
|
||||
for (int i = 0; i < (kLinuxMaxSymlinks / 2) + 1; i++) {
|
||||
interpreter_symlinks.push_back(ASSERT_NO_ERRNO_AND_VALUE(
|
||||
TempPath::CreateSymlinkTo(tmp_dir, interpreter_path)));
|
||||
interpreter_path = interpreter_symlinks[i].path();
|
||||
|
@ -679,18 +684,16 @@ TEST(ExecveatTest, UnshareFiles) {
|
|||
const FileDescriptor fd_closed_on_exec =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(tempFile.path(), O_RDONLY | O_CLOEXEC));
|
||||
|
||||
pid_t child;
|
||||
EXPECT_THAT(child = syscall(__NR_clone, SIGCHLD | CLONE_VFORK | CLONE_FILES,
|
||||
0, 0, 0, 0),
|
||||
SyscallSucceeds());
|
||||
ExecveArray argv = {"test"};
|
||||
ExecveArray envp;
|
||||
std::string child_path = RunfilePath(kBasicWorkload);
|
||||
pid_t child =
|
||||
syscall(__NR_clone, SIGCHLD | CLONE_VFORK | CLONE_FILES, 0, 0, 0, 0);
|
||||
if (child == 0) {
|
||||
ExecveArray argv = {"test"};
|
||||
ExecveArray envp;
|
||||
ASSERT_THAT(
|
||||
execve(RunfilePath(kBasicWorkload).c_str(), argv.get(), envp.get()),
|
||||
SyscallSucceeds());
|
||||
execve(child_path.c_str(), argv.get(), envp.get());
|
||||
_exit(1);
|
||||
}
|
||||
ASSERT_THAT(child, SyscallSucceeds());
|
||||
|
||||
int status;
|
||||
ASSERT_THAT(RetryEINTR(waitpid)(child, &status, 0), SyscallSucceeds());
|
||||
|
|
|
@ -125,12 +125,12 @@ PosixErrorOr<struct stat> Fstat(int fd) {
|
|||
|
||||
PosixErrorOr<bool> Exists(absl::string_view path) {
|
||||
struct stat stat_buf;
|
||||
int res = stat(std::string(path).c_str(), &stat_buf);
|
||||
int res = lstat(std::string(path).c_str(), &stat_buf);
|
||||
if (res < 0) {
|
||||
if (errno == ENOENT) {
|
||||
return false;
|
||||
}
|
||||
return PosixError(errno, absl::StrCat("stat ", path));
|
||||
return PosixError(errno, absl::StrCat("lstat ", path));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -44,9 +44,14 @@ PosixErrorOr<std::string> GetCWD();
|
|||
// can't be determined.
|
||||
PosixErrorOr<bool> Exists(absl::string_view path);
|
||||
|
||||
// Returns a stat structure for the given path or an error.
|
||||
// Returns a stat structure for the given path or an error. If the path
|
||||
// represents a symlink, it will be traversed.
|
||||
PosixErrorOr<struct stat> Stat(absl::string_view path);
|
||||
|
||||
// Returns a stat structure for the given path or an error. If the path
|
||||
// represents a symlink, it will not be traversed.
|
||||
PosixErrorOr<struct stat> Lstat(absl::string_view path);
|
||||
|
||||
// Returns a stat struct for the given fd.
|
||||
PosixErrorOr<struct stat> Fstat(int fd);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void TryDeleteRecursively(std::string const& path) {
|
|||
if (undeleted_dirs || undeleted_files || !status.ok()) {
|
||||
std::cerr << path << ": failed to delete " << undeleted_dirs
|
||||
<< " directories and " << undeleted_files
|
||||
<< " files: " << status;
|
||||
<< " files: " << status << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue