Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fa66634 authored by Florian Mayer's avatar Florian Mayer
Browse files

Read data set by android_add_crash_detail into tombstone.

Bug: 155462331
Bug: 309446525
Change-Id: I6d01aafca48e0e5e8cbd5ae87add6aec0c429503
parent 0bd010d9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
      process_info->scudo_ring_buffer = crash_info->data.d.scudo_ring_buffer;
      process_info->scudo_ring_buffer_size = crash_info->data.d.scudo_ring_buffer_size;
      *recoverable_gwp_asan_crash = crash_info->data.d.recoverable_gwp_asan_crash;
      process_info->crash_detail_page = crash_info->data.d.crash_detail_page;
      FALLTHROUGH_INTENDED;
    case 1:
    case 2:
+181 −0
Original line number Diff line number Diff line
@@ -939,6 +939,187 @@ TEST_F(CrasherTest, abort_message) {
  ASSERT_MATCH(result, R"(Abort message: 'x{4045}')");
}

static char g_crash_detail_value_changes[] = "crash_detail_value";
static char g_crash_detail_value[] = "crash_detail_value";
static char g_crash_detail_value2[] = "crash_detail_value2";

inline crash_detail_t* _Nullable android_register_crash_detail_strs(const char* _Nonnull name,
                                                                    const char* _Nonnull data) {
  return android_register_crash_detail(name, strlen(name), data, strlen(data));
}

TEST_F(CrasherTest, crash_detail_single) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
}

TEST_F(CrasherTest, crash_detail_single_byte_name) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    android_register_crash_detail_strs("CRASH_DETAIL_NAME\1", g_crash_detail_value);
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME\\1: 'crash_detail_value')");
}


TEST_F(CrasherTest, crash_detail_single_bytes) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    android_register_crash_detail("CRASH_DETAIL_NAME", strlen("CRASH_DETAIL_NAME"), "\1",
                                  sizeof("\1"));
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: '\\1\\0')");
}

TEST_F(CrasherTest, crash_detail_mixed) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    const char data[] = "helloworld\1\255\3";
    android_register_crash_detail_strs("CRASH_DETAIL_NAME", data);
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'helloworld\\1\\255\\3')");
}

TEST_F(CrasherTest, crash_detail_many) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    for (int i = 0; i < 1000; ++i) {
      std::string name = "CRASH_DETAIL_NAME" + std::to_string(i);
      std::string value = "CRASH_DETAIL_VALUE" + std::to_string(i);
      auto* h = android_register_crash_detail_strs(name.data(), value.data());
      android_unregister_crash_detail(h);
    }

    android_register_crash_detail_strs("FINAL_NAME", "FINAL_VALUE");
    android_register_crash_detail_strs("FINAL_NAME2", "FINAL_VALUE2");
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_NOT_MATCH(result, "CRASH_DETAIL_NAME");
  ASSERT_NOT_MATCH(result, "CRASH_DETAIL_VALUE");
  ASSERT_MATCH(result, R"(FINAL_NAME: 'FINAL_VALUE')");
  ASSERT_MATCH(result, R"(FINAL_NAME2: 'FINAL_VALUE2')");
}

TEST_F(CrasherTest, crash_detail_single_changes) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value_changes);
    g_crash_detail_value_changes[0] = 'C';
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'Crash_detail_value')");
}

TEST_F(CrasherTest, crash_detail_multiple) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
    android_register_crash_detail_strs("CRASH_DETAIL_NAME2", g_crash_detail_value2);
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME2: 'crash_detail_value2')");
}

TEST_F(CrasherTest, crash_detail_remove) {
  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
    auto* detail1 = android_register_crash_detail_strs("CRASH_DETAIL_NAME", g_crash_detail_value);
    android_unregister_crash_detail(detail1);
    android_register_crash_detail_strs("CRASH_DETAIL_NAME2", g_crash_detail_value2);
    abort();
  });
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_NOT_MATCH(result, R"(CRASH_DETAIL_NAME: 'crash_detail_value')");
  ASSERT_MATCH(result, R"(CRASH_DETAIL_NAME2: 'crash_detail_value2')");
}

TEST_F(CrasherTest, abort_message_newline_trimmed) {
  int intercept_result;
  unique_fd output_fd;
+1 −0
Original line number Diff line number Diff line
@@ -397,6 +397,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
    ASSERT_SAME_OFFSET(scudo_ring_buffer_size, scudo_ring_buffer_size);
    ASSERT_SAME_OFFSET(scudo_stack_depot_size, scudo_stack_depot_size);
    ASSERT_SAME_OFFSET(recoverable_gwp_asan_crash, recoverable_gwp_asan_crash);
    ASSERT_SAME_OFFSET(crash_detail_page, crash_detail_page);
#undef ASSERT_SAME_OFFSET

    iovs[3] = {.iov_base = &thread_info->process_info,
+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ struct AllocatorState;
struct AllocationMetadata;
};  // namespace gwp_asan

struct crash_detail_page_t;

// When updating this data structure, CrashInfoDataDynamic and the code in
// ReadCrashInfo() must also be updated.
struct __attribute__((packed)) debugger_process_info {
@@ -46,6 +48,7 @@ struct __attribute__((packed)) debugger_process_info {
  size_t scudo_ring_buffer_size;
  size_t scudo_stack_depot_size;
  bool recoverable_gwp_asan_crash;
  struct crash_detail_page_t* crash_detail_page;
};

// GWP-ASan calbacks to support the recoverable mode. Separate from the
+1 −0
Original line number Diff line number Diff line
@@ -56,4 +56,5 @@ struct ProcessInfo {
  bool has_fault_address = false;
  uintptr_t untagged_fault_address = 0;
  uintptr_t maybe_tagged_fault_address = 0;
  uintptr_t crash_detail_page = 0;
};
Loading