From 57f58f8e4a143f1208593c8b397b9a17d055dad0 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 15 Mar 2017 23:23:22 -0700 Subject: crash_dump: fetch process/thread names before dropping privileges. Processes that don't have dumpable set to 1 cannot have their process/thread names read by processes that don't have all of their capabilities. Fetch these names in crash_dump before dropping privileges. Bug: http://b/36237221 Test: debuggerd_test Test: debuggerd -b `pidof android.hardware.bluetooth@1.0-service` Change-Id: I174769e7b3c1ea9f11f9c8cbdff83028a4225783 --- debuggerd/crash_dump.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'debuggerd/crash_dump.cpp') diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp index 38b711ff4..88f390b0e 100644 --- a/debuggerd/crash_dump.cpp +++ b/debuggerd/crash_dump.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +54,21 @@ #include "debuggerd/util.h" using android::base::unique_fd; +using android::base::ReadFileToString; using android::base::StringPrintf; +using android::base::Trim; + +static std::string get_process_name(pid_t pid) { + std::string result = ""; + ReadFileToString(StringPrintf("/proc/%d/cmdline", pid), &result); + return result; +} + +static std::string get_thread_name(pid_t tid) { + std::string result = ""; + ReadFileToString(StringPrintf("/proc/%d/comm", tid), &result); + return Trim(result); +} static bool pid_contains_tid(int pid_proc_fd, pid_t tid) { struct stat st; @@ -253,7 +269,7 @@ int main(int argc, char** argv) { } // Seize the siblings. - std::set attached_siblings; + std::map threads; { std::set siblings; if (!android::procinfo::GetProcessTids(target, &siblings)) { @@ -269,12 +285,12 @@ int main(int argc, char** argv) { if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) { LOG(WARNING) << attach_error; } else { - attached_siblings.insert(sibling_tid); + threads.emplace(sibling_tid, get_thread_name(sibling_tid)); } } } - // Collect the backtrace map and open files, while the process still has PR_GET_DUMPABLE=1 + // Collect the backtrace map, open files, and process/thread names, while we still have caps. std::unique_ptr backtrace_map(BacktraceMap::Create(main_tid)); if (!backtrace_map) { LOG(FATAL) << "failed to create backtrace map"; @@ -284,6 +300,9 @@ int main(int argc, char** argv) { OpenFilesList open_files; populate_open_files_list(target, &open_files); + std::string process_name = get_process_name(main_tid); + threads.emplace(main_tid, get_thread_name(main_tid)); + // Drop our capabilities now that we've attached to the threads we care about. drop_capabilities(); @@ -341,10 +360,10 @@ int main(int argc, char** argv) { std::string amfd_data; if (backtrace) { - dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0); + dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0); } else { engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid, - &attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr); + process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr); } // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in -- cgit v1.2.3