Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ PERM_FREE_REALLOC = -DPERM_FREE_REALLOC=0
## 1 byte tag per addressable chunk of memory. These tags can
## be retrieved and verified. This feature will likely interfere
## with ARM MTE and PAC. See MEMORY_TAGGING.md for more information
MEMORY_TAGGING = -DMEMORY_TAGGING=0
MEMORY_TAGGING = -DMEMORY_TAGGING=1

## Enable abort() when isoalloc can't gather enough entropy.
ABORT_NO_ENTROPY = -DABORT_NO_ENTROPY=1
Expand Down Expand Up @@ -90,8 +90,12 @@ THP_PAGES = -DTHP_PAGES=1
## program. This file encodes the heap usage patterns of
## the target. This file can be consumed by the profiler
## CLI utility. See PROFILER.md for the format of this file
#HEAP_PROFILER = -DHEAP_PROFILER=1 -fno-omit-frame-pointer \
# -fno-optimize-sibling-calls -ldl
#HEAP_PROFILER = $(HEAP_PROFILER_FLAGS)

## Flags required to build with the heap profiler. Backtraces
## are collected by walking frame pointers so they must be kept
HEAP_PROFILER_FLAGS = -DHEAP_PROFILER=1 -fno-omit-frame-pointer \
-fno-optimize-sibling-calls

