Merge "Teach debuggerd to pass the secondary ring buffer to __scudo_get_error_info()." am: 90947d442c
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1588011 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I95f2381d16ab44434b1ac24484503c90bf23e4d6
This commit is contained in:
commit
1349a16b9d
6 changed files with 29 additions and 16 deletions
|
|
@ -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->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_stack_depot = crash_info->data.d.scudo_stack_depot;
|
||||||
process_info->scudo_region_info = crash_info->data.d.scudo_region_info;
|
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;
|
FALLTHROUGH_INTENDED;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,11 @@ static void SetTagCheckingLevelSync() {
|
||||||
}
|
}
|
||||||
#endif
|
#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 defined(__aarch64__)
|
||||||
if (!mte_supported()) {
|
if (!mte_supported()) {
|
||||||
GTEST_SKIP() << "Requires MTE";
|
GTEST_SKIP() << "Requires MTE";
|
||||||
|
|
@ -400,9 +404,9 @@ TEST_F(CrasherTest, mte_uaf) {
|
||||||
|
|
||||||
int intercept_result;
|
int intercept_result;
|
||||||
unique_fd output_fd;
|
unique_fd output_fd;
|
||||||
StartProcess([]() {
|
StartProcess([&]() {
|
||||||
SetTagCheckingLevelSync();
|
SetTagCheckingLevelSync();
|
||||||
volatile int* p = (volatile int*)malloc(16);
|
volatile int* p = (volatile int*)malloc(GetParam());
|
||||||
free((void *)p);
|
free((void *)p);
|
||||||
p[0] = 42;
|
p[0] = 42;
|
||||||
});
|
});
|
||||||
|
|
@ -417,8 +421,9 @@ TEST_F(CrasherTest, mte_uaf) {
|
||||||
std::string result;
|
std::string result;
|
||||||
ConsumeFd(std::move(output_fd), &result);
|
ConsumeFd(std::move(output_fd), &result);
|
||||||
|
|
||||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
|
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
|
||||||
ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a 16-byte allocation.*
|
ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a )" +
|
||||||
|
std::to_string(GetParam()) + R"(-byte allocation.*
|
||||||
|
|
||||||
allocated by thread .*
|
allocated by thread .*
|
||||||
#00 pc)");
|
#00 pc)");
|
||||||
|
|
@ -429,7 +434,7 @@ allocated by thread .*
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CrasherTest, mte_overflow) {
|
TEST_P(SizeParamCrasherTest, mte_overflow) {
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
if (!mte_supported()) {
|
if (!mte_supported()) {
|
||||||
GTEST_SKIP() << "Requires MTE";
|
GTEST_SKIP() << "Requires MTE";
|
||||||
|
|
@ -437,10 +442,10 @@ TEST_F(CrasherTest, mte_overflow) {
|
||||||
|
|
||||||
int intercept_result;
|
int intercept_result;
|
||||||
unique_fd output_fd;
|
unique_fd output_fd;
|
||||||
StartProcess([]() {
|
StartProcess([&]() {
|
||||||
SetTagCheckingLevelSync();
|
SetTagCheckingLevelSync();
|
||||||
volatile int* p = (volatile int*)malloc(16);
|
volatile char* p = (volatile char*)malloc(GetParam());
|
||||||
p[4] = 42;
|
p[GetParam()] = 42;
|
||||||
});
|
});
|
||||||
|
|
||||||
StartIntercept(&output_fd);
|
StartIntercept(&output_fd);
|
||||||
|
|
@ -454,7 +459,8 @@ TEST_F(CrasherTest, mte_overflow) {
|
||||||
ConsumeFd(std::move(output_fd), &result);
|
ConsumeFd(std::move(output_fd), &result);
|
||||||
|
|
||||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
|
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 .*
|
allocated by thread .*
|
||||||
#00 pc)");
|
#00 pc)");
|
||||||
|
|
@ -463,7 +469,7 @@ allocated by thread .*
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CrasherTest, mte_underflow) {
|
TEST_P(SizeParamCrasherTest, mte_underflow) {
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
if (!mte_supported()) {
|
if (!mte_supported()) {
|
||||||
GTEST_SKIP() << "Requires MTE";
|
GTEST_SKIP() << "Requires MTE";
|
||||||
|
|
@ -471,9 +477,9 @@ TEST_F(CrasherTest, mte_underflow) {
|
||||||
|
|
||||||
int intercept_result;
|
int intercept_result;
|
||||||
unique_fd output_fd;
|
unique_fd output_fd;
|
||||||
StartProcess([]() {
|
StartProcess([&]() {
|
||||||
SetTagCheckingLevelSync();
|
SetTagCheckingLevelSync();
|
||||||
volatile int* p = (volatile int*)malloc(16);
|
volatile int* p = (volatile int*)malloc(GetParam());
|
||||||
p[-1] = 42;
|
p[-1] = 42;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -488,7 +494,8 @@ TEST_F(CrasherTest, mte_underflow) {
|
||||||
ConsumeFd(std::move(output_fd), &result);
|
ConsumeFd(std::move(output_fd), &result);
|
||||||
|
|
||||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
|
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 .*
|
allocated by thread .*
|
||||||
#00 pc)");
|
#00 pc)");
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ struct debugger_process_info {
|
||||||
const gwp_asan::AllocationMetadata* gwp_asan_metadata;
|
const gwp_asan::AllocationMetadata* gwp_asan_metadata;
|
||||||
const char* scudo_stack_depot;
|
const char* scudo_stack_depot;
|
||||||
const char* scudo_region_info;
|
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.
|
// These callbacks are called in a signal handler, and thus must be async signal safe.
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ struct ProcessInfo {
|
||||||
uintptr_t gwp_asan_metadata = 0;
|
uintptr_t gwp_asan_metadata = 0;
|
||||||
uintptr_t scudo_stack_depot = 0;
|
uintptr_t scudo_stack_depot = 0;
|
||||||
uintptr_t scudo_region_info = 0;
|
uintptr_t scudo_region_info = 0;
|
||||||
|
uintptr_t scudo_ring_buffer = 0;
|
||||||
|
|
||||||
bool has_fault_address = false;
|
bool has_fault_address = false;
|
||||||
uintptr_t untagged_fault_address = 0;
|
uintptr_t untagged_fault_address = 0;
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ ScudoCrashData::ScudoCrashData(unwindstack::Memory* process_memory,
|
||||||
__scudo_get_stack_depot_size());
|
__scudo_get_stack_depot_size());
|
||||||
auto region_info = AllocAndReadFully(process_memory, process_info.scudo_region_info,
|
auto region_info = AllocAndReadFully(process_memory, process_info.scudo_region_info,
|
||||||
__scudo_get_region_info_size());
|
__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;
|
untagged_fault_addr_ = process_info.untagged_fault_address;
|
||||||
uintptr_t fault_page = untagged_fault_addr_ & ~(PAGE_SIZE - 1);
|
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(),
|
__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,
|
region_info.get(), ring_buffer.get(), memory.get(), memory_tags.get(),
|
||||||
memory_end - memory_begin);
|
memory_begin, memory_end - memory_begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScudoCrashData::CrashIsMine() const {
|
bool ScudoCrashData::CrashIsMine() const {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ struct __attribute__((__packed__)) CrashInfoDataDynamic : public CrashInfoDataSt
|
||||||
uintptr_t gwp_asan_metadata;
|
uintptr_t gwp_asan_metadata;
|
||||||
uintptr_t scudo_stack_depot;
|
uintptr_t scudo_stack_depot;
|
||||||
uintptr_t scudo_region_info;
|
uintptr_t scudo_region_info;
|
||||||
|
uintptr_t scudo_ring_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((__packed__)) CrashInfo {
|
struct __attribute__((__packed__)) CrashInfo {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue