mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Set options on the correct Task in PTRACE_SEIZE.
$ docker run --rm --runtime=runsc -it --cap-add=SYS_PTRACE debian bash -c "apt-get update && apt-get install strace && strace ls"
...
Setting up strace (4.15-2) ...
execve("/bin/ls", ["ls"], [/* 6 vars */]) = 0
brk(NULL) = 0x5646d8c1e000
uname({sysname="Linux", nodename="114ef93d2db3", ...}) = 0
...
PiperOrigin-RevId: 241643321
Change-Id: Ie4bce27a7fb147eef07bbae5895c6ef3f529e177
This commit is contained in:
@@ -374,7 +374,7 @@ func (t *Task) ptraceAttach(target *Task, seize bool, opts uintptr) error {
|
||||
return syserror.EPERM
|
||||
}
|
||||
if seize {
|
||||
if err := t.ptraceSetOptionsLocked(opts); err != nil {
|
||||
if err := target.ptraceSetOptionsLocked(opts); err != nil {
|
||||
return syserror.EIO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1120,6 +1120,46 @@ TEST(PtraceTest, Interrupt_Listen_RequireSeize) {
|
||||
<< " status " << status;
|
||||
}
|
||||
|
||||
TEST(PtraceTest, SeizeSetOptions) {
|
||||
pid_t const child_pid = fork();
|
||||
if (child_pid == 0) {
|
||||
// In child process.
|
||||
while (true) {
|
||||
SleepSafe(absl::Seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
// In parent process.
|
||||
ASSERT_THAT(child_pid, SyscallSucceeds());
|
||||
|
||||
// Attach to the child with PTRACE_SEIZE while setting PTRACE_O_TRACESYSGOOD.
|
||||
ASSERT_THAT(ptrace(PTRACE_SEIZE, child_pid, 0, PTRACE_O_TRACESYSGOOD),
|
||||
SyscallSucceeds());
|
||||
|
||||
// Stop the child with PTRACE_INTERRUPT.
|
||||
ASSERT_THAT(ptrace(PTRACE_INTERRUPT, child_pid, 0, 0), SyscallSucceeds());
|
||||
int status;
|
||||
ASSERT_THAT(waitpid(child_pid, &status, 0),
|
||||
SyscallSucceedsWithValue(child_pid));
|
||||
EXPECT_EQ(SIGTRAP | (kPtraceEventStop << 8), status >> 8);
|
||||
|
||||
// Resume the child with PTRACE_SYSCALL and wait for it to enter
|
||||
// syscall-enter-stop. The stop signal status from the syscall stop should be
|
||||
// SIGTRAP|0x80, reflecting PTRACE_O_TRACESYSGOOD.
|
||||
ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
|
||||
ASSERT_THAT(waitpid(child_pid, &status, 0),
|
||||
SyscallSucceedsWithValue(child_pid));
|
||||
EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
|
||||
<< " status " << status;
|
||||
|
||||
// SIGKILL the child (detaching the tracer) and wait for it to exit.
|
||||
ASSERT_THAT(kill(child_pid, SIGKILL), SyscallSucceeds());
|
||||
ASSERT_THAT(waitpid(child_pid, &status, 0),
|
||||
SyscallSucceedsWithValue(child_pid));
|
||||
EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
|
||||
<< " status " << status;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
||||
|
||||
Reference in New Issue
Block a user