cmake: Update CONFIG_ASAN support
This had bitrotten a bit, and didn't build as shipped. Current libasan implementations want -fsanitize=address passed as a linker argument too. We have grown a "lld" linker variant that needs the same cmake treatment as the "ld" binutils one, but never got it. But the various flags had been cut/pasted around to different places, with slightly different forms. That's really sort of a mess, as sanitizer support was only ever support with host toolchains for native_posix (and AFAICT no one anywhere has made this work on cross compilers in an embedded environment). And the separate "gcc" vs. "llvm" layers were silly, as there has only ever been one API for this feature (from LLVM, then picked up compatibly by gcc). Pull this stuff out and just do it in one place in the posix arch for simplicity. Also recent sanitizers are trying to add instrumentation padding around data that we use linker trickery to pack tightly (c.f. SYS_INIT, STRUCT_SECTION_ITERABLE) and we need a way ("__noasan") to turn that off. Actually for gcc, it was enough to just make the records const (already true for most of them, except a native_posix init struct), but clang apparently isn't smart enough. Finally, add an ASAN_RECOVER kconfig that enables the use of "halt_on_error=0" in $ASAN_OPTIONS, which continues execution past the first error. Signed-off-by: Andy Ross <andyross@google.com>
This commit is contained in:
parent
d6297988be
commit
74cc534758
13 changed files with 61 additions and 43 deletions
|
@ -28,15 +28,6 @@ if (CONFIG_GPROF)
|
|||
zephyr_compile_options($<TARGET_PROPERTY:compiler,gprof>)
|
||||
zephyr_link_libraries($<TARGET_PROPERTY:linker,gprof>)
|
||||
endif()
|
||||
if (CONFIG_ASAN)
|
||||
zephyr_compile_options($<TARGET_PROPERTY:compiler,sanitize_address>)
|
||||
zephyr_link_libraries($<TARGET_PROPERTY:linker,sanitize_address>)
|
||||
endif ()
|
||||
|
||||
if (CONFIG_UBSAN)
|
||||
zephyr_compile_options($<TARGET_PROPERTY:compiler,sanitize_undefined>)
|
||||
zephyr_link_libraries($<TARGET_PROPERTY:linker,sanitize_undefined>)
|
||||
endif ()
|
||||
|
||||
zephyr_compile_definitions(_POSIX_C_SOURCE=200809 _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED)
|
||||
|
||||
|
@ -53,5 +44,29 @@ zephyr_ld_options(
|
|||
# Zephyr which will clash with the native POSIX API] . It would also need to
|
||||
# be included in a few zephyr kernel files.
|
||||
|
||||
#
|
||||
# Support for the LLVM Sanitizer toolchain instrumentation frameworks
|
||||
# (supported by current gcc's as well)
|
||||
#
|
||||
|
||||
if(CONFIG_ASAN)
|
||||
list(APPEND LLVM_SANITIZERS "address")
|
||||
endif()
|
||||
|
||||
if(CONFIG_UBSAN)
|
||||
list(APPEND LLVM_SANITIZERS "undefined")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ASAN_RECOVER)
|
||||
zephyr_compile_options(-fsanitize-recover=all)
|
||||
endif()
|
||||
|
||||
list(JOIN LLVM_SANITIZERS "," LLVM_SANITIZERS_ARG)
|
||||
if(NOT ${LLVM_SANITIZERS_ARG} STREQUAL "")
|
||||
set(LLVM_SANITIZERS_ARG "-fsanitize=${LLVM_SANITIZERS_ARG}")
|
||||
zephyr_compile_options("${LLVM_SANITIZERS_ARG}")
|
||||
zephyr_link_libraries("${LLVM_SANITIZERS_ARG}")
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(core)
|
||||
|
|
|
@ -162,11 +162,6 @@ set_compiler_property(PROPERTY coverage "")
|
|||
# mwdt compiler flags for imacros. The specific header must be appended by user.
|
||||
set_compiler_property(PROPERTY imacros -imacros)
|
||||
|
||||
#no support of -fsanitize=address and -lasan
|
||||
set_compiler_property(PROPERTY sanitize_address "")
|
||||
|
||||
set_compiler_property(PROPERTY sanitize_undefined "")
|
||||
|
||||
# Security canaries.
|
||||
#no support of -mstack-protector-guard=global"
|
||||
set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
|
||||
|
|
|
@ -101,11 +101,6 @@ set_compiler_property(PROPERTY no_common)
|
|||
# Flags for imacros. The specific header must be appended by user.
|
||||
set_compiler_property(PROPERTY imacros)
|
||||
|
||||
# Compiler flags for sanitizing.
|
||||
set_compiler_property(PROPERTY sanitize_address)
|
||||
|
||||
set_compiler_property(PROPERTY sanitize_undefined)
|
||||
|
||||
# Compiler flag for turning off thread-safe initialization of local statics
|
||||
set_property(TARGET compiler-cpp PROPERTY no_threadsafe_statics)
|
||||
|
||||
|
|
|
@ -177,13 +177,8 @@ set_compiler_property(PROPERTY no_common -fno-common)
|
|||
# GCC compiler flags for imacros. The specific header must be appended by user.
|
||||
set_compiler_property(PROPERTY imacros -imacros)
|
||||
|
||||
# GCC compiler flags for sanitizing.
|
||||
set_compiler_property(PROPERTY sanitize_address -fsanitize=address)
|
||||
|
||||
set_compiler_property(PROPERTY gprof -pg)
|
||||
|
||||
set_compiler_property(PROPERTY sanitize_undefined -fsanitize=undefined)
|
||||
|
||||
# GCC compiler flag for turning off thread-safe initialization of local statics
|
||||
set_property(TARGET compiler-cpp PROPERTY no_threadsafe_statics "-fno-threadsafe-statics")
|
||||
|
||||
|
|
|
@ -2,8 +2,3 @@
|
|||
if (NOT CONFIG_COVERAGE_GCOV)
|
||||
set_property(TARGET linker PROPERTY coverage --coverage)
|
||||
endif()
|
||||
|
||||
# ld/clang linker flags for sanitizing.
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address)
|
||||
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined)
|
||||
|
|
|
@ -7,9 +7,4 @@ if (NOT CONFIG_COVERAGE_GCOV)
|
|||
set_property(TARGET linker PROPERTY coverage -lgcov)
|
||||
endif()
|
||||
|
||||
# ld/gcc linker flags for sanitizing.
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -lasan)
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address)
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined)
|
||||
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY gprof -pg)
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
# Set the property for the corresponding flags of the given toolchain.
|
||||
set_property(TARGET linker PROPERTY coverage)
|
||||
|
||||
# Linker flags for sanitizing.
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address)
|
||||
|
||||
check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined)
|
||||
|
||||
# Linker flag for printing of memusage.
|
||||
# Set this flag if the linker supports reporting of memusage as part of link,
|
||||
# such as ls --print-memory-usage flag.
|
||||
|
|
|
@ -91,7 +91,7 @@ void z_sys_init_run_level(int32_t level);
|
|||
*/
|
||||
#define Z_INIT_ENTRY_DEFINE(_entry_name, _init_fn, _device, _level, _prio) \
|
||||
static const Z_DECL_ALIGN(struct init_entry) \
|
||||
Z_INIT_ENTRY_NAME(_entry_name) __used \
|
||||
Z_INIT_ENTRY_NAME(_entry_name) __used __noasan \
|
||||
__attribute__((__section__(".z_init_" #_level STRINGIFY(_prio)"_"))) = { \
|
||||
.init = (_init_fn), \
|
||||
.dev = (_device), \
|
||||
|
|
|
@ -52,6 +52,21 @@
|
|||
#error "Invalid/unknown toolchain configuration"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def __noasan
|
||||
* @brief Disable address sanitizer
|
||||
*
|
||||
* When used in the definiton of a symbol, prevents that symbol (be it
|
||||
* a function or data) from being instrumented by the address
|
||||
* sanitizer feature of the compiler. Most commonly, this is used to
|
||||
* prevent padding around data that will be treated specially by the
|
||||
* Zephyr link (c.f. SYS_INIT records, STRUCT_SECTION_ITERABLE
|
||||
* definitions) in ways that don't understand the guard padding.
|
||||
*/
|
||||
#ifndef __noasan
|
||||
#define __noasan /**/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def GCC_VERSION
|
||||
* @brief GCC version in xxyyzz for xx.yy.zz. Zero if not GCC compatible.
|
||||
|
|
|
@ -209,7 +209,7 @@
|
|||
*/
|
||||
#define STRUCT_SECTION_ITERABLE(struct_type, name) \
|
||||
Z_DECL_ALIGN(struct struct_type) name \
|
||||
__in_section(_##struct_type, static, name) __used
|
||||
__in_section(_##struct_type, static, name) __used __noasan
|
||||
|
||||
/**
|
||||
* @brief Defines an alternate data type iterable section.
|
||||
|
@ -221,7 +221,7 @@
|
|||
*/
|
||||
#define STRUCT_SECTION_ITERABLE_ALTERNATE(out_type, struct_type, name) \
|
||||
Z_DECL_ALIGN(struct struct_type) name \
|
||||
__in_section(_##out_type, static, name) __used
|
||||
__in_section(_##out_type, static, name) __used __noasan
|
||||
|
||||
/**
|
||||
* @brief Iterate over a specified iterable section.
|
||||
|
|
|
@ -618,5 +618,11 @@ do { \
|
|||
*/
|
||||
#define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
|
||||
|
||||
#ifdef CONFIG_ASAN
|
||||
#define __noasan __attribute__((no_sanitize("address")))
|
||||
#else
|
||||
#define __noasan /**/
|
||||
#endif
|
||||
|
||||
#endif /* !_LINKER */
|
||||
#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */
|
||||
|
|
|
@ -43,7 +43,7 @@ void posix_soc_clean_up(void);
|
|||
* any Zephyr thread are running.
|
||||
*/
|
||||
#define NATIVE_TASK(fn, level, prio) \
|
||||
static void (*_CONCAT(__native_task_, fn)) __used \
|
||||
static const void (*_CONCAT(__native_task_, fn)) __used __noasan \
|
||||
__attribute__((__section__(".native_" #level STRINGIFY(prio) "_task")))\
|
||||
= fn
|
||||
|
||||
|
|
|
@ -120,6 +120,18 @@ config ASAN
|
|||
This behavior can be changes by adding leak_check_at_exit=1 to the
|
||||
environment variable ASAN_OPTIONS.
|
||||
|
||||
config ASAN_RECOVER
|
||||
bool "Continue after sanitizer errors"
|
||||
depends on ASAN
|
||||
default y
|
||||
help
|
||||
The default behavior of compiler sanitizers is to exit after
|
||||
the first error. Set this to y to enable the code to
|
||||
continue, which can be useful if a code base has known
|
||||
unsuppressed errors. You will also need to set
|
||||
"halt_on_error=0" in your ASAN_OPTIONS environment variable
|
||||
at runtime.
|
||||
|
||||
config ASAN_NOP_DLCLOSE
|
||||
bool "Override host OS dlclose() with a NOP"
|
||||
default y if HAS_SDL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue