summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao2017-02-08 18:06:26 -0600
committerJosh Gao2017-02-15 19:03:44 -0600
commite73c932373e59e4c0351cc7a8bd8cc5b8910d87e (patch)
treeb8b8a1945ab8caba4b31ad1440a055033276bf00 /debuggerd/handler
parentf6ad5851e689f54c9dee6bfc6668ca726726e818 (diff)
downloadplatform-system-core-e73c932373e59e4c0351cc7a8bd8cc5b8910d87e.tar.gz
platform-system-core-e73c932373e59e4c0351cc7a8bd8cc5b8910d87e.tar.xz
platform-system-core-e73c932373e59e4c0351cc7a8bd8cc5b8910d87e.zip
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')
-rw-r--r--debuggerd/handler/debuggerd_fallback.cpp48
-rw-r--r--debuggerd/handler/debuggerd_fallback_nop.cpp35
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp22
3 files changed, 97 insertions, 8 deletions
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
new file mode 100644
index 000000000..77ad6ac1e
--- /dev/null
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <stddef.h>
30#include <sys/ucontext.h>
31#include <unistd.h>
32
33#include "tombstone.h"
34
35extern "C" void __linker_use_fallback_allocator();
36
37extern "C" bool debuggerd_fallback(ucontext_t* ucontext, siginfo_t* siginfo, void* abort_message) {
38 // This is incredibly sketchy to do inside of a signal handler, especially when libbacktrace
39 // uses the C++ standard library throughout, but this code runs in the linker, so we'll be using
40 // the linker's malloc instead of the libc one. Switch it out for a replacement, just in case.
41 //
42 // This isn't the default method of dumping because it can fail in cases such as memory space
43 // exhaustion.
44 __linker_use_fallback_allocator();
45 engrave_tombstone_ucontext(-1, getpid(), gettid(), reinterpret_cast<uintptr_t>(abort_message),
46 siginfo, ucontext);
47 return true;
48}
diff --git a/debuggerd/handler/debuggerd_fallback_nop.cpp b/debuggerd/handler/debuggerd_fallback_nop.cpp
new file mode 100644
index 000000000..9b3053f3b
--- /dev/null
+++ b/debuggerd/handler/debuggerd_fallback_nop.cpp
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <stddef.h>
30#include <sys/ucontext.h>
31#include <unistd.h>
32
33extern "C" bool debuggerd_fallback(ucontext_t*, siginfo_t*, void*) {
34 return false;
35}
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 @@
62 62
63#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME 63#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
64 64
65extern "C" bool debuggerd_fallback(ucontext_t*, siginfo_t*, void*);
66
65static debuggerd_callbacks_t g_callbacks; 67static debuggerd_callbacks_t g_callbacks;
66 68
67// Mutex to ensure only one crashing thread dumps itself. 69// Mutex to ensure only one crashing thread dumps itself.
@@ -329,7 +331,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) {
329 331
330// Handler that does crash dumping by forking and doing the processing in the child. 332// Handler that does crash dumping by forking and doing the processing in the child.
331// Do this by ptracing the relevant thread, and then execing debuggerd to do the actual dump. 333// Do this by ptracing the relevant thread, and then execing debuggerd to do the actual dump.
332static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) { 334static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* context) {
333 int ret = pthread_mutex_lock(&crash_mutex); 335 int ret = pthread_mutex_lock(&crash_mutex);
334 if (ret != 0) { 336 if (ret != 0) {
335 __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret)); 337 __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*)
359 361
360 log_signal_summary(signal_number, info); 362 log_signal_summary(signal_number, info);
361 363
364 void* abort_message = nullptr;
365 if (g_callbacks.get_abort_message) {
366 abort_message = g_callbacks.get_abort_message();
367 }
368
362 if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) { 369 if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) {
363 // The process has NO_NEW_PRIVS enabled, so we can't transition to the crash_dump context. 370 ucontext_t* ucontext = static_cast<ucontext_t*>(context);
364 __libc_format_log(ANDROID_LOG_INFO, "libc", 371 if (signal_number == DEBUGGER_SIGNAL || !debuggerd_fallback(ucontext, info, abort_message)) {
365 "Suppressing debuggerd output because prctl(PR_GET_NO_NEW_PRIVS)==1"); 372 // The process has NO_NEW_PRIVS enabled, so we can't transition to the crash_dump context.
373 __libc_format_log(ANDROID_LOG_INFO, "libc",
374 "Suppressing debuggerd output because prctl(PR_GET_NO_NEW_PRIVS)==1");
375 }
366 resend_signal(info, false); 376 resend_signal(info, false);
367 return; 377 return;
368 } 378 }
369 379
370 void* abort_message = nullptr;
371 if (g_callbacks.get_abort_message) {
372 abort_message = g_callbacks.get_abort_message();
373 }
374 // Populate si_value with the abort message address, if found. 380 // Populate si_value with the abort message address, if found.
375 if (abort_message) { 381 if (abort_message) {
376 info->si_value.sival_ptr = abort_message; 382 info->si_value.sival_ptr = abort_message;