Skip to content

Commit

Permalink
add new files and fix android build
Browse files Browse the repository at this point in the history
  • Loading branch information
struct committed Dec 20, 2023
1 parent 255a058 commit d55e5af
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ To build Android libraries for x86_64 and ARM64 architectures just `cd` into the

For those of you on an M1 based Mac you can still build IsoAlloc with the following command:
`arch -x86_64 /bin/bash -c $ANDROID_NDK_HOME/build/ndk-build`
or
`~/Library/Android/sdk/ndk/26.1.10909125/ndk-build`

## Linking With C++

Expand Down
5 changes: 3 additions & 2 deletions android/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ LOCAL_CFLAGS := -DTHREAD_SUPPORT=1 -pthread \
-DPROTECT_FREE_BIG_ZONES=0 -DMASK_PTRS=1 -DSIGNAL_HANDLER=0 \
-DUSE_MLOCK=1 -DNO_ZERO_ALLOCATIONS=1 -DABORT_ON_NULL=0 \
-DABORT_NO_ENTROPY=1 -DMEMCPY_SANITY=0 -DMEMSET_SANITY=0 \
-DSTRONG_SIZE_ISOLATION=0 -DISO_DTOR_CLEANUP=0
-DSTRONG_SIZE_ISOLATION=0 -DISO_DTOR_CLEANUP=0 -DARM_MTE=1 \
-march=armv8.5-a+memtag

LOCAL_SRC_FILES := ../../src/iso_alloc.c ../../src/iso_alloc_printf.c ../../src/iso_alloc_random.c \
../../src/iso_alloc_search.c ../../src/iso_alloc_interfaces.c ../../src/iso_alloc_profiler.c \
../../src/iso_alloc_sanity.c ../../src/iso_alloc_util.c ../../src/malloc_hook.c \
../../src/libc_hook.c ../../src/iso_alloc_mem_tags.c
../../src/libc_hook.c ../../src/iso_alloc_mem_tags.c ../../src/iso_alloc_mte.c

LOCAL_C_INCLUDES := ../../include/

Expand Down
4 changes: 2 additions & 2 deletions android/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
APP_ABI := arm64-v8a x86_64
APP_PLATFORM := android-28
APP_ABI := arm64-v8a
APP_PLATFORM := android-34
2 changes: 1 addition & 1 deletion include/iso_alloc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ INTERNAL_HIDDEN void _iso_alloc_destroy(void);
#if ARM_MTE
INLINE uintptr_t iso_mte_untag_ptr(uintptr_t p);
INLINE uint8_t extractTag(uintptr_t p);
INLINE bool iso_is_mte_supported();
INLINE bool iso_is_mte_supported(void);
void *iso_mte_set_tag_range(void *p, size_t size);
uintptr_t iso_mte_create_tag(uintptr_t p, uintptr_t exclusion_mask);
void iso_mte_set_tag(uintptr_t p);
Expand Down
138 changes: 138 additions & 0 deletions src/iso_alloc_mte.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* iso_alloc_mte.c - A secure memory allocator
* 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:
* https://android.googlesource.com/platform/external/scudo/+/refs/tags/android-14.0.0_r1/standalone/
* Its license (The LLVM Project is under the Apache License v2.0 with LLVM Exceptions) can be found here
* https://android.googlesource.com/platform/external/scudo/+/refs/tags/android-14.0.0_r1/LICENSE.TXT */

#if ARM_MTE == 1

uintptr_t iso_mte_untag_ptr(uintptr_t p) {
return p & ((1ULL << 56) - 1);
}

uint8_t iso_mte_extract_tag(uintptr_t p) {
return (p >> 56) & 0xF;
}

/* Check for the MTE bit in the ELF Auxv */
bool iso_is_mte_supported(void) {
#ifndef HWCAP2_MTE
#define HWCAP2_MTE (1 << 18)
#endif
return getauxval(AT_HWCAP2) & HWCAP2_MTE;
}

