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

Commit 2e0997bc authored by Josh Gao's avatar Josh Gao Committed by android-build-merger
Browse files

Merge changes I32567010,I400d5991 am: 1d26b40e

am: 1e4efdae

Change-Id: I8f602d5602178cdf2a272d27d9c38be60c128747
parents 9297e0e3 1e4efdae
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>

// We test both kinds of logging.
@@ -189,6 +190,8 @@ static int usage() {
    fprintf(stderr, "  readdir-NULL          pass a null pointer to readdir\n");
    fprintf(stderr, "  strlen-NULL           pass a null pointer to strlen\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  no_new_privs          set PR_SET_NO_NEW_PRIVS and then abort\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "prefix any of the above with 'thread-' to run on a new thread\n");
    fprintf(stderr, "prefix any of the above with 'exhaustfd-' to exhaust\n");
    fprintf(stderr, "all available file descriptors before crashing.\n");
@@ -276,6 +279,12 @@ noinline int do_action(const char* arg) {
    } else if (!strcasecmp(arg, "kuser_cmpxchg64")) {
        return __kuser_cmpxchg64(0, 0, 0);
#endif
    } else if (!strcasecmp(arg, "no_new_privs")) {
        if (prctl(PR_SET_NO_NEW_PRIVS, 1) != 0) {
          fprintf(stderr, "prctl(PR_SET_NO_NEW_PRIVS, 1) failed: %s\n", strerror(errno));
          return EXIT_SUCCESS;
        }
        abort();
    } else {
        return usage();
    }
+36 −4
Original line number Diff line number Diff line
@@ -174,6 +174,41 @@ static bool have_siginfo(int signum) {
  return (old_action.sa_flags & SA_SIGINFO) != 0;
}

static void raise_caps() {
  // Raise CapInh to match CapPrm, so that we can set the ambient bits.
  __user_cap_header_struct capheader;
  memset(&capheader, 0, sizeof(capheader));
  capheader.version = _LINUX_CAPABILITY_VERSION_3;
  capheader.pid = 0;

  __user_cap_data_struct capdata[2];
  if (capget(&capheader, &capdata[0]) == -1) {
    fatal_errno("capget failed");
  }

  if (capdata[0].permitted != capdata[0].inheritable ||
      capdata[1].permitted != capdata[1].inheritable) {
    capdata[0].inheritable = capdata[0].permitted;
    capdata[1].inheritable = capdata[1].permitted;

    if (capset(&capheader, &capdata[0]) == -1) {
      __libc_format_log(ANDROID_LOG_ERROR, "libc", "capset failed: %s", strerror(errno));
    }
  }

  // Set the ambient capability bits so that crash_dump gets all of our caps and can ptrace us.
  uint64_t capmask = capdata[0].inheritable;
  capmask |= static_cast<uint64_t>(capdata[1].inheritable) << 32;
  for (unsigned long i = 0; i < 64; ++i) {
    if (capmask & (1 << i)) {
      if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) != 0) {
        __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to raise ambient capability %lu: %s",
                          i, strerror(errno));
      }
    }
  }
}

struct debugger_thread_info {
  bool crash_dump_started;
  pid_t crashing_tid;
@@ -217,10 +252,7 @@ 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) != -1; ++i) {
      prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0);
    }
    raise_caps();

    char buf[10];
    snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);