diff options
-rw-r--r-- | .github/workflows/test.yml | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 18 | ||||
-rw-r--r-- | CONTRIBUTING.md | 6 | ||||
-rw-r--r-- | cmake.deps/cmake/BuildLua.cmake | 2 | ||||
-rwxr-xr-x | contrib/asan.sh | 2 | ||||
-rw-r--r-- | contrib/flake.nix | 2 | ||||
-rw-r--r-- | src/.asan-blacklist | 3 | ||||
-rwxr-xr-x | src/nvim/CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/nvim/README.md | 6 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 4 | ||||
-rw-r--r-- | src/nvim/event/multiqueue.c | 1 | ||||
-rw-r--r-- | src/nvim/func_attr.h | 15 | ||||
-rw-r--r-- | src/uncrustify.cfg | 1 |
13 files changed, 48 insertions, 31 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e6f05d973..0d18f874c4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -132,11 +132,11 @@ jobs: - flavor: asan cc: clang runner: ubuntu-22.04 - flags: -D CLANG_ASAN_UBSAN=ON + flags: -D ENABLE_ASAN_UBSAN=ON - flavor: tsan cc: clang runner: ubuntu-22.04 - flags: -D CLANG_TSAN=ON + flags: -D ENABLE_TSAN=ON - flavor: uchar cc: gcc runner: ubuntu-22.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index 266ac0354b..262af9ab55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,19 +135,21 @@ endif() option(LOG_LIST_ACTIONS "Add list actions logging" OFF) -option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF) +option(ENABLE_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF) option(LOG_DEBUG "Enable debug log messages even in a release build" OFF) -option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF) -option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF) +option(ENABLE_MSAN "Enable Clang memory sanitizer for nvim binary." OFF) +option(ENABLE_TSAN "Enable Clang thread sanitizer for nvim binary." OFF) -if((CLANG_ASAN_UBSAN AND CLANG_MSAN) - OR (CLANG_ASAN_UBSAN AND CLANG_TSAN) - OR (CLANG_MSAN AND CLANG_TSAN)) +if((ENABLE_ASAN_UBSAN AND ENABLE_MSAN) + OR (ENABLE_ASAN_UBSAN AND ENABLE_TSAN) + OR (ENABLE_MSAN AND ENABLE_TSAN)) message(FATAL_ERROR "Sanitizers cannot be enabled simultaneously") endif() -if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") - message(FATAL_ERROR "Sanitizers are only supported for Clang") +if(ENABLE_ASAN_UBSAN OR ENABLE_MSAN OR ENABLE_TSAN) + if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_ID MATCHES "GNU") + message(FATAL_ERROR "Sanitizers are only supported for Clang and GCC") + endif() endif() # Place targets in bin/ or lib/ for all build configurations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91f2ff64dc..c73c205183 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -124,7 +124,7 @@ Each pull request must pass the automated builds on [Cirrus CI] and [GitHub Acti - If any tests fail, the build will fail. See [test/README.md#running-tests][run-tests] to run tests locally. - CI runs [ASan] and other analyzers. - To run valgrind locally: `VALGRIND=1 make test` - - To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DCLANG_ASAN_UBSAN=ON"` + - To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DENABLE_ASAN_UBSAN=ON"` - The [lint](#lint) build checks modified lines _and their immediate neighbors_, to encourage incrementally updating the legacy style to meet our [style](#style). (See [#3174][3174] for background.) @@ -183,7 +183,7 @@ master build. To view the defects, just request access; you will be approved. - To build Neovim with sanitizers enabled, use ``` - rm -rf build && CMAKE_EXTRA_FLAGS="-DCMAKE_C_COMPILER=clang -DCLANG_ASAN_UBSAN=1" make + rm -rf build && CMAKE_EXTRA_FLAGS="-DCMAKE_C_COMPILER=clang -DENABLE_ASAN_UBSAN=1" make ``` - When running Neovim, use ``` @@ -294,7 +294,7 @@ If a function in your Lua module should not be documented (e.g. internal functio ---@private ``` -Mark functions that are deprecated as +Mark functions that are deprecated as ``` ---@deprecated ``` diff --git a/cmake.deps/cmake/BuildLua.cmake b/cmake.deps/cmake/BuildLua.cmake index 2817418eb2..3e7b5dee51 100644 --- a/cmake.deps/cmake/BuildLua.cmake +++ b/cmake.deps/cmake/BuildLua.cmake @@ -19,7 +19,7 @@ endif() set(LUA_CFLAGS "-O0 -g3 -fPIC") set(LUA_LDFLAGS "") -if(CLANG_ASAN_UBSAN) +if(ENABLE_ASAN_UBSAN) set(LUA_CFLAGS "${LUA_CFLAGS} -fsanitize=address") set(LUA_CFLAGS "${LUA_CFLAGS} -fno-omit-frame-pointer") set(LUA_CFLAGS "${LUA_CFLAGS} -fno-optimize-sibling-calls") diff --git a/contrib/asan.sh b/contrib/asan.sh index 7e7dffa1af..baf7abb5a8 100755 --- a/contrib/asan.sh +++ b/contrib/asan.sh @@ -16,7 +16,7 @@ export ASAN_OPTIONS="detect_leaks=0:log_path=$log_path/asan" # Show backtraces in the logs. export UBSAN_OPTIONS="print_stacktrace=1" -make -C "$root_path" CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON" +make -C "$root_path" CMAKE_EXTRA_FLAGS="-DENABLE_ASAN_UBSAN=ON" VIMRUNTIME="$root_path"/runtime "$root_path"/build/bin/nvim # Need to manually reset terminal to avoid mangled output, nvim does not diff --git a/contrib/flake.nix b/contrib/flake.nix index 3884ee9a2b..75c94392e1 100644 --- a/contrib/flake.nix +++ b/contrib/flake.nix @@ -48,7 +48,7 @@ ] ++ final.lib.optionals final.stdenv.isLinux [ # https://github.com/google/sanitizers/wiki/AddressSanitizerFlags # https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports - "-DCLANG_ASAN_UBSAN=ON" + "-DENABLE_ASAN_UBSAN=ON" ]; }); }; diff --git a/src/.asan-blacklist b/src/.asan-blacklist deleted file mode 100644 index 928d81bd5a..0000000000 --- a/src/.asan-blacklist +++ /dev/null @@ -1,3 +0,0 @@ -# multiqueue.h pointer arithmetic is not accepted by asan -fun:multiqueue_node_data -fun:tv_dict_watcher_node_data diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 9b42a442a1..2117bc375c 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -200,9 +200,9 @@ endif() option(ENABLE_GCOV "Enable gcov support" OFF) if(ENABLE_GCOV) - if(CLANG_TSAN) + if(ENABLE_TSAN) # GCOV and TSAN results in false data race reports - message(FATAL_ERROR "ENABLE_GCOV cannot be used with CLANG_TSAN") + message(FATAL_ERROR "ENABLE_GCOV cannot be used with ENABLE_TSAN") endif() message(STATUS "Enabling gcov support") target_compile_options(main_lib INTERFACE --coverage) @@ -378,7 +378,7 @@ else() target_compile_definitions(nvim PRIVATE $<$<CONFIG:Debug>:NVIM_LOG_DEBUG>) endif() -if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) +if(ENABLE_ASAN_UBSAN OR ENABLE_MSAN OR ENABLE_TSAN) target_compile_definitions(main_lib INTERFACE EXITFREE) endif() @@ -791,7 +791,7 @@ set_target_properties( target_compile_definitions(libnvim PRIVATE MAKE_LIB) target_link_libraries(libnvim PRIVATE main_lib PUBLIC libuv) -if(CLANG_ASAN_UBSAN) +if(ENABLE_ASAN_UBSAN) message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.") if(CI_BUILD) # Try to recover from all sanitize issues so we get reports about all failures @@ -803,10 +803,9 @@ if(CLANG_ASAN_UBSAN) -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address - -fsanitize=undefined - -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist) + -fsanitize=undefined) target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) -elseif(CLANG_MSAN) +elseif(ENABLE_MSAN) message(STATUS "Enabling Clang memory sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=memory @@ -814,7 +813,7 @@ elseif(CLANG_MSAN) -fno-omit-frame-pointer -fno-optimize-sibling-calls) target_link_libraries(nvim PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) -elseif(CLANG_TSAN) +elseif(ENABLE_TSAN) message(STATUS "Enabling Clang thread sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=thread -fPIE) target_link_libraries(nvim PRIVATE -fsanitize=thread) diff --git a/src/nvim/README.md b/src/nvim/README.md index 5a6d63c662..69d5939c70 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -60,9 +60,9 @@ Requires clang 3.4 or later, and `llvm-symbolizer` must be in `$PATH`: Build Nvim with sanitizer instrumentation (choose one): - CC=clang make CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON" - CC=clang make CMAKE_EXTRA_FLAGS="-DCLANG_MSAN=ON" - CC=clang make CMAKE_EXTRA_FLAGS="-DCLANG_TSAN=ON" + CC=clang make CMAKE_EXTRA_FLAGS="-DENABLE_ASAN_UBSAN=ON" + CC=clang make CMAKE_EXTRA_FLAGS="-DENABLE_MSAN=ON" + CC=clang make CMAKE_EXTRA_FLAGS="-DENABLE_TSAN=ON" Create a directory to store logs: diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 4a2654f03e..84e4067f9d 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -518,13 +518,15 @@ static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_PURE - REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; + REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE + FUNC_ATTR_NO_SANITIZE_ADDRESS; /// Compute the `DictWatcher` address from a QUEUE node. /// /// This only exists for .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer /// arithmetic). static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) + FUNC_ATTR_NO_SANITIZE_ADDRESS { return QUEUE_DATA(q, DictWatcher, node); } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index e05084b656..8f8a36eff9 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -245,6 +245,7 @@ static void multiqueue_push(MultiQueue *this, Event event) } static MultiQueueItem *multiqueue_node_data(QUEUE *q) + FUNC_ATTR_NO_SANITIZE_ADDRESS { return QUEUE_DATA(q, MultiQueueItem, node); } diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index 6c049df6ff..4b434f6771 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -99,6 +99,10 @@ # undef FUNC_ATTR_NO_SANITIZE_UNDEFINED #endif +#ifdef FUNC_ATTR_NO_SANITIZE_ADDRESS +# undef FUNC_ATTR_NO_SANITIZE_ADDRESS +#endif + #ifdef FUNC_ATTR_PRINTF # undef FUNC_ATTR_PRINTF #endif @@ -139,6 +143,11 @@ # define REAL_FATTR_NO_SANITIZE_UNDEFINED \ __attribute__((no_sanitize("undefined"))) # endif + +# if NVIM_HAS_ATTRIBUTE(no_sanitize_address) +# define REAL_FATTR_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize_address)) +# endif # endif // Define attributes that are not defined for this compiler. @@ -199,6 +208,10 @@ # define REAL_FATTR_NO_SANITIZE_UNDEFINED # endif +# ifndef REAL_FATTR_NO_SANITIZE_ADDRESS +# define REAL_FATTR_NO_SANITIZE_ADDRESS +# endif + # ifndef REAL_FATTR_PRINTF # define REAL_FATTR_PRINTF(x, y) # endif @@ -233,6 +246,7 @@ # define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET # define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_NO_SANITIZE_ADDRESS REAL_FATTR_NO_SANITIZE_ADDRESS # define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y) #elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES) # define FUNC_ATTR_MALLOC @@ -249,5 +263,6 @@ # define FUNC_ATTR_NONNULL_RET # define FUNC_ATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_NO_SANITIZE_ADDRESS # define FUNC_ATTR_PRINTF(x, y) #endif diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg index f9e6617d40..9c6b6bac6c 100644 --- a/src/uncrustify.cfg +++ b/src/uncrustify.cfg @@ -3504,6 +3504,7 @@ set QUESTION FUNC_ATTR_NONNULL_ARG set QUESTION FUNC_ATTR_NONNULL_RET set QUESTION FUNC_ATTR_NORETURN set QUESTION FUNC_ATTR_NO_SANITIZE_UNDEFINED +set QUESTION FUNC_ATTR_NO_SANITIZE_ADDRESS set QUESTION FUNC_ATTR_PRINTF set QUESTION FUNC_ATTR_PURE set QUESTION FUNC_ATTR_UNUSED |