Skip to content

Commit 57527d4

Browse files
committed
cleanup uaf ptr page code
1 parent 1457da7 commit 57527d4

8 files changed

Lines changed: 70 additions & 11 deletions

File tree

Makefile

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ STARTUP_MEM_USAGE = -DSMALL_MEM_STARTUP=0
6868
PRE_POPULATE_PAGES = -DPRE_POPULATE_PAGES=0
6969

7070
## Enable some functionality that like IsoAlloc internals
71-
## for tests that need to verify security properties
71+
## for tests that need to verify security properties.
72+
## Only test code should use this.
7273
UNIT_TESTING = -DUNIT_TESTING=1
7374

7475
## Enable the malloc/free and new/delete hooks
@@ -183,6 +184,15 @@ AUTO_CTOR_DTOR = -DAUTO_CTOR_DTOR=1
183184
## that call free will segfault
184185
ISO_DTOR_CLEANUP = -DISO_DTOR_CLEANUP=0
185186

187+
## Register a signal handler for SIGSEGV that inspects si_addr
188+
## for an address managed by IsoAlloc. Optionally used when
189+
## UAF_PTR_PAGE is enabled for better crash handling
190+
SIGNAL_HANDLER = -DSIGNAL_HANDLER=1
191+
192+
## If you know your target will have an ARMv8.1-A or newer and
193+
## supports Top Byte Ignore (TBI) then you want to enable this
194+
ARM_TBI = 0
195+
186196
LTO = -flto
187197

188198
LIBNAME = libisoalloc.so
@@ -248,8 +258,9 @@ CFLAGS += $(COMMON_CFLAGS) $(SECURITY_FLAGS) $(BUILD_ERROR_FLAGS) $(HOOKS) $(HEA
248258
-std=c11 $(SANITIZER_SUPPORT) $(ALLOC_SANITY) $(MEMCPY_SANITY) $(UNINIT_READ_SANITY) $(CPU_PIN) $(SCHED_GETCPU) \
249259
$(EXPERIMENTAL) $(UAF_PTR_PAGE) $(VERIFY_FREE_BIT_SLOTS) $(NAMED_MAPPINGS) $(ABORT_ON_NULL) $(NO_ZERO_ALLOCATIONS) \
250260
$(ABORT_NO_ENTROPY) $(ISO_DTOR_CLEANUP) $(RANDOMIZE_FREELIST) $(USE_SPINLOCK) $(HUGE_PAGES) $(USE_MLOCK) \
251-
$(MEMORY_TAGGING) $(STRONG_SIZE_ISOLATION) $(MEMSET_SANITY) $(AUTO_CTOR_DTOR)
252-
CXXFLAGS += $(COMMON_CFLAGS) -DCPP_SUPPORT=1 -std=c++17 $(SANITIZER_SUPPORT) $(HOOKS)
261+
$(MEMORY_TAGGING) $(STRONG_SIZE_ISOLATION) $(MEMSET_SANITY) $(AUTO_CTOR_DTOR) $(SIGNAL_HANDLER)
262+
CXXFLAGS = $(COMMON_CFLAGS) -DCPP_SUPPORT=1 -std=c++17 $(SANITIZER_SUPPORT) $(HOOKS)
263+
253264
EXE_CFLAGS = -fPIE
254265
GDB_FLAGS = -g -ggdb3 -fno-omit-frame-pointer
255266
PERF_FLAGS = -pg -DPERF_TEST_BUILD=1
@@ -318,7 +329,7 @@ tests: clean library_debug_unit_tests
318329
@echo "make tests"
319330
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/rand_freelist.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/rand_freelist $(LDFLAGS)
320331
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/tests.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tests $(LDFLAGS)
321-
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/uaf.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/uaf $(LDFLAGS)
332+
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) $(UNIT_TESTING) tests/uaf.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/uaf $(LDFLAGS)
322333
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/interfaces_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/interfaces_test $(LDFLAGS)
323334
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/thread_tests.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/thread_tests $(LDFLAGS)
324335
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) $(UNIT_TESTING) tests/big_canary_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/big_canary_test $(LDFLAGS)

include/conf.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
* magic value that is written */
4646
#if UAF_PTR_PAGE
4747
#define UAF_PTR_PAGE_ODDS 1000000
48-
#define UAF_PTR_PAGE_ADDR 0xFF41414142434445
4948
#endif
5049

5150
/* Zones can be retired after a certain number of

include/iso_alloc_ds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ typedef struct {
102102
#if NO_ZERO_ALLOCATIONS
103103
void *zero_alloc_page;
104104
#endif
105+
#if UAF_PTR_PAGE
106+
void *uaf_ptr_page;
107+
#endif
105108
} __attribute__((aligned(sizeof(int64_t)))) iso_alloc_root;
106109

107110
typedef struct {

include/iso_alloc_internal.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ assert(sizeof(size_t) >= 64)
3838
#include <string.h>
3939
#include <unistd.h>
4040
#include <stdarg.h>
41+
#include <signal.h>
4142
#include <sys/mman.h>
4243
#include <sys/types.h>
4344

@@ -327,10 +328,6 @@ extern pthread_mutex_t root_busy_mutex;
327328
#define UNLOCK_BIG_ZONE()
328329
#endif
329330

330-
#if NO_ZERO_ALLOCATIONS
331-
extern void *_zero_alloc_page;
332-
#endif
333-
334331
/* The global root */
335332
extern iso_alloc_root *_root;
336333

