Skip to content

Commit

Permalink
Support building for MTE but disabling at runtime when not enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
struct committed Dec 21, 2023
1 parent 9f7e2c8 commit 37dcff1
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 16 deletions.
3 changes: 3 additions & 0 deletions include/iso_alloc_ds.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ typedef struct {
int32_t big_zone_free_count;
int32_t big_zone_used_count;
uint16_t zones_used;
#if ARM_MTE
bool arm_mte_enabled;
#endif
} __attribute__((aligned(sizeof(int64_t)))) iso_alloc_root;

typedef struct {
Expand Down
1 change: 1 addition & 0 deletions include/iso_alloc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ INTERNAL_HIDDEN void *create_guard_page(void *p);
INTERNAL_HIDDEN INLINE void darwin_reuse(void *p, size_t size);
INTERNAL_HIDDEN void unmap_guarded_pages(void *p, size_t size);
INTERNAL_HIDDEN ASSUME_ALIGNED void *mmap_guarded_rw_pages(size_t size, bool populate, const char *name);
INTERNAL_HIDDEN ASSUME_ALIGNED void *mmap_guarded_rw_mte_pages(size_t size, bool populate, const char *name);
INTERNAL_HIDDEN ASSUME_ALIGNED void *mmap_rw_pages(size_t size, bool populate, const char *name);
INTERNAL_HIDDEN ASSUME_ALIGNED void *mmap_rw_mte_pages(size_t size, bool populate, const char *name);
INTERNAL_HIDDEN ASSUME_ALIGNED void *mmap_pages(size_t size, bool populate, const char *name, int32_t prot);
Expand Down
1 change: 1 addition & 0 deletions include/os/android.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <sys/prctl.h>
#include <sys/auxv.h>

/* This magic number is usually defined by Android Bionic:
* https://android.googlesource.com/platform/bionic/+/263325d/libc/include/sys/prctl.h#42 */
Expand Down
1 change: 1 addition & 0 deletions include/os/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <sys/prctl.h>
#include <sys/auxv.h>
#include <byteswap.h>
/* Get linux kernel version */
#include <linux/version.h>
Expand Down
55 changes: 43 additions & 12 deletions src/iso_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ INTERNAL_HIDDEN void iso_alloc_initialize_global_root(void) {

#if ARM_MTE
if(iso_is_mte_supported() == false) {
LOG_AND_ABORT("ARM_MTE Enabled in build but not supported by this platform");
LOG("ARM_MTE Enabled in build but not supported by this platform");
_root->arm_mte_enabled = false;
} else {
_root->arm_mte_enabled = true;
prctl(PR_SET_TAGGED_ADDR_CTRL,
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT),
0, 0, 0);
}

prctl(PR_SET_TAGGED_ADDR_CTRL,
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT),
0, 0, 0);
#endif

_root->zone_retirement_shf = _log2(ZONE_ALLOC_RETIRE);
Expand Down Expand Up @@ -436,7 +438,17 @@ INTERNAL_HIDDEN iso_alloc_zone_t *_iso_new_zone(size_t size, bool internal, int3
tag_mapping_size = 0;
}
#endif
void *p = mmap_rw_pages(total_size, false, name);
void *p = NULL;

#if ARM_MTE
if(_root->arm_mte_enabled == true) {
p = mmap_rw_mte_pages(total_size, false, name);
} else {
p = mmap_rw_pages(total_size, false, name);
}
#else
p = mmap_rw_pages(total_size, false, name);
#endif

