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

Commit fee31585 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "crasher: add pac and bti crashes." into main am: 8f5fab42 am: 095a784d

parents 0dd8b96f 095a784d
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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
@@ -35,3 +36,4 @@ crashnostack:
	ldr r0, [r0]
	b .
	.cfi_endproc
	.size crash_no_stack, .-crash_no_stack
+42 −3
Original line number Diff line number Diff line
@@ -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
@@ -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
+46 −10
Original line number Diff line number Diff line
@@ -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>
@@ -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>
@@ -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);

@@ -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");
@@ -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");
@@ -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-"))) {
@@ -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")) {
@@ -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) {
+4 −2
Original line number Diff line number Diff line
@@ -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
@@ -54,3 +55,4 @@ crashnostack:
	ld t2, 0(zero)
	j .
	.cfi_endproc
	.size crash_no_stack, .-crash_no_stack
+4 −2
Original line number Diff line number Diff line
@@ -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