void *iso_mte_set_tag_range(void *p, size_t size) {
uintptr_t tagged_ptr = iso_mte_create_tag((uintptr_t) p, 0x0);
return (void *) iso_mte_set_tags(tagged_ptr, tagged_ptr + size);
}

/* Uses IRG to create a random tag */
uintptr_t iso_mte_create_tag(uintptr_t p, uintptr_t exclusion_mask) {
exclusion_mask |= 1;
uintptr_t tagged_ptr;
__asm__ __volatile__(
".arch_extension memtag\n"
"irg %[tagged_ptr], %[p], %[exclusion_mask]\n"
: [tagged_ptr] "=r"(tagged_ptr)
: [p] "r"(p), [exclusion_mask] "r"(exclusion_mask));
return tagged_ptr;
}

/* Uses STG to lock a tag to an address */
void iso_mte_set_tag(uintptr_t p) {
//DCHECK_EQ(0, Ptr % 16);
__asm__ __volatile__(
".arch_extension memtag\n"
"stg %0, [%0]\n"
:
: "r"(p)
: "memory");
}

/* Uses LDG to load a tag */
uintptr_t iso_mte_get_tag(uintptr_t p) {
//DCHECK_EQ(0, Ptr % 16);
uintptr_t tagged_ptr = p;
__asm__ __volatile__(
".arch_extension memtag\n"
"ldg %0, [%0]\n"
: "+r"(tagged_ptr)
:
: "memory");
return tagged_ptr;
}

/* Set tag for a region of memory, zeroize */
uintptr_t iso_mte_set_tags(uintptr_t start, uintptr_t end) {
//DCHECK_EQ(0, Begin % 16);
uintptr_t line_size, next, tmp;
__asm__ __volatile__(
".arch_extension memtag\n"

// Compute the cache line size in bytes (DCZID_EL0 stores it as the log2
// of the number of 4-byte words) and bail out to the slow path if DCZID_EL0
// indicates that the DC instructions are unavailable.
"DCZID .req %[tmp]\n"
"mrs DCZID, dczid_el0\n"
"tbnz DCZID, #4, 3f\n"
"and DCZID, DCZID, #15\n"
"mov %[line_size], #4\n"
"lsl %[line_size], %[line_size], DCZID\n"
".unreq DCZID\n"

// Our main loop doesn't handle the case where we don't need to perform any
// DC GZVA operations. If the size of our tagged region is less than
// twice the cache line size, bail out to the slow path since it's not
// guaranteed that we'll be able to do a DC GZVA.
"Size .req %[tmp]\n"
"sub Size, %[end], %[cur]\n"
"cmp Size, %[line_size], lsl #1\n"
"b.lt 3f\n"
".unreq Size\n"

"line_mask .req %[tmp]\n"
"sub line_mask, %[line_size], #1\n"

// STZG until the start of the next cache line.
"orr %[next], %[cur], line_mask\n"

"1:\n"
"stzg %[cur], [%[cur]], #16\n"
"cmp %[cur], %[next]\n"
"b.lt 1b\n"

// DC GZVA cache lines until we have no more full cache lines.
"bic %[next], %[end], line_mask\n"
".unreq line_mask\n"

"2:\n"
"dc gzva, %[cur]\n"
"add %[cur], %[cur], %[line_size]\n"
"cmp %[cur], %[next]\n"
"b.lt 2b\n"

// STZG until the end of the tagged region. This loop is also used to handle
// slow path cases.

"3:\n"
"cmp %[cur], %[end]\n"
"b.ge 4f\n"
"stzg %[cur], [%[cur]], #16\n"
"b 3b\n"

"4:\n"

: [cur] "+&r"(start), [line_size] "=&r"(line_size), [next] "=&r"(next), [tmp] "=&r"(tmp)
: [end] "r"(end)
: "memory");

return start;
}
#endif

0 comments on commit d55e5af

Please sign in to comment.