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

Commit 90947d44 authored by Peter Collingbourne's avatar Peter Collingbourne Committed by Gerrit Code Review
Browse files

Merge "Teach debuggerd to pass the secondary ring buffer to __scudo_get_error_info()."

parents bd83b72b bb4b49c6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -303,6 +303,7 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
      process_info->gwp_asan_metadata = crash_info->data.d.gwp_asan_metadata;
      process_info->scudo_stack_depot = crash_info->data.d.scudo_stack_depot;
      process_info->scudo_region_info = crash_info->data.d.scudo_region_info;
      process_info->scudo_ring_buffer = crash_info->data.d.scudo_ring_buffer;
      FALLTHROUGH_INTENDED;
    case 1:
    case 2:
+21 −14
Original line number Diff line number Diff line
@@ -392,7 +392,11 @@ static void SetTagCheckingLevelSync() {
}
#endif

TEST_F(CrasherTest, mte_uaf) {
struct SizeParamCrasherTest : CrasherTest, testing::WithParamInterface<size_t> {};

INSTANTIATE_TEST_SUITE_P(Sizes, SizeParamCrasherTest, testing::Values(16, 131072));

TEST_P(SizeParamCrasherTest, mte_uaf) {
#if defined(__aarch64__)
  if (!mte_supported()) {
    GTEST_SKIP() << "Requires MTE";
@@ -400,9 +404,9 @@ TEST_F(CrasherTest, mte_uaf) {

  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
  StartProcess([&]() {
    SetTagCheckingLevelSync();
    volatile int* p = (volatile int*)malloc(16);
    volatile int* p = (volatile int*)malloc(GetParam());
    free((void *)p);
    p[0] = 42;
  });
@@ -417,8 +421,9 @@ TEST_F(CrasherTest, mte_uaf) {
  std::string result;
  ConsumeFd(std::move(output_fd), &result);

  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a 16-byte allocation.*
  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a )" +
                           std::to_string(GetParam()) + R"(-byte allocation.*

allocated by thread .*
      #00 pc)");
@@ -429,7 +434,7 @@ allocated by thread .*
#endif
}

TEST_F(CrasherTest, mte_overflow) {
TEST_P(SizeParamCrasherTest, mte_overflow) {
#if defined(__aarch64__)
  if (!mte_supported()) {
    GTEST_SKIP() << "Requires MTE";
@@ -437,10 +442,10 @@ TEST_F(CrasherTest, mte_overflow) {

  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
  StartProcess([&]() {
    SetTagCheckingLevelSync();
    volatile int* p = (volatile int*)malloc(16);
    p[4] = 42;
    volatile char* p = (volatile char*)malloc(GetParam());
    p[GetParam()] = 42;
  });

  StartIntercept(&output_fd);
@@ -454,7 +459,8 @@ TEST_F(CrasherTest, mte_overflow) {
  ConsumeFd(std::move(output_fd), &result);

  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a 16-byte allocation.*
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a )" +
                           std::to_string(GetParam()) + R"(-byte allocation.*

allocated by thread .*
      #00 pc)");
@@ -463,7 +469,7 @@ allocated by thread .*
#endif
}

TEST_F(CrasherTest, mte_underflow) {
TEST_P(SizeParamCrasherTest, mte_underflow) {
#if defined(__aarch64__)
  if (!mte_supported()) {
    GTEST_SKIP() << "Requires MTE";
@@ -471,9 +477,9 @@ TEST_F(CrasherTest, mte_underflow) {

  int intercept_result;
  unique_fd output_fd;
  StartProcess([]() {
  StartProcess([&]() {
    SetTagCheckingLevelSync();
    volatile int* p = (volatile int*)malloc(16);
    volatile int* p = (volatile int*)malloc(GetParam());
    p[-1] = 42;
  });

@@ -488,7 +494,8 @@ TEST_F(CrasherTest, mte_underflow) {
  ConsumeFd(std::move(output_fd), &result);

  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Underflow, 4 bytes left of a 16-byte allocation.*
  ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Underflow, 4 bytes left of a )" +
                           std::to_string(GetParam()) + R"(-byte allocation.*

allocated by thread .*
      #00 pc)");
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ struct debugger_process_info {
  const gwp_asan::AllocationMetadata* gwp_asan_metadata;
  const char* scudo_stack_depot;
  const char* scudo_region_info;
  const char* scudo_ring_buffer;
};

// These callbacks are called in a signal handler, and thus must be async signal safe.
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct ProcessInfo {
  uintptr_t gwp_asan_metadata = 0;
  uintptr_t scudo_stack_depot = 0;
  uintptr_t scudo_region_info = 0;
  uintptr_t scudo_ring_buffer = 0;

  bool has_fault_address = false;
  uintptr_t untagged_fault_address = 0;
+4 −2
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ ScudoCrashData::ScudoCrashData(unwindstack::Memory* process_memory,
                                       __scudo_get_stack_depot_size());
  auto region_info = AllocAndReadFully(process_memory, process_info.scudo_region_info,
                                       __scudo_get_region_info_size());
  auto ring_buffer = AllocAndReadFully(process_memory, process_info.scudo_ring_buffer,
                                       __scudo_get_ring_buffer_size());

  untagged_fault_addr_ = process_info.untagged_fault_address;
  uintptr_t fault_page = untagged_fault_addr_ & ~(PAGE_SIZE - 1);
@@ -68,8 +70,8 @@ ScudoCrashData::ScudoCrashData(unwindstack::Memory* process_memory,
  }

  __scudo_get_error_info(&error_info_, process_info.maybe_tagged_fault_address, stack_depot.get(),
                         region_info.get(), memory.get(), memory_tags.get(), memory_begin,
                         memory_end - memory_begin);
                         region_info.get(), ring_buffer.get(), memory.get(), memory_tags.get(),
                         memory_begin, memory_end - memory_begin);
}

bool ScudoCrashData::CrashIsMine() const {
Loading