From c4caccd54042ea80a6e8b5a8f5ce59ee87a7f424 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Tue, 2 Apr 2019 18:12:11 -0700 Subject: 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 --- test/syscalls/linux/ptrace.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'test/syscalls') diff --git a/test/syscalls/linux/ptrace.cc b/test/syscalls/linux/ptrace.cc index 6d5c425d8..8fc0045ce 100644 --- a/test/syscalls/linux/ptrace.cc +++ b/test/syscalls/linux/ptrace.cc @@ -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 -- cgit v1.2.3