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 <dirent.h>
18 #include <dlfcn.h>
19 #include <err.h>
20 #include <fcntl.h>
21 #include <linux/prctl.h>
22 #include <malloc.h>
23 #include <pthread.h>
24 #include <setjmp.h>
25 #include <stdlib.h>
26 #include <sys/capability.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29 #include <sys/ptrace.h>
30 #include <sys/resource.h>
31 #include <sys/syscall.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 
35 #include <chrono>
36 #include <regex>
37 #include <set>
38 #include <string>
39 #include <thread>
40 
41 #include <android/crash_detail.h>
42 #include <android/dlext.h>
43 #include <android/fdsan.h>
44 #include <android/set_abort_message.h>
45 #include <bionic/malloc.h>
46 #include <bionic/mte.h>
47 #include <bionic/reserved_signals.h>
48 
49 #include <android-base/cmsg.h>
50 #include <android-base/file.h>
51 #include <android-base/logging.h>
52 #include <android-base/macros.h>
53 #include <android-base/parseint.h>
54 #include <android-base/properties.h>
55 #include <android-base/stringprintf.h>
56 #include <android-base/strings.h>
57 #include <android-base/test_utils.h>
58 #include <android-base/unique_fd.h>
59 #include <cutils/sockets.h>
60 #include <gmock/gmock.h>
61 #include <gtest/gtest.h>
62 
63 #include <unwindstack/Elf.h>
64 #include <unwindstack/Memory.h>
65 
66 #include <libminijail.h>
67 #include <scoped_minijail.h>
68 
69 #include "crash_test.h"
70 #include "debuggerd/handler.h"
71 #include "gtest/gtest.h"
72 #include "libdebuggerd/utility.h"
73 #include "protocol.h"
74 #include "tombstoned/tombstoned.h"
75 #include "util.h"
76 
77 using namespace std::chrono_literals;
78 
79 using android::base::SendFileDescriptors;
80 using android::base::unique_fd;
81 using ::testing::HasSubstr;
82 
83 #if defined(__LP64__)
84 #define ARCH_SUFFIX "64"
85 #else
86 #define ARCH_SUFFIX ""
87 #endif
88 
89 constexpr char kWaitForDebuggerKey[] = "debug.debuggerd.wait_for_debugger";
90 
91 #define TIMEOUT(seconds, expr)                                     \
92   [&]() {                                                          \
93     struct sigaction old_sigaction;                                \
94     struct sigaction new_sigaction = {};                           \
95     new_sigaction.sa_handler = [](int) {};                         \
96     if (sigaction(SIGALRM, &new_sigaction, &old_sigaction) != 0) { \
97       err(1, "sigaction failed");                                  \
98     }                                                              \
99     alarm(seconds * android::base::HwTimeoutMultiplier());         \
100     auto value = expr;                                             \
101     int saved_errno = errno;                                       \
102     if (sigaction(SIGALRM, &old_sigaction, nullptr) != 0) {        \
103       err(1, "sigaction failed");                                  \
104     }                                                              \
105     alarm(0);                                                      \
106     errno = saved_errno;                                           \
107     return value;                                                  \
108   }()
109 
110 // Backtrace frame dump could contain:
111 //   #01 pc 0001cded  /data/tmp/debuggerd_test32 (raise_debugger_signal+80)
112 // or
113 //   #01 pc 00022a09  /data/tmp/debuggerd_test32 (offset 0x12000) (raise_debugger_signal+80)
114 #define ASSERT_BACKTRACE_FRAME(result, frame_name) \
115   ASSERT_MATCH(result,                             \
116                R"(#\d\d pc [0-9a-f]+\s+ \S+ (\(offset 0x[0-9a-f]+\) )?\()" frame_name R"(\+)");
117 
tombstoned_intercept(pid_t target_pid,unique_fd * intercept_fd,unique_fd * output_fd,InterceptResponse * response,DebuggerdDumpType intercept_type)118 static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
119                                  InterceptResponse* response, DebuggerdDumpType intercept_type) {
120   intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
121                                           ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
122   if (intercept_fd->get() == -1) {
123     FAIL() << "failed to contact tombstoned: " << strerror(errno);
124   }
125 
126   InterceptRequest req = {
127       .dump_type = intercept_type,
128       .pid = target_pid,
129   };
130 
131   unique_fd output_pipe_write;
132   if (!Pipe(output_fd, &output_pipe_write)) {
133     FAIL() << "failed to create output pipe: " << strerror(errno);
134   }
135 
136   std::string pipe_size_str;
137   int pipe_buffer_size;
138   if (!android::base::ReadFileToString("/proc/sys/fs/pipe-max-size", &pipe_size_str)) {
139     FAIL() << "failed to read /proc/sys/fs/pipe-max-size: " << strerror(errno);
140   }
141 
142   pipe_size_str = android::base::Trim(pipe_size_str);
143 
144   if (!android::base::ParseInt(pipe_size_str.c_str(), &pipe_buffer_size, 0)) {
145     FAIL() << "failed to parse pipe max size";
146   }
147 
148   if (fcntl(output_fd->get(), F_SETPIPE_SZ, pipe_buffer_size) != pipe_buffer_size) {
149     FAIL() << "failed to set pipe size: " << strerror(errno);
150   }
151 
152   ASSERT_GE(pipe_buffer_size, 1024 * 1024);
153 
154   ssize_t rc = SendFileDescriptors(intercept_fd->get(), &req, sizeof(req), output_pipe_write.get());
155   output_pipe_write.reset();
156   if (rc != sizeof(req)) {
157     FAIL() << "failed to send output fd to tombstoned: " << strerror(errno);
158   }
159 
160   rc = TEMP_FAILURE_RETRY(read(intercept_fd->get(), response, sizeof(*response)));
161   if (rc == -1) {
162     FAIL() << "failed to read response from tombstoned: " << strerror(errno);
163   } else if (rc == 0) {
164     FAIL() << "failed to read response from tombstoned (EOF)";
165   } else if (rc != sizeof(*response)) {
166     FAIL() << "received packet of unexpected length from tombstoned: expected " << sizeof(*response)
167            << ", received " << rc;
168   }
169 }
170 
pac_supported()171 static bool pac_supported() {
172 #if defined(__aarch64__)
173   return getauxval(AT_HWCAP) & HWCAP_PACA;
174 #else
175   return false;
176 #endif
177 }
178 
179 class CrasherTest : public ::testing::Test {
180  public:
181   pid_t crasher_pid = -1;
182   bool previous_wait_for_debugger;
183   unique_fd crasher_pipe;
184   unique_fd intercept_fd;
185 
186   CrasherTest();
187   ~CrasherTest();
188 
189   void StartIntercept(unique_fd* output_fd, DebuggerdDumpType intercept_type = kDebuggerdTombstone);
190 
191   // Returns -1 if we fail to read a response from tombstoned, otherwise the received return code.
192   void FinishIntercept(int* result);
193 
194   void StartProcess(std::function<void()> function, std::function<pid_t()> forker = fork);
195   void StartCrasher(const std::string& crash_type);
196   void FinishCrasher();
197   void AssertDeath(int signo);
198 
199   static void Trap(void* ptr);
200 };
201 
CrasherTest()202 CrasherTest::CrasherTest() {
203   previous_wait_for_debugger = android::base::GetBoolProperty(kWaitForDebuggerKey, false);
204   android::base::SetProperty(kWaitForDebuggerKey, "0");
205 
206   // Clear the old property too, just in case someone's been using it
207   // on this device. (We only document the new name, but we still support
208   // the old name so we don't break anyone's existing setups.)
209   android::base::SetProperty("debug.debuggerd.wait_for_gdb", "0");
210 }
211 
~CrasherTest()212 CrasherTest::~CrasherTest() {
213   if (crasher_pid != -1) {
214     kill(crasher_pid, SIGKILL);
215     int status;
216     TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, WUNTRACED));
217   }
218 
219   android::base::SetProperty(kWaitForDebuggerKey, previous_wait_for_debugger ? "1" : "0");
220 }
221 
StartIntercept(unique_fd * output_fd,DebuggerdDumpType intercept_type)222 void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType intercept_type) {
223   if (crasher_pid == -1) {
224     FAIL() << "crasher hasn't been started";
225   }
226 
227   InterceptResponse response = {};
228   tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &response, intercept_type);
229   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
230       << "Error message: " << response.error_message;
231 }
232 
FinishIntercept(int * result)233 void CrasherTest::FinishIntercept(int* result) {
234   InterceptResponse response;
235 
236   ssize_t rc = TIMEOUT(30, read(intercept_fd.get(), &response, sizeof(response)));
237   if (rc == -1) {
238     FAIL() << "failed to read response from tombstoned: " << strerror(errno);
239   } else if (rc == 0) {
240     *result = -1;
241   } else if (rc != sizeof(response)) {
242     FAIL() << "received packet of unexpected length from tombstoned: expected " << sizeof(response)
243            << ", received " << rc;
244   } else {
245     *result = response.status == InterceptStatus::kStarted ? 1 : 0;
246   }
247 }
248 
StartProcess(std::function<void ()> function,std::function<pid_t ()> forker)249 void CrasherTest::StartProcess(std::function<void()> function, std::function<pid_t()> forker) {
250   unique_fd read_pipe;
251   unique_fd crasher_read_pipe;
252   if (!Pipe(&crasher_read_pipe, &crasher_pipe)) {
253     FAIL() << "failed to create pipe: " << strerror(errno);
254   }
255 
256   crasher_pid = forker();
257   if (crasher_pid == -1) {
258     FAIL() << "fork failed: " << strerror(errno);
259   } else if (crasher_pid == 0) {
260     char dummy;
261     crasher_pipe.reset();
262     TEMP_FAILURE_RETRY(read(crasher_read_pipe.get(), &dummy, 1));
263     function();
264     _exit(0);
265   }
266 }
267 
FinishCrasher()268 void CrasherTest::FinishCrasher() {
269   if (crasher_pipe == -1) {
270     FAIL() << "crasher pipe uninitialized";
271   }
272 
273   ssize_t rc = TEMP_FAILURE_RETRY(write(crasher_pipe.get(), "\n", 1));
274   if (rc == -1) {
275     FAIL() << "failed to write to crasher pipe: " << strerror(errno);
276   } else if (rc == 0) {
277     FAIL() << "crasher pipe was closed";
278   }
279 }
280 
AssertDeath(int signo)281 void CrasherTest::AssertDeath(int signo) {
282   int status;
283   pid_t pid = TIMEOUT(30, waitpid(crasher_pid, &status, 0));
284   if (pid != crasher_pid) {
285     printf("failed to wait for crasher (expected pid %d, return value %d): %s\n", crasher_pid, pid,
286            strerror(errno));
287     sleep(100);
288     FAIL() << "failed to wait for crasher: " << strerror(errno);
289   }
290 
291   if (signo == 0) {
292     ASSERT_TRUE(WIFEXITED(status)) << "Terminated due to unexpected signal " << WTERMSIG(status);
293     ASSERT_EQ(0, WEXITSTATUS(signo));
294   } else {
295     ASSERT_FALSE(WIFEXITED(status));
296     ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
297     ASSERT_EQ(signo, WTERMSIG(status));
298   }
299   crasher_pid = -1;
300 }
301 
ConsumeFd(unique_fd fd,std::string * output)302 static void ConsumeFd(unique_fd fd, std::string* output) {
303   ASSERT_TRUE(android::base::ReadFdToString(fd, output));
304 }
305 
306 class LogcatCollector {
307  public:
LogcatCollector()308   LogcatCollector() { system("logcat -c"); }
309 
Collect(std::string * output)310   void Collect(std::string* output) {
311     FILE* cmd_stdout = popen("logcat -d '*:S DEBUG'", "r");
312     ASSERT_NE(cmd_stdout, nullptr);
313     unique_fd tmp_fd(TEMP_FAILURE_RETRY(dup(fileno(cmd_stdout))));
314     ConsumeFd(std::move(tmp_fd), output);
315     pclose(cmd_stdout);
316   }
317 };
318 
TEST_F(CrasherTest,smoke)319 TEST_F(CrasherTest, smoke) {
320   int intercept_result;
321   unique_fd output_fd;
322   StartProcess([]() {
323     *reinterpret_cast<volatile char*>(0xdead) = '1';
324   });
325 
326   StartIntercept(&output_fd);
327   FinishCrasher();
328   AssertDeath(SIGSEGV);
329   FinishIntercept(&intercept_result);
330 
331   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
332 
333   std::string result;
334   ConsumeFd(std::move(output_fd), &result);
335   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+dead)");
336 
337   if (mte_supported()) {
338     // Test that the default TAGGED_ADDR_CTRL value is set.
339     ASSERT_MATCH(result, R"(tagged_addr_ctrl: 000000000007fff3)"
340                          R"( \(PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, mask 0xfffe\))");
341   }
342 
343   if (pac_supported()) {
344     // Test that the default PAC_ENABLED_KEYS value is set.
345     ASSERT_MATCH(result, R"(pac_enabled_keys: 000000000000000f)"
346                          R"( \(PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY\))");
347   }
348 }
349 
TEST_F(CrasherTest,tagged_fault_addr)350 TEST_F(CrasherTest, tagged_fault_addr) {
351 #if !defined(__aarch64__)
352   GTEST_SKIP() << "Requires aarch64";
353 #endif
354   // HWASan crashes with SIGABRT on tag mismatch.
355   SKIP_WITH_HWASAN;
356   int intercept_result;
357   unique_fd output_fd;
358   StartProcess([]() {
359     *reinterpret_cast<volatile char*>(0x100000000000dead) = '1';
360   });
361 
362   StartIntercept(&output_fd);
363   FinishCrasher();
364   AssertDeath(SIGSEGV);
365   FinishIntercept(&intercept_result);
366 
367   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
368 
369   std::string result;
370   ConsumeFd(std::move(output_fd), &result);
371 
372   // The address can either be tagged (new kernels) or untagged (old kernels).
373   ASSERT_MATCH(
374       result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x[01]00000000000dead)");
375 }
376 
Trap(void * ptr)377 void CrasherTest::Trap(void* ptr) {
378   void (*volatile f)(void*) = nullptr;
379   __asm__ __volatile__("" : : "r"(f) : "memory");
380   f(ptr);
381 }
382 
TEST_F(CrasherTest,heap_addr_in_register)383 TEST_F(CrasherTest, heap_addr_in_register) {
384 #if defined(__i386__)
385   GTEST_SKIP() << "architecture does not pass arguments in registers";
386 #endif
387   // The memory dump in HWASan crashes sadly shows the memory near the registers
388   // in the HWASan dump function, rather the faulting context. This is a known
389   // issue.
390   SKIP_WITH_HWASAN;
391   int intercept_result;
392   unique_fd output_fd;
393   StartProcess([]() {
394     // Crash with a heap pointer in the first argument register.
395     Trap(malloc(1));
396   });
397 
398   StartIntercept(&output_fd);
399   FinishCrasher();
400   int status;
401   ASSERT_EQ(crasher_pid, TIMEOUT(30, waitpid(crasher_pid, &status, 0)));
402   ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
403   // Don't test the signal number because different architectures use different signals for
404   // __builtin_trap().
405   FinishIntercept(&intercept_result);
406 
407   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
408 
409   std::string result;
410   ConsumeFd(std::move(output_fd), &result);
411 
412 #if defined(__aarch64__)
413   ASSERT_MATCH(result, "memory near x0 \\(\\[anon:");
414 #elif defined(__arm__)
415   ASSERT_MATCH(result, "memory near r0 \\(\\[anon:");
416 #elif defined(__riscv)
417   ASSERT_MATCH(result, "memory near a0 \\(\\[anon:");
418 #elif defined(__x86_64__)
419   ASSERT_MATCH(result, "memory near rdi \\(\\[anon:");
420 #else
421   ASSERT_TRUE(false) << "unsupported architecture";
422 #endif
423 }
424 
425 #if defined(__aarch64__)
SetTagCheckingLevelSync()426 static void SetTagCheckingLevelSync() {
427   if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_SYNC) == 0) {
428     abort();
429   }
430 }
431 
SetTagCheckingLevelAsync()432 static void SetTagCheckingLevelAsync() {
433   if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_ASYNC) == 0) {
434     abort();
435   }
436 }
437 #endif
438 
439 struct SizeParamCrasherTest : CrasherTest, testing::WithParamInterface<size_t> {};
440 
441 INSTANTIATE_TEST_SUITE_P(Sizes, SizeParamCrasherTest, testing::Values(0, 16, 131072));
442 
TEST_P(SizeParamCrasherTest,mte_uaf)443 TEST_P(SizeParamCrasherTest, mte_uaf) {
444 #if defined(__aarch64__)
445   if (!mte_supported()) {
446     GTEST_SKIP() << "Requires MTE";
447   }
448 
449   // Any UAF on a zero-sized allocation will be out-of-bounds so it won't be reported.
450   if (GetParam() == 0) {
451     return;
452   }
453 
454   LogcatCollector logcat_collector;
455 
456   int intercept_result;
457   unique_fd output_fd;
458   StartProcess([&]() {
459     SetTagCheckingLevelSync();
460     volatile int* p = (volatile int*)malloc(GetParam());
461     free((void *)p);
462     p[0] = 42;
463   });
464 
465   StartIntercept(&output_fd);
466   FinishCrasher();
467   AssertDeath(SIGSEGV);
468   FinishIntercept(&intercept_result);
469 
470   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
471 
472   std::vector<std::string> log_sources(2);
473   ConsumeFd(std::move(output_fd), &log_sources[0]);
474   logcat_collector.Collect(&log_sources[1]);
475   // Tag dump only available in the tombstone, not logcat.
476   ASSERT_MATCH(log_sources[0], "Memory tags around the fault address");
477 
478   for (const auto& result : log_sources) {
479     ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
480     ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a )" +
481                              std::to_string(GetParam()) + R"(-byte allocation)");
482     ASSERT_MATCH(result, R"(deallocated by thread .*?\n.*#00 pc)");
483     ASSERT_MATCH(result, R"((^|\s)allocated by thread .*?\n.*#00 pc)");
484   }
485 #else
486   GTEST_SKIP() << "Requires aarch64";
487 #endif
488 }
489 
TEST_P(SizeParamCrasherTest,mte_oob_uaf)490 TEST_P(SizeParamCrasherTest, mte_oob_uaf) {
491 #if defined(__aarch64__)
492   if (!mte_supported()) {
493     GTEST_SKIP() << "Requires MTE";
494   }
495 
496   int intercept_result;
497   unique_fd output_fd;
498   StartProcess([&]() {
499     SetTagCheckingLevelSync();
500     volatile int* p = (volatile int*)malloc(GetParam());
501     free((void *)p);
502     p[-1] = 42;
503   });
504 
505   StartIntercept(&output_fd);
506   FinishCrasher();
507   AssertDeath(SIGSEGV);
508   FinishIntercept(&intercept_result);
509 
510   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
511 
512   std::string result;
513   ConsumeFd(std::move(output_fd), &result);
514 
515   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
516   ASSERT_NOT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 4 bytes left)");
517 #else
518   GTEST_SKIP() << "Requires aarch64";
519 #endif
520 }
521 
TEST_P(SizeParamCrasherTest,mte_overflow)522 TEST_P(SizeParamCrasherTest, mte_overflow) {
523 #if defined(__aarch64__)
524   if (!mte_supported()) {
525     GTEST_SKIP() << "Requires MTE";
526   }
527 
528   LogcatCollector logcat_collector;
529   int intercept_result;
530   unique_fd output_fd;
531   StartProcess([&]() {
532     SetTagCheckingLevelSync();
533     volatile char* p = (volatile char*)malloc(GetParam());
534     p[GetParam()] = 42;
535   });
536 
537   StartIntercept(&output_fd);
538   FinishCrasher();
539   AssertDeath(SIGSEGV);
540   FinishIntercept(&intercept_result);
541 
542   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
543 
544   std::vector<std::string> log_sources(2);
545   ConsumeFd(std::move(output_fd), &log_sources[0]);
546   logcat_collector.Collect(&log_sources[1]);
547 
548   // Tag dump only in tombstone, not logcat, and tagging is not used for
549   // overflow protection in the scudo secondary (guard pages are used instead).
550   if (GetParam() < 0x10000) {
551     ASSERT_MATCH(log_sources[0], "Memory tags around the fault address");
552   }
553 
554   for (const auto& result : log_sources) {
555     ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
556     ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a )" +
557                              std::to_string(GetParam()) + R"(-byte allocation)");
558     ASSERT_MATCH(result, R"((^|\s)allocated by thread .*?\n.*#00 pc)");
559   }
560 #else
561   GTEST_SKIP() << "Requires aarch64";
562 #endif
563 }
564 
TEST_P(SizeParamCrasherTest,mte_underflow)565 TEST_P(SizeParamCrasherTest, mte_underflow) {
566 #if defined(__aarch64__)
567   if (!mte_supported()) {
568     GTEST_SKIP() << "Requires MTE";
569   }
570 
571   int intercept_result;
572   unique_fd output_fd;
573   StartProcess([&]() {
574     SetTagCheckingLevelSync();
575     volatile int* p = (volatile int*)malloc(GetParam());
576     p[-1] = 42;
577   });
578 
579   StartIntercept(&output_fd);
580   FinishCrasher();
581   AssertDeath(SIGSEGV);
582   FinishIntercept(&intercept_result);
583 
584   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
585 
586   std::string result;
587   ConsumeFd(std::move(output_fd), &result);
588 
589   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
590   ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Underflow, 4 bytes left of a )" +
591                            std::to_string(GetParam()) + R"(-byte allocation)");
592   ASSERT_MATCH(result, R"((^|\s)allocated by thread .*
593       #00 pc)");
594   ASSERT_MATCH(result, "Memory tags around the fault address");
595 #else
596   GTEST_SKIP() << "Requires aarch64";
597 #endif
598 }
599 
mte_illegal_setjmp_helper(jmp_buf & jump_buf)600 __attribute__((noinline)) void mte_illegal_setjmp_helper(jmp_buf& jump_buf) {
601   // This frame is at least 8 bytes for storing and restoring the LR before the
602   // setjmp below. So this can never get an empty stack frame, even if we omit
603   // the frame pointer. So, the SP of this is always less (numerically) than the
604   // calling function frame.
605   setjmp(jump_buf);
606 }
607 
TEST_F(CrasherTest,DISABLED_mte_illegal_setjmp)608 TEST_F(CrasherTest, DISABLED_mte_illegal_setjmp) {
609   // This setjmp is illegal because it jumps back into a function that already returned.
610   // Quoting man 3 setjmp:
611   //     If the function which called setjmp() returns before longjmp() is
612   //     called, the behavior is undefined.  Some kind of subtle or
613   //     unsubtle chaos is sure to result.
614   // https://man7.org/linux/man-pages/man3/longjmp.3.html
615 #if defined(__aarch64__)
616   if (!mte_supported()) {
617     GTEST_SKIP() << "Requires MTE";
618   }
619 
620   int intercept_result;
621   unique_fd output_fd;
622   StartProcess([&]() {
623     SetTagCheckingLevelSync();
624     jmp_buf jump_buf;
625     mte_illegal_setjmp_helper(jump_buf);
626     longjmp(jump_buf, 1);
627   });
628 
629   StartIntercept(&output_fd);
630   FinishCrasher();
631   AssertDeath(SIGABRT);
632   FinishIntercept(&intercept_result);
633 
634   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
635 
636   std::string result;
637   ConsumeFd(std::move(output_fd), &result);
638 
639   // In our test-case, we have a NEGATIVE stack adjustment, which is being
640   // interpreted as unsigned integer, and thus is "too large".
641   // TODO(fmayer): fix the error message for this
642   ASSERT_MATCH(result, R"(memtag_handle_longjmp: stack adjustment too large)");
643 #else
644   GTEST_SKIP() << "Requires aarch64";
645 #endif
646 }
647 
TEST_F(CrasherTest,mte_async)648 TEST_F(CrasherTest, mte_async) {
649 #if defined(__aarch64__)
650   if (!mte_supported()) {
651     GTEST_SKIP() << "Requires MTE";
652   }
653 
654   int intercept_result;
655   unique_fd output_fd;
656   StartProcess([&]() {
657     SetTagCheckingLevelAsync();
658     volatile int* p = (volatile int*)malloc(16);
659     p[-1] = 42;
660   });
661 
662   StartIntercept(&output_fd);
663   FinishCrasher();
664   AssertDeath(SIGSEGV);
665   FinishIntercept(&intercept_result);
666 
667   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
668 
669   std::string result;
670   ConsumeFd(std::move(output_fd), &result);
671 
672   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code [89] \(SEGV_MTE[AS]ERR\), fault addr)");
673 #else
674   GTEST_SKIP() << "Requires aarch64";
675 #endif
676 }
677 
TEST_F(CrasherTest,mte_multiple_causes)678 TEST_F(CrasherTest, mte_multiple_causes) {
679 #if defined(__aarch64__)
680   if (!mte_supported()) {
681     GTEST_SKIP() << "Requires MTE";
682   }
683 
684   LogcatCollector logcat_collector;
685 
686   int intercept_result;
687   unique_fd output_fd;
688   StartProcess([]() {
689     SetTagCheckingLevelSync();
690 
691     // Make two allocations with the same tag and close to one another. Check for both properties
692     // with a bounds check -- this relies on the fact that only if the allocations have the same tag
693     // would they be measured as closer than 128 bytes to each other. Otherwise they would be about
694     // (some non-zero value << 56) apart.
695     //
696     // The out-of-bounds access will be considered either an overflow of one or an underflow of the
697     // other.
698     std::set<uintptr_t> allocs;
699     for (int i = 0; i != 4096; ++i) {
700       uintptr_t alloc = reinterpret_cast<uintptr_t>(malloc(16));
701       auto it = allocs.insert(alloc).first;
702       if (it != allocs.begin() && *std::prev(it) + 128 > alloc) {
703         *reinterpret_cast<int*>(*std::prev(it) + 16) = 42;
704       }
705       if (std::next(it) != allocs.end() && alloc + 128 > *std::next(it)) {
706         *reinterpret_cast<int*>(alloc + 16) = 42;
707       }
708     }
709   });
710 
711   StartIntercept(&output_fd);
712   FinishCrasher();
713   AssertDeath(SIGSEGV);
714   FinishIntercept(&intercept_result);
715 
716   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
717 
718   std::vector<std::string> log_sources(2);
719   ConsumeFd(std::move(output_fd), &log_sources[0]);
720   logcat_collector.Collect(&log_sources[1]);
721 
722   // Tag dump only in the tombstone, not logcat.
723   ASSERT_MATCH(log_sources[0], "Memory tags around the fault address");
724 
725   for (const auto& result : log_sources) {
726     ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
727     ASSERT_THAT(result, HasSubstr("Note: multiple potential causes for this crash were detected, "
728                                   "listing them in decreasing order of likelihood."));
729     // Adjacent untracked allocations may cause us to see the wrong underflow here (or only
730     // overflows), so we can't match explicitly for an underflow message.
731     ASSERT_MATCH(result,
732                  R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a 16-byte allocation)");
733     // Ensure there's at least two allocation traces (one for each cause).
734     ASSERT_MATCH(
735         result,
736         R"((^|\s)allocated by thread .*?\n.*#00 pc(.|\n)*?(^|\s)allocated by thread .*?\n.*#00 pc)");
737   }
738 #else
739   GTEST_SKIP() << "Requires aarch64";
740 #endif
741 }
742 
743 #if defined(__aarch64__)
CreateTagMapping()744 static uintptr_t CreateTagMapping() {
745   // Some of the MTE tag dump tests assert that there is an inaccessible page to the left and right
746   // of the PROT_MTE page, so map three pages and set the two guard pages to PROT_NONE.
747   size_t page_size = getpagesize();
748   void* mapping = mmap(nullptr, page_size * 3, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
749   uintptr_t mapping_uptr = reinterpret_cast<uintptr_t>(mapping);
750   if (mapping == MAP_FAILED) {
751     return 0;
752   }
753   mprotect(reinterpret_cast<void*>(mapping_uptr + page_size), page_size,
754            PROT_READ | PROT_WRITE | PROT_MTE);
755   // Stripe the mapping, where even granules get tag '1', and odd granules get tag '0'.
756   for (uintptr_t offset = 0; offset < page_size; offset += 2 * kTagGranuleSize) {
757     uintptr_t tagged_addr = mapping_uptr + page_size + offset + (1ULL << 56);
758     __asm__ __volatile__(".arch_extension mte; stg %0, [%0]" : : "r"(tagged_addr) : "memory");
759   }
760   return mapping_uptr + page_size;
761 }
762 #endif
763 
TEST_F(CrasherTest,mte_register_tag_dump)764 TEST_F(CrasherTest, mte_register_tag_dump) {
765 #if defined(__aarch64__)
766   if (!mte_supported()) {
767     GTEST_SKIP() << "Requires MTE";
768   }
769 
770   int intercept_result;
771   unique_fd output_fd;
772   StartProcess([&]() {
773     SetTagCheckingLevelSync();
774     Trap(reinterpret_cast<void *>(CreateTagMapping()));
775   });
776 
777   StartIntercept(&output_fd);
778   FinishCrasher();
779   AssertDeath(SIGSEGV);
780   FinishIntercept(&intercept_result);
781 
782   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
783 
784   std::string result;
785   ConsumeFd(std::move(output_fd), &result);
786 
787   ASSERT_MATCH(result, R"(memory near x0:
788 .*
789 .*
790     01.............0 0000000000000000 0000000000000000  ................
791     00.............0)");
792 #else
793   GTEST_SKIP() << "Requires aarch64";
794 #endif
795 }
796 
TEST_F(CrasherTest,mte_fault_tag_dump_front_truncated)797 TEST_F(CrasherTest, mte_fault_tag_dump_front_truncated) {
798 #if defined(__aarch64__)
799   if (!mte_supported()) {
800     GTEST_SKIP() << "Requires MTE";
801   }
802 
803   int intercept_result;
804   unique_fd output_fd;
805   StartProcess([&]() {
806     SetTagCheckingLevelSync();
807     volatile char* p = reinterpret_cast<char*>(CreateTagMapping());
808     p[0] = 0;  // Untagged pointer, tagged memory.
809   });
810 
811   StartIntercept(&output_fd);
812   FinishCrasher();
813   AssertDeath(SIGSEGV);
814   FinishIntercept(&intercept_result);
815 
816   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
817 
818   std::string result;
819   ConsumeFd(std::move(output_fd), &result);
820 
821   ASSERT_MATCH(result, R"(Memory tags around the fault address.*
822 \s*=>0x[0-9a-f]+000:\[1\] 0  1  0)");
823 #else
824   GTEST_SKIP() << "Requires aarch64";
825 #endif
826 }
827 
TEST_F(CrasherTest,mte_fault_tag_dump)828 TEST_F(CrasherTest, mte_fault_tag_dump) {
829 #if defined(__aarch64__)
830   if (!mte_supported()) {
831     GTEST_SKIP() << "Requires MTE";
832   }
833 
834   int intercept_result;
835   unique_fd output_fd;
836   StartProcess([&]() {
837     SetTagCheckingLevelSync();
838     volatile char* p = reinterpret_cast<char*>(CreateTagMapping());
839     p[320] = 0;  // Untagged pointer, tagged memory.
840   });
841 
842   StartIntercept(&output_fd);
843   FinishCrasher();
844   AssertDeath(SIGSEGV);
845   FinishIntercept(&intercept_result);
846 
847   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
848 
849   std::string result;
850   ConsumeFd(std::move(output_fd), &result);
851 
852   ASSERT_MATCH(result, R"(Memory tags around the fault address.*
853 \s*0x[0-9a-f]+: 1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0
854 \s*=>0x[0-9a-f]+: 1  0  1  0 \[1\] 0  1  0  1  0  1  0  1  0  1  0
855 \s*0x[0-9a-f]+: 1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0
856 )");
857 #else
858   GTEST_SKIP() << "Requires aarch64";
859 #endif
860 }
861 
TEST_F(CrasherTest,mte_fault_tag_dump_rear_truncated)862 TEST_F(CrasherTest, mte_fault_tag_dump_rear_truncated) {
863 #if defined(__aarch64__)
864   if (!mte_supported()) {
865     GTEST_SKIP() << "Requires MTE";
866   }
867 
868   int intercept_result;
869   unique_fd output_fd;
870   StartProcess([&]() {
871     SetTagCheckingLevelSync();
872     size_t page_size = getpagesize();
873     volatile char* p = reinterpret_cast<char*>(CreateTagMapping());
874     p[page_size - kTagGranuleSize * 2] = 0;  // Untagged pointer, tagged memory.
875   });
876 
877   StartIntercept(&output_fd);
878   FinishCrasher();
879   AssertDeath(SIGSEGV);
880   FinishIntercept(&intercept_result);
881 
882   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
883 
884   std::string result;
885   ConsumeFd(std::move(output_fd), &result);
886 
887   ASSERT_MATCH(result, R"(Memory tags around the fault address)");
888   ASSERT_MATCH(result,
889                R"(\s*0x[0-9a-f]+: 1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0
890 \s*=>0x[0-9a-f]+: 1  0  1  0  1  0  1  0  1  0  1  0  1  0 \[1\] 0
891 
892 )");  // Ensure truncation happened and there's a newline after the tag fault.
893 #else
894   GTEST_SKIP() << "Requires aarch64";
895 #endif
896 }
897 
TEST_F(CrasherTest,LD_PRELOAD)898 TEST_F(CrasherTest, LD_PRELOAD) {
899   int intercept_result;
900   unique_fd output_fd;
901   StartProcess([]() {
902     setenv("LD_PRELOAD", "nonexistent.so", 1);
903     *reinterpret_cast<volatile char*>(0xdead) = '1';
904   });
905 
906   StartIntercept(&output_fd);
907   FinishCrasher();
908   AssertDeath(SIGSEGV);
909   FinishIntercept(&intercept_result);
910 
911   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
912 
913   std::string result;
914   ConsumeFd(std::move(output_fd), &result);
915   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+dead)");
916 }
917 
TEST_F(CrasherTest,abort)918 TEST_F(CrasherTest, abort) {
919   int intercept_result;
920   unique_fd output_fd;
921   StartProcess([]() {
922     abort();
923   });
924   StartIntercept(&output_fd);
925   FinishCrasher();
926   AssertDeath(SIGABRT);
927   FinishIntercept(&intercept_result);
928 
929   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
930 
931   std::string result;
932   ConsumeFd(std::move(output_fd), &result);
933   ASSERT_BACKTRACE_FRAME(result, "abort");
934 }
935 
TEST_F(CrasherTest,signal)936 TEST_F(CrasherTest, signal) {
937   int intercept_result;
938   unique_fd output_fd;
939   StartProcess([]() {
940     while (true) {
941       sleep(1);
942     }
943   });
944   StartIntercept(&output_fd);
945   FinishCrasher();
946   ASSERT_EQ(0, kill(crasher_pid, SIGSEGV));
947 
948   AssertDeath(SIGSEGV);
949   FinishIntercept(&intercept_result);
950 
951   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
952 
953   std::string result;
954   ConsumeFd(std::move(output_fd), &result);
955   ASSERT_MATCH(
956       result,
957       R"(signal 11 \(SIGSEGV\), code 0 \(SI_USER from pid \d+, uid \d+\), fault addr --------)");
958   ASSERT_MATCH(result, R"(backtrace:)");
959 }
960 
TEST_F(CrasherTest,abort_message)961 TEST_F(CrasherTest, abort_message) {
962   int intercept_result;
963   unique_fd output_fd;
964   StartProcess([]() {
965     // Arrived at experimentally;
966     // logd truncates at 4062.
967     // strlen("Abort message: ''") is 17.
968     // That's 4045, but we also want a NUL.
969     char buf[4045 + 1];
970     memset(buf, 'x', sizeof(buf));
971     buf[sizeof(buf) - 1] = '\0';
972     android_set_abort_message(buf);
973     abort();
974   });
975   StartIntercept(&output_fd);
976   FinishCrasher();
977   AssertDeath(SIGABRT);
978   FinishIntercept(&intercept_result);
979 
980   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
981 
982   std::string result;
983   ConsumeFd(std::move(output_fd), &result);
984   ASSERT_MATCH(result, R"(Abort message: 'x{4045}')");
985 }
986 
987 static char g_crash_detail_value_changes[] = "crash_detail_value";
988 static char g_crash_detail_value[] = "crash_detail_value";
989 static char g_crash_detail_value2[] = "crash_detail_value2";
990 
android_register_crash_detail_strs(const char * _Nonnull name,const char * _Nonnull data)991 inline crash_detail_t* _Nullable android_register_crash_detail_strs(const char* _Nonnull name,
992                                                                     const char* _Nonnull data) {
993   return android_crash_detail_register(name, strlen(name), data, strlen(data));
994 }
995 
TEST_F(CrasherTest,crash_detail_single)996 TEST_F(CrasherTest, crash_detail_single) {
997   int intercept_result;
998   unique_fd output_fd;
999   StartProcess([]() {
1000     android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
1001     abort();
1002   });
1003   StartIntercept(&output_fd);
1004   FinishCrasher();
1005   AssertDeath(SIGABRT);
1006   FinishIntercept(&intercept_result);
1007 
1008   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1009 
1010   std::string result;
1011   ConsumeFd(std::move(output_fd), &result);
1012   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
1013 }
1014 
TEST_F(CrasherTest,crash_detail_replace_data)1015 TEST_F(CrasherTest, crash_detail_replace_data) {
1016   int intercept_result;
1017   unique_fd output_fd;
1018   StartProcess([]() {
1019     auto *cd = android_register_crash_detail_strs("CRASH_DETAIL_NAME", "original_data");
1020     android_crash_detail_replace_data(cd, "new_data", strlen("new_data"));
1021     abort();
1022   });
1023   StartIntercept(&output_fd);
1024   FinishCrasher();
1025   AssertDeath(SIGABRT);
1026   FinishIntercept(&intercept_result);
1027 
1028   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1029 
1030   std::string result;
1031   ConsumeFd(std::move(output_fd), &result);
1032   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'new_data')");
1033   // Ensure the old one no longer shows up, i.e. that we actually replaced
1034   // it, not added a new one.
1035   ASSERT_NOT_MATCH(result, R"(CRASH_DETAIL_NAME: 'original_data')");
1036 }
1037 
TEST_F(CrasherTest,crash_detail_replace_name)1038 TEST_F(CrasherTest, crash_detail_replace_name) {
1039   int intercept_result;
1040   unique_fd output_fd;
1041   StartProcess([]() {
1042     auto *cd = android_register_crash_detail_strs("old_name", g_crash_detail_value);
1043     android_crash_detail_replace_name(cd, "new_name", strlen("new_name"));
1044     abort();
1045   });
1046   StartIntercept(&output_fd);
1047   FinishCrasher();
1048   AssertDeath(SIGABRT);
1049   FinishIntercept(&intercept_result);
1050 
1051   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1052 
1053   std::string result;
1054   ConsumeFd(std::move(output_fd), &result);
1055   ASSERT_MATCH(result, R"(new_name: 'crash_detail_value')");
1056   // Ensure the old one no longer shows up, i.e. that we actually replaced
1057   // it, not added a new one.
1058   ASSERT_NOT_MATCH(result, R"(old_name: 'crash_detail_value')");
1059 }
1060 
TEST_F(CrasherTest,crash_detail_single_byte_name)1061 TEST_F(CrasherTest, crash_detail_single_byte_name) {
1062   int intercept_result;
1063   unique_fd output_fd;
1064   StartProcess([]() {
1065     android_register_crash_detail_strs("CRASH_DETAIL_NAME\1", g_crash_detail_value);
1066     abort();
1067   });
1068   StartIntercept(&output_fd);
1069   FinishCrasher();
1070   AssertDeath(SIGABRT);
1071   FinishIntercept(&intercept_result);
1072 
1073   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1074 
1075   std::string result;
1076   ConsumeFd(std::move(output_fd), &result);
1077   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME\\1: 'crash_detail_value')");
1078 }
1079 
1080 
TEST_F(CrasherTest,crash_detail_single_bytes)1081 TEST_F(CrasherTest, crash_detail_single_bytes) {
1082   int intercept_result;
1083   unique_fd output_fd;
1084   StartProcess([]() {
1085     android_crash_detail_register("CRASH_DETAIL_NAME", strlen("CRASH_DETAIL_NAME"), "\1",
1086                                   sizeof("\1"));
1087     abort();
1088   });
1089   StartIntercept(&output_fd);
1090   FinishCrasher();
1091   AssertDeath(SIGABRT);
1092   FinishIntercept(&intercept_result);
1093 
1094   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1095 
1096   std::string result;
1097   ConsumeFd(std::move(output_fd), &result);
1098   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: '\\1\\0')");
1099 }
1100 
TEST_F(CrasherTest,crash_detail_mixed)1101 TEST_F(CrasherTest, crash_detail_mixed) {
1102   int intercept_result;
1103   unique_fd output_fd;
1104   StartProcess([]() {
1105     const char data[] = "helloworld\1\255\3";
1106     android_register_crash_detail_strs("CRASH_DETAIL_NAME", data);
1107     abort();
1108   });
1109   StartIntercept(&output_fd);
1110   FinishCrasher();
1111   AssertDeath(SIGABRT);
1112   FinishIntercept(&intercept_result);
1113 
1114   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1115 
1116   std::string result;
1117   ConsumeFd(std::move(output_fd), &result);
1118   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'helloworld\\1\\255\\3')");
1119 }
1120 
TEST_F(CrasherTest,crash_detail_many)1121 TEST_F(CrasherTest, crash_detail_many) {
1122   int intercept_result;
1123   unique_fd output_fd;
1124   StartProcess([]() {
1125     for (int i = 0; i < 1000; ++i) {
1126       std::string name = "CRASH_DETAIL_NAME" + std::to_string(i);
1127       std::string value = "CRASH_DETAIL_VALUE" + std::to_string(i);
1128       auto* h = android_register_crash_detail_strs(name.data(), value.data());
1129       android_crash_detail_unregister(h);
1130     }
1131 
1132     android_register_crash_detail_strs("FINAL_NAME", "FINAL_VALUE");
1133     android_register_crash_detail_strs("FINAL_NAME2", "FINAL_VALUE2");
1134     abort();
1135   });
1136   StartIntercept(&output_fd);
1137   FinishCrasher();
1138   AssertDeath(SIGABRT);
1139   FinishIntercept(&intercept_result);
1140 
1141   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1142 
1143   std::string result;
1144   ConsumeFd(std::move(output_fd), &result);
1145   ASSERT_NOT_MATCH(result, "CRASH_DETAIL_NAME");
1146   ASSERT_NOT_MATCH(result, "CRASH_DETAIL_VALUE");
1147   ASSERT_MATCH(result, R"(FINAL_NAME: 'FINAL_VALUE')");
1148   ASSERT_MATCH(result, R"(FINAL_NAME2: 'FINAL_VALUE2')");
1149 }
1150 
TEST_F(CrasherTest,crash_detail_single_changes)1151 TEST_F(CrasherTest, crash_detail_single_changes) {
1152   int intercept_result;
1153   unique_fd output_fd;
1154   StartProcess([]() {
1155     android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value_changes);
1156     g_crash_detail_value_changes[0] = 'C';
1157     abort();
1158   });
1159   StartIntercept(&output_fd);
1160   FinishCrasher();
1161   AssertDeath(SIGABRT);
1162   FinishIntercept(&intercept_result);
1163 
1164   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1165 
1166   std::string result;
1167   ConsumeFd(std::move(output_fd), &result);
1168   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'Crash_detail_value')");
1169 }
1170 
TEST_F(CrasherTest,crash_detail_multiple)1171 TEST_F(CrasherTest, crash_detail_multiple) {
1172   int intercept_result;
1173   unique_fd output_fd;
1174   StartProcess([]() {
1175     android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
1176     android_register_crash_detail_strs("CRASH_DETAIL_NAME2", g_crash_detail_value2);
1177     abort();
1178   });
1179   StartIntercept(&output_fd);
1180   FinishCrasher();
1181   AssertDeath(SIGABRT);
1182   FinishIntercept(&intercept_result);
1183 
1184   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1185 
1186   std::string result;
1187   ConsumeFd(std::move(output_fd), &result);
1188   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
1189   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME2: 'crash_detail_value2')");
1190 }
1191 
TEST_F(CrasherTest,crash_detail_remove)1192 TEST_F(CrasherTest, crash_detail_remove) {
1193   int intercept_result;
1194   unique_fd output_fd;
1195   StartProcess([]() {
1196     auto* detail1 = android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
1197     android_crash_detail_unregister(detail1);
1198     android_register_crash_detail_strs("CRASH_DETAIL_NAME2", g_crash_detail_value2);
1199     abort();
1200   });
1201   StartIntercept(&output_fd);
1202   FinishCrasher();
1203   AssertDeath(SIGABRT);
1204   FinishIntercept(&intercept_result);
1205 
1206   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1207 
1208   std::string result;
1209   ConsumeFd(std::move(output_fd), &result);
1210   ASSERT_NOT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
1211   ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME2: 'crash_detail_value2')");
1212 }
1213 
TEST_F(CrasherTest,abort_message_newline_trimmed)1214 TEST_F(CrasherTest, abort_message_newline_trimmed) {
1215   int intercept_result;
1216   unique_fd output_fd;
1217   StartProcess([]() {
1218     android_set_abort_message("Message with a newline.\n");
1219     abort();
1220   });
1221   StartIntercept(&output_fd);
1222   FinishCrasher();
1223   AssertDeath(SIGABRT);
1224   FinishIntercept(&intercept_result);
1225 
1226   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1227 
1228   std::string result;
1229   ConsumeFd(std::move(output_fd), &result);
1230   ASSERT_MATCH(result, R"(Abort message: 'Message with a newline.')");
1231 }
1232 
TEST_F(CrasherTest,abort_message_multiple_newlines_trimmed)1233 TEST_F(CrasherTest, abort_message_multiple_newlines_trimmed) {
1234   int intercept_result;
1235   unique_fd output_fd;
1236   StartProcess([]() {
1237     android_set_abort_message("Message with multiple newlines.\n\n\n\n\n");
1238     abort();
1239   });
1240   StartIntercept(&output_fd);
1241   FinishCrasher();
1242   AssertDeath(SIGABRT);
1243   FinishIntercept(&intercept_result);
1244 
1245   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1246 
1247   std::string result;
1248   ConsumeFd(std::move(output_fd), &result);
1249   ASSERT_MATCH(result, R"(Abort message: 'Message with multiple newlines.')");
1250 }
1251 
TEST_F(CrasherTest,abort_message_backtrace)1252 TEST_F(CrasherTest, abort_message_backtrace) {
1253   int intercept_result;
1254   unique_fd output_fd;
1255   StartProcess([]() {
1256     android_set_abort_message("not actually aborting");
1257     raise(BIONIC_SIGNAL_DEBUGGER);
1258     exit(0);
1259   });
1260   StartIntercept(&output_fd);
1261   FinishCrasher();
1262   AssertDeath(0);
1263   FinishIntercept(&intercept_result);
1264 
1265   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1266 
1267   std::string result;
1268   ConsumeFd(std::move(output_fd), &result);
1269   ASSERT_NOT_MATCH(result, R"(Abort message:)");
1270 }
1271 
TEST_F(CrasherTest,intercept_timeout)1272 TEST_F(CrasherTest, intercept_timeout) {
1273   int intercept_result;
1274   unique_fd output_fd;
1275   StartProcess([]() {
1276     abort();
1277   });
1278   StartIntercept(&output_fd);
1279 
1280   // Don't let crasher finish until we timeout.
1281   FinishIntercept(&intercept_result);
1282 
1283   ASSERT_NE(1, intercept_result) << "tombstoned reported success? (intercept_result = "
1284                                  << intercept_result << ")";
1285 
1286   FinishCrasher();
1287   AssertDeath(SIGABRT);
1288 }
1289 
TEST_F(CrasherTest,wait_for_debugger)1290 TEST_F(CrasherTest, wait_for_debugger) {
1291   if (!android::base::SetProperty(kWaitForDebuggerKey, "1")) {
1292     FAIL() << "failed to enable wait_for_debugger";
1293   }
1294   sleep(1);
1295 
1296   StartProcess([]() {
1297     abort();
1298   });
1299   FinishCrasher();
1300 
1301   int status;
1302   ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, WUNTRACED)));
1303   ASSERT_TRUE(WIFSTOPPED(status));
1304   ASSERT_EQ(SIGSTOP, WSTOPSIG(status));
1305 
1306   ASSERT_EQ(0, kill(crasher_pid, SIGCONT));
1307 
1308   AssertDeath(SIGABRT);
1309 }
1310 
TEST_F(CrasherTest,backtrace)1311 TEST_F(CrasherTest, backtrace) {
1312   std::string result;
1313   int intercept_result;
1314   unique_fd output_fd;
1315 
1316   StartProcess([]() {
1317     abort();
1318   });
1319   StartIntercept(&output_fd, kDebuggerdNativeBacktrace);
1320 
1321   std::this_thread::sleep_for(500ms);
1322 
1323   sigval val;
1324   val.sival_int = 1;
1325   ASSERT_EQ(0, sigqueue(crasher_pid, BIONIC_SIGNAL_DEBUGGER, val)) << strerror(errno);
1326   FinishIntercept(&intercept_result);
1327   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1328   ConsumeFd(std::move(output_fd), &result);
1329   ASSERT_BACKTRACE_FRAME(result, "read");
1330 
1331   int status;
1332   ASSERT_EQ(0, waitpid(crasher_pid, &status, WNOHANG | WUNTRACED));
1333 
1334   StartIntercept(&output_fd);
1335   FinishCrasher();
1336   AssertDeath(SIGABRT);
1337   FinishIntercept(&intercept_result);
1338   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1339   ConsumeFd(std::move(output_fd), &result);
1340   ASSERT_BACKTRACE_FRAME(result, "abort");
1341 }
1342 
TEST_F(CrasherTest,PR_SET_DUMPABLE_0_crash)1343 TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
1344   int intercept_result;
1345   unique_fd output_fd;
1346   StartProcess([]() {
1347     prctl(PR_SET_DUMPABLE, 0);
1348     abort();
1349   });
1350 
1351   StartIntercept(&output_fd);
1352   FinishCrasher();
1353   AssertDeath(SIGABRT);
1354   FinishIntercept(&intercept_result);
1355 
1356   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1357 
1358   std::string result;
1359   ConsumeFd(std::move(output_fd), &result);
1360   ASSERT_BACKTRACE_FRAME(result, "abort");
1361 }
1362 
TEST_F(CrasherTest,capabilities)1363 TEST_F(CrasherTest, capabilities) {
1364   ASSERT_EQ(0U, getuid()) << "capability test requires root";
1365 
1366   StartProcess([]() {
1367     if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
1368       err(1, "failed to set PR_SET_KEEPCAPS");
1369     }
1370 
1371     if (setresuid(1, 1, 1) != 0) {
1372       err(1, "setresuid failed");
1373     }
1374 
1375     __user_cap_header_struct capheader;
1376     __user_cap_data_struct capdata[2];
1377     memset(&capheader, 0, sizeof(capheader));
1378     memset(&capdata, 0, sizeof(capdata));
1379 
1380     capheader.version = _LINUX_CAPABILITY_VERSION_3;
1381     capheader.pid = 0;
1382 
1383     // Turn on every third capability.
1384     static_assert(CAP_LAST_CAP > 33, "CAP_LAST_CAP <= 32");
1385     for (int i = 0; i < CAP_LAST_CAP; i += 3) {
1386       capdata[CAP_TO_INDEX(i)].permitted |= CAP_TO_MASK(i);
1387       capdata[CAP_TO_INDEX(i)].effective |= CAP_TO_MASK(i);
1388     }
1389 
1390     // Make sure CAP_SYS_PTRACE is off.
1391     capdata[CAP_TO_INDEX(CAP_SYS_PTRACE)].permitted &= ~(CAP_TO_MASK(CAP_SYS_PTRACE));
1392     capdata[CAP_TO_INDEX(CAP_SYS_PTRACE)].effective &= ~(CAP_TO_MASK(CAP_SYS_PTRACE));
1393 
1394     if (capset(&capheader, &capdata[0]) != 0) {
1395       err(1, "capset failed");
1396     }
1397 
1398     if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) != 0) {
1399       err(1, "failed to drop ambient capabilities");
1400     }
1401 
1402     pthread_setname_np(pthread_self(), "thread_name");
1403     raise(SIGSYS);
1404   });
1405 
1406   unique_fd output_fd;
1407   StartIntercept(&output_fd);
1408   FinishCrasher();
1409   AssertDeath(SIGSYS);
1410 
1411   std::string result;
1412   int intercept_result;
1413   FinishIntercept(&intercept_result);
1414   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1415   ConsumeFd(std::move(output_fd), &result);
1416   ASSERT_MATCH(result, R"(name: thread_name\s+>>> .+debuggerd_test(32|64) <<<)");
1417   ASSERT_BACKTRACE_FRAME(result, "tgkill");
1418 }
1419 
TEST_F(CrasherTest,fake_pid)1420 TEST_F(CrasherTest, fake_pid) {
1421   int intercept_result;
1422   unique_fd output_fd;
1423 
1424   // Prime the getpid/gettid caches.
1425   UNUSED(getpid());
1426   UNUSED(gettid());
1427 
1428   std::function<pid_t()> clone_fn = []() {
1429     return syscall(__NR_clone, SIGCHLD, nullptr, nullptr, nullptr, nullptr);
1430   };
1431   StartProcess(
1432       []() {
1433         ASSERT_NE(getpid(), syscall(__NR_getpid));
1434         ASSERT_NE(gettid(), syscall(__NR_gettid));
1435         raise(SIGSEGV);
1436       },
1437       clone_fn);
1438 
1439   StartIntercept(&output_fd);
1440   FinishCrasher();
1441   AssertDeath(SIGSEGV);
1442   FinishIntercept(&intercept_result);
1443 
1444   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1445 
1446   std::string result;
1447   ConsumeFd(std::move(output_fd), &result);
1448   ASSERT_BACKTRACE_FRAME(result, "tgkill");
1449 }
1450 
1451 static const char* const kDebuggerdSeccompPolicy =
1452     "/system/etc/seccomp_policy/crash_dump." ABI_STRING ".policy";
1453 
setup_jail(minijail * jail)1454 static void setup_jail(minijail* jail) {
1455   if (!jail) {
1456     LOG(FATAL) << "failed to create minijail";
1457   }
1458 
1459   std::string policy;
1460   if (!android::base::ReadFileToString(kDebuggerdSeccompPolicy, &policy)) {
1461     PLOG(FATAL) << "failed to read policy file";
1462   }
1463 
1464   // Allow a bunch of syscalls used by the tests.
1465   policy += "\nclone: 1";
1466   policy += "\nsigaltstack: 1";
1467   policy += "\nnanosleep: 1";
1468   policy += "\ngetrlimit: 1";
1469   policy += "\nugetrlimit: 1";
1470 
1471   FILE* tmp_file = tmpfile();
1472   if (!tmp_file) {
1473     PLOG(FATAL) << "tmpfile failed";
1474   }
1475 
1476   unique_fd tmp_fd(TEMP_FAILURE_RETRY(dup(fileno(tmp_file))));
1477   if (!android::base::WriteStringToFd(policy, tmp_fd.get())) {
1478     PLOG(FATAL) << "failed to write policy to tmpfile";
1479   }
1480 
1481   if (lseek(tmp_fd.get(), 0, SEEK_SET) != 0) {
1482     PLOG(FATAL) << "failed to seek tmp_fd";
1483   }
1484 
1485   minijail_no_new_privs(jail);
1486   minijail_log_seccomp_filter_failures(jail);
1487   minijail_use_seccomp_filter(jail);
1488   minijail_parse_seccomp_filters_from_fd(jail, tmp_fd.release());
1489 }
1490 
seccomp_fork_impl(void (* prejail)())1491 static pid_t seccomp_fork_impl(void (*prejail)()) {
1492   ScopedMinijail jail{minijail_new()};
1493   setup_jail(jail.get());
1494 
1495   pid_t result = fork();
1496   if (result == -1) {
1497     return result;
1498   } else if (result != 0) {
1499     return result;
1500   }
1501 
1502   // Spawn and detach a thread that spins forever.
1503   std::atomic<bool> thread_ready(false);
1504   std::thread thread([&jail, &thread_ready]() {
1505     minijail_enter(jail.get());
1506     thread_ready = true;
1507     for (;;)
1508       ;
1509   });
1510   thread.detach();
1511 
1512   while (!thread_ready) {
1513     continue;
1514   }
1515 
1516   if (prejail) {
1517     prejail();
1518   }
1519 
1520   minijail_enter(jail.get());
1521   return result;
1522 }
1523 
seccomp_fork()1524 static pid_t seccomp_fork() {
1525   return seccomp_fork_impl(nullptr);
1526 }
1527 
TEST_F(CrasherTest,seccomp_crash)1528 TEST_F(CrasherTest, seccomp_crash) {
1529   int intercept_result;
1530   unique_fd output_fd;
1531 
1532   StartProcess([]() { abort(); }, &seccomp_fork);
1533 
1534   StartIntercept(&output_fd);
1535   FinishCrasher();
1536   AssertDeath(SIGABRT);
1537   FinishIntercept(&intercept_result);
1538   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1539 
1540   std::string result;
1541   ConsumeFd(std::move(output_fd), &result);
1542   ASSERT_BACKTRACE_FRAME(result, "abort");
1543 }
1544 
seccomp_fork_rlimit()1545 static pid_t seccomp_fork_rlimit() {
1546   return seccomp_fork_impl([]() {
1547     struct rlimit rlim = {
1548         .rlim_cur = 512 * 1024 * 1024,
1549         .rlim_max = 512 * 1024 * 1024,
1550     };
1551 
1552     if (setrlimit(RLIMIT_AS, &rlim) != 0) {
1553       raise(SIGINT);
1554     }
1555   });
1556 }
1557 
TEST_F(CrasherTest,seccomp_crash_oom)1558 TEST_F(CrasherTest, seccomp_crash_oom) {
1559   int intercept_result;
1560   unique_fd output_fd;
1561 
1562   StartProcess(
1563       []() {
1564         std::vector<void*> vec;
1565         for (int i = 0; i < 512; ++i) {
1566           char* buf = static_cast<char*>(malloc(1024 * 1024));
1567           if (!buf) {
1568             abort();
1569           }
1570           memset(buf, 0xff, 1024 * 1024);
1571           vec.push_back(buf);
1572         }
1573       },
1574       &seccomp_fork_rlimit);
1575 
1576   StartIntercept(&output_fd);
1577   FinishCrasher();
1578   AssertDeath(SIGABRT);
1579   FinishIntercept(&intercept_result);
1580   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1581 
1582   // We can't actually generate a backtrace, just make sure that the process terminates.
1583 }
1584 
raise_debugger_signal(DebuggerdDumpType dump_type)1585 __attribute__((__noinline__)) extern "C" bool raise_debugger_signal(DebuggerdDumpType dump_type) {
1586   siginfo_t siginfo;
1587   siginfo.si_code = SI_QUEUE;
1588   siginfo.si_pid = getpid();
1589   siginfo.si_uid = getuid();
1590 
1591   if (dump_type != kDebuggerdNativeBacktrace && dump_type != kDebuggerdTombstone) {
1592     PLOG(FATAL) << "invalid dump type";
1593   }
1594 
1595   siginfo.si_value.sival_int = dump_type == kDebuggerdNativeBacktrace;
1596 
1597   if (syscall(__NR_rt_tgsigqueueinfo, getpid(), gettid(), BIONIC_SIGNAL_DEBUGGER, &siginfo) != 0) {
1598     PLOG(ERROR) << "libdebuggerd_client: failed to send signal to self";
1599     return false;
1600   }
1601 
1602   return true;
1603 }
1604 
foo()1605 extern "C" void foo() {
1606   LOG(INFO) << "foo";
1607   std::this_thread::sleep_for(1s);
1608 }
1609 
bar()1610 extern "C" void bar() {
1611   LOG(INFO) << "bar";
1612   std::this_thread::sleep_for(1s);
1613 }
1614 
TEST_F(CrasherTest,seccomp_tombstone)1615 TEST_F(CrasherTest, seccomp_tombstone) {
1616   int intercept_result;
1617   unique_fd output_fd;
1618 
1619   static const auto dump_type = kDebuggerdTombstone;
1620   StartProcess(
1621       []() {
1622         std::thread a(foo);
1623         std::thread b(bar);
1624 
1625         std::this_thread::sleep_for(100ms);
1626 
1627         raise_debugger_signal(dump_type);
1628         _exit(0);
1629       },
1630       &seccomp_fork);
1631 
1632   StartIntercept(&output_fd, dump_type);
1633   FinishCrasher();
1634   AssertDeath(0);
1635   FinishIntercept(&intercept_result);
1636   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1637 
1638   std::string result;
1639   ConsumeFd(std::move(output_fd), &result);
1640   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
1641   ASSERT_BACKTRACE_FRAME(result, "foo");
1642   ASSERT_BACKTRACE_FRAME(result, "bar");
1643 }
1644 
TEST_F(CrasherTest,seccomp_tombstone_thread_abort)1645 TEST_F(CrasherTest, seccomp_tombstone_thread_abort) {
1646   int intercept_result;
1647   unique_fd output_fd;
1648 
1649   static const auto dump_type = kDebuggerdTombstone;
1650   StartProcess(
1651       []() {
1652         std::thread abort_thread([] { abort(); });
1653         abort_thread.join();
1654       },
1655       &seccomp_fork);
1656 
1657   StartIntercept(&output_fd, dump_type);
1658   FinishCrasher();
1659   AssertDeath(SIGABRT);
1660   FinishIntercept(&intercept_result);
1661   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1662 
1663   std::string result;
1664   ConsumeFd(std::move(output_fd), &result);
1665   ASSERT_MATCH(
1666       result,
1667       R"(signal 6 \(SIGABRT\))");
1668   ASSERT_BACKTRACE_FRAME(result, "abort");
1669 }
1670 
TEST_F(CrasherTest,seccomp_tombstone_multiple_threads_abort)1671 TEST_F(CrasherTest, seccomp_tombstone_multiple_threads_abort) {
1672   int intercept_result;
1673   unique_fd output_fd;
1674 
1675   static const auto dump_type = kDebuggerdTombstone;
1676   StartProcess(
1677       []() {
1678         std::thread a(foo);
1679         std::thread b(bar);
1680 
1681         std::this_thread::sleep_for(100ms);
1682 
1683         std::thread abort_thread([] { abort(); });
1684         abort_thread.join();
1685       },
1686       &seccomp_fork);
1687 
1688   StartIntercept(&output_fd, dump_type);
1689   FinishCrasher();
1690   AssertDeath(SIGABRT);
1691   FinishIntercept(&intercept_result);
1692   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1693 
1694   std::string result;
1695   ConsumeFd(std::move(output_fd), &result);
1696   ASSERT_BACKTRACE_FRAME(result, "abort");
1697   ASSERT_BACKTRACE_FRAME(result, "foo");
1698   ASSERT_BACKTRACE_FRAME(result, "bar");
1699   ASSERT_BACKTRACE_FRAME(result, "main");
1700 }
1701 
TEST_F(CrasherTest,seccomp_backtrace)1702 TEST_F(CrasherTest, seccomp_backtrace) {
1703   int intercept_result;
1704   unique_fd output_fd;
1705 
1706   static const auto dump_type = kDebuggerdNativeBacktrace;
1707   StartProcess(
1708       []() {
1709         std::thread a(foo);
1710         std::thread b(bar);
1711 
1712         std::this_thread::sleep_for(100ms);
1713 
1714         raise_debugger_signal(dump_type);
1715         _exit(0);
1716       },
1717       &seccomp_fork);
1718 
1719   StartIntercept(&output_fd, dump_type);
1720   FinishCrasher();
1721   AssertDeath(0);
1722   FinishIntercept(&intercept_result);
1723   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1724 
1725   std::string result;
1726   ConsumeFd(std::move(output_fd), &result);
1727   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
1728   ASSERT_BACKTRACE_FRAME(result, "foo");
1729   ASSERT_BACKTRACE_FRAME(result, "bar");
1730 }
1731 
TEST_F(CrasherTest,seccomp_backtrace_from_thread)1732 TEST_F(CrasherTest, seccomp_backtrace_from_thread) {
1733   int intercept_result;
1734   unique_fd output_fd;
1735 
1736   static const auto dump_type = kDebuggerdNativeBacktrace;
1737   StartProcess(
1738       []() {
1739         std::thread a(foo);
1740         std::thread b(bar);
1741 
1742         std::this_thread::sleep_for(100ms);
1743 
1744         std::thread raise_thread([] {
1745           raise_debugger_signal(dump_type);
1746           _exit(0);
1747         });
1748         raise_thread.join();
1749       },
1750       &seccomp_fork);
1751 
1752   StartIntercept(&output_fd, dump_type);
1753   FinishCrasher();
1754   AssertDeath(0);
1755   FinishIntercept(&intercept_result);
1756   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1757 
1758   std::string result;
1759   ConsumeFd(std::move(output_fd), &result);
1760   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
1761   ASSERT_BACKTRACE_FRAME(result, "foo");
1762   ASSERT_BACKTRACE_FRAME(result, "bar");
1763   ASSERT_BACKTRACE_FRAME(result, "main");
1764 }
1765 
TEST_F(CrasherTest,seccomp_crash_logcat)1766 TEST_F(CrasherTest, seccomp_crash_logcat) {
1767   StartProcess([]() { abort(); }, &seccomp_fork);
1768   FinishCrasher();
1769 
1770   // Make sure we don't get SIGSYS when trying to dump a crash to logcat.
1771   AssertDeath(SIGABRT);
1772 }
1773 
TEST_F(CrasherTest,competing_tracer)1774 TEST_F(CrasherTest, competing_tracer) {
1775   int intercept_result;
1776   unique_fd output_fd;
1777   StartProcess([]() {
1778     raise(SIGABRT);
1779   });
1780 
1781   StartIntercept(&output_fd);
1782 
1783   ASSERT_EQ(0, ptrace(PTRACE_SEIZE, crasher_pid, 0, 0));
1784   FinishCrasher();
1785 
1786   int status;
1787   ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, 0)));
1788   ASSERT_TRUE(WIFSTOPPED(status));
1789   ASSERT_EQ(SIGABRT, WSTOPSIG(status));
1790 
1791   ASSERT_EQ(0, ptrace(PTRACE_CONT, crasher_pid, 0, SIGABRT));
1792   FinishIntercept(&intercept_result);
1793   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1794 
1795   std::string result;
1796   ConsumeFd(std::move(output_fd), &result);
1797   std::string regex = R"(failed to attach to thread \d+, already traced by )";
1798   regex += std::to_string(gettid());
1799   regex += R"( \(.+debuggerd_test)";
1800   ASSERT_MATCH(result, regex.c_str());
1801 
1802   ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, 0)));
1803   ASSERT_TRUE(WIFSTOPPED(status));
1804   ASSERT_EQ(SIGABRT, WSTOPSIG(status));
1805 
1806   ASSERT_EQ(0, ptrace(PTRACE_DETACH, crasher_pid, 0, SIGABRT));
1807   AssertDeath(SIGABRT);
1808 }
1809 
1810 struct GwpAsanTestParameters {
1811   size_t alloc_size;
1812   bool free_before_access;
1813   int access_offset;
1814   std::string cause_needle;  // Needle to be found in the "Cause: [GWP-ASan]" line.
1815 };
1816 
1817 struct GwpAsanCrasherTest
1818     : CrasherTest,
1819       testing::WithParamInterface<
1820           std::tuple<GwpAsanTestParameters, /* recoverable */ bool, /* seccomp */ bool>> {};
1821 
1822 GwpAsanTestParameters gwp_asan_tests[] = {
1823     {/* alloc_size */ 7, /* free_before_access */ true, /* access_offset */ 0,
1824      "Use After Free, 0 bytes into a 7-byte allocation"},
1825     {/* alloc_size */ 15, /* free_before_access */ true, /* access_offset */ 1,
1826      "Use After Free, 1 byte into a 15-byte allocation"},
1827     {/* alloc_size */ static_cast<size_t>(getpagesize()), /* free_before_access */ false,
1828      /* access_offset */ getpagesize() + 2,
1829      android::base::StringPrintf("Buffer Overflow, 2 bytes right of a %d-byte allocation",
1830                                  getpagesize())},
1831     {/* alloc_size */ static_cast<size_t>(getpagesize()), /* free_before_access */ false,
1832      /* access_offset */ -1,
1833      android::base::StringPrintf("Buffer Underflow, 1 byte left of a %d-byte allocation",
1834                                  getpagesize())},
1835 };
1836 
1837 INSTANTIATE_TEST_SUITE_P(
1838     GwpAsanTests, GwpAsanCrasherTest,
1839     testing::Combine(testing::ValuesIn(gwp_asan_tests),
1840                      /* recoverable */ testing::Bool(),
1841                      /* seccomp */ testing::Bool()),
1842     [](const testing::TestParamInfo<
__anon38df3a1c3502(const testing::TestParamInfo< std::tuple<GwpAsanTestParameters, bool, bool>>& info) 1843         std::tuple<GwpAsanTestParameters, /* recoverable */ bool, /* seccomp */ bool>>& info) {
1844       const GwpAsanTestParameters& params = std::get<0>(info.param);
1845       std::string name = params.free_before_access ? "UseAfterFree" : "Overflow";
1846       name += testing::PrintToString(params.alloc_size);
1847       name += "Alloc";
1848       if (params.access_offset < 0) {
1849         name += "Left";
1850         name += testing::PrintToString(params.access_offset * -1);
1851       } else {
1852         name += "Right";
1853         name += testing::PrintToString(params.access_offset);
1854       }
1855       name += "Bytes";
1856       if (std::get<1>(info.param)) name += "Recoverable";
1857       if (std::get<2>(info.param)) name += "Seccomp";
1858       return name;
1859     });
1860 
TEST_P(GwpAsanCrasherTest,run_gwp_asan_test)1861 TEST_P(GwpAsanCrasherTest, run_gwp_asan_test) {
1862   if (mte_supported()) {
1863     // Skip this test on MTE hardware, as MTE will reliably catch these errors
1864     // instead of GWP-ASan.
1865     GTEST_SKIP() << "Skipped on MTE.";
1866   }
1867   // Skip this test on HWASan, which will reliably catch test errors as well.
1868   SKIP_WITH_HWASAN;
1869 
1870   GwpAsanTestParameters params = std::get<0>(GetParam());
1871   bool recoverable = std::get<1>(GetParam());
1872   LogcatCollector logcat_collector;
1873 
1874   int intercept_result;
1875   unique_fd output_fd;
1876   StartProcess([&recoverable]() {
1877     const char* env[] = {"GWP_ASAN_SAMPLE_RATE=1", "GWP_ASAN_PROCESS_SAMPLING=1",
1878                          "GWP_ASAN_MAX_ALLOCS=40000", nullptr, nullptr};
1879     if (!recoverable) {
1880       env[3] = "GWP_ASAN_RECOVERABLE=false";
1881     }
1882     std::string test_name = ::testing::UnitTest::GetInstance()->current_test_info()->name();
1883     test_name = std::regex_replace(test_name, std::regex("run_gwp_asan_test"),
1884                                    "DISABLED_run_gwp_asan_test");
1885     std::string test_filter = "--gtest_filter=*";
1886     test_filter += test_name;
1887     std::string this_binary = android::base::GetExecutablePath();
1888     const char* args[] = {this_binary.c_str(), "--gtest_also_run_disabled_tests",
1889                           test_filter.c_str(), nullptr};
1890     // We check the crash report from a debuggerd handler and from logcat. The
1891     // echo from stdout/stderr of the subprocess trips up atest, because it
1892     // doesn't like that two tests started in a row without the first one
1893     // finishing (even though the second one is in a subprocess).
1894     close(STDOUT_FILENO);
1895     close(STDERR_FILENO);
1896     execve(this_binary.c_str(), const_cast<char**>(args), const_cast<char**>(env));
1897   });
1898 
1899   StartIntercept(&output_fd);
1900   FinishCrasher();
1901   if (recoverable) {
1902     AssertDeath(0);
1903   } else {
1904     AssertDeath(SIGSEGV);
1905   }
1906   FinishIntercept(&intercept_result);
1907 
1908   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1909 
1910   std::vector<std::string> log_sources(2);
1911   ConsumeFd(std::move(output_fd), &log_sources[0]);
1912   logcat_collector.Collect(&log_sources[1]);
1913 
1914   // seccomp forces the fallback handler, which doesn't print GWP-ASan debugging
1915   // information. Make sure the recovery still works, but the report won't be
1916   // hugely useful, it looks like a regular SEGV.
1917   bool seccomp = std::get<2>(GetParam());
1918   if (!seccomp) {
1919     for (const auto& result : log_sources) {
1920       ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\))");
1921       ASSERT_MATCH(result, R"(Cause: \[GWP-ASan\]: )" + params.cause_needle);
1922       if (params.free_before_access) {
1923         ASSERT_MATCH(result, R"(deallocated by thread .*\n.*#00 pc)");
1924       }
1925       ASSERT_MATCH(result, R"((^|\s)allocated by thread .*\n.*#00 pc)");
1926     }
1927   }
1928 }
1929 
TEST_P(GwpAsanCrasherTest,DISABLED_run_gwp_asan_test)1930 TEST_P(GwpAsanCrasherTest, DISABLED_run_gwp_asan_test) {
1931   GwpAsanTestParameters params = std::get<0>(GetParam());
1932   bool seccomp = std::get<2>(GetParam());
1933   if (seccomp) {
1934     ScopedMinijail jail{minijail_new()};
1935     setup_jail(jail.get());
1936     minijail_enter(jail.get());
1937   }
1938 
1939   // Use 'volatile' to prevent a very clever compiler eliminating the store.
1940   char* volatile p = reinterpret_cast<char* volatile>(malloc(params.alloc_size));
1941   if (params.free_before_access) free(static_cast<void*>(const_cast<char*>(p)));
1942   p[params.access_offset] = 42;
1943   if (!params.free_before_access) free(static_cast<void*>(const_cast<char*>(p)));
1944 
1945   bool recoverable = std::get<1>(GetParam());
1946   ASSERT_TRUE(recoverable);  // Non-recoverable should have crashed.
1947 
1948   // As we're in recoverable mode, trigger another 2x use-after-frees (ensuring
1949   // we end with at least one in a different slot), make sure the process still
1950   // doesn't crash.
1951   p = reinterpret_cast<char* volatile>(malloc(params.alloc_size));
1952   char* volatile p2 = reinterpret_cast<char* volatile>(malloc(params.alloc_size));
1953   free(static_cast<void*>(const_cast<char*>(p)));
1954   free(static_cast<void*>(const_cast<char*>(p2)));
1955   *p = 42;
1956   *p2 = 42;
1957 
1958   // Under clang coverage (which is a default TEST_MAPPING presubmit target), the
1959   // recoverable+seccomp tests fail because the minijail prevents some atexit syscalls that clang
1960   // coverage does. Thus, skip the atexit handlers.
1961   _exit(0);
1962 }
1963 
TEST_F(CrasherTest,fdsan_warning_abort_message)1964 TEST_F(CrasherTest, fdsan_warning_abort_message) {
1965   int intercept_result;
1966   unique_fd output_fd;
1967 
1968   StartProcess([]() {
1969     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
1970     unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY | O_CLOEXEC)));
1971     if (fd == -1) {
1972       abort();
1973     }
1974     close(fd.get());
1975     _exit(0);
1976   });
1977 
1978   StartIntercept(&output_fd);
1979   FinishCrasher();
1980   AssertDeath(0);
1981   FinishIntercept(&intercept_result);
1982   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
1983 
1984   std::string result;
1985   ConsumeFd(std::move(output_fd), &result);
1986   ASSERT_MATCH(result, "Abort message: 'attempted to close");
1987 }
1988 
TEST(crash_dump,zombie)1989 TEST(crash_dump, zombie) {
1990   pid_t forkpid = fork();
1991 
1992   pid_t rc;
1993   int status;
1994 
1995   if (forkpid == 0) {
1996     errno = 0;
1997     rc = waitpid(-1, &status, WNOHANG | __WALL | __WNOTHREAD);
1998     if (rc != -1 || errno != ECHILD) {
1999       errx(2, "first waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
2000     }
2001 
2002     raise(BIONIC_SIGNAL_DEBUGGER);
2003 
2004     errno = 0;
2005     rc = TEMP_FAILURE_RETRY(waitpid(-1, &status, __WALL | __WNOTHREAD));
2006     if (rc != -1 || errno != ECHILD) {
2007       errx(2, "second waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
2008     }
2009     _exit(0);
2010   } else {
2011     rc = TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0));
2012     ASSERT_EQ(forkpid, rc);
2013     ASSERT_TRUE(WIFEXITED(status));
2014     ASSERT_EQ(0, WEXITSTATUS(status));
2015   }
2016 }
2017 
TEST(tombstoned,no_notify)2018 TEST(tombstoned, no_notify) {
2019   // Do this a few times.
2020   for (int i = 0; i < 3; ++i) {
2021     pid_t pid = 123'456'789 + i;
2022 
2023     unique_fd intercept_fd, output_fd;
2024     InterceptResponse response = {};
2025     tombstoned_intercept(pid, &intercept_fd, &output_fd, &response, kDebuggerdTombstone);
2026     ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2027         << "Error message: " << response.error_message;
2028 
2029     {
2030       unique_fd tombstoned_socket, input_fd;
2031       ASSERT_TRUE(tombstoned_connect(pid, &tombstoned_socket, &input_fd, kDebuggerdTombstone));
2032       ASSERT_TRUE(android::base::WriteFully(input_fd.get(), &pid, sizeof(pid)));
2033     }
2034 
2035     pid_t read_pid;
2036     ASSERT_TRUE(android::base::ReadFully(output_fd.get(), &read_pid, sizeof(read_pid)));
2037     ASSERT_EQ(read_pid, pid);
2038   }
2039 }
2040 
TEST(tombstoned,stress)2041 TEST(tombstoned, stress) {
2042   // Spawn threads to simultaneously do a bunch of failing dumps and a bunch of successful dumps.
2043   static constexpr int kDumpCount = 100;
2044 
2045   std::atomic<bool> start(false);
2046   std::vector<std::thread> threads;
2047   threads.emplace_back([&start]() {
2048     while (!start) {
2049       continue;
2050     }
2051 
2052     // Use a way out of range pid, to avoid stomping on an actual process.
2053     pid_t pid_base = 1'000'000;
2054 
2055     for (int dump = 0; dump < kDumpCount; ++dump) {
2056       pid_t pid = pid_base + dump;
2057 
2058       unique_fd intercept_fd, output_fd;
2059       InterceptResponse response = {};
2060       tombstoned_intercept(pid, &intercept_fd, &output_fd, &response, kDebuggerdTombstone);
2061       ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2062           << "Error messeage: " << response.error_message;
2063 
2064       // Pretend to crash, and then immediately close the socket.
2065       unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
2066                                            ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
2067       if (sockfd == -1) {
2068         FAIL() << "failed to connect to tombstoned: " << strerror(errno);
2069       }
2070       TombstonedCrashPacket packet = {};
2071       packet.packet_type = CrashPacketType::kDumpRequest;
2072       packet.packet.dump_request.pid = pid;
2073       if (TEMP_FAILURE_RETRY(write(sockfd, &packet, sizeof(packet))) != sizeof(packet)) {
2074         FAIL() << "failed to write to tombstoned: " << strerror(errno);
2075       }
2076 
2077       continue;
2078     }
2079   });
2080 
2081   threads.emplace_back([&start]() {
2082     while (!start) {
2083       continue;
2084     }
2085 
2086     // Use a way out of range pid, to avoid stomping on an actual process.
2087     pid_t pid_base = 2'000'000;
2088 
2089     for (int dump = 0; dump < kDumpCount; ++dump) {
2090       pid_t pid = pid_base + dump;
2091 
2092       unique_fd intercept_fd, output_fd;
2093       InterceptResponse response = {};
2094       tombstoned_intercept(pid, &intercept_fd, &output_fd, &response, kDebuggerdTombstone);
2095       ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2096           << "Error message: " << response.error_message;
2097 
2098       {
2099         unique_fd tombstoned_socket, input_fd;
2100         ASSERT_TRUE(tombstoned_connect(pid, &tombstoned_socket, &input_fd, kDebuggerdTombstone));
2101         ASSERT_TRUE(android::base::WriteFully(input_fd.get(), &pid, sizeof(pid)));
2102         tombstoned_notify_completion(tombstoned_socket.get());
2103       }
2104 
2105       // TODO: Fix the race that requires this sleep.
2106       std::this_thread::sleep_for(50ms);
2107 
2108       pid_t read_pid;
2109       ASSERT_TRUE(android::base::ReadFully(output_fd.get(), &read_pid, sizeof(read_pid)));
2110       ASSERT_EQ(read_pid, pid);
2111     }
2112   });
2113 
2114   start = true;
2115 
2116   for (std::thread& thread : threads) {
2117     thread.join();
2118   }
2119 }
2120 
TEST(tombstoned,intercept_java_trace_smoke)2121 TEST(tombstoned, intercept_java_trace_smoke) {
2122   // Using a "real" PID is a little dangerous here - if the test fails
2123   // or crashes, we might end up getting a bogus / unreliable stack
2124   // trace.
2125   const pid_t self = getpid();
2126 
2127   unique_fd intercept_fd, output_fd;
2128   InterceptResponse response = {};
2129   tombstoned_intercept(self, &intercept_fd, &output_fd, &response, kDebuggerdJavaBacktrace);
2130   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2131       << "Error message: " << response.error_message;
2132 
2133   // First connect to tombstoned requesting a native tombstone. This
2134   // should result in a "regular" FD and not the installed intercept.
2135   const char native[] = "native";
2136   unique_fd tombstoned_socket, input_fd;
2137   ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdTombstone));
2138   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native)));
2139   tombstoned_notify_completion(tombstoned_socket.get());
2140 
2141   // Then, connect to tombstoned asking for a java backtrace. This *should*
2142   // trigger the intercept.
2143   const char java[] = "java";
2144   ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace));
2145   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java)));
2146   tombstoned_notify_completion(tombstoned_socket.get());
2147 
2148   char outbuf[sizeof(java)];
2149   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
2150   ASSERT_STREQ("java", outbuf);
2151 }
2152 
TEST(tombstoned,intercept_multiple_dump_types)2153 TEST(tombstoned, intercept_multiple_dump_types) {
2154   const pid_t fake_pid = 1'234'567;
2155   unique_fd intercept_fd, output_fd;
2156   InterceptResponse response = {};
2157   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdJavaBacktrace);
2158   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2159       << "Error message: " << response.error_message;
2160 
2161   unique_fd intercept_fd_2, output_fd_2;
2162   tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &response,
2163                        kDebuggerdNativeBacktrace);
2164   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2165       << "Error message: " << response.error_message;
2166 }
2167 
TEST(tombstoned,intercept_bad_pid)2168 TEST(tombstoned, intercept_bad_pid) {
2169   const pid_t fake_pid = -1;
2170   unique_fd intercept_fd, output_fd;
2171   InterceptResponse response = {};
2172   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdNativeBacktrace);
2173   ASSERT_EQ(InterceptStatus::kFailed, response.status)
2174       << "Error message: " << response.error_message;
2175   ASSERT_MATCH(response.error_message, "bad pid");
2176 }
2177 
TEST(tombstoned,intercept_bad_dump_types)2178 TEST(tombstoned, intercept_bad_dump_types) {
2179   const pid_t fake_pid = 1'234'567;
2180   unique_fd intercept_fd, output_fd;
2181   InterceptResponse response = {};
2182   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response,
2183                        static_cast<DebuggerdDumpType>(20));
2184   ASSERT_EQ(InterceptStatus::kFailed, response.status)
2185       << "Error message: " << response.error_message;
2186   ASSERT_MATCH(response.error_message, "bad dump type \\[unknown\\]");
2187 
2188   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdAnyIntercept);
2189   ASSERT_EQ(InterceptStatus::kFailed, response.status)
2190       << "Error message: " << response.error_message;
2191   ASSERT_MATCH(response.error_message, "bad dump type kDebuggerdAnyIntercept");
2192 
2193   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdTombstoneProto);
2194   ASSERT_EQ(InterceptStatus::kFailed, response.status)
2195       << "Error message: " << response.error_message;
2196   ASSERT_MATCH(response.error_message, "bad dump type kDebuggerdTombstoneProto");
2197 }
2198 
TEST(tombstoned,intercept_already_registered)2199 TEST(tombstoned, intercept_already_registered) {
2200   const pid_t fake_pid = 1'234'567;
2201   unique_fd intercept_fd1, output_fd1;
2202   InterceptResponse response = {};
2203   tombstoned_intercept(fake_pid, &intercept_fd1, &output_fd1, &response, kDebuggerdTombstone);
2204   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2205       << "Error message: " << response.error_message;
2206 
2207   unique_fd intercept_fd2, output_fd2;
2208   tombstoned_intercept(fake_pid, &intercept_fd2, &output_fd2, &response, kDebuggerdTombstone);
2209   ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, response.status)
2210       << "Error message: " << response.error_message;
2211   ASSERT_MATCH(response.error_message, "already registered, type kDebuggerdTombstone");
2212 }
2213 
TEST(tombstoned,intercept_tombstone_proto_matched_to_tombstone)2214 TEST(tombstoned, intercept_tombstone_proto_matched_to_tombstone) {
2215   const pid_t fake_pid = 1'234'567;
2216 
2217   unique_fd intercept_fd, output_fd;
2218   InterceptResponse response = {};
2219   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdTombstone);
2220   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2221       << "Error message: " << response.error_message;
2222 
2223   const char data[] = "tombstone_proto";
2224   unique_fd tombstoned_socket, input_fd;
2225   ASSERT_TRUE(
2226       tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdTombstoneProto));
2227   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), data, sizeof(data)));
2228   tombstoned_notify_completion(tombstoned_socket.get());
2229 
2230   char outbuf[sizeof(data)];
2231   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
2232   ASSERT_STREQ("tombstone_proto", outbuf);
2233 }
2234 
TEST(tombstoned,intercept_any)2235 TEST(tombstoned, intercept_any) {
2236   const pid_t fake_pid = 1'234'567;
2237 
2238   unique_fd intercept_fd, output_fd;
2239   InterceptResponse response = {};
2240   tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &response, kDebuggerdNativeBacktrace);
2241   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2242       << "Error message: " << response.error_message;
2243 
2244   const char any[] = "any";
2245   unique_fd tombstoned_socket, input_fd;
2246   ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept));
2247   ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any)));
2248   tombstoned_notify_completion(tombstoned_socket.get());
2249 
2250   char outbuf[sizeof(any)];
2251   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
2252   ASSERT_STREQ("any", outbuf);
2253 }
2254 
TEST(tombstoned,intercept_any_failed_with_multiple_intercepts)2255 TEST(tombstoned, intercept_any_failed_with_multiple_intercepts) {
2256   const pid_t fake_pid = 1'234'567;
2257 
2258   InterceptResponse response = {};
2259   unique_fd intercept_fd1, output_fd1;
2260   tombstoned_intercept(fake_pid, &intercept_fd1, &output_fd1, &response, kDebuggerdNativeBacktrace);
2261   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2262       << "Error message: " << response.error_message;
2263 
2264   unique_fd intercept_fd2, output_fd2;
2265   tombstoned_intercept(fake_pid, &intercept_fd2, &output_fd2, &response, kDebuggerdJavaBacktrace);
2266   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2267       << "Error message: " << response.error_message;
2268 
2269   unique_fd tombstoned_socket, input_fd;
2270   ASSERT_FALSE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept));
2271 }
2272 
TEST(tombstoned,intercept_multiple_verify_intercept)2273 TEST(tombstoned, intercept_multiple_verify_intercept) {
2274   // Need to use our pid for java since that will verify the pid.
2275   const pid_t fake_pid = getpid();
2276 
2277   InterceptResponse response = {};
2278   unique_fd intercept_fd1, output_fd1;
2279   tombstoned_intercept(fake_pid, &intercept_fd1, &output_fd1, &response, kDebuggerdNativeBacktrace);
2280   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2281       << "Error message: " << response.error_message;
2282 
2283   unique_fd intercept_fd2, output_fd2;
2284   tombstoned_intercept(fake_pid, &intercept_fd2, &output_fd2, &response, kDebuggerdJavaBacktrace);
2285   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2286       << "Error message: " << response.error_message;
2287 
2288   unique_fd intercept_fd3, output_fd3;
2289   tombstoned_intercept(fake_pid, &intercept_fd3, &output_fd3, &response, kDebuggerdTombstone);
2290   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2291       << "Error message: " << response.error_message;
2292 
2293   const char native_data[] = "native";
2294   unique_fd tombstoned_socket1, input_fd1;
2295   ASSERT_TRUE(
2296       tombstoned_connect(fake_pid, &tombstoned_socket1, &input_fd1, kDebuggerdNativeBacktrace));
2297   ASSERT_TRUE(android::base::WriteFully(input_fd1.get(), native_data, sizeof(native_data)));
2298   tombstoned_notify_completion(tombstoned_socket1.get());
2299 
2300   char native_outbuf[sizeof(native_data)];
2301   ASSERT_TRUE(android::base::ReadFully(output_fd1.get(), native_outbuf, sizeof(native_outbuf)));
2302   ASSERT_STREQ("native", native_outbuf);
2303 
2304   const char java_data[] = "java";
2305   unique_fd tombstoned_socket2, input_fd2;
2306   ASSERT_TRUE(
2307       tombstoned_connect(fake_pid, &tombstoned_socket2, &input_fd2, kDebuggerdJavaBacktrace));
2308   ASSERT_TRUE(android::base::WriteFully(input_fd2.get(), java_data, sizeof(java_data)));
2309   tombstoned_notify_completion(tombstoned_socket2.get());
2310 
2311   char java_outbuf[sizeof(java_data)];
2312   ASSERT_TRUE(android::base::ReadFully(output_fd2.get(), java_outbuf, sizeof(java_outbuf)));
2313   ASSERT_STREQ("java", java_outbuf);
2314 
2315   const char tomb_data[] = "tombstone";
2316   unique_fd tombstoned_socket3, input_fd3;
2317   ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket3, &input_fd3, kDebuggerdTombstone));
2318   ASSERT_TRUE(android::base::WriteFully(input_fd3.get(), tomb_data, sizeof(tomb_data)));
2319   tombstoned_notify_completion(tombstoned_socket3.get());
2320 
2321   char tomb_outbuf[sizeof(tomb_data)];
2322   ASSERT_TRUE(android::base::ReadFully(output_fd3.get(), tomb_outbuf, sizeof(tomb_outbuf)));
2323   ASSERT_STREQ("tombstone", tomb_outbuf);
2324 }
2325 
TEST(tombstoned,interceptless_backtrace)2326 TEST(tombstoned, interceptless_backtrace) {
2327   // Generate 50 backtraces, and then check to see that we haven't created 50 new tombstones.
2328   auto get_tombstone_timestamps = []() -> std::map<int, time_t> {
2329     std::map<int, time_t> result;
2330     for (int i = 0; i < 99; ++i) {
2331       std::string path = android::base::StringPrintf("/data/tombstones/tombstone_%02d", i);
2332       struct stat st;
2333       if (stat(path.c_str(), &st) == 0) {
2334         result[i] = st.st_mtim.tv_sec;
2335       }
2336     }
2337     return result;
2338   };
2339 
2340   auto before = get_tombstone_timestamps();
2341   for (int i = 0; i < 50; ++i) {
2342     raise_debugger_signal(kDebuggerdNativeBacktrace);
2343   }
2344   auto after = get_tombstone_timestamps();
2345 
2346   int diff = 0;
2347   for (int i = 0; i < 99; ++i) {
2348     if (after.count(i) == 0) {
2349       continue;
2350     }
2351     if (before.count(i) == 0) {
2352       ++diff;
2353       continue;
2354     }
2355     if (before[i] != after[i]) {
2356       ++diff;
2357     }
2358   }
2359 
2360   // We can't be sure that nothing's crash looping in the background.
2361   // This should be good enough, though...
2362   ASSERT_LT(diff, 10) << "too many new tombstones; is something crashing in the background?";
2363 }
2364 
overflow_stack(void * p)2365 static __attribute__((__noinline__)) void overflow_stack(void* p) {
2366   void* buf[1];
2367   buf[0] = p;
2368   static volatile void* global = buf;
2369   if (global) {
2370     global = buf;
2371     overflow_stack(&buf);
2372   }
2373 }
2374 
TEST_F(CrasherTest,stack_overflow)2375 TEST_F(CrasherTest, stack_overflow) {
2376   int intercept_result;
2377   unique_fd output_fd;
2378   StartProcess([]() { overflow_stack(nullptr); });
2379 
2380   StartIntercept(&output_fd);
2381   FinishCrasher();
2382   AssertDeath(SIGSEGV);
2383   FinishIntercept(&intercept_result);
2384 
2385   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2386 
2387   std::string result;
2388   ConsumeFd(std::move(output_fd), &result);
2389   ASSERT_MATCH(result, R"(Cause: stack pointer[^\n]*stack overflow.\n)");
2390 }
2391 
GetTestLibraryPath()2392 static std::string GetTestLibraryPath() {
2393   std::string test_lib(testing::internal::GetArgvs()[0]);
2394   auto const value = test_lib.find_last_of('/');
2395   if (value == std::string::npos) {
2396     test_lib = "./";
2397   } else {
2398     test_lib = test_lib.substr(0, value + 1) + "./";
2399   }
2400   return test_lib + "libcrash_test.so";
2401 }
2402 
CreateEmbeddedLibrary(int out_fd)2403 static void CreateEmbeddedLibrary(int out_fd) {
2404   std::string test_lib(GetTestLibraryPath());
2405   android::base::unique_fd fd(open(test_lib.c_str(), O_RDONLY | O_CLOEXEC));
2406   ASSERT_NE(fd.get(), -1);
2407   off_t file_size = lseek(fd, 0, SEEK_END);
2408   ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
2409   std::vector<uint8_t> contents(file_size);
2410   ASSERT_TRUE(android::base::ReadFully(fd, contents.data(), contents.size()));
2411 
2412   // Put the shared library data at a pagesize() offset.
2413   ASSERT_EQ(lseek(out_fd, 4 * getpagesize(), SEEK_CUR), 4 * getpagesize());
2414   ASSERT_EQ(static_cast<size_t>(write(out_fd, contents.data(), contents.size())), contents.size());
2415 }
2416 
TEST_F(CrasherTest,non_zero_offset_in_library)2417 TEST_F(CrasherTest, non_zero_offset_in_library) {
2418   int intercept_result;
2419   unique_fd output_fd;
2420   TemporaryFile tf;
2421   CreateEmbeddedLibrary(tf.fd);
2422   StartProcess([&tf]() {
2423     android_dlextinfo extinfo{};
2424     extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
2425     extinfo.library_fd = tf.fd;
2426     extinfo.library_fd_offset = 4 * getpagesize();
2427     void* handle = android_dlopen_ext(tf.path, RTLD_NOW, &extinfo);
2428     if (handle == nullptr) {
2429       _exit(1);
2430     }
2431     void (*crash_func)() = reinterpret_cast<void (*)()>(dlsym(handle, "crash"));
2432     if (crash_func == nullptr) {
2433       _exit(1);
2434     }
2435     crash_func();
2436   });
2437 
2438   StartIntercept(&output_fd);
2439   FinishCrasher();
2440   AssertDeath(SIGSEGV);
2441   FinishIntercept(&intercept_result);
2442 
2443   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2444 
2445   std::string result;
2446   ConsumeFd(std::move(output_fd), &result);
2447 
2448   // Verify the crash includes an offset value in the backtrace.
2449   std::string match_str = android::base::StringPrintf("%s\\!libcrash_test.so \\(offset 0x%x\\)",
2450                                                       tf.path, 4 * getpagesize());
2451   ASSERT_MATCH(result, match_str);
2452 }
2453 
CopySharedLibrary(const char * tmp_dir,std::string * tmp_so_name)2454 static bool CopySharedLibrary(const char* tmp_dir, std::string* tmp_so_name) {
2455   std::string test_lib(GetTestLibraryPath());
2456 
2457   *tmp_so_name = std::string(tmp_dir) + "/libcrash_test.so";
2458   std::string cp_cmd = android::base::StringPrintf("cp %s %s", test_lib.c_str(), tmp_dir);
2459 
2460   // Copy the shared so to a tempory directory.
2461   return system(cp_cmd.c_str()) == 0;
2462 }
2463 
TEST_F(CrasherTest,unreadable_elf)2464 TEST_F(CrasherTest, unreadable_elf) {
2465   int intercept_result;
2466   unique_fd output_fd;
2467   std::string tmp_so_name;
2468   StartProcess([&tmp_so_name]() {
2469     TemporaryDir td;
2470     if (!CopySharedLibrary(td.path, &tmp_so_name)) {
2471       _exit(1);
2472     }
2473     void* handle = dlopen(tmp_so_name.c_str(), RTLD_NOW);
2474     if (handle == nullptr) {
2475       _exit(1);
2476     }
2477     // Delete the original shared library so that we get the warning
2478     // about unreadable elf files.
2479     if (unlink(tmp_so_name.c_str()) == -1) {
2480       _exit(1);
2481     }
2482     void (*crash_func)() = reinterpret_cast<void (*)()>(dlsym(handle, "crash"));
2483     if (crash_func == nullptr) {
2484       _exit(1);
2485     }
2486     crash_func();
2487   });
2488 
2489   StartIntercept(&output_fd);
2490   FinishCrasher();
2491   AssertDeath(SIGSEGV);
2492   FinishIntercept(&intercept_result);
2493 
2494   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2495 
2496   std::string result;
2497   ConsumeFd(std::move(output_fd), &result);
2498   ASSERT_MATCH(result, R"(NOTE: Function names and BuildId information is missing )");
2499   std::string match_str = "NOTE:   " + tmp_so_name;
2500   ASSERT_MATCH(result, match_str);
2501 }
2502 
CheckForTombstone(const struct stat & text_st,std::optional<std::string> & tombstone_file)2503 void CheckForTombstone(const struct stat& text_st, std::optional<std::string>& tombstone_file) {
2504   static std::regex tombstone_re("tombstone_\\d+");
2505   std::unique_ptr<DIR, decltype(&closedir)> dir_h(opendir("/data/tombstones"), closedir);
2506   ASSERT_TRUE(dir_h != nullptr);
2507   dirent* entry;
2508   while ((entry = readdir(dir_h.get())) != nullptr) {
2509     if (!std::regex_match(entry->d_name, tombstone_re)) {
2510       continue;
2511     }
2512     std::string path = android::base::StringPrintf("/data/tombstones/%s", entry->d_name);
2513 
2514     struct stat st;
2515     if (TEMP_FAILURE_RETRY(stat(path.c_str(), &st)) != 0) {
2516       continue;
2517     }
2518 
2519     if (st.st_dev == text_st.st_dev && st.st_ino == text_st.st_ino) {
2520       tombstone_file = path;
2521       break;
2522     }
2523   }
2524 }
2525 
TEST(tombstoned,proto)2526 TEST(tombstoned, proto) {
2527   const pid_t self = getpid();
2528   unique_fd tombstoned_socket, text_fd, proto_fd;
2529   ASSERT_TRUE(
2530       tombstoned_connect(self, &tombstoned_socket, &text_fd, &proto_fd, kDebuggerdTombstoneProto));
2531 
2532   tombstoned_notify_completion(tombstoned_socket.get());
2533 
2534   ASSERT_NE(-1, text_fd.get());
2535   ASSERT_NE(-1, proto_fd.get());
2536 
2537   struct stat text_st;
2538   ASSERT_EQ(0, fstat(text_fd.get(), &text_st));
2539 
2540   std::optional<std::string> tombstone_file;
2541   // Allow up to 5 seconds for the tombstone to be written to the system.
2542   const auto max_wait_time = std::chrono::seconds(5) * android::base::HwTimeoutMultiplier();
2543   const auto start = std::chrono::high_resolution_clock::now();
2544   while (true) {
2545     std::this_thread::sleep_for(100ms);
2546     CheckForTombstone(text_st, tombstone_file);
2547     if (tombstone_file) {
2548       break;
2549     }
2550     if (std::chrono::high_resolution_clock::now() - start > max_wait_time) {
2551       break;
2552     }
2553   }
2554 
2555   ASSERT_TRUE(tombstone_file) << "Timed out trying to find tombstone file.";
2556   std::string proto_path = tombstone_file.value() + ".pb";
2557 
2558   struct stat proto_fd_st;
2559   struct stat proto_file_st;
2560   ASSERT_EQ(0, fstat(proto_fd.get(), &proto_fd_st));
2561   ASSERT_EQ(0, stat(proto_path.c_str(), &proto_file_st));
2562 
2563   ASSERT_EQ(proto_fd_st.st_dev, proto_file_st.st_dev);
2564   ASSERT_EQ(proto_fd_st.st_ino, proto_file_st.st_ino);
2565 }
2566 
TEST(tombstoned,proto_intercept)2567 TEST(tombstoned, proto_intercept) {
2568   const pid_t self = getpid();
2569   unique_fd intercept_fd, output_fd;
2570 
2571   InterceptResponse response = {};
2572   tombstoned_intercept(self, &intercept_fd, &output_fd, &response, kDebuggerdTombstone);
2573   ASSERT_EQ(InterceptStatus::kRegistered, response.status)
2574       << "Error message: " << response.error_message;
2575 
2576   unique_fd tombstoned_socket, text_fd, proto_fd;
2577   ASSERT_TRUE(
2578       tombstoned_connect(self, &tombstoned_socket, &text_fd, &proto_fd, kDebuggerdTombstoneProto));
2579   ASSERT_TRUE(android::base::WriteStringToFd("foo", text_fd.get()));
2580   tombstoned_notify_completion(tombstoned_socket.get());
2581 
2582   text_fd.reset();
2583 
2584   std::string output;
2585   ASSERT_TRUE(android::base::ReadFdToString(output_fd, &output));
2586   ASSERT_EQ("foo", output);
2587 }
2588 
2589 // Verify that when an intercept is present for the main thread, and the signal
2590 // is received on a different thread, the intercept still works.
TEST_F(CrasherTest,intercept_for_main_thread_signal_on_side_thread)2591 TEST_F(CrasherTest, intercept_for_main_thread_signal_on_side_thread) {
2592   StartProcess([]() {
2593     std::thread thread([]() {
2594       // Raise the signal on the side thread.
2595       raise_debugger_signal(kDebuggerdNativeBacktrace);
2596     });
2597     thread.join();
2598     _exit(0);
2599   });
2600 
2601   unique_fd output_fd;
2602   StartIntercept(&output_fd, kDebuggerdNativeBacktrace);
2603   FinishCrasher();
2604   AssertDeath(0);
2605 
2606   int intercept_result;
2607   FinishIntercept(&intercept_result);
2608   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2609 
2610   std::string result;
2611   ConsumeFd(std::move(output_fd), &result);
2612   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
2613 }
2614 
format_pointer(uintptr_t ptr)2615 static std::string format_pointer(uintptr_t ptr) {
2616 #if defined(__LP64__)
2617   return android::base::StringPrintf("%08x'%08x", static_cast<uint32_t>(ptr >> 32),
2618                                      static_cast<uint32_t>(ptr & 0xffffffff));
2619 #else
2620   return android::base::StringPrintf("%08x", static_cast<uint32_t>(ptr & 0xffffffff));
2621 #endif
2622 }
2623 
format_pointer(void * ptr)2624 static std::string format_pointer(void* ptr) {
2625   return format_pointer(reinterpret_cast<uintptr_t>(ptr));
2626 }
2627 
format_full_pointer(uintptr_t ptr)2628 static std::string format_full_pointer(uintptr_t ptr) {
2629 #if defined(__LP64__)
2630   return android::base::StringPrintf("%016" PRIx64, ptr);
2631 #else
2632   return android::base::StringPrintf("%08x", ptr);
2633 #endif
2634 }
2635 
format_full_pointer(void * ptr)2636 static std::string format_full_pointer(void* ptr) {
2637   return format_full_pointer(reinterpret_cast<uintptr_t>(ptr));
2638 }
2639 
crash_call(uintptr_t ptr)2640 __attribute__((__noinline__)) int crash_call(uintptr_t ptr) {
2641   int* crash_ptr = reinterpret_cast<int*>(ptr);
2642   *crash_ptr = 1;
2643   return *crash_ptr;
2644 }
2645 
2646 // Verify that a fault address before the first map is properly handled.
TEST_F(CrasherTest,fault_address_before_first_map)2647 TEST_F(CrasherTest, fault_address_before_first_map) {
2648   StartProcess([]() {
2649     ASSERT_EQ(0, crash_call(0x1024));
2650     _exit(0);
2651   });
2652 
2653   unique_fd output_fd;
2654   StartIntercept(&output_fd);
2655   FinishCrasher();
2656   AssertDeath(SIGSEGV);
2657 
2658   int intercept_result;
2659   FinishIntercept(&intercept_result);
2660   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2661 
2662   std::string result;
2663   ConsumeFd(std::move(output_fd), &result);
2664   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+1024)");
2665 
2666   ASSERT_MATCH(result, R"(\nmemory map \(.*\):\n)");
2667 
2668   std::string match_str = android::base::StringPrintf(
2669       R"(memory map .*:\n--->Fault address falls at %s before any mapped regions\n    )",
2670       format_pointer(0x1024).c_str());
2671   ASSERT_MATCH(result, match_str);
2672 }
2673 
2674 // Verify that a fault address after the last map is properly handled.
TEST_F(CrasherTest,fault_address_after_last_map)2675 TEST_F(CrasherTest, fault_address_after_last_map) {
2676   // This makes assumptions about the memory layout that are not true in HWASan
2677   // processes.
2678   SKIP_WITH_HWASAN;
2679   uintptr_t crash_uptr = untag_address(UINTPTR_MAX - 15);
2680   StartProcess([crash_uptr]() {
2681     ASSERT_EQ(0, crash_call(crash_uptr));
2682     _exit(0);
2683   });
2684 
2685   unique_fd output_fd;
2686   StartIntercept(&output_fd);
2687   FinishCrasher();
2688   AssertDeath(SIGSEGV);
2689 
2690   int intercept_result;
2691   FinishIntercept(&intercept_result);
2692   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2693 
2694   std::string result;
2695   ConsumeFd(std::move(output_fd), &result);
2696 
2697   std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
2698   match_str += format_full_pointer(crash_uptr);
2699   ASSERT_MATCH(result, match_str);
2700 
2701   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->\)\n)");
2702 
2703   // Verifies that the fault address error message is at the end of the
2704   // maps section. To do this, the check below looks for the start of the
2705   // open files section or the start of the log file section. It's possible
2706   // for either of these sections to be present after the maps section right
2707   // now.
2708   // If the sections move around, this check might need to be modified.
2709   match_str = android::base::StringPrintf(
2710       R"(\n--->Fault address falls at %s after any mapped regions\n(---------|\nopen files:))",
2711       format_pointer(crash_uptr).c_str());
2712   ASSERT_MATCH(result, match_str);
2713 }
2714 
2715 // Verify that a fault address between maps is properly handled.
TEST_F(CrasherTest,fault_address_between_maps)2716 TEST_F(CrasherTest, fault_address_between_maps) {
2717   // Create a map before the fork so it will be present in the child.
2718   void* start_ptr =
2719       mmap(nullptr, 3 * getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2720   ASSERT_NE(MAP_FAILED, start_ptr);
2721   // Unmap the page in the middle.
2722   void* middle_ptr =
2723       reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start_ptr) + getpagesize());
2724   ASSERT_EQ(0, munmap(middle_ptr, getpagesize()));
2725 
2726   StartProcess([middle_ptr]() {
2727     ASSERT_EQ(0, crash_call(reinterpret_cast<uintptr_t>(middle_ptr)));
2728     _exit(0);
2729   });
2730 
2731   // Unmap the two maps.
2732   ASSERT_EQ(0, munmap(start_ptr, getpagesize()));
2733   void* end_ptr =
2734       reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start_ptr) + 2 * getpagesize());
2735   ASSERT_EQ(0, munmap(end_ptr, getpagesize()));
2736 
2737   unique_fd output_fd;
2738   StartIntercept(&output_fd);
2739   FinishCrasher();
2740   AssertDeath(SIGSEGV);
2741 
2742   int intercept_result;
2743   FinishIntercept(&intercept_result);
2744   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2745 
2746   std::string result;
2747   ConsumeFd(std::move(output_fd), &result);
2748 
2749   std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
2750   match_str += format_full_pointer(reinterpret_cast<uintptr_t>(middle_ptr));
2751   ASSERT_MATCH(result, match_str);
2752 
2753   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->\)\n)");
2754 
2755   match_str = android::base::StringPrintf(
2756       R"(    %s.*\n--->Fault address falls at %s between mapped regions\n    %s)",
2757       format_pointer(start_ptr).c_str(), format_pointer(middle_ptr).c_str(),
2758       format_pointer(end_ptr).c_str());
2759   ASSERT_MATCH(result, match_str);
2760 }
2761 
2762 // Verify that a fault address happens in the correct map.
TEST_F(CrasherTest,fault_address_in_map)2763 TEST_F(CrasherTest, fault_address_in_map) {
2764   // Create a map before the fork so it will be present in the child.
2765   void* ptr = mmap(nullptr, getpagesize(), 0, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2766   ASSERT_NE(MAP_FAILED, ptr);
2767 
2768   StartProcess([ptr]() {
2769     ASSERT_EQ(0, crash_call(reinterpret_cast<uintptr_t>(ptr)));
2770     _exit(0);
2771   });
2772 
2773   ASSERT_EQ(0, munmap(ptr, getpagesize()));
2774 
2775   unique_fd output_fd;
2776   StartIntercept(&output_fd);
2777   FinishCrasher();
2778   AssertDeath(SIGSEGV);
2779 
2780   int intercept_result;
2781   FinishIntercept(&intercept_result);
2782   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2783 
2784   std::string result;
2785   ConsumeFd(std::move(output_fd), &result);
2786 
2787   std::string match_str = R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\), fault addr 0x)";
2788   match_str += format_full_pointer(reinterpret_cast<uintptr_t>(ptr));
2789   ASSERT_MATCH(result, match_str);
2790 
2791   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->\)\n)");
2792 
2793   match_str = android::base::StringPrintf(R"(\n--->%s.*\n)", format_pointer(ptr).c_str());
2794   ASSERT_MATCH(result, match_str);
2795 }
2796 
2797 static constexpr uint32_t kDexData[] = {
2798     0x0a786564, 0x00383330, 0xc98b3ab8, 0xf3749d94, 0xaecca4d8, 0xffc7b09a, 0xdca9ca7f, 0x5be5deab,
2799     0x00000220, 0x00000070, 0x12345678, 0x00000000, 0x00000000, 0x0000018c, 0x00000008, 0x00000070,
2800     0x00000004, 0x00000090, 0x00000002, 0x000000a0, 0x00000000, 0x00000000, 0x00000003, 0x000000b8,
2801     0x00000001, 0x000000d0, 0x00000130, 0x000000f0, 0x00000122, 0x0000012a, 0x00000132, 0x00000146,
2802     0x00000151, 0x00000154, 0x00000158, 0x0000016d, 0x00000001, 0x00000002, 0x00000004, 0x00000006,
2803     0x00000004, 0x00000002, 0x00000000, 0x00000005, 0x00000002, 0x0000011c, 0x00000000, 0x00000000,
2804     0x00010000, 0x00000007, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000,
2805     0x00000003, 0x00000000, 0x0000017e, 0x00000000, 0x00010001, 0x00000001, 0x00000173, 0x00000004,
2806     0x00021070, 0x000e0000, 0x00010001, 0x00000000, 0x00000178, 0x00000001, 0x0000000e, 0x00000001,
2807     0x3c060003, 0x74696e69, 0x4c06003e, 0x6e69614d, 0x4c12003b, 0x6176616a, 0x6e616c2f, 0x624f2f67,
2808     0x7463656a, 0x4d09003b, 0x2e6e6961, 0x6176616a, 0x00560100, 0x004c5602, 0x6a4c5b13, 0x2f617661,
2809     0x676e616c, 0x7274532f, 0x3b676e69, 0x616d0400, 0x01006e69, 0x000e0700, 0x07000103, 0x0000000e,
2810     0x81000002, 0x01f00480, 0x02880901, 0x0000000c, 0x00000000, 0x00000001, 0x00000000, 0x00000001,
2811     0x00000008, 0x00000070, 0x00000002, 0x00000004, 0x00000090, 0x00000003, 0x00000002, 0x000000a0,
2812     0x00000005, 0x00000003, 0x000000b8, 0x00000006, 0x00000001, 0x000000d0, 0x00002001, 0x00000002,
2813     0x000000f0, 0x00001001, 0x00000001, 0x0000011c, 0x00002002, 0x00000008, 0x00000122, 0x00002003,
2814     0x00000002, 0x00000173, 0x00002000, 0x00000001, 0x0000017e, 0x00001000, 0x00000001, 0x0000018c,
2815 };
2816 
TEST_F(CrasherTest,verify_dex_pc_with_function_name)2817 TEST_F(CrasherTest, verify_dex_pc_with_function_name) {
2818   StartProcess([]() {
2819     TemporaryDir td;
2820     std::string tmp_so_name;
2821     if (!CopySharedLibrary(td.path, &tmp_so_name)) {
2822       _exit(1);
2823     }
2824 
2825     // In order to cause libunwindstack to look for this __dex_debug_descriptor
2826     // move the library to which has a basename of libart.so.
2827     std::string art_so_name = android::base::Dirname(tmp_so_name) + "/libart.so";
2828     ASSERT_EQ(0, rename(tmp_so_name.c_str(), art_so_name.c_str()));
2829     void* handle = dlopen(art_so_name.c_str(), RTLD_NOW | RTLD_LOCAL);
2830     if (handle == nullptr) {
2831       _exit(1);
2832     }
2833 
2834     void* ptr =
2835         mmap(nullptr, sizeof(kDexData), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2836     ASSERT_TRUE(ptr != MAP_FAILED);
2837     memcpy(ptr, kDexData, sizeof(kDexData));
2838     prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, sizeof(kDexData), "dex");
2839 
2840     JITCodeEntry dex_entry = {.symfile_addr = reinterpret_cast<uintptr_t>(ptr),
2841                               .symfile_size = sizeof(kDexData)};
2842 
2843     JITDescriptor* dex_debug =
2844         reinterpret_cast<JITDescriptor*>(dlsym(handle, "__dex_debug_descriptor"));
2845     ASSERT_TRUE(dex_debug != nullptr);
2846     dex_debug->version = 1;
2847     dex_debug->action_flag = 0;
2848     dex_debug->relevant_entry = 0;
2849     dex_debug->first_entry = reinterpret_cast<uintptr_t>(&dex_entry);
2850 
2851     // This sets the magic dex pc value for register 0, using the value
2852     // of register 1 + 0x102.
2853     asm(".cfi_escape "
2854         "0x16 /* DW_CFA_val_expression */, 0, 0x0a /* size */,"
2855         "0x0c /* DW_OP_const4u */, 0x44, 0x45, 0x58, 0x31, /* magic = 'DEX1' */"
2856         "0x13 /* DW_OP_drop */,"
2857         "0x92 /* DW_OP_bregx */, 1, 0x82, 0x02 /* 2-byte SLEB128 */");
2858 
2859     // For each different architecture, set register one to the dex ptr mmap
2860     // created above. Then do a nullptr dereference to force a crash.
2861 #if defined(__arm__)
2862     asm volatile(
2863         "mov r1, %[base]\n"
2864         "mov r2, #0\n"
2865         "str r2, [r2]\n"
2866         : [base] "+r"(ptr)
2867         :
2868         : "r1", "r2", "memory");
2869 #elif defined(__aarch64__)
2870     asm volatile(
2871         "mov x1, %[base]\n"
2872         "mov x2, #0\n"
2873         "str xzr, [x2]\n"
2874         : [base] "+r"(ptr)
2875         :
2876         : "x1", "x2", "memory");
2877 #elif defined(__riscv)
2878     // TODO: x1 is ra (the link register) on riscv64, so this might have
2879     // unintended consequences, but we'll need to change the .cfi_escape if so.
2880     asm volatile(
2881         "mv x1, %[base]\n"
2882         "sw zero, 0(zero)\n"
2883         : [base] "+r"(ptr)
2884         :
2885         : "x1", "memory");
2886 #elif defined(__i386__)
2887     asm volatile(
2888         "mov %[base], %%ecx\n"
2889         "movl $0, 0\n"
2890         : [base] "+r"(ptr)
2891         :
2892         : "ecx", "memory");
2893 #elif defined(__x86_64__)
2894     asm volatile(
2895         "mov %[base], %%rdx\n"
2896         "movq $0, 0\n"
2897         : [base] "+r"(ptr)
2898         :
2899         : "rdx", "memory");
2900 #else
2901 #error "Unsupported architecture"
2902 #endif
2903     _exit(0);
2904   });
2905 
2906   unique_fd output_fd;
2907   StartIntercept(&output_fd);
2908   FinishCrasher();
2909   AssertDeath(SIGSEGV);
2910 
2911   int intercept_result;
2912   FinishIntercept(&intercept_result);
2913   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2914 
2915   std::string result;
2916   ConsumeFd(std::move(output_fd), &result);
2917 
2918   // Verify the process crashed properly.
2919   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0*)");
2920 
2921   // Now verify that the dex_pc frame includes a proper function name.
2922   ASSERT_MATCH(result, R"( \[anon:dex\] \(Main\.\<init\>\+2)");
2923 }
2924 
format_map_pointer(uintptr_t ptr)2925 static std::string format_map_pointer(uintptr_t ptr) {
2926 #if defined(__LP64__)
2927   return android::base::StringPrintf("%08x'%08x", static_cast<uint32_t>(ptr >> 32),
2928                                      static_cast<uint32_t>(ptr & 0xffffffff));
2929 #else
2930   return android::base::StringPrintf("%08x", ptr);
2931 #endif
2932 }
2933 
2934 // Verify that map data is properly formatted.
TEST_F(CrasherTest,verify_map_format)2935 TEST_F(CrasherTest, verify_map_format) {
2936   // Create multiple maps to make sure that the map data is formatted properly.
2937   void* none_map = mmap(nullptr, getpagesize(), 0, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2938   ASSERT_NE(MAP_FAILED, none_map);
2939   void* r_map = mmap(nullptr, getpagesize(), PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2940   ASSERT_NE(MAP_FAILED, r_map);
2941   void* w_map = mmap(nullptr, getpagesize(), PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2942   ASSERT_NE(MAP_FAILED, w_map);
2943   void* x_map = mmap(nullptr, getpagesize(), PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
2944   ASSERT_NE(MAP_FAILED, x_map);
2945 
2946   TemporaryFile tf;
2947   ASSERT_EQ(0x2000, lseek(tf.fd, 0x2000, SEEK_SET));
2948   char c = 'f';
2949   ASSERT_EQ(1, write(tf.fd, &c, 1));
2950   ASSERT_EQ(0x5000, lseek(tf.fd, 0x5000, SEEK_SET));
2951   ASSERT_EQ(1, write(tf.fd, &c, 1));
2952   ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
2953   void* file_map = mmap(nullptr, 0x3001, PROT_READ, MAP_PRIVATE, tf.fd, 0x2000);
2954   ASSERT_NE(MAP_FAILED, file_map);
2955 
2956   StartProcess([]() { abort(); });
2957 
2958   ASSERT_EQ(0, munmap(none_map, getpagesize()));
2959   ASSERT_EQ(0, munmap(r_map, getpagesize()));
2960   ASSERT_EQ(0, munmap(w_map, getpagesize()));
2961   ASSERT_EQ(0, munmap(x_map, getpagesize()));
2962   ASSERT_EQ(0, munmap(file_map, 0x3001));
2963 
2964   unique_fd output_fd;
2965   StartIntercept(&output_fd);
2966   FinishCrasher();
2967   AssertDeath(SIGABRT);
2968   int intercept_result;
2969   FinishIntercept(&intercept_result);
2970 
2971   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
2972 
2973   std::string result;
2974   ConsumeFd(std::move(output_fd), &result);
2975 
2976   std::string match_str;
2977   // Verify none.
2978   match_str = android::base::StringPrintf(
2979       "    %s-%s ---         0      %x\\n",
2980       format_map_pointer(reinterpret_cast<uintptr_t>(none_map)).c_str(),
2981       format_map_pointer(reinterpret_cast<uintptr_t>(none_map) + getpagesize() - 1).c_str(),
2982       getpagesize());
2983   ASSERT_MATCH(result, match_str);
2984 
2985   // Verify read-only.
2986   match_str = android::base::StringPrintf(
2987       "    %s-%s r--         0      %x\\n",
2988       format_map_pointer(reinterpret_cast<uintptr_t>(r_map)).c_str(),
2989       format_map_pointer(reinterpret_cast<uintptr_t>(r_map) + getpagesize() - 1).c_str(),
2990       getpagesize());
2991   ASSERT_MATCH(result, match_str);
2992 
2993   // Verify write-only.
2994   match_str = android::base::StringPrintf(
2995       "    %s-%s -w-         0      %x\\n",
2996       format_map_pointer(reinterpret_cast<uintptr_t>(w_map)).c_str(),
2997       format_map_pointer(reinterpret_cast<uintptr_t>(w_map) + getpagesize() - 1).c_str(),
2998       getpagesize());
2999   ASSERT_MATCH(result, match_str);
3000 
3001   // Verify exec-only.
3002   match_str = android::base::StringPrintf(
3003       "    %s-%s --x         0      %x\\n",
3004       format_map_pointer(reinterpret_cast<uintptr_t>(x_map)).c_str(),
3005       format_map_pointer(reinterpret_cast<uintptr_t>(x_map) + getpagesize() - 1).c_str(),
3006       getpagesize());
3007   ASSERT_MATCH(result, match_str);
3008 
3009   // Verify file map with non-zero offset and a name.
3010   match_str = android::base::StringPrintf(
3011       "    %s-%s r--      2000      4000  %s\\n",
3012       format_map_pointer(reinterpret_cast<uintptr_t>(file_map)).c_str(),
3013       format_map_pointer(reinterpret_cast<uintptr_t>(file_map) + 0x3fff).c_str(), tf.path);
3014   ASSERT_MATCH(result, match_str);
3015 }
3016 
3017 // Verify that the tombstone map data is correct.
TEST_F(CrasherTest,verify_header)3018 TEST_F(CrasherTest, verify_header) {
3019   StartProcess([]() { abort(); });
3020 
3021   unique_fd output_fd;
3022   StartIntercept(&output_fd);
3023   FinishCrasher();
3024   AssertDeath(SIGABRT);
3025   int intercept_result;
3026   FinishIntercept(&intercept_result);
3027 
3028   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3029 
3030   std::string result;
3031   ConsumeFd(std::move(output_fd), &result);
3032 
3033   std::string match_str = android::base::StringPrintf(
3034       "Build fingerprint: '%s'\\nRevision: '%s'\\n",
3035       android::base::GetProperty("ro.build.fingerprint", "unknown").c_str(),
3036       android::base::GetProperty("ro.revision", "unknown").c_str());
3037   match_str += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
3038   ASSERT_MATCH(result, match_str);
3039 }
3040 
3041 // Verify that the thread header is formatted properly.
TEST_F(CrasherTest,verify_thread_header)3042 TEST_F(CrasherTest, verify_thread_header) {
3043   void* shared_map =
3044       mmap(nullptr, sizeof(pid_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
3045   ASSERT_NE(MAP_FAILED, shared_map);
3046   memset(shared_map, 0, sizeof(pid_t));
3047 
3048   StartProcess([&shared_map]() {
3049     std::atomic_bool tid_written;
3050     std::thread thread([&tid_written, &shared_map]() {
3051       pid_t tid = gettid();
3052       memcpy(shared_map, &tid, sizeof(pid_t));
3053       tid_written = true;
3054       volatile bool done = false;
3055       while (!done)
3056         ;
3057     });
3058     thread.detach();
3059     while (!tid_written.load(std::memory_order_acquire))
3060       ;
3061     abort();
3062   });
3063 
3064   pid_t primary_pid = crasher_pid;
3065 
3066   unique_fd output_fd;
3067   StartIntercept(&output_fd);
3068   FinishCrasher();
3069   AssertDeath(SIGABRT);
3070   int intercept_result;
3071   FinishIntercept(&intercept_result);
3072   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3073 
3074   // Read the tid data out.
3075   pid_t tid;
3076   memcpy(&tid, shared_map, sizeof(pid_t));
3077   ASSERT_NE(0, tid);
3078 
3079   ASSERT_EQ(0, munmap(shared_map, sizeof(pid_t)));
3080 
3081   std::string result;
3082   ConsumeFd(std::move(output_fd), &result);
3083 
3084   // Verify that there are two headers, one where the tid is "primary_pid"
3085   // and the other where the tid is "tid".
3086   std::string match_str = android::base::StringPrintf("pid: %d, tid: %d, name: .*  >>> .* <<<\\n",
3087                                                       primary_pid, primary_pid);
3088   ASSERT_MATCH(result, match_str);
3089 
3090   match_str =
3091       android::base::StringPrintf("pid: %d, tid: %d, name: .*  >>> .* <<<\\n", primary_pid, tid);
3092   ASSERT_MATCH(result, match_str);
3093 }
3094 
3095 // Verify that there is a BuildID present in the map section and set properly.
TEST_F(CrasherTest,verify_build_id)3096 TEST_F(CrasherTest, verify_build_id) {
3097   StartProcess([]() { abort(); });
3098 
3099   unique_fd output_fd;
3100   StartIntercept(&output_fd);
3101   FinishCrasher();
3102   AssertDeath(SIGABRT);
3103   int intercept_result;
3104   FinishIntercept(&intercept_result);
3105   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3106 
3107   std::string result;
3108   ConsumeFd(std::move(output_fd), &result);
3109 
3110   // Find every /system or /apex lib and verify the BuildID is displayed
3111   // properly.
3112   bool found_valid_elf = false;
3113   std::smatch match;
3114   std::regex build_id_regex(R"(  ((/system/|/apex/)\S+) \(BuildId: ([^\)]+)\))");
3115   for (std::string prev_file; std::regex_search(result, match, build_id_regex);
3116        result = match.suffix()) {
3117     if (prev_file == match[1]) {
3118       // Already checked this file.
3119       continue;
3120     }
3121 
3122     prev_file = match[1];
3123     auto elf_memory = unwindstack::Memory::CreateFileMemory(prev_file, 0);
3124     unwindstack::Elf elf(elf_memory);
3125     if (!elf.Init() || !elf.valid()) {
3126       // Skipping invalid elf files.
3127       continue;
3128     }
3129     ASSERT_EQ(match[3], elf.GetPrintableBuildID());
3130 
3131     found_valid_elf = true;
3132   }
3133   ASSERT_TRUE(found_valid_elf) << "Did not find any elf files with valid BuildIDs to check.";
3134 }
3135 
3136 const char kLogMessage[] = "Should not see this log message.";
3137 
3138 // Verify that the logd process does not read the log.
TEST_F(CrasherTest,logd_skips_reading_logs)3139 TEST_F(CrasherTest, logd_skips_reading_logs) {
3140   StartProcess([]() {
3141     pthread_setname_np(pthread_self(), "logd");
3142     LOG(INFO) << kLogMessage;
3143     abort();
3144   });
3145 
3146   unique_fd output_fd;
3147   StartIntercept(&output_fd);
3148   FinishCrasher();
3149   AssertDeath(SIGABRT);
3150   int intercept_result;
3151   FinishIntercept(&intercept_result);
3152   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3153 
3154   std::string result;
3155   ConsumeFd(std::move(output_fd), &result);
3156   // logd should not contain our log message.
3157   ASSERT_NOT_MATCH(result, kLogMessage);
3158 }
3159 
3160 // Verify that the logd process does not read the log when the non-main
3161 // thread crashes.
TEST_F(CrasherTest,logd_skips_reading_logs_not_main_thread)3162 TEST_F(CrasherTest, logd_skips_reading_logs_not_main_thread) {
3163   StartProcess([]() {
3164     pthread_setname_np(pthread_self(), "logd");
3165     LOG(INFO) << kLogMessage;
3166 
3167     std::thread thread([]() {
3168       pthread_setname_np(pthread_self(), "not_logd_thread");
3169       // Raise the signal on the side thread.
3170       raise_debugger_signal(kDebuggerdTombstone);
3171     });
3172     thread.join();
3173     _exit(0);
3174   });
3175 
3176   unique_fd output_fd;
3177   StartIntercept(&output_fd, kDebuggerdTombstone);
3178   FinishCrasher();
3179   AssertDeath(0);
3180 
3181   int intercept_result;
3182   FinishIntercept(&intercept_result);
3183   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3184 
3185   std::string result;
3186   ConsumeFd(std::move(output_fd), &result);
3187   ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
3188   ASSERT_NOT_MATCH(result, kLogMessage);
3189 }
3190 
3191 // Disable this test since there is a high liklihood that this would
3192 // be flaky since it requires 500 messages being in the log.
TEST_F(CrasherTest,DISABLED_max_log_messages)3193 TEST_F(CrasherTest, DISABLED_max_log_messages) {
3194   StartProcess([]() {
3195     for (size_t i = 0; i < 600; i++) {
3196       LOG(INFO) << "Message number " << i;
3197     }
3198     abort();
3199   });
3200 
3201   unique_fd output_fd;
3202   StartIntercept(&output_fd);
3203   FinishCrasher();
3204   AssertDeath(SIGABRT);
3205   int intercept_result;
3206   FinishIntercept(&intercept_result);
3207   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3208 
3209   std::string result;
3210   ConsumeFd(std::move(output_fd), &result);
3211   ASSERT_NOT_MATCH(result, "Message number 99");
3212   ASSERT_MATCH(result, "Message number 100");
3213   ASSERT_MATCH(result, "Message number 599");
3214 }
3215 
TEST_F(CrasherTest,log_with_newline)3216 TEST_F(CrasherTest, log_with_newline) {
3217   StartProcess([]() {
3218     LOG(INFO) << "This line has a newline.\nThis is on the next line.";
3219     abort();
3220   });
3221 
3222   unique_fd output_fd;
3223   StartIntercept(&output_fd);
3224   FinishCrasher();
3225   AssertDeath(SIGABRT);
3226   int intercept_result;
3227   FinishIntercept(&intercept_result);
3228   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
3229 
3230   std::string result;
3231   ConsumeFd(std::move(output_fd), &result);
3232   ASSERT_MATCH(result, ":\\s*This line has a newline.");
3233   ASSERT_MATCH(result, ":\\s*This is on the next line.");
3234 }
3235