diff options
author | Josh Gao <jmgao@google.com> | 2016-07-14 16:43:12 -0700 |
---|---|---|
committer | gitbuildkicker <android-build@google.com> | 2016-08-16 15:52:46 -0700 |
commit | d2d95688f81fcce492b46b8e260bdf4f6e0b679b (patch) | |
tree | 62273ca194a87316582c85380f8da15c7bc403f8 /debuggerd/utility.cpp | |
parent | 3b268646f802d72f9b53800ac00540201223cf2e (diff) | |
download | system_core-d2d95688f81fcce492b46b8e260bdf4f6e0b679b.tar.gz system_core-d2d95688f81fcce492b46b8e260bdf4f6e0b679b.tar.bz2 system_core-d2d95688f81fcce492b46b8e260bdf4f6e0b679b.zip |
DO NOT MERGE: debuggerd: verify that traced threads belong to the right process.
Fix two races in debuggerd's PTRACE_ATTACH logic:
1. The target thread in a crash dump request could exit between the
/proc/<pid>/task/<tid> check and the PTRACE_ATTACH.
2. Sibling threads could exit between listing /proc/<pid>/task and the
PTRACE_ATTACH.
Backport of NYC change I4dfe1ea30e2c211d2389321bd66e3684dd757591
Bug: http://b/29555636
Change-Id: I6c6efcf82a49bca140d761b2d1de04215ba4d252
Diffstat (limited to 'debuggerd/utility.cpp')
-rw-r--r-- | debuggerd/utility.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp index 9f340a8ac..236d667a3 100644 --- a/debuggerd/utility.cpp +++ b/debuggerd/utility.cpp @@ -20,6 +20,7 @@ #include <errno.h> #include <signal.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ptrace.h> @@ -207,3 +208,31 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f _LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str()); } } + +bool pid_contains_tid(pid_t pid, pid_t tid) { + char task_path[PATH_MAX]; + if (snprintf(task_path, PATH_MAX, "/proc/%d/task/%d", pid, tid) >= PATH_MAX) { + ALOGE("debuggerd: task path overflow (pid = %d, tid = %d)\n", pid, tid); + exit(1); + } + + return access(task_path, F_OK) == 0; +} + +// Attach to a thread, and verify that it's still a member of the given process +bool ptrace_attach_thread(pid_t pid, pid_t tid) { + if (ptrace(PTRACE_ATTACH, tid, 0, 0) != 0) { + return false; + } + + // Make sure that the task we attached to is actually part of the pid we're dumping. + if (!pid_contains_tid(pid, tid)) { + if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { + ALOGE("debuggerd: failed to detach from thread '%d'", tid); + exit(1); + } + return false; + } + + return true; +} |