diff options
author | Josh Gao <jmgao@google.com> | 2017-02-08 16:06:26 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2017-02-15 17:03:44 -0800 |
commit | e73c932373e59e4c0351cc7a8bd8cc5b8910d87e (patch) | |
tree | b8b8a1945ab8caba4b31ad1440a055033276bf00 /debuggerd/handler/debuggerd_handler.cpp | |
parent | f6ad5851e689f54c9dee6bfc6668ca726726e818 (diff) |
libdebuggerd_handler: in-process crash dumping for seccomped processes.
Do an in-process unwind for processes that have PR_SET_NO_NEW_PRIVS
enabled.
Bug: http://b/34684590
Test: debuggerd_test, killall -ABRT media.codec
Change-Id: I62562ec2c419d6643970100ab1cc0288982a1eed
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r-- | debuggerd/handler/debuggerd_handler.cpp | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index b1dc01aca..680ba4bee 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp @@ -62,6 +62,8 @@ #define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME +extern "C" bool debuggerd_fallback(ucontext_t*, siginfo_t*, void*); + static debuggerd_callbacks_t g_callbacks; // Mutex to ensure only one crashing thread dumps itself. @@ -329,7 +331,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) { // Handler that does crash dumping by forking and doing the processing in the child. // Do this by ptracing the relevant thread, and then execing debuggerd to do the actual dump. -static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) { +static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* context) { int ret = pthread_mutex_lock(&crash_mutex); if (ret != 0) { __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret)); @@ -359,18 +361,22 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) log_signal_summary(signal_number, info); + void* abort_message = nullptr; + if (g_callbacks.get_abort_message) { + abort_message = g_callbacks.get_abort_message(); + } + if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) { - // The process has NO_NEW_PRIVS enabled, so we can't transition to the crash_dump context. - __libc_format_log(ANDROID_LOG_INFO, "libc", - "Suppressing debuggerd output because prctl(PR_GET_NO_NEW_PRIVS)==1"); + ucontext_t* ucontext = static_cast<ucontext_t*>(context); + if (signal_number == DEBUGGER_SIGNAL || !debuggerd_fallback(ucontext, info, abort_message)) { + // The process has NO_NEW_PRIVS enabled, so we can't transition to the crash_dump context. + __libc_format_log(ANDROID_LOG_INFO, "libc", + "Suppressing debuggerd output because prctl(PR_GET_NO_NEW_PRIVS)==1"); + } resend_signal(info, false); return; } - void* abort_message = nullptr; - if (g_callbacks.get_abort_message) { - abort_message = g_callbacks.get_abort_message(); - } // Populate si_value with the abort message address, if found. if (abort_message) { info->si_value.sival_ptr = abort_message; |