From 256de6841041067ab71c545fd3a2cd82d84a5313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 6 Jun 2026 13:52:36 +0200 Subject: [PATCH] Integrate address sanitizer --- build.sh | 2 +- src/arena.c | 6 ++++++ src/arena.h | 13 +++++++++++++ src/base_core.h | 7 ++++++- src/main.c | 6 ++++-- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 1483a3a..b4be581 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,3 @@ #!/bin/sh set -x -gcc -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -std=gnu23 src/*c +gcc -fsanitize=address -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -std=gnu23 $CFLAGS src/*c diff --git a/src/arena.c b/src/arena.c index 852b4dd..e05648e 100644 --- a/src/arena.c +++ b/src/arena.c @@ -26,6 +26,8 @@ Arena *arena_alloc_(const ArenaParams *params) // Note: only backend now is malloc void *base = memory_allocate(params->size); + //((U8*)base)[1023+ARENA_HEADER_SZ] = 1; + Assert(base != NULL); Arena *arena = (Arena *)base; @@ -37,6 +39,7 @@ Arena *arena_alloc_(const ArenaParams *params) arena->prev = NULL; arena->checkpoint_level = 0; + ASAN_POISON_MEMORY_REGION(&arena->base[arena->pos], arena_available(arena)); return arena; } @@ -83,6 +86,7 @@ void *arena_push(Arena *arena, U32 size, U32 align) U8 *mem = ¤t->base[start_pos]; current->pos = end_pos; + ASAN_UNPOISON_MEMORY_REGION(mem, size); return mem; } @@ -94,6 +98,7 @@ void arena_pop_to(Arena *arena, U32 abs_pos) Arena *prev = current->prev; if (current->base_pos >= abs_pos) { + ASAN_UNPOISON_MEMORY_REGION(current->base, current->size); memory_release(current->base); arena->current = prev; } else { @@ -102,6 +107,7 @@ void arena_pop_to(Arena *arena, U32 abs_pos) // is the right thing . shouldn't be able to pop to larger than what's already commited Assert(new_pos <= current->size); current->pos = new_pos; + ASAN_POISON_MEMORY_REGION(¤t->base[current->pos], arena_available(arena)); break; } diff --git a/src/arena.h b/src/arena.h index fb21cea..f493fd0 100644 --- a/src/arena.h +++ b/src/arena.h @@ -1,6 +1,19 @@ #pragma once #include "base_core.h" +#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#include +#define ASAN_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) +#else +#define ASAN_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#endif + typedef U32 ArenaFlags; typedef struct ArenaParams ArenaParams; diff --git a/src/base_core.h b/src/base_core.h index 104665b..ae62c85 100644 --- a/src/base_core.h +++ b/src/base_core.h @@ -187,7 +187,12 @@ typedef unsigned __int128 U128; // memory #define MemSet(ptr, val, len) memset(ptr, val, len) -#define MemoryZero(ptr, len) explicit_bzero(ptr,len) +#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define MemoryZero(ptr, len) memset(ptr, 0, len) +// explicity bzero is usually not being intercepted +#else +#define MemoryZero(ptr, len) explicit_bzero(ptr, len) +#endif #define MemMove(dst, src, len) memmove(dst, src, len) #define MemCpy(dst, src, len) memcpy(dst, src, len) #define MemAppend(dst, src, len) mempcpy(dst, src, len) diff --git a/src/main.c b/src/main.c index 03e30d0..ae11172 100644 --- a/src/main.c +++ b/src/main.c @@ -24,8 +24,8 @@ static void arena_test_1(void) arena_params.size = 1024+ARENA_HEADER_SZ; Arena *arena = arena_alloc_(&arena_params); arena_dump(arena); - char *ptr = arena_push(arena, 1024, 1); - MemoryZero(ptr, 1024); + char *ptr = arena_push(arena, 512, 1); + MemoryZero(ptr, 512); printf("Allocated ptr %p\n", ptr); arena_dump(arena); ptr = arena_push(arena, 512, 1); @@ -62,6 +62,7 @@ static void arena_test_2(void) arena_pop_to(arena, 1088); arena_dump(arena); ptr = arena_push(arena, 1, 1); + ((U8*)ptr)[1] =1; //OOB ptr = arena_push(arena, 1, 1); arena_pop_to(arena, 1089); arena_dump(arena); @@ -71,5 +72,6 @@ static void arena_test_2(void) int main(int argc, char *argv[]) { + arena_test_1(); arena_test_2(); }