Skip to content

Commit 931a2c9

Browse files
committed
add named mappings for Android using prctl
1 parent 70bdd7f commit 931a2c9

3 files changed

Lines changed: 51 additions & 11 deletions

File tree

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ EXPERIMENTAL = -DEXPERIMENTAL=0
119119
## In a release build you probably want them all to be 0
120120
DEBUG_LOG_FLAGS = -DDEBUG=1 -DLEAK_DETECTOR=1 -DMEM_USAGE=1
121121

122+
## On Android we use prctl to name mappings so they are
123+
## visible in /proc/pid/maps
124+
NAMED_MAPPINGS = -DNAMED_MAPPINGS=1
125+
122126
UNAME := $(shell uname)
123127
ifeq ($(UNAME), Darwin)
124128
OS_FLAGS = -framework Security
@@ -135,7 +139,7 @@ COMMON_CFLAGS = -Wall -Iinclude/ $(THREAD_SUPPORT) $(PRE_POPULATE_PAGES) $(START
135139
BUILD_ERROR_FLAGS = -Werror -pedantic -Wno-pointer-arith -Wno-gnu-zero-variadic-macro-arguments -Wno-format-pedantic
136140
CFLAGS = $(COMMON_CFLAGS) $(SECURITY_FLAGS) $(BUILD_ERROR_FLAGS) $(HOOKS) $(HEAP_PROFILER) -fvisibility=hidden \
137141
-std=c11 $(SANITIZER_SUPPORT) $(ALLOC_SANITY) $(UNINIT_READ_SANITY) $(CPU_PIN) $(EXPERIMENTAL) $(UAF_PTR_PAGE) \
138-
$(VERIFY_BIT_SLOT_CACHE)
142+
$(VERIFY_BIT_SLOT_CACHE) $(NAMED_MAPPINGS)
139143
CXXFLAGS = $(COMMON_CFLAGS) -DCPP_SUPPORT=1 -std=c++17 $(SANITIZER_SUPPORT) $(HOOKS)
140144
EXE_CFLAGS = -fPIE
141145
GDB_FLAGS = -g -ggdb3 -fno-omit-frame-pointer

include/iso_alloc_internal.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#define _GNU_SOURCE 1
88
#endif
99

10-
#if !__x86_64__
10+
#if !__aarch64__ && !__x86_64__
1111
#pragma message "IsoAlloc is untested and unsupported on 32 bit platforms"
1212
#endif
1313

@@ -59,6 +59,11 @@
5959
#include <stdatomic.h>
6060
#endif
6161

62+
#if __linux__ || __ANDROID__
63+
#include <sys/prctl.h>
64+
#endif
65+
66+
6267
#if defined(CPU_PIN) && defined(_GNU_SOURCE) && defined(__linux__)
6368
#include <sched.h>
6469
#endif
@@ -129,6 +134,16 @@
129134
#define OK 0
130135
#define ERR -1
131136

137+
#ifdef __ANDROID__
138+
#ifndef PR_SET_VMA
139+
#define PR_SET_VMA 0x53564d41
140+
#endif
141+
142+
#ifndef PR_SET_VMA_ANON_NAME
143+
#define PR_SET_VMA_ANON_NAME 0
144+
#endif
145+
#endif
146+
132147
#define LIKELY(x) __builtin_expect(!!(x), 1)
133148
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
134149

@@ -507,7 +522,7 @@ INTERNAL_HIDDEN void _iso_alloc_protect_root(void);
507522
INTERNAL_HIDDEN void _iso_alloc_unprotect_root(void);
508523
INTERNAL_HIDDEN void _unmap_zone(iso_alloc_zone *zone);
509524
INTERNAL_HIDDEN void *create_guard_page(void *p);
510-
INTERNAL_HIDDEN void *mmap_rw_pages(size_t size, bool populate);
525+
INTERNAL_HIDDEN void *mmap_rw_pages(size_t size, bool populate, const char *name);
511526
INTERNAL_HIDDEN void *_iso_big_alloc(size_t size);
512527
INTERNAL_HIDDEN void *_iso_alloc(iso_alloc_zone *zone, size_t size);
513528
INTERNAL_HIDDEN void *_iso_alloc_bitslot_from_zone(bit_slot_t bitslot, iso_alloc_zone *zone);
@@ -525,6 +540,7 @@ INTERNAL_HIDDEN uint64_t __iso_alloc_mem_usage(void);
525540
INTERNAL_HIDDEN uint64_t rand_uint64(void);
526541
INTERNAL_HIDDEN size_t _iso_alloc_print_stats();
527542
INTERNAL_HIDDEN size_t _iso_chunk_size(void *p);
543+
INTERNAL_HIDDEN int32_t name_mapping(void *p, size_t sz, const char *name);
528544
INTERNAL_HIDDEN int8_t *_fmt(uint64_t n, uint32_t base);
529545
INTERNAL_HIDDEN void _iso_alloc_printf(int32_t fd, const char *f, ...);
530546
INTERNAL_HIDDEN void _initialize_profiler(void);

src/iso_alloc.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ INTERNAL_HIDDEN INLINE void iso_clear_user_chunk(uint8_t *p, size_t size) {
254254

255255
INTERNAL_HIDDEN void *create_guard_page(void *p) {
256256
if(p == NULL) {
257-
p = mmap_rw_pages(g_page_size, false);
257+
p = mmap_rw_pages(g_page_size, false, "guard page");
258258

259259
if(p == NULL) {
260260
LOG_AND_ABORT("Could not allocate guard page");
@@ -268,7 +268,7 @@ INTERNAL_HIDDEN void *create_guard_page(void *p) {
268268
return p;
269269
}
270270

271-
INTERNAL_HIDDEN void *mmap_rw_pages(size_t size, bool populate) {
271+
INTERNAL_HIDDEN void *mmap_rw_pages(size_t size, bool populate, const char *name) {
272272
size = ROUND_UP_PAGE(size);
273273
void *p = NULL;
274274

@@ -288,6 +288,10 @@ INTERNAL_HIDDEN void *mmap_rw_pages(size_t size, bool populate) {
288288
return NULL;
289289
}
290290

291+
if(name != NULL) {
292+
name_mapping(p, size, name);
293+
}
294+
291295
return p;
292296
}
293297

@@ -305,7 +309,7 @@ INTERNAL_HIDDEN iso_alloc_root *iso_alloc_new_root(void) {
305309

306310
size_t _root_size = sizeof(iso_alloc_root) + (g_page_size << 1);
307311

308-
p = (void *) mmap_rw_pages(_root_size, true);
312+
p = (void *) mmap_rw_pages(_root_size, true, "isoalloc root");
309313

310314
if(p == NULL) {
311315
LOG_AND_ABORT("Cannot allocate pages for root");
@@ -340,11 +344,12 @@ INTERNAL_HIDDEN void iso_alloc_initialize_global_root(void) {
340344
_root->zones_size = ROUND_UP_PAGE(_root->zones_size);
341345

342346
/* Allocate memory with guard pages to hold zone data */
343-
void *p = mmap_rw_pages(_root->zones_size, false);
347+
void *p = mmap_rw_pages(_root->zones_size, false, NULL);
344348
create_guard_page(p);
345349
create_guard_page((void *) (uintptr_t)(p + _root->zones_size) - g_page_size);
346350

347351
_root->zones = (void *) (p + g_page_size);
352+
name_mapping(p, _root->zones_size, "isoalloc zone metadata");
348353

349354
for(int64_t i = 0; i < _default_zone_count; i++) {
350355
if((_iso_new_zone(default_zones[i], true)) == NULL) {
@@ -543,6 +548,13 @@ __attribute__((destructor(LAST_DTOR))) void iso_alloc_dtor(void) {
543548
UNLOCK_ROOT();
544549
}
545550

551+
INTERNAL_HIDDEN int32_t name_mapping(void *p, size_t sz, const char *name) {
552+
#if NAMED_MAPPINGS && __ANDROID__
553+
return prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, sz, name);
554+
#endif
555+
return 0;
556+
}
557+
546558
INTERNAL_HIDDEN iso_alloc_zone *iso_new_zone(size_t size, bool internal) {
547559
LOCK_ROOT();
548560
iso_alloc_zone *zone = _iso_new_zone(size, internal);
@@ -583,7 +595,7 @@ INTERNAL_HIDDEN iso_alloc_zone *_iso_new_zone(size_t size, bool internal) {
583595

584596
/* All of the following fields are immutable
585597
* and should not change once they are set */
586-
void *p = mmap_rw_pages(new_zone->bitmap_size + (_root->system_page_size << 1), true);
598+
void *p = mmap_rw_pages(new_zone->bitmap_size + (_root->system_page_size << 1), true, "isoalloc zone bitmap");
587599

588600
void *bitmap_pages_guard_below = p;
589601
new_zone->bitmap_start = (p + _root->system_page_size);
@@ -597,10 +609,18 @@ INTERNAL_HIDDEN iso_alloc_zone *_iso_new_zone(size_t size, bool internal) {
597609
madvise(new_zone->bitmap_start, new_zone->bitmap_size, MADV_WILLNEED);
598610
madvise(new_zone->bitmap_start, new_zone->bitmap_size, MADV_SEQUENTIAL);
599611

612+
char *name;
613+
614+
if(internal == true) {
615+
name = "internal isoalloc user zone";
616+
} else {
617+
name = "custom isoalloc user zone";
618+
}
619+
600620
/* All user pages use MAP_POPULATE. This might seem like we are asking
601621
* the kernel to commit a lot of memory for us that we may never use
602622
* but when we call create_canary_chunks() that will happen anyway */
603-
p = mmap_rw_pages(ZONE_USER_SIZE + (_root->system_page_size << 1), true);
623+
p = mmap_rw_pages(ZONE_USER_SIZE + (_root->system_page_size << 1), true, name);
604624

605625
void *user_pages_guard_below = p;
606626
new_zone->user_pages_start = (p + _root->system_page_size);
@@ -853,14 +873,14 @@ INTERNAL_HIDDEN void *_iso_big_alloc(size_t size) {
853873
if(big == NULL) {
854874
/* User data is allocated separately from big zone meta
855875
* data to prevent an attacker from targeting it */
856-
void *user_pages = mmap_rw_pages((_root->system_page_size << BIG_ZONE_USER_PAGE_COUNT_SHIFT) + size, false);
876+
void *user_pages = mmap_rw_pages((_root->system_page_size << BIG_ZONE_USER_PAGE_COUNT_SHIFT) + size, false, "isoalloc big zone user data");
857877

858878
if(user_pages == NULL) {
859879
UNLOCK_BIG_ZONE();
860880
return NULL;
861881
}
862882

863-
void *p = mmap_rw_pages((_root->system_page_size * BIG_ZONE_META_DATA_PAGE_COUNT), false);
883+
void *p = mmap_rw_pages((_root->system_page_size * BIG_ZONE_META_DATA_PAGE_COUNT), false, "isoalloc big zone metadata");
864884

865885
/* The first page before meta data is a guard page */
866886
create_guard_page(p);

0 commit comments

Comments
 (0)