diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index 4dfcb9a28245..4ad249e60bd3 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -28,15 +28,6 @@ if (CONFIG_GPROF) zephyr_compile_options($) zephyr_link_libraries($) endif() -if (CONFIG_ASAN) - zephyr_compile_options($) - zephyr_link_libraries($) -endif () - -if (CONFIG_UBSAN) - zephyr_compile_options($) - zephyr_link_libraries($) -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) diff --git a/cmake/compiler/arcmwdt/compiler_flags.cmake b/cmake/compiler/arcmwdt/compiler_flags.cmake index ed2e6179618b..341256ec10ee 100644 --- a/cmake/compiler/arcmwdt/compiler_flags.cmake +++ b/cmake/compiler/arcmwdt/compiler_flags.cmake @@ -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) diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index 28b2e7a805a0..44bca0324d95 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -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) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index b051e15b2216..ac0724022b8f 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -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") diff --git a/cmake/linker/ld/clang/linker_flags.cmake b/cmake/linker/ld/clang/linker_flags.cmake index 5f4c036b68c8..fd4f6f2b48ef 100644 --- a/cmake/linker/ld/clang/linker_flags.cmake +++ b/cmake/linker/ld/clang/linker_flags.cmake @@ -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) diff --git a/cmake/linker/ld/gcc/linker_flags.cmake b/cmake/linker/ld/gcc/linker_flags.cmake index 7a2ffdf4c0cc..4a816a78fcca 100644 --- a/cmake/linker/ld/gcc/linker_flags.cmake +++ b/cmake/linker/ld/gcc/linker_flags.cmake @@ -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) diff --git a/cmake/linker/linker_flags_template.cmake b/cmake/linker/linker_flags_template.cmake index 7b7c3cca7922..910515c31196 100644 --- a/cmake/linker/linker_flags_template.cmake +++ b/cmake/linker/linker_flags_template.cmake @@ -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. diff --git a/include/zephyr/init.h b/include/zephyr/init.h index 11780c5e20bf..1abadcdbc193 100644 --- a/include/zephyr/init.h +++ b/include/zephyr/init.h @@ -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), \ diff --git a/include/zephyr/toolchain.h b/include/zephyr/toolchain.h index 6e8deefe3d77..ca348fea60e7 100644 --- a/include/zephyr/toolchain.h +++ b/include/zephyr/toolchain.h @@ -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. diff --git a/include/zephyr/toolchain/common.h b/include/zephyr/toolchain/common.h index e7b58a5ac564..cf2dce5676dc 100644 --- a/include/zephyr/toolchain/common.h +++ b/include/zephyr/toolchain/common.h @@ -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. diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index 756830c4d964..f3cef4d12a8e 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -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_ */ diff --git a/soc/posix/inf_clock/soc.h b/soc/posix/inf_clock/soc.h index fb79b7e1bee9..5805ba3218e7 100644 --- a/soc/posix/inf_clock/soc.h +++ b/soc/posix/inf_clock/soc.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 diff --git a/subsys/debug/Kconfig b/subsys/debug/Kconfig index 60a3dc9a1c25..19abfc5b0c51 100644 --- a/subsys/debug/Kconfig +++ b/subsys/debug/Kconfig @@ -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