#if(__ANDROID__ || KERNEL_VERSION_SEQ_5_17) && NAMED_MAPPINGS && MEMORY_TAGGING
if(new_zone->tagged == false) {
Expand Down Expand Up @@ -1119,7 +1131,9 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc(iso_alloc_zone_t *zone, size_t s
populate_zone_cache(zone);

#if ARM_MTE
p = iso_mte_set_tag_range(p, zone->chunk_size);
if(_root->arm_mte_enabled == true) {
p = iso_mte_set_tag_range(p, zone->chunk_size);
}
#endif
return p;
} else {
Expand Down Expand Up @@ -1606,7 +1620,9 @@ INTERNAL_HIDDEN iso_alloc_zone_t *_iso_free_internal_unlocked(void *p, bool perm
#endif

#if ARM_MTE
p = iso_mte_set_tag_range(p, zone->chunk_size);
if(_root->arm_mte_enabled == true) {
p = iso_mte_set_tag_range(p, zone->chunk_size);
}
#endif
return zone;
} else {
Expand Down Expand Up @@ -1802,7 +1818,9 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_big_alloc(size_t size) {
mprotect_pages(big->user_pages_start, big->size, PROT_READ | PROT_WRITE);
#endif
#if ARM_MTE
big->user_pages_start = iso_mte_set_tag_range(big->user_pages_start, big->size);
if(_root->arm_mte_enabled == true) {
big->user_pages_start = iso_mte_set_tag_range(big->user_pages_start, big->size);
}
#endif
return big->user_pages_start;
}
Expand All @@ -1822,10 +1840,21 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_big_alloc(size_t size) {

/* The free list contained no usable entries
* so we need to create a new one */
void *user_pages = NULL;
#if ARM_MTE
#if BIG_ZONE_GUARD
void *user_pages = mmap_guarded_rw_pages(size, false, BIG_ZONE_UD_NAME);
user_pages = mmap_guarded_rw_pages(size, false, BIG_ZONE_UD_NAME);
#else
void *user_pages = mmap_rw_pages(size, false, BIG_ZONE_UD_NAME);
if(_root->arm_mte_enabled == true) {
user_pages = mmap_rw_mte_pages(size, false, BIG_ZONE_UD_NAME);
}
#endif
#else
#if BIG_ZONE_GUARD
user_pages = mmap_guarded_rw_pages(size, false, BIG_ZONE_UD_NAME);
#else
user_pages = mmap_rw_pages(size, false, BIG_ZONE_UD_NAME);
#endif
#endif

if(UNLIKELY(user_pages == NULL)) {
Expand Down Expand Up @@ -1869,7 +1898,9 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_big_alloc(size_t size) {

UNLOCK_BIG_ZONE_USED();
#if ARM_MTE
new_big->user_pages_start = iso_mte_set_tag_range(new_big->user_pages_start, new_big->size);
if(_root->arm_mte_enabled == true) {
new_big->user_pages_start = iso_mte_set_tag_range(new_big->user_pages_start, new_big->size);
}
#endif
return new_big->user_pages_start;
}
Expand Down
1 change: 0 additions & 1 deletion src/iso_alloc_mte.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* Copyright 2024 - [email protected] */

#include "iso_alloc_internal.h"
#include <sys/auxv.h>

/* The majority of this code is adapted from Scudos implementation
* of ARM MTE support. That code can be found here:
Expand Down
19 changes: 16 additions & 3 deletions src/iso_alloc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,28 @@ void *mmap_guarded_rw_pages(size_t size, bool populate, const char *name) {
return NULL;
}

void *p = mmap_rw_pages(sz + (g_page_size * 2), populate, name);

create_guard_page(p);
create_guard_page(p + (g_page_size + sz));
return (p + g_page_size);
}

#if ARM_MTE
void *mmap_guarded_rw_mte_pages(size_t size, bool populate, const char *name) {
size_t sz = ROUND_UP_PAGE(size);

if(sz < size) {
return NULL;
}

void *p = mmap_rw_mte_pages(sz + (g_page_size * 2), populate, name);
#else
void *p = mmap_rw_pages(sz + (g_page_size * 2), populate, name);
#endif

create_guard_page(p);
create_guard_page(p + (g_page_size + sz));
return (p + g_page_size);
}
#endif

void *mmap_rw_pages(size_t size, bool populate, const char *name) {
return mmap_pages(size, populate, name, PROT_READ | PROT_WRITE);
Expand Down

0 comments on commit 37dcff1

Please sign in to comment.