diff options
| author | Josh Gao <jmgao@google.com> | 2017-02-06 18:37:54 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-02-06 18:37:55 +0000 |
| commit | f8ef9e1b10e9e69fd6ac0ddbcdc6ee1b5ff3cf02 (patch) | |
| tree | fae2f15b0b9f3ded29a22f2ba52718b5f3285c9e /debuggerd/handler/debuggerd_handler.cpp | |
| parent | 0872ce254a120f7cfc95dd76d09c3dc84f758845 (diff) | |
| parent | 86a881f66cb45db04dbe205690af76a236c2df9c (diff) | |
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.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index 9469bbdeb1..156534e19f 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; } } |
