summaryrefslogtreecommitdiffstats
path: root/debuggerd
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2016-04-19 15:53:13 -0700
committerChristopher Ferris <cferris@google.com>2016-04-20 11:30:33 -0700
commit0fc89f34b99f20f0ebc0111df74490f4ebd44076 (patch)
tree237b2b3cec17040b364476b34bc6047dcf41995b /debuggerd
parentded0f36822864506ca950466fb1de37de78ab51b (diff)
downloadsystem_core-0fc89f34b99f20f0ebc0111df74490f4ebd44076.tar.gz
system_core-0fc89f34b99f20f0ebc0111df74490f4ebd44076.tar.bz2
system_core-0fc89f34b99f20f0ebc0111df74490f4ebd44076.zip
Connect to activity manager as root.
Before dropping root privileges, connect to the activity manager. Also, only connect to the activity manager if this is a crash. Bug: 28210681 Change-Id: Ie266031910519fa2aa6835644a95c1fc56e24d8d
Diffstat (limited to 'debuggerd')
-rw-r--r--debuggerd/debuggerd.cpp57
-rw-r--r--debuggerd/tombstone.cpp41
-rw-r--r--debuggerd/tombstone.h2
3 files changed, 55 insertions, 45 deletions
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 12f507a79..7f0e5bb19 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -25,9 +25,11 @@
#include <sys/poll.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/un.h>
#include <time.h>
#include <set>
@@ -36,6 +38,7 @@
#include <log/logger.h>
+#include <android-base/unique_fd.h>
#include <cutils/debugger.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
@@ -248,6 +251,43 @@ static int read_request(int fd, debugger_request_t* out_request) {
return 0;
}
+static int activity_manager_connect() {
+ android::base::unique_fd amfd(socket(PF_UNIX, SOCK_STREAM, 0));
+ if (amfd.get() < -1) {
+ ALOGE("debuggerd: Unable to connect to activity manager (socket failed: %s)", strerror(errno));
+ return -1;
+ }
+
+ struct sockaddr_un address;
+ memset(&address, 0, sizeof(address));
+ address.sun_family = AF_UNIX;
+ // The path used here must match the value defined in NativeCrashListener.java.
+ strncpy(address.sun_path, "/data/system/ndebugsocket", sizeof(address.sun_path));
+ if (TEMP_FAILURE_RETRY(connect(amfd.get(), reinterpret_cast<struct sockaddr*>(&address),
+ sizeof(address))) == -1) {
+ ALOGE("debuggerd: Unable to connect to activity manager (connect failed: %s)", strerror(errno));
+ return -1;
+ }
+
+ struct timeval tv;
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_sec = 1; // tight leash
+ if (setsockopt(amfd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
+ ALOGE("debuggerd: Unable to connect to activity manager (setsockopt SO_SNDTIMEO failed: %s)",
+ strerror(errno));
+ return -1;
+ }
+
+ tv.tv_sec = 3; // 3 seconds on handshake read
+ if (setsockopt(amfd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
+ ALOGE("debuggerd: Unable to connect to activity manager (setsockopt SO_RCVTIMEO failed: %s)",
+ strerror(errno));
+ return -1;
+ }
+
+ return amfd.release();
+}
+
static bool should_attach_gdb(const debugger_request_t& request) {
if (request.action == DEBUGGER_ACTION_CRASH) {
return property_get_bool("debug.debuggerd.wait_for_gdb", false);
@@ -375,7 +415,7 @@ static void ptrace_siblings(pid_t pid, pid_t main_tid, std::set<pid_t>& tids) {
static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd,
BacktraceMap* backtrace_map, const std::set<pid_t>& siblings,
- int* crash_signal) {
+ int* crash_signal, int amfd) {
if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno));
return false;
@@ -393,7 +433,7 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston
if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
ALOGV("debuggerd: stopped -- dumping to tombstone");
engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
- request.original_si_code, request.abort_msg_address);
+ request.original_si_code, request.abort_msg_address, amfd);
} else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
ALOGV("debuggerd: stopped -- dumping to fd");
dump_backtrace(fd, -1, backtrace_map, request.pid, request.tid, siblings);
@@ -420,7 +460,7 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston
ALOGV("stopped -- fatal signal\n");
*crash_signal = signal;
engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
- request.original_si_code, request.abort_msg_address);
+ request.original_si_code, request.abort_msg_address, amfd);
break;
default:
@@ -506,6 +546,12 @@ static void worker_process(int fd, debugger_request_t& request) {
// Generate the backtrace map before dropping privileges.
std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid));
+ int amfd = -1;
+ if (request.action == DEBUGGER_ACTION_CRASH) {
+ // Connect to the activity manager before dropping privileges.
+ amfd = activity_manager_connect();
+ }
+
bool succeeded = false;
// Now that we've done everything that requires privileges, we can drop them.
@@ -515,7 +561,8 @@ static void worker_process(int fd, debugger_request_t& request) {
}
int crash_signal = SIGKILL;
- succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings, &crash_signal);
+ succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings,
+ &crash_signal, amfd);
if (succeeded) {
if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
if (!tombstone_path.empty()) {
@@ -559,6 +606,8 @@ static void worker_process(int fd, debugger_request_t& request) {
uninit_getevent();
}
+ close(amfd);
+
exit(!succeeded);
}
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 7cf2ffc71..d802c8c07 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -28,9 +28,7 @@
#include <string.h>
#include <time.h>
#include <sys/ptrace.h>
-#include <sys/socket.h>
#include <sys/stat.h>
-#include <sys/un.h>
#include <memory>
#include <string>
@@ -59,9 +57,6 @@
#define TOMBSTONE_DIR "/data/tombstones"
#define TOMBSTONE_TEMPLATE (TOMBSTONE_DIR"/tombstone_%02d")
-// Must match the path defined in NativeCrashListener.java
-#define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
-
static bool signal_has_si_addr(int sig) {
switch (sig) {
case SIGBUS:
@@ -711,39 +706,9 @@ int open_tombstone(std::string* out_path) {
return fd;
}
-static int activity_manager_connect() {
- int amfd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (amfd >= 0) {
- struct sockaddr_un address;
- int err;
-
- memset(&address, 0, sizeof(address));
- address.sun_family = AF_UNIX;
- strncpy(address.sun_path, NCRASH_SOCKET_PATH, sizeof(address.sun_path));
- err = TEMP_FAILURE_RETRY(connect(
- amfd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address)));
- if (!err) {
- struct timeval tv;
- memset(&tv, 0, sizeof(tv));
- tv.tv_sec = 1; // tight leash
- err = setsockopt(amfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (!err) {
- tv.tv_sec = 3; // 3 seconds on handshake read
- err = setsockopt(amfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- }
- }
- if (err) {
- close(amfd);
- amfd = -1;
- }
- }
-
- return amfd;
-}
-
void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
const std::set<pid_t>& siblings, int signal, int original_si_code,
- uintptr_t abort_msg_address) {
+ uintptr_t abort_msg_address, int amfd) {
log_t log;
log.current_tid = tid;
log.crashed_tid = tid;
@@ -756,10 +721,6 @@ void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid
log.tfd = tombstone_fd;
// Preserve amfd since it can be modified through the calls below without
// being closed.
- int amfd = activity_manager_connect();
log.amfd = amfd;
dump_crash(&log, map, pid, tid, siblings, signal, original_si_code, abort_msg_address);
-
- // This file descriptor can be -1, any error is ignored.
- close(amfd);
}
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index 2b8b8bed7..7f3eebe0b 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -34,6 +34,6 @@ int open_tombstone(std::string* path);
/* Creates a tombstone file and writes the crash dump to it. */
void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
const std::set<pid_t>& siblings, int signal, int original_si_code,
- uintptr_t abort_msg_address);
+ uintptr_t abort_msg_address, int amfd);
#endif // _DEBUGGERD_TOMBSTONE_H