Loading debuggerd/crasher/crasher.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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"); Loading Loading @@ -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(); } Loading debuggerd/handler/debuggerd_handler.cpp +36 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading
debuggerd/crasher/crasher.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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"); Loading Loading @@ -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(); } Loading
debuggerd/handler/debuggerd_handler.cpp +36 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading