From cadb870ee38af6e4b6f61d9a1b104b8d3d517fac Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 20 Dec 2017 10:11:54 +0300 Subject: [PATCH] Mark unallocated/freed memory as inaccessible using ASan functionality Note: to disable it, AO_NO_MALLOC_POISON should be defined by client. * src/atomic_ops_malloc.c [AO_ADDRESS_SANITIZER && !AO_NO_MALLOC_POISON] (__asan_poison_memory_region, __asan_unpoison_memory_region): Prototype. * src/atomic_ops_malloc.c (ASAN_POISON_MEMORY_REGION, ASAN_UNPOISON_MEMORY_REGION): New macro. * src/atomic_ops_malloc.c (add_chunk_as): Call ASAN_POISON_MEMORY_REGION() for each pushed region. * src/atomic_ops_malloc.c (AO_malloc): Call ASAN_UNPOISON_MEMORY_REGION() for the returned memory region. * src/atomic_ops_malloc.c (AO_free): Call ASAN_POISON_MEMORY_REGION() before pushing the freed region to AO_free_list. --- src/atomic_ops_malloc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/atomic_ops_malloc.c b/src/atomic_ops_malloc.c index 7cc7ada..acb00a0 100644 --- a/src/atomic_ops_malloc.c +++ b/src/atomic_ops_malloc.c @@ -31,6 +31,19 @@ # include #endif +#if defined(AO_ADDRESS_SANITIZER) && !defined(AO_NO_MALLOC_POISON) + /* #include "sanitizer/asan_interface.h" */ + void __asan_poison_memory_region(void *, size_t); + void __asan_unpoison_memory_region(void *, size_t); +# 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)0 +# define ASAN_UNPOISON_MEMORY_REGION(addr, size) (void)0 +#endif /* !AO_ADDRESS_SANITIZER */ + #if (defined(_WIN32_WCE) || defined(__MINGW32CE__)) && !defined(AO_HAVE_abort) # define abort() _exit(-1) /* there is no abort() in WinCE */ #endif @@ -244,6 +257,8 @@ static void add_chunk_as(void * chunk, unsigned log_sz) assert (CHUNK_SIZE >= sz); limit = (size_t)CHUNK_SIZE - sz; for (ofs = ALIGNMENT - sizeof(AO_t); ofs <= limit; ofs += sz) { + ASAN_POISON_MEMORY_REGION((char *)chunk + ofs + sizeof(AO_t), + sz - sizeof(AO_t)); AO_stack_push(&AO_free_list[log_sz], (AO_t *)((char *)chunk + ofs)); } } @@ -330,6 +345,7 @@ AO_malloc(size_t sz) fprintf(stderr, "%p: AO_malloc(%lu) = %p\n", (void *)pthread_self(), (unsigned long)sz, (void *)(result + 1)); # endif + ASAN_UNPOISON_MEMORY_REGION(result + 1, sz); return result + 1; } @@ -355,6 +371,7 @@ AO_free(void *p) if (AO_EXPECT_FALSE(log_sz > LOG_MAX_SIZE)) { AO_free_large(p); } else { + ASAN_POISON_MEMORY_REGION(base + 1, ((size_t)1 << log_sz) - sizeof(AO_t)); AO_stack_push(AO_free_list + log_sz, base); } } -- 2.40.0