From 34221df2f831d9ace6c97ee1c8fe344366cbd685 Mon Sep 17 00:00:00 2001 From: Ayrton Munoz Date: Mon, 25 Mar 2024 20:43:02 -0400 Subject: [PATCH] runtime/libia2: enable MTE --- runtime/libia2/ia2.c | 11 ++++++++--- .../libia2/include/ia2_compartment_init.inc | 4 ++-- runtime/libia2/include/ia2_internal.h | 4 ++-- runtime/libia2/init.c | 18 ++++++++++++++++-- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/runtime/libia2/ia2.c b/runtime/libia2/ia2.c index 45e932815..246811b79 100644 --- a/runtime/libia2/ia2.c +++ b/runtime/libia2/ia2.c @@ -127,6 +127,7 @@ int ia2_mprotect_with_tag(void *addr, size_t len, int prot, int tag) { int res = mprotect(addr, len, prot | PROT_MTE); if (res != 0) { /* Skip memory tagging if mprotect returned an error */ + printf("mprotect failed with %d\n", res); return res; } /* Protect each page */ @@ -236,9 +237,13 @@ static bool in_extra_libraries(struct dl_phdr_info *info, const char *extra_libr /// Map ELF segment flags to mprotect access flags static int segment_flags_to_access_flags(Elf64_Word flags) { - return ((flags & PF_X) != 0 ? PROT_EXEC : 0) | - ((flags & PF_W) != 0 ? PROT_WRITE : 0) | - ((flags & PF_R) != 0 ? PROT_READ : 0); + return +#if defined(__aarch64__) + PROT_MTE | +#endif + ((flags & PF_X) != 0 ? PROT_EXEC : 0) | + ((flags & PF_W) != 0 ? PROT_WRITE : 0) | + ((flags & PF_R) != 0 ? PROT_READ : 0); } int protect_tls_pages(struct dl_phdr_info *info, size_t size, void *data) { diff --git a/runtime/libia2/include/ia2_compartment_init.inc b/runtime/libia2/include/ia2_compartment_init.inc index 964623516..eb86a1cd9 100644 --- a/runtime/libia2/include/ia2_compartment_init.inc +++ b/runtime/libia2/include/ia2_compartment_init.inc @@ -44,9 +44,9 @@ extern int ia2_n_pkeys_to_alloc; extern char __start_ia2_shared_data __attribute__((visibility("hidden"))), __stop_ia2_shared_data __attribute__((visibility("hidden"))); -void ensure_pkeys_allocated(int *n_to_alloc); +void ia2_set_up_tags(int *n_to_alloc); __attribute__((constructor)) static void COMPARTMENT_IDENT(init_pkey)() { - ensure_pkeys_allocated(&ia2_n_pkeys_to_alloc); + ia2_set_up_tags(&ia2_n_pkeys_to_alloc); struct IA2SharedSection shared_sections[2] = {{ &__start_ia2_shared_data, &__stop_ia2_shared_data, diff --git a/runtime/libia2/include/ia2_internal.h b/runtime/libia2/include/ia2_internal.h index 03a6336c5..50673fb53 100644 --- a/runtime/libia2/include/ia2_internal.h +++ b/runtime/libia2/include/ia2_internal.h @@ -339,7 +339,7 @@ static int ia2_mprotect_with_tag(void *addr, size_t len, int prot, int tag) { #endif char *allocate_stack(int i); void verify_tls_padding(void); -void ensure_pkeys_allocated(int *n_to_alloc); +void ia2_set_up_tags(int *n_to_alloc); __attribute__((__noreturn__)) void ia2_reinit_stack_err(int i); /* clang-format can't handle inline asm in macros */ @@ -435,7 +435,7 @@ __attribute__((__noreturn__)) void ia2_reinit_stack_err(int i); \ __attribute__((constructor)) static void ia2_init(void) { \ /* Set up global resources. */ \ - ensure_pkeys_allocated(&ia2_n_pkeys_to_alloc); \ + ia2_set_up_tags(&ia2_n_pkeys_to_alloc); \ /* Initialize stacks for the main thread/ */ \ init_stacks_and_setup_tls(); \ REPEATB##n(setup_destructors_for_compartment, nop_macro); \ diff --git a/runtime/libia2/init.c b/runtime/libia2/init.c index 62bf5c894..cd663952f 100644 --- a/runtime/libia2/init.c +++ b/runtime/libia2/init.c @@ -1,4 +1,6 @@ #include "ia2_internal.h" +#include +#include /* The 0th compartment is unprivileged and does not protect its memory, */ /* so declare its stack pointer in the shared object that sets up the */ @@ -43,8 +45,8 @@ void verify_tls_padding(void) { } } -/* Ensure that all required pkeys are allocated or no-op on aarch64. */ -void ensure_pkeys_allocated(int *n_to_alloc) { +/* Allocates the required pkeys on x86 or enables MTE on aarch64 */ +void ia2_set_up_tags(int *n_to_alloc) { #if defined(__x86_64__) if (*n_to_alloc != 0) { for (int pkey = 1; pkey <= *n_to_alloc; pkey++) { @@ -62,6 +64,18 @@ void ensure_pkeys_allocated(int *n_to_alloc) { } *n_to_alloc = 0; } +#elif defined(__aarch64__) + if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) { + printf("MTE is not supported\n"); + exit(-1); + } + int res = prctl(PR_SET_TAGGED_ADDR_CTRL, + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xFFFE << PR_MTE_TAG_SHIFT), + 0, 0, 0); + if (res) { + printf("prctl(PR_SET_TAGGED_ADDR_CTRL) failed to enable MTE: (%s)\n", errno_s); + exit(-1); + } #endif }