Loading debuggerd/crasher/arm/crashglue.S +5 −3 Original line number Diff line number Diff line Loading @@ -23,10 +23,11 @@ crash1: ldr lr, [lr] b . .cfi_endproc .size crash1, .-crash1 .globl crashnostack .type crashnostack, %function crashnostack: .globl crash_no_stack .type crash_no_stack, %function crash_no_stack: .cfi_startproc mov r1, sp .cfi_def_cfa_register r1 Loading @@ -35,3 +36,4 @@ crashnostack: ldr r0, [r0] b . .cfi_endproc .size crash_no_stack, .-crash_no_stack debuggerd/crasher/arm64/crashglue.S +42 −3 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ crash1: ldr x30, [x30] b . .cfi_endproc .size crash1, .-crash1 .globl crashnostack .type crashnostack, %function crashnostack: .globl crash_no_stack .type crash_no_stack, %function crash_no_stack: .cfi_startproc mov x1, sp .cfi_def_cfa_register x1 Loading @@ -54,3 +55,41 @@ crashnostack: ldr x0, [x0] b . .cfi_endproc .size crash_no_stack, .-crash_no_stack .globl crash_bti .type crash_bti, %function crash_bti: .cfi_startproc adr x16, 1f br x16 1: // Deliberatly not a bti instruction so we crash here. b . .cfi_endproc .size crash_bti, .-crash_bti .globl crash_pac .type crash_pac, %function crash_pac: .cfi_startproc paciasp // Since sp is a pac input, this ensures a mismatch. sub sp, sp, #16 autiasp b . .cfi_endproc .size crash_pac, .-crash_pac // Set the PAC and BTI bits for this object file. .section .note.gnu.property, "a" .balign 8 .long 4 .long 0x10 .long 0x5 .asciz "GNU" .long 0xc0000000 .long 4 .long 0x3 .long 0 debuggerd/crasher/crasher.cpp +46 −10 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <assert.h> #include <dirent.h> #include <errno.h> #include <error.h> #include <fcntl.h> #include <pthread.h> #include <signal.h> Loading @@ -29,6 +30,9 @@ #include <sys/prctl.h> #include <unistd.h> #include <android-base/file.h> #include <android-base/strings.h> // We test both kinds of logging. #include <android-base/logging.h> #include <log/log.h> Loading Loading @@ -59,8 +63,10 @@ typedef int (__kuser_cmpxchg64_t)(const int64_t*, const int64_t*, volatile int64 // Avoid name mangling so that stacks are more readable. extern "C" { void crash1(void); void crashnostack(void); void crash1(); void crash_no_stack(); void crash_bti(); void crash_pac(); int do_action(const char* arg); Loading Loading @@ -196,13 +202,6 @@ static int usage() { fprintf(stderr, " fdsan_file close a file descriptor that's owned by a FILE*\n"); fprintf(stderr, " fdsan_dir close a file descriptor that's owned by a DIR*\n"); fprintf(stderr, " seccomp fail a seccomp check\n"); #if defined(__arm__) fprintf(stderr, " kuser_helper_version call kuser_helper_version\n"); fprintf(stderr, " kuser_get_tls call kuser_get_tls\n"); fprintf(stderr, " kuser_cmpxchg call kuser_cmpxchg\n"); fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n"); fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n"); #endif fprintf(stderr, " xom read execute-only memory\n"); fprintf(stderr, "\n"); fprintf(stderr, " LOG_ALWAYS_FATAL call liblog LOG_ALWAYS_FATAL\n"); Loading @@ -223,6 +222,20 @@ static int usage() { fprintf(stderr, "\n"); fprintf(stderr, " no_new_privs set PR_SET_NO_NEW_PRIVS and then abort\n"); fprintf(stderr, "\n"); #if defined(__arm__) fprintf(stderr, "Also, since this is an arm32 binary:\n"); fprintf(stderr, " kuser_helper_version call kuser_helper_version\n"); fprintf(stderr, " kuser_get_tls call kuser_get_tls\n"); fprintf(stderr, " kuser_cmpxchg call kuser_cmpxchg\n"); fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n"); fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n"); #endif #if defined(__aarch64__) fprintf(stderr, "Also, since this is an arm64 binary:\n"); fprintf(stderr, " bti fail a branch target identification (BTI) check\n"); fprintf(stderr, " pac fail a pointer authentication (PAC) check\n"); #endif 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 @@ -231,6 +244,21 @@ static int usage() { return EXIT_FAILURE; } [[maybe_unused]] static void CheckCpuFeature(const std::string& name) { std::string cpuinfo; if (!android::base::ReadFileToString("/proc/cpuinfo", &cpuinfo)) { error(1, errno, "couldn't read /proc/cpuinfo"); } std::vector<std::string> lines = android::base::Split(cpuinfo, "\n"); for (std::string_view line : lines) { if (!android::base::ConsumePrefix(&line, "Features\t:")) continue; std::vector<std::string> features = android::base::Split(std::string(line), " "); if (std::find(features.begin(), features.end(), name) == features.end()) { error(1, 0, "/proc/cpuinfo does not report feature '%s'", name.c_str()); } } } noinline int do_action(const char* arg) { // Prefixes. if (!strncmp(arg, "wait-", strlen("wait-"))) { Loading @@ -256,7 +284,7 @@ noinline int do_action(const char* arg) { } else if (!strcasecmp(arg, "stack-overflow")) { overflow_stack(nullptr); } else if (!strcasecmp(arg, "nostack")) { crashnostack(); crash_no_stack(); } else if (!strcasecmp(arg, "exit")) { exit(1); } else if (!strcasecmp(arg, "call-null")) { Loading Loading @@ -349,6 +377,14 @@ noinline int do_action(const char* arg) { __kuser_dmb(); } else if (!strcasecmp(arg, "kuser_cmpxchg64")) { return __kuser_cmpxchg64(0, 0, 0); #endif #if defined(__aarch64__) } else if (!strcasecmp(arg, "bti")) { CheckCpuFeature("bti"); crash_bti(); } else if (!strcasecmp(arg, "pac")) { CheckCpuFeature("paca"); crash_pac(); #endif } else if (!strcasecmp(arg, "no_new_privs")) { if (prctl(PR_SET_NO_NEW_PRIVS, 1) != 0) { Loading debuggerd/crasher/riscv64/crashglue.S +4 −2 Original line number Diff line number Diff line Loading @@ -43,10 +43,11 @@ crash1: ld t2, 0(zero) j . .cfi_endproc .size crash1, .-crash1 .globl crashnostack crashnostack: .globl crash_no_stack crash_no_stack: .cfi_startproc mv t1, sp .cfi_def_cfa_register t1 Loading @@ -54,3 +55,4 @@ crashnostack: ld t2, 0(zero) j . .cfi_endproc .size crash_no_stack, .-crash_no_stack debuggerd/crasher/x86/crashglue.S +4 −2 Original line number Diff line number Diff line Loading @@ -6,13 +6,15 @@ crash1: movl $0, %edx jmp *%edx .size crash1, .-crash1 .globl crashnostack crashnostack: .globl crash_no_stack crash_no_stack: .cfi_startproc movl %esp, %eax .cfi_def_cfa_register %eax movl $0, %esp movl (%esp), %ebx .cfi_endproc .size crash_no_stack, .-crash_no_stack Loading
debuggerd/crasher/arm/crashglue.S +5 −3 Original line number Diff line number Diff line Loading @@ -23,10 +23,11 @@ crash1: ldr lr, [lr] b . .cfi_endproc .size crash1, .-crash1 .globl crashnostack .type crashnostack, %function crashnostack: .globl crash_no_stack .type crash_no_stack, %function crash_no_stack: .cfi_startproc mov r1, sp .cfi_def_cfa_register r1 Loading @@ -35,3 +36,4 @@ crashnostack: ldr r0, [r0] b . .cfi_endproc .size crash_no_stack, .-crash_no_stack
debuggerd/crasher/arm64/crashglue.S +42 −3 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ crash1: ldr x30, [x30] b . .cfi_endproc .size crash1, .-crash1 .globl crashnostack .type crashnostack, %function crashnostack: .globl crash_no_stack .type crash_no_stack, %function crash_no_stack: .cfi_startproc mov x1, sp .cfi_def_cfa_register x1 Loading @@ -54,3 +55,41 @@ crashnostack: ldr x0, [x0] b . .cfi_endproc .size crash_no_stack, .-crash_no_stack .globl crash_bti .type crash_bti, %function crash_bti: .cfi_startproc adr x16, 1f br x16 1: // Deliberatly not a bti instruction so we crash here. b . .cfi_endproc .size crash_bti, .-crash_bti .globl crash_pac .type crash_pac, %function crash_pac: .cfi_startproc paciasp // Since sp is a pac input, this ensures a mismatch. sub sp, sp, #16 autiasp b . .cfi_endproc .size crash_pac, .-crash_pac // Set the PAC and BTI bits for this object file. .section .note.gnu.property, "a" .balign 8 .long 4 .long 0x10 .long 0x5 .asciz "GNU" .long 0xc0000000 .long 4 .long 0x3 .long 0
debuggerd/crasher/crasher.cpp +46 −10 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <assert.h> #include <dirent.h> #include <errno.h> #include <error.h> #include <fcntl.h> #include <pthread.h> #include <signal.h> Loading @@ -29,6 +30,9 @@ #include <sys/prctl.h> #include <unistd.h> #include <android-base/file.h> #include <android-base/strings.h> // We test both kinds of logging. #include <android-base/logging.h> #include <log/log.h> Loading Loading @@ -59,8 +63,10 @@ typedef int (__kuser_cmpxchg64_t)(const int64_t*, const int64_t*, volatile int64 // Avoid name mangling so that stacks are more readable. extern "C" { void crash1(void); void crashnostack(void); void crash1(); void crash_no_stack(); void crash_bti(); void crash_pac(); int do_action(const char* arg); Loading Loading @@ -196,13 +202,6 @@ static int usage() { fprintf(stderr, " fdsan_file close a file descriptor that's owned by a FILE*\n"); fprintf(stderr, " fdsan_dir close a file descriptor that's owned by a DIR*\n"); fprintf(stderr, " seccomp fail a seccomp check\n"); #if defined(__arm__) fprintf(stderr, " kuser_helper_version call kuser_helper_version\n"); fprintf(stderr, " kuser_get_tls call kuser_get_tls\n"); fprintf(stderr, " kuser_cmpxchg call kuser_cmpxchg\n"); fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n"); fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n"); #endif fprintf(stderr, " xom read execute-only memory\n"); fprintf(stderr, "\n"); fprintf(stderr, " LOG_ALWAYS_FATAL call liblog LOG_ALWAYS_FATAL\n"); Loading @@ -223,6 +222,20 @@ static int usage() { fprintf(stderr, "\n"); fprintf(stderr, " no_new_privs set PR_SET_NO_NEW_PRIVS and then abort\n"); fprintf(stderr, "\n"); #if defined(__arm__) fprintf(stderr, "Also, since this is an arm32 binary:\n"); fprintf(stderr, " kuser_helper_version call kuser_helper_version\n"); fprintf(stderr, " kuser_get_tls call kuser_get_tls\n"); fprintf(stderr, " kuser_cmpxchg call kuser_cmpxchg\n"); fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n"); fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n"); #endif #if defined(__aarch64__) fprintf(stderr, "Also, since this is an arm64 binary:\n"); fprintf(stderr, " bti fail a branch target identification (BTI) check\n"); fprintf(stderr, " pac fail a pointer authentication (PAC) check\n"); #endif 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 @@ -231,6 +244,21 @@ static int usage() { return EXIT_FAILURE; } [[maybe_unused]] static void CheckCpuFeature(const std::string& name) { std::string cpuinfo; if (!android::base::ReadFileToString("/proc/cpuinfo", &cpuinfo)) { error(1, errno, "couldn't read /proc/cpuinfo"); } std::vector<std::string> lines = android::base::Split(cpuinfo, "\n"); for (std::string_view line : lines) { if (!android::base::ConsumePrefix(&line, "Features\t:")) continue; std::vector<std::string> features = android::base::Split(std::string(line), " "); if (std::find(features.begin(), features.end(), name) == features.end()) { error(1, 0, "/proc/cpuinfo does not report feature '%s'", name.c_str()); } } } noinline int do_action(const char* arg) { // Prefixes. if (!strncmp(arg, "wait-", strlen("wait-"))) { Loading @@ -256,7 +284,7 @@ noinline int do_action(const char* arg) { } else if (!strcasecmp(arg, "stack-overflow")) { overflow_stack(nullptr); } else if (!strcasecmp(arg, "nostack")) { crashnostack(); crash_no_stack(); } else if (!strcasecmp(arg, "exit")) { exit(1); } else if (!strcasecmp(arg, "call-null")) { Loading Loading @@ -349,6 +377,14 @@ noinline int do_action(const char* arg) { __kuser_dmb(); } else if (!strcasecmp(arg, "kuser_cmpxchg64")) { return __kuser_cmpxchg64(0, 0, 0); #endif #if defined(__aarch64__) } else if (!strcasecmp(arg, "bti")) { CheckCpuFeature("bti"); crash_bti(); } else if (!strcasecmp(arg, "pac")) { CheckCpuFeature("paca"); crash_pac(); #endif } else if (!strcasecmp(arg, "no_new_privs")) { if (prctl(PR_SET_NO_NEW_PRIVS, 1) != 0) { Loading
debuggerd/crasher/riscv64/crashglue.S +4 −2 Original line number Diff line number Diff line Loading @@ -43,10 +43,11 @@ crash1: ld t2, 0(zero) j . .cfi_endproc .size crash1, .-crash1 .globl crashnostack crashnostack: .globl crash_no_stack crash_no_stack: .cfi_startproc mv t1, sp .cfi_def_cfa_register t1 Loading @@ -54,3 +55,4 @@ crashnostack: ld t2, 0(zero) j . .cfi_endproc .size crash_no_stack, .-crash_no_stack
debuggerd/crasher/x86/crashglue.S +4 −2 Original line number Diff line number Diff line Loading @@ -6,13 +6,15 @@ crash1: movl $0, %edx jmp *%edx .size crash1, .-crash1 .globl crashnostack crashnostack: .globl crash_no_stack crash_no_stack: .cfi_startproc movl %esp, %eax .cfi_def_cfa_register %eax movl $0, %esp movl (%esp), %ebx .cfi_endproc .size crash_no_stack, .-crash_no_stack