From 51b867612ecdb99a9b7473a752e452773cb690a0 Mon Sep 17 00:00:00 2001 From: Luis Hector Chavez Date: Wed, 4 Apr 2018 10:13:25 -0700 Subject: [PATCH] Make sys_ptrace_test.cpp Yama LSM-aware This change enables the tracer process to be able to call ptrace(2) on the worker process, which is does not have a direct-ancestor dependency. Bug: 77146512 Test: adb shell \ /data/nativetest{,64}/bionic-unit-tests{,-static}/bionic-unit-tests-{,-static} \ --gtest_filter='spawn*' # aosp_sailfish and Chrome OS Test: cts-tradefed run singleCommand cts --skip-preconditions \ -m CtsBionicTestCases --test 'PtraceResumptionTest*' # aosp_sailfish # and Chrome OS Change-Id: I9e41b3ddde64c0623ba9299cede9d5b2001c8e30 Merged-In: I9e41b3ddde64c0623ba9299cede9d5b2001c8e30 (cherry picked from commit 7300d83b2ee7c2e4ee937f09414194d5c8392754) --- tests/sys_ptrace_test.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp index e6a1e22ea..83fd93be2 100644 --- a/tests/sys_ptrace_test.cpp +++ b/tests/sys_ptrace_test.cpp @@ -384,22 +384,40 @@ class PtraceResumptionTest : public ::testing::Test { PtraceResumptionTest() { unique_fd worker_pipe_read; - int pipefd[2]; - if (pipe2(pipefd, O_CLOEXEC) != 0) { + if (!android::base::Pipe(&worker_pipe_read, &worker_pipe_write)) { err(1, "failed to create pipe"); } - worker_pipe_read.reset(pipefd[0]); - worker_pipe_write.reset(pipefd[1]); + // Second pipe to synchronize the Yama ptracer setup. + unique_fd worker_pipe_setup_read, worker_pipe_setup_write; + if (!android::base::Pipe(&worker_pipe_setup_read, &worker_pipe_setup_write)) { + err(1, "failed to create pipe"); + } worker = fork(); if (worker == -1) { err(1, "failed to fork worker"); } else if (worker == 0) { char buf; + // Allow the tracer process, which is not a direct process ancestor, to + // be able to use ptrace(2) on this process when Yama LSM is active. + if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) { + // if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this + // case since it's expected behaviour. + if (errno != EINVAL) { + err(1, "prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed for pid %d", getpid()); + } + } + worker_pipe_setup_write.reset(); + worker_pipe_write.reset(); TEMP_FAILURE_RETRY(read(worker_pipe_read.get(), &buf, sizeof(buf))); exit(0); + } else { + // Wait until the Yama ptracer is setup. + char buf; + worker_pipe_setup_write.reset(); + TEMP_FAILURE_RETRY(read(worker_pipe_setup_read.get(), &buf, sizeof(buf))); } }