From a6fac881b208079c71a9cd55faa798348f06e3ca Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 7 Mar 2022 17:01:17 -0800 Subject: [PATCH] Remove dead non-proto tombstone reporting code. Bug: 197981919 Change-Id: I58a98070198ef0b686229bd54f87b9073df12d66 --- debuggerd/Android.bp | 1 - debuggerd/libdebuggerd/gwp_asan.cpp | 109 ---------- .../include/libdebuggerd/gwp_asan.h | 20 -- .../libdebuggerd/include/libdebuggerd/scudo.h | 4 - debuggerd/libdebuggerd/scudo.cpp | 84 ------- .../libdebuggerd/test/tombstone_test.cpp | 205 ------------------ 6 files changed, 423 deletions(-) delete mode 100644 debuggerd/libdebuggerd/test/tombstone_test.cpp diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp index a541f6e23..e0c138b56 100644 --- a/debuggerd/Android.bp +++ b/debuggerd/Android.bp @@ -282,7 +282,6 @@ cc_test { "libdebuggerd/test/elf_fake.cpp", "libdebuggerd/test/log_fake.cpp", "libdebuggerd/test/open_files_list_test.cpp", - "libdebuggerd/test/tombstone_test.cpp", "libdebuggerd/test/utility_test.cpp", ], diff --git a/debuggerd/libdebuggerd/gwp_asan.cpp b/debuggerd/libdebuggerd/gwp_asan.cpp index ed2b974ea..b2077baf1 100644 --- a/debuggerd/libdebuggerd/gwp_asan.cpp +++ b/debuggerd/libdebuggerd/gwp_asan.cpp @@ -161,112 +161,3 @@ void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinde set_human_readable_cause(cause, crash_address_); } - -void GwpAsanCrashData::DumpCause(log_t* log) const { - if (!CrashIsMine()) { - ALOGE("Internal Error: DumpCause() on a non-GWP-ASan crash."); - return; - } - - if (error_ == gwp_asan::Error::UNKNOWN) { - _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: Unknown error occurred at 0x%" PRIxPTR ".\n", - crash_address_); - return; - } - - if (!responsible_allocation_) { - _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s at 0x%" PRIxPTR ".\n", error_string_, - crash_address_); - return; - } - - uintptr_t alloc_address = __gwp_asan_get_allocation_address(responsible_allocation_); - size_t alloc_size = __gwp_asan_get_allocation_size(responsible_allocation_); - - uintptr_t diff; - const char* location_str; - - if (crash_address_ < alloc_address) { - // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. - location_str = "left of"; - diff = alloc_address - crash_address_; - } else if (crash_address_ - alloc_address < alloc_size) { - // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. - location_str = "into"; - diff = crash_address_ - alloc_address; - } else { - // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef, or - // Invalid Free, 47 bytes right of a 41-byte allocation at 0xdeadbeef. - location_str = "right of"; - diff = crash_address_ - alloc_address; - if (error_ == gwp_asan::Error::BUFFER_OVERFLOW) { - diff -= alloc_size; - } - } - - // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. - const char* byte_suffix = "s"; - if (diff == 1) { - byte_suffix = ""; - } - _LOG(log, logtype::HEADER, - "Cause: [GWP-ASan]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", - error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); -} - -bool GwpAsanCrashData::HasDeallocationTrace() const { - assert(CrashIsMine() && "HasDeallocationTrace(): Crash is not mine!"); - if (!responsible_allocation_ || !__gwp_asan_is_deallocated(responsible_allocation_)) { - return false; - } - return true; -} - -void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { - assert(HasDeallocationTrace() && "DumpDeallocationTrace(): No dealloc trace!"); - uint64_t thread_id = __gwp_asan_get_deallocation_thread_id(responsible_allocation_); - - std::unique_ptr frames(new uintptr_t[kMaxTraceLength]); - size_t num_frames = - __gwp_asan_get_deallocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); - - if (thread_id == gwp_asan::kInvalidThreadID) { - _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread :\n"); - } else { - _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %" PRIu64 ":\n", thread_id); - } - - unwinder->SetDisplayBuildID(true); - for (size_t i = 0; i < num_frames; ++i) { - unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); - frame_data.num = i; - _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); - } -} - -bool GwpAsanCrashData::HasAllocationTrace() const { - assert(CrashIsMine() && "HasAllocationTrace(): Crash is not mine!"); - return responsible_allocation_ != nullptr; -} - -void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { - assert(HasAllocationTrace() && "DumpAllocationTrace(): No dealloc trace!"); - uint64_t thread_id = __gwp_asan_get_allocation_thread_id(responsible_allocation_); - - std::unique_ptr frames(new uintptr_t[kMaxTraceLength]); - size_t num_frames = - __gwp_asan_get_allocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); - - if (thread_id == gwp_asan::kInvalidThreadID) { - _LOG(log, logtype::BACKTRACE, "\nallocated by thread :\n"); - } else { - _LOG(log, logtype::BACKTRACE, "\nallocated by thread %" PRIu64 ":\n", thread_id); - } - - unwinder->SetDisplayBuildID(true); - for (size_t i = 0; i < num_frames; ++i) { - unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); - frame_data.num = i; - _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); - } -} diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h index f9c2481a9..a97937005 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h @@ -52,26 +52,6 @@ class GwpAsanCrashData { // allocator crash state. uintptr_t GetFaultAddress() const; - // Dump the GWP-ASan stringified cause of this crash. May only be called if - // CrashIsMine() returns true. - void DumpCause(log_t* log) const; - - // Returns whether this crash has a deallocation trace. May only be called if - // CrashIsMine() returns true. - bool HasDeallocationTrace() const; - - // Dump the GWP-ASan deallocation trace for this crash. May only be called if - // HasDeallocationTrace() returns true. - void DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; - - // Returns whether this crash has a allocation trace. May only be called if - // CrashIsMine() returns true. - bool HasAllocationTrace() const; - - // Dump the GWP-ASan allocation trace for this crash. May only be called if - // HasAllocationTrace() returns true. - void DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; - void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; protected: diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h b/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h index c3b95d608..172ffe961 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h @@ -34,16 +34,12 @@ class ScudoCrashData { bool CrashIsMine() const; - void DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const; void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; private: scudo_error_info error_info_ = {}; uintptr_t untagged_fault_addr_; - void DumpReport(const scudo_error_report* report, log_t* log, - unwindstack::Unwinder* unwinder) const; - void FillInCause(Cause* cause, const scudo_error_report* report, unwindstack::Unwinder* unwinder) const; }; diff --git a/debuggerd/libdebuggerd/scudo.cpp b/debuggerd/libdebuggerd/scudo.cpp index a2933f2ce..a4836d753 100644 --- a/debuggerd/libdebuggerd/scudo.cpp +++ b/debuggerd/libdebuggerd/scudo.cpp @@ -130,87 +130,3 @@ void ScudoCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* FillInCause(tombstone->add_causes(), &error_info_.reports[report_num++], unwinder); } } - -void ScudoCrashData::DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const { - if (error_info_.reports[1].error_type != UNKNOWN) { - _LOG(log, logtype::HEADER, - "\nNote: multiple potential causes for this crash were detected, listing them in " - "decreasing order of likelihood.\n"); - } - - size_t report_num = 0; - while (report_num < sizeof(error_info_.reports) / sizeof(error_info_.reports[0]) && - error_info_.reports[report_num].error_type != UNKNOWN) { - DumpReport(&error_info_.reports[report_num++], log, unwinder); - } -} - -void ScudoCrashData::DumpReport(const scudo_error_report* report, log_t* log, - unwindstack::Unwinder* unwinder) const { - const char *error_type_str; - switch (report->error_type) { - case USE_AFTER_FREE: - error_type_str = "Use After Free"; - break; - case BUFFER_OVERFLOW: - error_type_str = "Buffer Overflow"; - break; - case BUFFER_UNDERFLOW: - error_type_str = "Buffer Underflow"; - break; - default: - error_type_str = "Unknown"; - break; - } - - uintptr_t diff; - const char* location_str; - - if (untagged_fault_addr_ < report->allocation_address) { - // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. - location_str = "left of"; - diff = report->allocation_address - untagged_fault_addr_; - } else if (untagged_fault_addr_ - report->allocation_address < report->allocation_size) { - // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. - location_str = "into"; - diff = untagged_fault_addr_ - report->allocation_address; - } else { - // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef. - location_str = "right of"; - diff = untagged_fault_addr_ - report->allocation_address - report->allocation_size; - } - - // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. - const char* byte_suffix = "s"; - if (diff == 1) { - byte_suffix = ""; - } - _LOG(log, logtype::HEADER, - "\nCause: [MTE]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", - error_type_str, diff, byte_suffix, location_str, report->allocation_size, - report->allocation_address); - - if (report->allocation_trace[0]) { - _LOG(log, logtype::BACKTRACE, "\nallocated by thread %u:\n", report->allocation_tid); - unwinder->SetDisplayBuildID(true); - for (size_t i = 0; i < arraysize(report->allocation_trace) && report->allocation_trace[i]; - ++i) { - unwindstack::FrameData frame_data = - unwinder->BuildFrameFromPcOnly(report->allocation_trace[i]); - frame_data.num = i; - _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); - } - } - - if (report->deallocation_trace[0]) { - _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %u:\n", report->deallocation_tid); - unwinder->SetDisplayBuildID(true); - for (size_t i = 0; i < arraysize(report->deallocation_trace) && report->deallocation_trace[i]; - ++i) { - unwindstack::FrameData frame_data = - unwinder->BuildFrameFromPcOnly(report->deallocation_trace[i]); - frame_data.num = i; - _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); - } - } -} diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp deleted file mode 100644 index 1cbfb56b6..000000000 --- a/debuggerd/libdebuggerd/test/tombstone_test.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "libdebuggerd/utility.h" - -#include "UnwinderMock.h" -#include "host_signal_fixup.h" -#include "log_fake.h" - -#include "gwp_asan.cpp" - -using ::testing::MatchesRegex; - -class TombstoneTest : public ::testing::Test { - protected: - virtual void SetUp() { - unwinder_mock_.reset(new UnwinderMock()); - - char tmp_file[256]; - const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX"; - memcpy(tmp_file, data_template, sizeof(data_template)); - int tombstone_fd = mkstemp(tmp_file); - if (tombstone_fd == -1) { - const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX"; - memcpy(tmp_file, tmp_template, sizeof(tmp_template)); - tombstone_fd = mkstemp(tmp_file); - if (tombstone_fd == -1) { - abort(); - } - } - if (unlink(tmp_file) == -1) { - abort(); - } - - log_.tfd = tombstone_fd; - amfd_data_.clear(); - log_.amfd_data = &amfd_data_; - log_.crashed_tid = 12; - log_.current_tid = 12; - log_.should_retrieve_logcat = false; - - resetLogs(); - } - - virtual void TearDown() { - if (log_.tfd >= 0) { - close(log_.tfd); - } - } - - std::unique_ptr unwinder_mock_; - - log_t log_; - std::string amfd_data_; -}; - -class GwpAsanCrashDataTest : public GwpAsanCrashData { -public: - GwpAsanCrashDataTest( - gwp_asan::Error error, - const gwp_asan::AllocationMetadata *responsible_allocation) : - GwpAsanCrashData(nullptr, ProcessInfo{}, ThreadInfo{}) { - is_gwp_asan_responsible_ = true; - error_ = error; - responsible_allocation_ = responsible_allocation; - error_string_ = gwp_asan::ErrorToString(error_); - } - - void SetCrashAddress(uintptr_t crash_address) { - crash_address_ = crash_address; - } -}; - -TEST_F(TombstoneTest, gwp_asan_cause_uaf_exact) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::USE_AFTER_FREE, &meta); - crash_data.SetCrashAddress(0x1000); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT(tombstone_contents, MatchesRegex("Cause: \\[GWP-ASan\\]: Use After Free, 0 bytes " - "into a 32-byte allocation at 0x[a-fA-F0-9]+\n")); -} - -TEST_F(TombstoneTest, gwp_asan_cause_double_free) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::DOUBLE_FREE, &meta); - crash_data.SetCrashAddress(0x1000); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT(tombstone_contents, MatchesRegex("Cause: \\[GWP-ASan\\]: Double Free, 0 bytes into a " - "32-byte allocation at 0x[a-fA-F0-9]+\n")); -} - -TEST_F(TombstoneTest, gwp_asan_cause_overflow) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_OVERFLOW, &meta); - crash_data.SetCrashAddress(0x1025); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT( - tombstone_contents, - MatchesRegex( - "Cause: \\[GWP-ASan\\]: Buffer Overflow, 5 bytes right of a 32-byte " - "allocation at 0x[a-fA-F0-9]+\n")); -} - -TEST_F(TombstoneTest, gwp_asan_cause_underflow) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_UNDERFLOW, &meta); - crash_data.SetCrashAddress(0xffe); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT( - tombstone_contents, - MatchesRegex( - "Cause: \\[GWP-ASan\\]: Buffer Underflow, 2 bytes left of a 32-byte " - "allocation at 0x[a-fA-F0-9]+\n")); -} - -TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_inside) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta); - crash_data.SetCrashAddress(0x1001); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT( - tombstone_contents, - MatchesRegex( - "Cause: \\[GWP-ASan\\]: Invalid \\(Wild\\) Free, 1 byte into a 32-byte " - "allocation at 0x[a-fA-F0-9]+\n")); -} - -TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_outside) { - gwp_asan::AllocationMetadata meta; - meta.Addr = 0x1000; - meta.RequestedSize = 32; - - GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta); - crash_data.SetCrashAddress(0x1021); - - crash_data.DumpCause(&log_); - ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); - std::string tombstone_contents; - ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); - ASSERT_THAT( - tombstone_contents, - MatchesRegex( - "Cause: \\[GWP-ASan\\]: Invalid \\(Wild\\) Free, 33 bytes right of a 32-byte " - "allocation at 0x[a-fA-F0-9]+\n")); -}