@@ -402,6 +399,10 @@ INTERNAL_HIDDEN int64_t check_canary_no_abort(iso_alloc_zone_t *zone, const void
402399
INTERNAL_HIDDEN void _iso_alloc_initialize(void);
403400
INTERNAL_HIDDEN void _iso_alloc_destroy(void);
404401

402+
#if SIGNAL_HANDLER
403+
INTERNAL_HIDDEN void handle_signal(int sig, siginfo_t *si, void *ctx);
404+
#endif
405+
405406
#if EXPERIMENTAL
406407
INTERNAL_HIDDEN void _iso_alloc_search_stack(uint8_t *stack_start);
407408
#endif

src/iso_alloc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,28 @@ INTERNAL_HIDDEN void _iso_alloc_initialize(void) {
253253
_root->zero_alloc_page = mmap_pages(g_page_size, false, NULL, PROT_NONE);
254254
#endif
255255

256+
#if UAF_PTR_PAGE
257+
_root->uaf_ptr_page = mmap_pages(g_page_size, false, NULL, PROT_NONE);
258+
#endif
259+
256260
#if ALLOC_SANITY && UNINIT_READ_SANITY
257261
_iso_alloc_setup_userfaultfd();
258262
#endif
259263

260264
#if ALLOC_SANITY
261265
_sanity_canary = us_rand_uint64(&_root->seed);
262266
#endif
267+
268+
#if SIGNAL_HANDLER
269+
struct sigaction sa;
270+
sigemptyset(&sa.sa_mask);
271+
sa.sa_flags = SA_NODEFER | SA_SIGINFO;
272+
sa.sa_sigaction = &handle_signal;
273+
274+
if(sigaction(SIGSEGV, &sa, NULL) == ERR) {
275+
LOG("Could not register signal handler");
276+
}
277+
#endif
263278
}
264279

265280
#if AUTO_CTOR_DTOR
@@ -1909,6 +1924,10 @@ INTERNAL_HIDDEN void _iso_alloc_destroy(void) {
19091924
munmap(_root->zero_alloc_page, g_page_size);
19101925
#endif
19111926

1927+
#if UAF_PTR_PAGE
1928+
munmap(_root->uaf_ptr_page, g_page_size);
1929+
#endif
1930+
19121931
#if DEBUG && (LEAK_DETECTOR || MEM_USAGE)
19131932
#if MEM_USAGE
19141933
uint64_t mb = 0;

src/iso_alloc_search.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ INTERNAL_HIDDEN void *_iso_alloc_ptr_search(void *n, bool poison) {
2525
return search;
2626
} else {
2727
#if UAF_PTR_PAGE
28-
*(uint64_t *) search = UAF_PTR_PAGE_ADDR;
28+
*(uint64_t *) search = (uint64_t)(_root->uaf_ptr_page);
2929
return search;
3030
#endif
3131
}

src/iso_alloc_signal.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* iso_alloc_signal.c - A secure memory allocator
2+
* Copyright 2022 - chris.rohlf@gmail.com */
3+
4+
#include "iso_alloc_internal.h"
5+
6+
#if SIGNAL_HANDLER
7+
INTERNAL_HIDDEN void handle_signal(int sig, siginfo_t *si, void *ctx) {
8+
#if UAF_PTR_PAGE
9+
void *crash_addr = si->si_addr;
10+
11+
if(si->si_addr == NULL) {
12+
LOG_AND_ABORT("si->si_addr == NULL");
13+
}
14+
15+
/* Check for the address within 2 pages in
16+
* either direction of _root->uaf_ptr_page */
17+
if(crash_addr >= _root->uaf_ptr_page - (g_page_size * 2) &&
18+
crash_addr <= _root->uaf_ptr_page + (g_page_size * 2)) {
19+
LOG_AND_ABORT("Use after free detected! Crashed at _root->uaf_ptr_page 0x%x", si->si_addr);
20+
}
21+
22+
LOG_AND_ABORT("Unknown segmentation fault @ 0x%p", crash_addr);
23+
#endif
24+
}
25+
#endif

tests/uaf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ int main(int argc, char *argv[]) {
2626

2727
/* Dereference a pointer that should have been
2828
* detected and overwritten with UAF_PTR_PAGE */
29-
fprintf(stdout, "Dereferencing test->str @ %p. Fault address will be %lx\n", test->str, UAF_PTR_PAGE_ADDR);
29+
iso_alloc_root *root = _get_root();
30+
fprintf(stdout, "Dereferencing test->str @ %p. Fault address will be %p\n", test->str, root->uaf_ptr_page);
3031
fprintf(stdout, "[%s]\n", test->str);
3132
iso_free_permanently(test);
3233

0 commit comments

Comments
 (0)