Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d61bfb9a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Connect to activity manager as root."

parents 0652728e 8fb38ae8
Loading
Loading
Loading
Loading
+52 −4
Original line number Diff line number Diff line
@@ -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>
@@ -248,6 +250,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 +414,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 +432,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);
@@ -419,7 +458,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:
@@ -505,6 +544,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.
@@ -514,7 +559,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()) {
@@ -558,6 +604,8 @@ static void worker_process(int fd, debugger_request_t& request) {
    uninit_getevent();
  }

  close(amfd);

  exit(!succeeded);
}

+1 −40
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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