From 461fee5328fd4450126c495cb6823c33c0588672 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 14 May 2020 17:42:54 +0200 Subject: BLI: deduplicate address sanitizer code Reviewers: brecht, campbellbarton Differential Revision: https://developer.blender.org/D7731 --- source/blender/blenlib/BLI_asan.h | 45 ++++++++++++++++++++++++++++ source/blender/blenlib/CMakeLists.txt | 2 +- source/blender/blenlib/intern/BLI_memarena.c | 21 ++++--------- source/blender/blenlib/intern/BLI_memiter.c | 21 ++++--------- 4 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 source/blender/blenlib/BLI_asan.h (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_asan.h b/source/blender/blenlib/BLI_asan.h new file mode 100644 index 00000000000..fdade805c2a --- /dev/null +++ b/source/blender/blenlib/BLI_asan.h @@ -0,0 +1,45 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __BLI_ADDRESS_SANITIZER_H__ +#define __BLI_ADDRESS_SANITIZER_H__ + +/* Clang defines this. */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) +# include "sanitizer/asan_interface.h" +#else +/* Ensure return value is used. Just using UNUSED_VARS results in a warning. */ +# define ASAN_POISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) +# define ASAN_UNPOISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) +#endif + +/** + * Mark a region of memory as "freed". When using address sanitizer, accessing the given memory + * region will cause an use-after-poison error. This can be used to find errors when dealing with + * uninitialized memory in custom containers. + */ +#define BLI_asan_poison(addr, size) ASAN_POISON_MEMORY_REGION(addr, size) + +/** + * Mark a region of memory as usable again. + */ +#define BLI_asan_unpoison(addr, size) ASAN_UNPOISON_MEMORY_REGION(addr, size) + +#endif /* __BLI_ADDRESS_SANITIZER_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ab9b3e19ab9..18d58cdcaf3 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -138,7 +138,7 @@ set(SRC intern/list_sort_impl.h - + BLI_asan.h BLI_alloca.h BLI_allocator.hh BLI_args.h diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index fd2367aa992..fc381c22315 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -34,6 +34,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_asan.h" #include "BLI_memarena.h" #include "BLI_strict_flags.h" #include "BLI_utildefines.h" @@ -46,18 +47,6 @@ # define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) UNUSED_VARS(pool, addr, size) #endif -/* Clang defines this. */ -#ifndef __has_feature -# define __has_feature(x) 0 -#endif -#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) -# include "sanitizer/asan_interface.h" -#else -/* Ensure return value is used. */ -# define ASAN_POISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) -# define ASAN_UNPOISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) -#endif - struct MemBuf { struct MemBuf *next; uchar data[0]; @@ -80,7 +69,7 @@ static void memarena_buf_free_all(struct MemBuf *mb) struct MemBuf *mb_next = mb->next; /* Unpoison memory because MEM_freeN might overwrite it. */ - ASAN_UNPOISON_MEMORY_REGION(mb, (uint)MEM_allocN_len(mb)); + BLI_asan_unpoison(mb, (uint)MEM_allocN_len(mb)); MEM_freeN(mb); mb = mb_next; @@ -160,7 +149,7 @@ void *BLI_memarena_alloc(MemArena *ma, size_t size) mb->next = ma->bufs; ma->bufs = mb; - ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize); + BLI_asan_poison(ma->curbuf, ma->cursize); memarena_curbuf_align(ma); } @@ -171,7 +160,7 @@ void *BLI_memarena_alloc(MemArena *ma, size_t size) VALGRIND_MEMPOOL_ALLOC(ma, ptr, size); - ASAN_UNPOISON_MEMORY_REGION(ptr, size); + BLI_asan_unpoison(ptr, size); return ptr; } @@ -215,7 +204,7 @@ void BLI_memarena_clear(MemArena *ma) if (ma->use_calloc) { memset(ma->curbuf, 0, curbuf_used); } - ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize); + BLI_asan_poison(ma->curbuf, ma->cursize); } VALGRIND_DESTROY_MEMPOOL(ma); diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c index 017f08f8d35..1b9509e36d8 100644 --- a/source/blender/blenlib/intern/BLI_memiter.c +++ b/source/blender/blenlib/intern/BLI_memiter.c @@ -40,6 +40,7 @@ #include #include +#include "BLI_asan.h" #include "BLI_utildefines.h" #include "BLI_memiter.h" /* own include */ @@ -50,18 +51,6 @@ /* TODO: Valgrind. */ -/* Clang defines this. */ -#ifndef __has_feature -# define __has_feature(x) 0 -#endif -#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) -# include "sanitizer/asan_interface.h" -#else -/* Ensure return value is used. */ -# define ASAN_POISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) -# define ASAN_UNPOISON_MEMORY_REGION(addr, size) (void)(0 && ((size) != 0 && (addr) != NULL)) -#endif - typedef uintptr_t data_t; typedef intptr_t offset_t; @@ -114,7 +103,7 @@ static void memiter_set_rewind_offset(BLI_memiter *mi) { BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr; - ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem)); + BLI_asan_unpoison(elem, sizeof(BLI_memiter_elem)); elem->size = (offset_t)(((data_t *)mi->tail) - mi->data_curr); BLI_assert(elem->size < 0); @@ -197,14 +186,14 @@ void *BLI_memiter_alloc(BLI_memiter *mi, uint elem_size) mi->data_last = chunk->data + (chunk_size - 1); data_curr_next = mi->data_curr + (1 + data_offset); - ASAN_POISON_MEMORY_REGION(chunk->data, chunk_size * sizeof(data_t)); + BLI_asan_poison(chunk->data, chunk_size * sizeof(data_t)); } BLI_assert(data_curr_next <= mi->data_last); BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr; - ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem) + elem_size); + BLI_asan_unpoison(elem, sizeof(BLI_memiter_elem) + elem_size); elem->size = (offset_t)elem_size; mi->data_curr = data_curr_next; @@ -242,7 +231,7 @@ static void memiter_free_data(BLI_memiter *mi) BLI_memiter_chunk *chunk_next = chunk->next; /* Unpoison memory because MEM_freeN might overwrite it. */ - ASAN_UNPOISON_MEMORY_REGION(chunk, MEM_allocN_len(chunk)); + BLI_asan_unpoison(chunk, MEM_allocN_len(chunk)); MEM_freeN(chunk); chunk = chunk_next; -- cgit v1.2.3