summaryrefslogtreecommitdiff
path: root/debuggerd/handler/debuggerd_handler.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-02-13 14:46:19 -0800
committerJosh Gao <jmgao@google.com>2017-02-14 21:19:38 -0800
commit2f11a25a48897efe35d065472f921759d5941eba (patch)
tree1574e011b4aaf69b8050c6224edbd76ce73597dc /debuggerd/handler/debuggerd_handler.cpp
parent1d26b40ed5b9a8739425c252603c529d9f8d63fb (diff)
debuggerd_handler: set PR_SET_DUMPABLE before running crash_dump.
Set and restore PR_SET_DUMPABLE when performing a dump, so that processes that have it implicitly cleared (e.g. services that acquire filesystem capabilities) still get crash dumps. Bug: http://b/35174939 Test: debuggerd -b `pidof surfaceflinger` Change-Id: Ife933c10086e546726dec12a7efa3f9cedfeea60
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index cb8f0172f..a5de83a29 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -254,9 +254,11 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
raise_caps();
- char buf[10];
- snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
- execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
+ char main_tid[10];
+ char pseudothread_tid[10];
+ snprintf(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
+ snprintf(pseudothread_tid, sizeof(pseudothread_tid), "%d", thread_info->pseudothread_tid);
+ execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, main_tid, pseudothread_tid, nullptr);
fatal_errno("exec failed");
} else {
@@ -381,6 +383,12 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*)
.info = info
};
+ // Set PR_SET_DUMPABLE to 1, so that crash_dump can ptrace us.
+ int orig_dumpable = prctl(PR_GET_DUMPABLE);
+ if (prctl(PR_SET_DUMPABLE, 1) != 0) {
+ fatal_errno("failed to set dumpable");
+ }
+
// Essentially pthread_create without CLONE_FILES (see debuggerd_dispatch_pseudothread).
pid_t child_pid =
clone(debuggerd_dispatch_pseudothread, pseudothread_stack,
@@ -396,6 +404,11 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*)
// and then wait for it to finish.
__futex_wait(&thread_info.pseudothread_tid, child_pid, nullptr);
+ // Restore PR_SET_DUMPABLE to its original value.
+ if (prctl(PR_SET_DUMPABLE, orig_dumpable) != 0) {
+ fatal_errno("failed to restore dumpable");
+ }
+
// Signals can either be fatal or nonfatal.
// For fatal signals, crash_dump will PTRACE_CONT us with the signal we
// crashed with, so that processes using waitpid on us will see that we