summaryrefslogtreecommitdiffstats
path: root/debuggerd/handler/debuggerd_handler.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-02-06 18:37:54 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-02-06 18:37:55 +0000
commit279cb8b39aeda9e8642a52794e6e67aa84fa2af7 (patch)
treefae2f15b0b9f3ded29a22f2ba52718b5f3285c9e /debuggerd/handler/debuggerd_handler.cpp
parent564aeca94e18cd708f93619551e05b3d59d4abe2 (diff)
parentb3ee52e4d0ee6f52c78d5f12cdc551686b1ebba7 (diff)
downloadsystem_core-279cb8b39aeda9e8642a52794e6e67aa84fa2af7.tar.gz
system_core-279cb8b39aeda9e8642a52794e6e67aa84fa2af7.tar.bz2
system_core-279cb8b39aeda9e8642a52794e6e67aa84fa2af7.zip
Merge changes from topic 'debuggerd_ambient'
* changes: debuggerd_handler: don't use clone(..., SIGCHLD, ...) crash_dump: drop capabilities after we ptrace attach. crash_dump: use /proc/<pid> fd to check tid process membership. debuggerd_handler: raise ambient capset before execing. Revert "Give crash_dump CAP_SYS_PTRACE."
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 9469bbdeb..156534e19 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -39,6 +39,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/capability.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/socket.h>
@@ -207,7 +208,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
}
// Don't use fork(2) to avoid calling pthread_atfork handlers.
- int forkpid = clone(nullptr, nullptr, SIGCHLD, nullptr);
+ int forkpid = clone(nullptr, nullptr, 0, nullptr);
if (forkpid == -1) {
__libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to fork in debuggerd signal handler: %s",
strerror(errno));
@@ -216,6 +217,11 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
close(pipefds[0]);
close(pipefds[1]);
+ // Set all of the ambient capability bits we can, so that crash_dump can ptrace us.
+ for (unsigned long i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0); ++i) {
+ prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0);
+ }
+
char buf[10];
snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
@@ -242,10 +248,12 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
close(pipefds[0]);
// Don't leave a zombie child.
- siginfo_t child_siginfo;
- if (TEMP_FAILURE_RETRY(waitid(P_PID, forkpid, &child_siginfo, WEXITED)) != 0) {
+ int status;
+ if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, __WCLONE)) == -1 && errno != ECHILD) {
__libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
strerror(errno));
+ } else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
+ __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
thread_info->crash_dump_started = false;
}
}