arch/posix: Add MemorySanitizer support
Wire this up the same way ASAN works. Right now it's support only by recent clang versions (not gcc), and only in 64 bit mode. But it's capable of detecting uninitialized data reads, which ASAN is not. This support is wired into the sys_heap (and thus k_heap/k_malloc) layers, allowing detection of heap misuse like use-after-free. Note that there is one false negative lurking: due to complexity, in the case where a sys_heap_realloc() call is able to shrink memory in place, the now-unused suffix is not marked uninitialized immediately, making it impossible to detect use-after-free of those particular bytes. But the system will recover cleanly the next time the memory gets allocated. Also no attempt was made to integrate this handling into the newlib or picolibc allocators, though that should hopefully be possible via similar means. Signed-off-by: Andy Ross <andyross@google.com>
This commit is contained in:
parent
74cc534758
commit
02b23f3733
3 changed files with 24 additions and 0 deletions
|
@ -53,6 +53,10 @@ if(CONFIG_ASAN)
|
|||
list(APPEND LLVM_SANITIZERS "address")
|
||||
endif()
|
||||
|
||||
if(CONFIG_MSAN)
|
||||
list(APPEND LLVM_SANITIZERS "memory")
|
||||
endif()
|
||||
|
||||
if(CONFIG_UBSAN)
|
||||
list(APPEND LLVM_SANITIZERS "undefined")
|
||||
endif()
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include <zephyr/kernel.h>
|
||||
#include <string.h>
|
||||
#include "heap.h"
|
||||
#ifdef CONFIG_MSAN
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
|
||||
static inline void increase_allocated_bytes(struct z_heap *h, size_t num_bytes)
|
||||
|
@ -291,6 +294,7 @@ void *sys_heap_alloc(struct sys_heap *heap, size_t bytes)
|
|||
chunksz_to_bytes(h, chunk_size(h, c)));
|
||||
#endif
|
||||
|
||||
IF_ENABLED(CONFIG_MSAN, (__msan_allocated_memory(mem, bytes)));
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
@ -358,6 +362,7 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes)
|
|||
}
|
||||
|
||||
set_chunk_used(h, c, true);
|
||||
|
||||
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
|
||||
increase_allocated_bytes(h, chunksz_to_bytes(h, chunk_size(h, c)));
|
||||
#endif
|
||||
|
@ -367,6 +372,7 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes)
|
|||
chunksz_to_bytes(h, chunk_size(h, c)));
|
||||
#endif
|
||||
|
||||
IF_ENABLED(CONFIG_MSAN, (__msan_allocated_memory(mem, bytes)));
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
@ -478,6 +484,8 @@ void *sys_heap_aligned_realloc(struct sys_heap *heap, void *ptr,
|
|||
|
||||
void sys_heap_init(struct sys_heap *heap, void *mem, size_t bytes)
|
||||
{
|
||||
IF_ENABLED(CONFIG_MSAN, (__sanitizer_dtor_callback(mem, bytes)));
|
||||
|
||||
if (IS_ENABLED(CONFIG_SYS_HEAP_SMALL_ONLY)) {
|
||||
/* Must fit in a 15 bit count of HUNK_UNIT */
|
||||
__ASSERT(bytes / CHUNK_UNIT <= 0x7fffU, "heap size is too big");
|
||||
|
|
|
@ -154,6 +154,18 @@ config UBSAN
|
|||
architecture, and requires a recent-ish compiler with the
|
||||
``-fsanitize=undefined`` command line option.
|
||||
|
||||
config MSAN
|
||||
bool "Build with memory sanitizer"
|
||||
depends on ARCH_POSIX
|
||||
help
|
||||
Builds Zephyr with the LLVM MemorySanitizer enabled. Works
|
||||
only on the posix architecture currently, and only with host
|
||||
compilers recent enough to support the feature (currently
|
||||
clang on x86_64 only). It cannot be used in tandem with
|
||||
CONFIG_ASAN due to clang limitations. You must choose one
|
||||
or the other (but can combine it with CONFIG_UBSAN if you
|
||||
like)
|
||||
|
||||
config STACK_USAGE
|
||||
bool "Generate stack usage information"
|
||||
help
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue