Unshare files on exec

The current task can share its fdtable with a few other tasks,
but after exec, this should be a completely separate process.

PiperOrigin-RevId: 314999565
This commit is contained in:
Andrei Vagin
2020-06-05 14:45:32 -07:00
committed by gVisor bot
parent e4e11f2798
commit 8c1f5b5cd8
2 changed files with 31 additions and 0 deletions
+4
View File
@@ -198,6 +198,10 @@ func (r *runSyscallAfterExecStop) execute(t *Task) taskRunState {
t.tg.oldRSeqCritical.Store(&OldRSeqCriticalRegion{})
t.tg.pidns.owner.mu.Unlock()
oldFDTable := t.fdTable
t.fdTable = t.fdTable.Fork()
oldFDTable.DecRef()
// Remove FDs with the CloseOnExec flag set.
t.fdTable.RemoveIf(func(_ *fs.File, _ *vfs.FileDescription, flags FDFlags) bool {
return flags.CloseOnExec
+27
View File
@@ -673,6 +673,33 @@ TEST(ExecveatTest, SymlinkNoFollowWithRelativePath) {
EXPECT_EQ(execve_errno, ELOOP);
}
TEST(ExecveatTest, UnshareFiles) {
TempPath tempFile = ASSERT_NO_ERRNO_AND_VALUE(
TempPath::CreateFileWith(GetAbsoluteTestTmpdir(), "bar", 0755));
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());
if (child == 0) {
ExecveArray argv = {"test"};
ExecveArray envp;
ASSERT_THAT(
execve(RunfilePath(kBasicWorkload).c_str(), argv.get(), envp.get()),
SyscallSucceeds());
_exit(1);
}
int status;
ASSERT_THAT(RetryEINTR(waitpid)(child, &status, 0), SyscallSucceeds());
EXPECT_EQ(status, 0);
struct stat st;
EXPECT_THAT(fstat(fd_closed_on_exec.get(), &st), SyscallSucceeds());
}
TEST(ExecveatTest, SymlinkNoFollowWithAbsolutePath) {
std::string parent_dir = "/tmp";
TempPath link = ASSERT_NO_ERRNO_AND_VALUE(