## Enable CPU pinning support on a per-zone basis. This is
## a minor security feature which introduces an allocation
Expand Down Expand Up @@ -425,6 +429,7 @@ tests: clean library_debug_unit_tests
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/tests.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tests $(LDFLAGS)
$(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)
$(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)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/aligned_alloc_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/aligned_alloc_test $(LDFLAGS)
$(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)
$(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)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/big_tests.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/big_tests $(LDFLAGS)
Expand Down Expand Up @@ -463,9 +468,19 @@ tagging_tests: clean cpp_library_debug
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/uaf_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/uaf_tag_ptr_test $(LDFLAGS)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/bad_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/bad_tag_ptr_test $(LDFLAGS)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/verify_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/verify_tag_ptr_test $(LDFLAGS)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/valid_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/valid_tag_ptr_test $(LDFLAGS)
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/tag_refresh_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tag_refresh_test $(LDFLAGS)
$(CXX) -DMEMORY_TAGGING=1 $(CXXFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(EXE_CFLAGS) $(OS_FLAGS) tests/tagged_ptr_test.cpp $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tagged_ptr_test_cpp $(LDFLAGS)
utils/run_tagging_tests.sh

## Build the library with the heap profiler and run its test.
## The profiler data file is checked by the runner script
profiler_tests: clean
@echo "make profiler_tests"
$(CC) $(CFLAGS) $(HEAP_PROFILER_FLAGS) $(LIBRARY) $(OS_FLAGS) $(UNIT_TESTING) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(C_SRCS) -o $(BUILD_DIR)/$(LIBNAME) -ldl
$(CC) $(CFLAGS) $(HEAP_PROFILER_FLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/profiler_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/profiler_test $(LDFLAGS) -ldl
utils/run_profiler_tests.sh

init_test: clean library_debug_unit_tests
@echo "make init_test"
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/init_destroy.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/init_destroy $(LDFLAGS)
Expand Down Expand Up @@ -530,6 +545,6 @@ format-ci:

clean:
rm -rf build/* tests_perf_analysis.txt big_tests_perf_analysis.txt gmon.out \
tagging_test_output.txt test_output.txt *.dSYM core* iso_alloc_profiler.data
tagging_test_output.txt test_output.txt profiler_test_output.txt *.dSYM core* iso_alloc_profiler.data
rm -rf android/libs android/obj
mkdir -p build/
12 changes: 11 additions & 1 deletion include/iso_alloc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ extern pthread_mutex_t root_busy_mutex;
/* The global root */
extern iso_alloc_root *_root;

/* These are C functions and may be called from iso_alloc.cpp */
#ifdef __cplusplus
extern "C" {
#endif
INTERNAL_HIDDEN INLINE void check_big_canary(iso_alloc_big_zone_t *big);
INTERNAL_HIDDEN INLINE void check_canary(iso_alloc_zone_t *zone, const void *p);
INTERNAL_HIDDEN INLINE void iso_clear_user_chunk(uint8_t *p, size_t size);
Expand All @@ -377,6 +381,7 @@ INTERNAL_HIDDEN INLINE void flush_chunk_quarantine(void);
INTERNAL_HIDDEN INLINE void clear_zone_cache(void);
INTERNAL_HIDDEN iso_alloc_big_zone_t *iso_find_big_zone(void *p, bool remove);
INTERNAL_HIDDEN FLATTEN iso_alloc_zone_t *is_zone_usable(iso_alloc_zone_t *zone, size_t size);
INTERNAL_HIDDEN iso_alloc_zone_t *find_exact_fit_zone(size_t size);
INTERNAL_HIDDEN iso_alloc_zone_t *find_suitable_zone(size_t size);
INTERNAL_HIDDEN iso_alloc_zone_t *iso_new_zone(size_t size, bool internal);
INTERNAL_HIDDEN iso_alloc_zone_t *_iso_new_zone(size_t size, bool internal, int32_t index);
Expand All @@ -389,6 +394,7 @@ INTERNAL_HIDDEN INLINE bit_slot_t get_next_free_bit_slot(iso_alloc_zone_t *zone)
INTERNAL_HIDDEN iso_alloc_root *iso_alloc_new_root(void);
INTERNAL_HIDDEN bool is_pow2(uint64_t sz);
INTERNAL_HIDDEN bool _is_zone_retired(iso_alloc_zone_t *zone);
INTERNAL_HIDDEN void _iso_alloc_refresh_chunk_tag(void *p, iso_alloc_zone_t *zone);
INTERNAL_HIDDEN bool _refresh_zone_mem_tags(iso_alloc_zone_t *zone);
INTERNAL_HIDDEN iso_alloc_zone_t *_iso_free_internal_unlocked(void *p, bool permanent, iso_alloc_zone_t *zone);
INTERNAL_HIDDEN void fill_free_bit_slots(iso_alloc_zone_t *zone);
Expand All @@ -414,8 +420,9 @@ INTERNAL_HIDDEN INLINE void dont_need_pages(void *p, size_t size);
INTERNAL_HIDDEN void *_tag_ptr(void *p, iso_alloc_zone_t *zone);
INTERNAL_HIDDEN void *_untag_ptr(void *p, iso_alloc_zone_t *zone);
INTERNAL_HIDDEN void _free_big_zone_list(iso_alloc_big_zone_t *head);
INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_big_alloc(size_t size);
INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_big_alloc(size_t size, size_t alignment);
INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc(iso_alloc_zone_t *zone, size_t size);
INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc_aligned(size_t size, size_t alignment);
INTERNAL_HIDDEN INLINE ASSUME_ALIGNED void *_iso_alloc_bitslot_from_zone(bit_slot_t bitslot, iso_alloc_zone_t *zone);
INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_calloc(size_t nmemb, size_t size);
#if UAF_PTR_PAGE
Expand All @@ -430,6 +437,9 @@ INTERNAL_HIDDEN size_t _iso_chunk_size(void *p);
INTERNAL_HIDDEN int64_t check_canary_no_abort(iso_alloc_zone_t *zone, const void *p);
INTERNAL_HIDDEN void _iso_alloc_initialize(void);
INTERNAL_HIDDEN void _iso_alloc_destroy(void);
#ifdef __cplusplus
}
#endif

#if ARM_MTE
INLINE void *iso_mte_untag_ptr(void *p);
Expand Down
26 changes: 15 additions & 11 deletions include/iso_alloc_profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,33 @@
/* The IsoAlloc profiler is not thread local but these
* globals should only ever be touched by internal
* allocator functions when the root is locked */
uint64_t _alloc_count;
uint64_t _free_count;
uint64_t _alloc_sampled_count;
uint64_t _free_sampled_count;

int32_t profiler_fd;
extern uint64_t _alloc_count;
extern uint64_t _free_count;
extern uint64_t _alloc_sampled_count;
extern uint64_t _free_sampled_count;

typedef struct {
uint64_t total;
uint64_t count;
} zone_profiler_map_t;

zone_profiler_map_t _zone_profiler_map[SMALL_SIZE_MAX];
/* These are defined once in iso_alloc_profiler.c. This
* header is included by several translation units so
* defining them here fails to link under -fno-common */
extern int32_t profiler_fd;

/* Indexed by chunk size, which can be exactly SMALL_SIZE_MAX */
extern zone_profiler_map_t _zone_profiler_map[SMALL_SIZE_MAX + 1];

/* iso_alloc_traces_t is a public structure, and
* is defined in the public header iso_alloc.h */
iso_alloc_traces_t _alloc_bts[BACKTRACE_DEPTH_SZ];
size_t _alloc_bts_count;
extern iso_alloc_traces_t _alloc_bts[BACKTRACE_DEPTH_SZ];
extern size_t _alloc_bts_count;

/* iso_free_traces_t is a public structure, and
* is defined in the public header iso_alloc.h */
iso_free_traces_t _free_bts[BACKTRACE_DEPTH_SZ];
size_t _free_bts_count;
extern iso_free_traces_t _free_bts[BACKTRACE_DEPTH_SZ];
extern size_t _free_bts_count;

INTERNAL_HIDDEN INLINE uint64_t _get_backtrace_hash(void);
INTERNAL_HIDDEN INLINE void _save_backtrace(iso_alloc_traces_t *abts);
Expand Down
Loading
Loading