Home | History | Annotate | Download | only in debuggerd
      1 /*
      2  * Copyright 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <err.h>
     18 #include <fcntl.h>
     19 #include <stdlib.h>
     20 #include <sys/capability.h>
     21 #include <sys/prctl.h>
     22 #include <sys/ptrace.h>
     23 #include <sys/resource.h>
     24 #include <sys/syscall.h>
     25 #include <sys/types.h>
     26 #include <unistd.h>
     27 
     28 #include <chrono>
     29 #include <regex>
     30 #include <thread>
     31 
     32 #include <android/set_abort_message.h>
     33 
     34 #include <android-base/file.h>
     35 #include <android-base/logging.h>
     36 #include <android-base/macros.h>
     37 #include <android-base/parseint.h>
     38 #include <android-base/properties.h>
     39 #include <android-base/strings.h>
     40 #include <android-base/test_utils.h>
     41 #include <android-base/unique_fd.h>
     42 #include <cutils/sockets.h>
     43 #include <gtest/gtest.h>
     44 
     45 #include <libminijail.h>
     46 #include <scoped_minijail.h>
     47 
     48 #include "debuggerd/handler.h"
     49 #include "protocol.h"
     50 #include "tombstoned/tombstoned.h"
     51 #include "util.h"
     52 
     53 using namespace std::chrono_literals;
     54 using android::base::unique_fd;
     55 
     56 #if defined(__LP64__)
     57 #define ARCH_SUFFIX "64"
     58 #else
     59 #define ARCH_SUFFIX ""
     60 #endif
     61 
     62 constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
     63 
     64 #define TIMEOUT(seconds, expr)                                     \
     65   [&]() {                                                          \
     66     struct sigaction old_sigaction;                                \
     67     struct sigaction new_sigaction = {};                           \
     68     new_sigaction.sa_handler = [](int) {};                         \
     69     if (sigaction(SIGALRM, &new_sigaction, &new_sigaction) != 0) { \
     70       err(1, "sigaction failed");                                  \
     71     }                                                              \
     72     alarm(seconds);                                                \
     73     auto value = expr;                                             \
     74     int saved_errno = errno;                                       \
     75     if (sigaction(SIGALRM, &old_sigaction, nullptr) != 0) {        \
     76       err(1, "sigaction failed");                                  \
     77     }                                                              \
     78     alarm(0);                                                      \
     79     errno = saved_errno;                                           \
     80     return value;                                                  \
     81   }()
     82 
     83 #define ASSERT_BACKTRACE_FRAME(result, frame_name) \
     84   ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ \S+ \()" frame_name R"(\+)");
     85 
     86 static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
     87                                  InterceptStatus* status, DebuggerdDumpType intercept_type) {
     88   intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
     89                                           ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
     90   if (intercept_fd->get() == -1) {
     91     FAIL() << "failed to contact tombstoned: " << strerror(errno);
     92   }
     93 
     94   InterceptRequest req = {.pid = target_pid, .dump_type = intercept_type};
     95 
     96   unique_fd output_pipe_write;
     97   if (!Pipe(output_fd, &output_pipe_write)) {
     98     FAIL() << "failed to create output pipe: " << strerror(errno);
     99   }
    100 
    101   std::string pipe_size_str;
    102   int pipe_buffer_size;
    103   if (!android::base::ReadFileToString("/proc/sys/fs/pipe-max-size", &pipe_size_str)) {
    104     FAIL() << "failed to read /proc/sys/fs/pipe-max-size: " << strerror(errno);
    105   }
    106 
    107   pipe_size_str = android::base::Trim(pipe_size_str);
    108 
    109   if (!android::base::ParseInt(pipe_size_str.c_str(), &pipe_buffer_size, 0)) {
    110     FAIL() << "failed to parse pipe max size";
    111   }
    112 
    113   if (fcntl(output_fd->get(), F_SETPIPE_SZ, pipe_buffer_size) != pipe_buffer_size) {
    114     FAIL() << "failed to set pipe size: " << strerror(errno);
    115   }
    116 
    117   ASSERT_GE(pipe_buffer_size, 1024 * 1024);
    118 
    119   if (send_fd(intercept_fd->get(), &req, sizeof(req), std::move(output_pipe_write)) != sizeof(req)) {
    120     FAIL() << "failed to send output fd to tombstoned: " << strerror(errno);
    121   }
    122 
    123   InterceptResponse response;
    124   ssize_t rc = TEMP_FAILURE_RETRY(read(intercept_fd->get(), &response, sizeof(response)));
    125   if (rc == -1) {
    126     FAIL() << "failed to read response from tombstoned: " << strerror(errno);
    127   } else if (rc == 0) {
    128     FAIL() << "failed to read response from tombstoned (EOF)";
    129   } else if (rc != sizeof(response)) {
    130     FAIL() << "received packet of unexpected length from tombstoned: expected " << sizeof(response)
    131            << ", received " << rc;
    132   }
    133 
    134   *status = response.status;
    135 }
    136 
    137 class CrasherTest : public ::testing::Test {
    138  public:
    139   pid_t crasher_pid = -1;
    140   bool previous_wait_for_gdb;
    141   unique_fd crasher_pipe;
    142   unique_fd intercept_fd;
    143 
    144   CrasherTest();
    145   ~CrasherTest();
    146 
    147   void StartIntercept(unique_fd* output_fd, DebuggerdDumpType intercept_type = kDebuggerdTombstone);
    148 
    149   // Returns -1 if we fail to read a response from tombstoned, otherwise the received return code.
    150   void FinishIntercept(int* result);
    151 
    152   void StartProcess(std::function<void()> function, std::function<pid_t()> forker = fork);
    153   void StartCrasher(const std::string& crash_type);
    154   void FinishCrasher();
    155   void AssertDeath(int signo);
    156 };
    157 
    158 CrasherTest::CrasherTest() {
    159   previous_wait_for_gdb = android::base::GetBoolProperty(kWaitForGdbKey, false);
    160   android::base::SetProperty(kWaitForGdbKey, "0");
    161 }
    162 
    163 CrasherTest::~CrasherTest() {
    164   if (crasher_pid != -1) {
    165     kill(crasher_pid, SIGKILL);
    166     int status;
    167     waitpid(crasher_pid, &status, WUNTRACED);
    168   }
    169 
    170   android::base::SetProperty(kWaitForGdbKey, previous_wait_for_gdb ? "1" : "0");
    171 }
    172 
    173 void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType intercept_type) {
    174   if (crasher_pid == -1) {
    175     FAIL() << "crasher hasn't been started";
    176   }
    177 
    178   InterceptStatus status;
    179   tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &status, intercept_type);
    180   ASSERT_EQ(InterceptStatus::kRegistered, status);
    181 }
    182 
    183 void CrasherTest::FinishIntercept(int* result) {
    184   InterceptResponse response;
    185 
    186   // Timeout for tombstoned intercept is 10 seconds.
    187   ssize_t rc = TIMEOUT(20, read(intercept_fd.get(), &response, sizeof(response)));
    188   if (rc == -1) {
    189     FAIL() << "failed to read response from tombstoned: " << strerror(errno);
    190   } else if (rc == 0) {
    191     *result = -1;
    192   } else if (rc != sizeof(response)) {
    193     FAIL() << "received packet of unexpected length from tombstoned: expected " << sizeof(response)
    194            << ", received " << rc;
    195   } else {
    196     *result = response.status == InterceptStatus::kStarted ? 1 : 0;
    197   }
    198 }
    199 
    200 void CrasherTest::StartProcess(std::function<void()> function, std::function<pid_t()> forker) {
    201   unique_fd read_pipe;
    202   unique_fd crasher_read_pipe;
    203   if (!Pipe(&crasher_read_pipe, &crasher_pipe)) {
    204     FAIL() << "failed to create pipe: " << strerror(errno);
    205   }
    206 
    207   crasher_pid = forker();
    208   if (crasher_pid == -1) {
    209     FAIL() << "fork failed: " << strerror(errno);
    210   } else if (crasher_pid == 0) {
    211     char dummy;
    212     crasher_pipe.reset();
    213     TEMP_FAILURE_RETRY(read(crasher_read_pipe.get(), &dummy, 1));
    214     function();
    215     _exit(0);
    216   }
    217 }
    218 
    219 void CrasherTest::FinishCrasher() {
    220   if (crasher_pipe == -1) {
    221     FAIL() << "crasher pipe uninitialized";
    222   }
    223 
    224   ssize_t rc = write(crasher_pipe.get(), "\n", 1);
    225   if (rc == -1) {
    226     FAIL() << "failed to write to crasher pipe: " << strerror(errno);
    227   } else if (rc == 0) {
    228     FAIL() << "crasher pipe was closed";
    229   }
    230 }
    231 
    232 void CrasherTest::AssertDeath(int signo) {
    233   int status;
    234   pid_t pid = TIMEOUT(5, waitpid(crasher_pid, &status, 0));
    235   if (pid != crasher_pid) {
    236     printf("failed to wait for crasher (pid %d)\n", crasher_pid);
    237     sleep(100);
    238     FAIL() << "failed to wait for crasher: " << strerror(errno);
    239   }
    240 
    241   if (signo == 0) {
    242     ASSERT_TRUE(WIFEXITED(status));
    243     ASSERT_EQ(0, WEXITSTATUS(signo));
    244   } else {
    245     ASSERT_FALSE(WIFEXITED(status));
    246     ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
    247     ASSERT_EQ(signo, WTERMSIG(status));
    248   }
    249   crasher_pid = -1;
    250 }
    251 
    252 static void ConsumeFd(unique_fd fd, std::string* output) {
    253   constexpr size_t read_length = PAGE_SIZE;
    254   std::string result;
    255 
    256   while (true) {
    257     size_t offset = result.size();
    258     result.resize(result.size() + PAGE_SIZE);
    259     ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &result[offset], read_length));
    260     if (rc == -1) {
    261       FAIL() << "read failed: " << strerror(errno);
    262     } else if (rc == 0) {
    263       result.resize(result.size() - PAGE_SIZE);
    264       break;
    265     }
    266 
    267     result.resize(result.size() - PAGE_SIZE + rc);
    268   }
    269 
    270   *output = std::move(result);
    271 }
    272 
    273 TEST_F(CrasherTest, smoke) {
    274   int intercept_result;
    275   unique_fd output_fd;
    276   StartProcess([]() {
    277     *reinterpret_cast<volatile char*>(0xdead) = '1';
    278   });
    279 
    280   StartIntercept(&output_fd);
    281   FinishCrasher();
    282   AssertDeath(SIGSEGV);
    283   FinishIntercept(&intercept_result);
    284 
    285   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    286 
    287   std::string result;
    288   ConsumeFd(std::move(output_fd), &result);
    289   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
    290 }
    291 
    292 TEST_F(CrasherTest, LD_PRELOAD) {
    293   int intercept_result;
    294   unique_fd output_fd;
    295   StartProcess([]() {
    296     setenv("LD_PRELOAD", "nonexistent.so", 1);
    297     *reinterpret_cast<volatile char*>(0xdead) = '1';
    298   });
    299 
    300   StartIntercept(&output_fd);
    301   FinishCrasher();
    302   AssertDeath(SIGSEGV);
    303   FinishIntercept(&intercept_result);
    304 
    305   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    306 
    307   std::string result;
    308   ConsumeFd(std::move(output_fd), &result);
    309   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
    310 }
    311 
    312 TEST_F(CrasherTest, abort) {
    313   int intercept_result;
    314   unique_fd output_fd;
    315   StartProcess([]() {
    316     abort();
    317   });
    318   StartIntercept(&output_fd);
    319   FinishCrasher();
    320   AssertDeath(SIGABRT);
    321   FinishIntercept(&intercept_result);
    322 
    323   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    324 
    325   std::string result;
    326   ConsumeFd(std::move(output_fd), &result);
    327   ASSERT_BACKTRACE_FRAME(result, "abort");
    328 }
    329 
    330 TEST_F(CrasherTest, signal) {
    331   int intercept_result;
    332   unique_fd output_fd;
    333   StartProcess([]() {
    334     while (true) {
    335       sleep(1);
    336     }
    337   });
    338   StartIntercept(&output_fd);
    339   FinishCrasher();
    340   ASSERT_EQ(0, kill(crasher_pid, SIGSEGV));
    341 
    342   AssertDeath(SIGSEGV);
    343   FinishIntercept(&intercept_result);
    344 
    345   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    346 
    347   std::string result;
    348   ConsumeFd(std::move(output_fd), &result);
    349   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 0 \(SI_USER\), fault addr --------)");
    350   ASSERT_MATCH(result, R"(backtrace:)");
    351 }
    352 
    353 TEST_F(CrasherTest, abort_message) {
    354   int intercept_result;
    355   unique_fd output_fd;
    356   StartProcess([]() {
    357     android_set_abort_message("abort message goes here");
    358     abort();
    359   });
    360   StartIntercept(&output_fd);
    361   FinishCrasher();
    362   AssertDeath(SIGABRT);
    363   FinishIntercept(&intercept_result);
    364 
    365   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    366 
    367   std::string result;
    368   ConsumeFd(std::move(output_fd), &result);
    369   ASSERT_MATCH(result, R"(Abort message: 'abort message goes here')");
    370 }
    371 
    372 TEST_F(CrasherTest, abort_message_backtrace) {
    373   int intercept_result;
    374   unique_fd output_fd;
    375   StartProcess([]() {
    376     android_set_abort_message("not actually aborting");
    377     raise(DEBUGGER_SIGNAL);
    378     exit(0);
    379   });
    380   StartIntercept(&output_fd);
    381   FinishCrasher();
    382   AssertDeath(0);
    383   FinishIntercept(&intercept_result);
    384 
    385   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    386 
    387   std::string result;
    388   ConsumeFd(std::move(output_fd), &result);
    389   ASSERT_NOT_MATCH(result, R"(Abort message:)");
    390 }
    391 
    392 TEST_F(CrasherTest, intercept_timeout) {
    393   int intercept_result;
    394   unique_fd output_fd;
    395   StartProcess([]() {
    396     abort();
    397   });
    398   StartIntercept(&output_fd);
    399 
    400   // Don't let crasher finish until we timeout.
    401   FinishIntercept(&intercept_result);
    402 
    403   ASSERT_NE(1, intercept_result) << "tombstoned reported success? (intercept_result = "
    404                                  << intercept_result << ")";
    405 
    406   FinishCrasher();
    407   AssertDeath(SIGABRT);
    408 }
    409 
    410 TEST_F(CrasherTest, wait_for_gdb) {
    411   if (!android::base::SetProperty(kWaitForGdbKey, "1")) {
    412     FAIL() << "failed to enable wait_for_gdb";
    413   }
    414   sleep(1);
    415 
    416   StartProcess([]() {
    417     abort();
    418   });
    419   FinishCrasher();
    420 
    421   int status;
    422   ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, WUNTRACED));
    423   ASSERT_TRUE(WIFSTOPPED(status));
    424   ASSERT_EQ(SIGSTOP, WSTOPSIG(status));
    425 
    426   ASSERT_EQ(0, kill(crasher_pid, SIGCONT));
    427 
    428   AssertDeath(SIGABRT);
    429 }
    430 
    431 TEST_F(CrasherTest, backtrace) {
    432   std::string result;
    433   int intercept_result;
    434   unique_fd output_fd;
    435 
    436   StartProcess([]() {
    437     abort();
    438   });
    439   StartIntercept(&output_fd, kDebuggerdNativeBacktrace);
    440 
    441   std::this_thread::sleep_for(500ms);
    442 
    443   sigval val;
    444   val.sival_int = 1;
    445   ASSERT_EQ(0, sigqueue(crasher_pid, DEBUGGER_SIGNAL, val)) << strerror(errno);
    446   FinishIntercept(&intercept_result);
    447   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    448   ConsumeFd(std::move(output_fd), &result);
    449   ASSERT_BACKTRACE_FRAME(result, "read");
    450 
    451   int status;
    452   ASSERT_EQ(0, waitpid(crasher_pid, &status, WNOHANG | WUNTRACED));
    453 
    454   StartIntercept(&output_fd);
    455   FinishCrasher();
    456   AssertDeath(SIGABRT);
    457   FinishIntercept(&intercept_result);
    458   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    459   ConsumeFd(std::move(output_fd), &result);
    460   ASSERT_BACKTRACE_FRAME(result, "abort");
    461 }
    462 
    463 TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
    464   int intercept_result;
    465   unique_fd output_fd;
    466   StartProcess([]() {
    467     prctl(PR_SET_DUMPABLE, 0);
    468     abort();
    469   });
    470 
    471   StartIntercept(&output_fd);
    472   FinishCrasher();
    473   AssertDeath(SIGABRT);
    474   FinishIntercept(&intercept_result);
    475 
    476   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    477 
    478   std::string result;
    479   ConsumeFd(std::move(output_fd), &result);
    480   ASSERT_BACKTRACE_FRAME(result, "abort");
    481 }
    482 
    483 TEST_F(CrasherTest, capabilities) {
    484   ASSERT_EQ(0U, getuid()) << "capability test requires root";
    485 
    486   StartProcess([]() {
    487     if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
    488       err(1, "failed to set PR_SET_KEEPCAPS");
    489     }
    490 
    491     if (setresuid(1, 1, 1) != 0) {
    492       err(1, "setresuid failed");
    493     }
    494 
    495     __user_cap_header_struct capheader;
    496     __user_cap_data_struct capdata[2];
    497     memset(&capheader, 0, sizeof(capheader));
    498     memset(&capdata, 0, sizeof(capdata));
    499 
    500     capheader.version = _LINUX_CAPABILITY_VERSION_3;
    501     capheader.pid = 0;
    502 
    503     // Turn on every third capability.
    504     static_assert(CAP_LAST_CAP > 33, "CAP_LAST_CAP <= 32");
    505     for (int i = 0; i < CAP_LAST_CAP; i += 3) {
    506       capdata[CAP_TO_INDEX(i)].permitted |= CAP_TO_MASK(i);
    507       capdata[CAP_TO_INDEX(i)].effective |= CAP_TO_MASK(i);
    508     }
    509 
    510     // Make sure CAP_SYS_PTRACE is off.
    511     capdata[CAP_TO_INDEX(CAP_SYS_PTRACE)].permitted &= ~(CAP_TO_MASK(CAP_SYS_PTRACE));
    512     capdata[CAP_TO_INDEX(CAP_SYS_PTRACE)].effective &= ~(CAP_TO_MASK(CAP_SYS_PTRACE));
    513 
    514     if (capset(&capheader, &capdata[0]) != 0) {
    515       err(1, "capset failed");
    516     }
    517 
    518     if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) != 0) {
    519       err(1, "failed to drop ambient capabilities");
    520     }
    521 
    522     pthread_setname_np(pthread_self(), "thread_name");
    523     raise(SIGSYS);
    524   });
    525 
    526   unique_fd output_fd;
    527   StartIntercept(&output_fd);
    528   FinishCrasher();
    529   AssertDeath(SIGSYS);
    530 
    531   std::string result;
    532   int intercept_result;
    533   FinishIntercept(&intercept_result);
    534   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    535   ConsumeFd(std::move(output_fd), &result);
    536   ASSERT_MATCH(result, R"(name: thread_name\s+>>> .+debuggerd_test(32|64) <<<)");
    537   ASSERT_BACKTRACE_FRAME(result, "tgkill");
    538 }
    539 
    540 TEST_F(CrasherTest, fake_pid) {
    541   int intercept_result;
    542   unique_fd output_fd;
    543 
    544   // Prime the getpid/gettid caches.
    545   UNUSED(getpid());
    546   UNUSED(gettid());
    547 
    548   std::function<pid_t()> clone_fn = []() {
    549     return syscall(__NR_clone, SIGCHLD, nullptr, nullptr, nullptr, nullptr);
    550   };
    551   StartProcess(
    552       []() {
    553         ASSERT_NE(getpid(), syscall(__NR_getpid));
    554         ASSERT_NE(gettid(), syscall(__NR_gettid));
    555         raise(SIGSEGV);
    556       },
    557       clone_fn);
    558 
    559   StartIntercept(&output_fd);
    560   FinishCrasher();
    561   AssertDeath(SIGSEGV);
    562   FinishIntercept(&intercept_result);
    563 
    564   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    565 
    566   std::string result;
    567   ConsumeFd(std::move(output_fd), &result);
    568   ASSERT_BACKTRACE_FRAME(result, "tgkill");
    569 }
    570 
    571 static const char* const kDebuggerdSeccompPolicy =
    572     "/system/etc/seccomp_policy/crash_dump." ABI_STRING ".policy";
    573 
    574 static pid_t seccomp_fork_impl(void (*prejail)()) {
    575   unique_fd policy_fd(open(kDebuggerdSeccompPolicy, O_RDONLY | O_CLOEXEC));
    576   if (policy_fd == -1) {
    577     LOG(FATAL) << "failed to open policy " << kDebuggerdSeccompPolicy;
    578   }
    579 
    580   ScopedMinijail jail{minijail_new()};
    581   if (!jail) {
    582     LOG(FATAL) << "failed to create minijail";
    583   }
    584 
    585   minijail_no_new_privs(jail.get());
    586   minijail_log_seccomp_filter_failures(jail.get());
    587   minijail_use_seccomp_filter(jail.get());
    588   minijail_parse_seccomp_filters_from_fd(jail.get(), policy_fd.release());
    589 
    590   pid_t result = fork();
    591   if (result == -1) {
    592     return result;
    593   } else if (result != 0) {
    594     return result;
    595   }
    596 
    597   // Spawn and detach a thread that spins forever.
    598   std::atomic<bool> thread_ready(false);
    599   std::thread thread([&jail, &thread_ready]() {
    600     minijail_enter(jail.get());
    601     thread_ready = true;
    602     for (;;)
    603       ;
    604   });
    605   thread.detach();
    606 
    607   while (!thread_ready) {
    608     continue;
    609   }
    610 
    611   if (prejail) {
    612     prejail();
    613   }
    614 
    615   minijail_enter(jail.get());
    616   return result;
    617 }
    618 
    619 static pid_t seccomp_fork() {
    620   return seccomp_fork_impl(nullptr);
    621 }
    622 
    623 TEST_F(CrasherTest, seccomp_crash) {
    624   int intercept_result;
    625   unique_fd output_fd;
    626 
    627   StartProcess([]() { abort(); }, &seccomp_fork);
    628 
    629   StartIntercept(&output_fd);
    630   FinishCrasher();
    631   AssertDeath(SIGABRT);
    632   FinishIntercept(&intercept_result);
    633   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    634 
    635   std::string result;
    636   ConsumeFd(std::move(output_fd), &result);
    637   ASSERT_BACKTRACE_FRAME(result, "abort");
    638 }
    639 
    640 static pid_t seccomp_fork_rlimit() {
    641   return seccomp_fork_impl([]() {
    642     struct rlimit rlim = {
    643         .rlim_cur = 512 * 1024 * 1024,
    644         .rlim_max = 512 * 1024 * 1024,
    645     };
    646 
    647     if (setrlimit(RLIMIT_AS, &rlim) != 0) {
    648       raise(SIGINT);
    649     }
    650   });
    651 }
    652 
    653 TEST_F(CrasherTest, seccomp_crash_oom) {
    654   int intercept_result;
    655   unique_fd output_fd;
    656 
    657   StartProcess(
    658       []() {
    659         std::vector<void*> vec;
    660         for (int i = 0; i < 512; ++i) {
    661           char* buf = static_cast<char*>(malloc(1024 * 1024));
    662           if (!buf) {
    663             abort();
    664           }
    665           memset(buf, 0xff, 1024 * 1024);
    666           vec.push_back(buf);
    667         }
    668       },
    669       &seccomp_fork_rlimit);
    670 
    671   StartIntercept(&output_fd);
    672   FinishCrasher();
    673   AssertDeath(SIGABRT);
    674   FinishIntercept(&intercept_result);
    675   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    676 
    677   // We can't actually generate a backtrace, just make sure that the process terminates.
    678 }
    679 
    680 __attribute__((noinline)) extern "C" bool raise_debugger_signal(DebuggerdDumpType dump_type) {
    681   siginfo_t siginfo;
    682   siginfo.si_code = SI_QUEUE;
    683   siginfo.si_pid = getpid();
    684   siginfo.si_uid = getuid();
    685 
    686   if (dump_type != kDebuggerdNativeBacktrace && dump_type != kDebuggerdTombstone) {
    687     PLOG(FATAL) << "invalid dump type";
    688   }
    689 
    690   siginfo.si_value.sival_int = dump_type == kDebuggerdNativeBacktrace;
    691 
    692   if (syscall(__NR_rt_tgsigqueueinfo, getpid(), gettid(), DEBUGGER_SIGNAL, &siginfo) != 0) {
    693     PLOG(ERROR) << "libdebuggerd_client: failed to send signal to self";
    694     return false;
    695   }
    696 
    697   return true;
    698 }
    699 
    700 TEST_F(CrasherTest, seccomp_tombstone) {
    701   int intercept_result;
    702   unique_fd output_fd;
    703 
    704   static const auto dump_type = kDebuggerdTombstone;
    705   StartProcess(
    706       []() {
    707         raise_debugger_signal(dump_type);
    708         _exit(0);
    709       },
    710       &seccomp_fork);
    711 
    712   StartIntercept(&output_fd, dump_type);
    713   FinishCrasher();
    714   AssertDeath(0);
    715   FinishIntercept(&intercept_result);
    716   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    717 
    718   std::string result;
    719   ConsumeFd(std::move(output_fd), &result);
    720   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
    721 }
    722 
    723 TEST_F(CrasherTest, seccomp_backtrace) {
    724   int intercept_result;
    725   unique_fd output_fd;
    726 
    727   static const auto dump_type = kDebuggerdNativeBacktrace;
    728   StartProcess(
    729       []() {
    730         raise_debugger_signal(dump_type);
    731         _exit(0);
    732       },
    733       &seccomp_fork);
    734 
    735   StartIntercept(&output_fd, dump_type);
    736   FinishCrasher();
    737   AssertDeath(0);
    738   FinishIntercept(&intercept_result);
    739   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    740 
    741   std::string result;
    742   ConsumeFd(std::move(output_fd), &result);
    743   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
    744 }
    745 
    746 TEST_F(CrasherTest, seccomp_crash_logcat) {
    747   StartProcess([]() { abort(); }, &seccomp_fork);
    748   FinishCrasher();
    749 
    750   // Make sure we don't get SIGSYS when trying to dump a crash to logcat.
    751   AssertDeath(SIGABRT);
    752 }
    753 
    754 TEST_F(CrasherTest, competing_tracer) {
    755   int intercept_result;
    756   unique_fd output_fd;
    757   StartProcess([]() {
    758     raise(SIGABRT);
    759   });
    760 
    761   StartIntercept(&output_fd);
    762 
    763   ASSERT_EQ(0, ptrace(PTRACE_SEIZE, crasher_pid, 0, 0));
    764   FinishCrasher();
    765 
    766   int status;
    767   ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, 0));
    768   ASSERT_TRUE(WIFSTOPPED(status));
    769   ASSERT_EQ(SIGABRT, WSTOPSIG(status));
    770 
    771   ASSERT_EQ(0, ptrace(PTRACE_CONT, crasher_pid, 0, SIGABRT));
    772   FinishIntercept(&intercept_result);
    773   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
    774 
    775   std::string result;
    776   ConsumeFd(std::move(output_fd), &result);
    777   std::string regex = R"(failed to attach to thread \d+, already traced by )";
    778   regex += std::to_string(gettid());
    779   regex += R"( \(.+debuggerd_test)";
    780   ASSERT_MATCH(result, regex.c_str());
    781 
    782   ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, 0));
    783   ASSERT_TRUE(WIFSTOPPED(status));
    784   ASSERT_EQ(SIGABRT, WSTOPSIG(status));
    785 
    786   ASSERT_EQ(0, ptrace(PTRACE_DETACH, crasher_pid, 0, SIGABRT));
    787   AssertDeath(SIGABRT);
    788 }
    789 
    790 TEST(crash_dump, zombie) {
    791   pid_t forkpid = fork();
    792 
    793   pid_t rc;
    794   int status;
    795 
    796   if (forkpid == 0) {
    797     errno = 0;
    798     rc = waitpid(-1, &status, WNOHANG | __WALL | __WNOTHREAD);
    799     if (rc != -1 || errno != ECHILD) {
    800       errx(2, "first waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
    801     }
    802 
    803     raise(DEBUGGER_SIGNAL);
    804 
    805     errno = 0;
    806     rc = waitpid(-1, &status, __WALL | __WNOTHREAD);
    807     if (rc != -1 || errno != ECHILD) {
    808       errx(2, "second waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
    809     }
    810     _exit(0);
    811   } else {
    812     rc = waitpid(forkpid, &status, 0);
    813     ASSERT_EQ(forkpid, rc);
    814     ASSERT_TRUE(WIFEXITED(status));
    815     ASSERT_EQ(0, WEXITSTATUS(status));
    816   }
    817 }
    818 
    819 TEST(tombstoned, no_notify) {
    820   // Do this a few times.
    821   for (int i = 0; i < 3; ++i) {
    822     pid_t pid = 123'456'789 + i;
    823 
    824     unique_fd intercept_fd, output_fd;
    825     InterceptStatus status;
    826     tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
    827     ASSERT_EQ(InterceptStatus::kRegistered, status);
    828 
    829     {
    830       unique_fd tombstoned_socket, input_fd;
    831       ASSERT_TRUE(tombstoned_connect(pid, &tombstoned_socket, &input_fd, kDebuggerdTombstone));
    832       ASSERT_TRUE(android::base::WriteFully(input_fd.get(), &pid, sizeof(pid)));
    833     }
    834 
    835     pid_t read_pid;
    836     ASSERT_TRUE(android::base::ReadFully(output_fd.get(), &read_pid, sizeof(read_pid)));
    837     ASSERT_EQ(read_pid, pid);
    838   }
    839 }
    840 
    841 TEST(tombstoned, stress) {
    842   // Spawn threads to simultaneously do a bunch of failing dumps and a bunch of successful dumps.
    843   static constexpr int kDumpCount = 100;
    844 
    845   std::atomic<bool> start(false);
    846   std::vector<std::thread> threads;
    847   threads.emplace_back([&start]() {
    848     while (!start) {
    849       continue;
    850     }
    851 
    852     // Use a way out of range pid, to avoid stomping on an actual process.
    853     pid_t pid_base = 1'000'000;
    854 
    855     for (int dump = 0; dump < kDumpCount; ++dump) {
    856       pid_t pid = pid_base + dump;
    857 
    858       unique_fd intercept_fd, output_fd;
    859       InterceptStatus status;
    860       tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
    861       ASSERT_EQ(InterceptStatus::kRegistered, status);
    862 
    863       // Pretend to crash, and then immediately close the socket.
    864       unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
    865                                            ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
    866       if (sockfd == -1) {
    867         FAIL() << "failed to connect to tombstoned: " << strerror(errno);
    868       }
    869       TombstonedCrashPacket packet = {};
    870       packet.packet_type = CrashPacketType::kDumpRequest;
    871       packet.packet.dump_request.pid = pid;
    872       if (TEMP_FAILURE_RETRY(write(sockfd, &packet, sizeof(packet))) != sizeof(packet)) {
    873         FAIL() << "failed to write to tombstoned: " << strerror(errno);
    874       }
    875 
    876       continue;
    877     }
    878   });
    879 
    880   threads.emplace_back([&start]() {
    881     while (!start) {
    882       continue;
    883     }
    884 
    885     // Use a way out of range pid, to avoid stomping on an actual process.
    886     pid_t pid_base = 2'000'000;
    887 
    888     for (int dump = 0; dump < kDumpCount; ++dump) {
    889       pid_t pid = pid_base + dump;
    890 
    891       unique_fd intercept_fd, output_fd;
    892       InterceptStatus status;
    893       tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
    894       ASSERT_EQ(InterceptStatus::kRegistered, status);
    895 
    896       {
    897         unique_fd tombstoned_socket, input_fd;
    898         ASSERT_TRUE(tombstoned_connect(pid, &tombstoned_socket, &input_fd, kDebuggerdTombstone));
    899         ASSERT_TRUE(android::base::WriteFully(input_fd.get(), &pid, sizeof(pid)));
    900         tombstoned_notify_completion(tombstoned_socket.get());
    901       }
    902 
    903       // TODO: Fix the race that requires this sleep.
    904       std::this_thread::sleep_for(50ms);
    905 
    906       pid_t read_pid;
    907       ASSERT_TRUE(android::base::ReadFully(output_fd.get(), &read_pid, sizeof(read_pid)));
    908       ASSERT_EQ(read_pid, pid);
    909     }
    910   });
    911 
    912   start = true;
    913 
    914   for (std::thread& thread : threads) {
    915     thread.join();
    916   }
    917 }
    918 
    919 TEST(tombstoned, java_trace_intercept_smoke) {
    920   // Using a "real" PID is a little dangerous here - if the test fails
    921   // or crashes, we might end up getting a bogus / unreliable stack
    922   // trace.
    923   const pid_t self = getpid();
    924 
    925   unique_fd intercept_fd, output_fd;
    926   InterceptStatus status;
    927   tombstoned_intercept(self, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
    928   ASSERT_EQ(InterceptStatus::kRegistered, status);
    929 
    930   // First connect to tombstoned requesting a native backtrace. This
    931   // should result in a "regular" FD and not the installed intercept.
    932   const char native[] = "native";
    933   unique_fd tombstoned_socket, input_fd;
    934   ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdNativeBacktrace));
    935   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native)));
    936   tombstoned_notify_completion(tombstoned_socket.get());
    937 
    938   // Then, connect to tombstoned asking for a java backtrace. This *should*
    939   // trigger the intercept.
    940   const char java[] = "java";
    941   ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace));
    942   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java)));
    943   tombstoned_notify_completion(tombstoned_socket.get());
    944 
    945   char outbuf[sizeof(java)];
    946   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
    947   ASSERT_STREQ("java", outbuf);
    948 }
    949 
    950 TEST(tombstoned, multiple_intercepts) {
    951   const pid_t fake_pid = 1'234'567;
    952   unique_fd intercept_fd, output_fd;
    953   InterceptStatus status;
    954   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
    955   ASSERT_EQ(InterceptStatus::kRegistered, status);
    956 
    957   unique_fd intercept_fd_2, output_fd_2;
    958   tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &status, kDebuggerdNativeBacktrace);
    959   ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, status);
    960 }
    961 
    962 TEST(tombstoned, intercept_any) {
    963   const pid_t fake_pid = 1'234'567;
    964 
    965   unique_fd intercept_fd, output_fd;
    966   InterceptStatus status;
    967   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdNativeBacktrace);
    968   ASSERT_EQ(InterceptStatus::kRegistered, status);
    969 
    970   const char any[] = "any";
    971   unique_fd tombstoned_socket, input_fd;
    972   ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept));
    973   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any)));
    974   tombstoned_notify_completion(tombstoned_socket.get());
    975 
    976   char outbuf[sizeof(any)];
    977   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
    978   ASSERT_STREQ("any", outbuf);
    979 }
    980