mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 16:26:36 +00:00
[nsan] Add nsan_preinit.cpp and make it static library only
#94322 defines .preinit_array to initialize nsan early. DT_PREINIT_ARRAY can only be used with the main executable. GNU ld would complain when a DSO has .preinit_array. Therefore, nsan_preinit.cpp cannot be linked into `libclang_rt.nsan.so` (#98415). Working with @alexander-shaposhnikov, we noticed that `Nsan-x86_64-Test --gtest_output=json` without `.preinit_array` will sigsegv. This is because googletest with the JSON output calls `localtime_r` , which calls `free(0)` and fails when `REAL(free)` remains uninitialized (nullptr). This is benign with the default output because malloc/free are all paired and `REAL(free)(ptr)` is not called. To fix the unittest failure, `__nsan_init` needs to be called early (.preinit_array). `asan/tests/CMakeLists.txt:ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS` ues `-fsanitize=address` to ensure `asan_preinit.cpp.o` is linked into the unittest executable. Port the approach and remove `NSAN_TEST_RUNTIME_OBJECTS`. Fix #98523 Pull Request: https://github.com/llvm/llvm-project/pull/98564
This commit is contained in:
parent
1bafe77d77
commit
a853fe25df
@ -11,6 +11,9 @@ set(NSAN_SOURCES
|
|||||||
nsan_suppressions.cpp
|
nsan_suppressions.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(NSAN_PREINIT_SOURCES
|
||||||
|
nsan_preinit.cpp)
|
||||||
|
|
||||||
set(NSAN_HEADERS
|
set(NSAN_HEADERS
|
||||||
nsan.h
|
nsan.h
|
||||||
nsan_flags.h
|
nsan_flags.h
|
||||||
@ -61,6 +64,12 @@ if(NOT APPLE)
|
|||||||
ADDITIONAL_HEADERS ${NSAN_HEADERS}
|
ADDITIONAL_HEADERS ${NSAN_HEADERS}
|
||||||
CFLAGS ${NSAN_CFLAGS})
|
CFLAGS ${NSAN_CFLAGS})
|
||||||
|
|
||||||
|
add_compiler_rt_object_libraries(RTNsan_preinit
|
||||||
|
ARCHS ${NSAN_SUPPORTED_ARCH}
|
||||||
|
SOURCES ${NSAN_PREINIT_SOURCES}
|
||||||
|
ADDITIONAL_HEADERS ${NSAN_HEADERS}
|
||||||
|
CFLAGS ${NSAN_CFLAGS})
|
||||||
|
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
|
||||||
add_compiler_rt_object_libraries(RTNsan_dynamic_version_script_dummy
|
add_compiler_rt_object_libraries(RTNsan_dynamic_version_script_dummy
|
||||||
ARCHS ${NSAN_SUPPORTED_ARCH}
|
ARCHS ${NSAN_SUPPORTED_ARCH}
|
||||||
@ -72,7 +81,7 @@ add_compiler_rt_runtime(
|
|||||||
clang_rt.nsan
|
clang_rt.nsan
|
||||||
STATIC
|
STATIC
|
||||||
ARCHS ${NSAN_SUPPORTED_ARCH}
|
ARCHS ${NSAN_SUPPORTED_ARCH}
|
||||||
OBJECT_LIBS RTNsan
|
OBJECT_LIBS RTNsan_preinit RTNsan
|
||||||
${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
|
${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
|
||||||
CFLAGS ${NSAN_CFLAGS}
|
CFLAGS ${NSAN_CFLAGS}
|
||||||
PARENT_TARGET nsan)
|
PARENT_TARGET nsan)
|
||||||
|
@ -801,8 +801,3 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __nsan_init() {
|
|||||||
nsan_init_is_running = false;
|
nsan_init_is_running = false;
|
||||||
nsan_initialized = true;
|
nsan_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SANITIZER_CAN_USE_PREINIT_ARRAY
|
|
||||||
__attribute__((section(".preinit_array"),
|
|
||||||
used)) static void (*nsan_init_ptr)() = __nsan_init;
|
|
||||||
#endif
|
|
||||||
|
@ -32,6 +32,8 @@ using __sanitizer::uptr;
|
|||||||
// Private nsan interface. Used e.g. by interceptors.
|
// Private nsan interface. Used e.g. by interceptors.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
void __nsan_init();
|
||||||
|
|
||||||
// This marks the shadow type of the given block of application memory as
|
// This marks the shadow type of the given block of application memory as
|
||||||
// unknown.
|
// unknown.
|
||||||
// printf-free (see comment in nsan_interceptors.cc).
|
// printf-free (see comment in nsan_interceptors.cc).
|
||||||
|
21
compiler-rt/lib/nsan/nsan_preinit.cpp
Normal file
21
compiler-rt/lib/nsan/nsan_preinit.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//===- nsan_preinit.cpp ---------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Call __nsan_init early using ELF DT_PREINIT_ARRAY.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "nsan/nsan.h"
|
||||||
|
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||||
|
|
||||||
|
#if SANITIZER_CAN_USE_PREINIT_ARRAY
|
||||||
|
|
||||||
|
__attribute__((section(".preinit_array"), used)) static auto nsan_preinit =
|
||||||
|
__nsan_init;
|
||||||
|
|
||||||
|
#endif
|
@ -15,6 +15,8 @@ set(NSAN_UNITTEST_LINK_FLAGS
|
|||||||
${COMPILER_RT_UNITTEST_LINK_FLAGS}
|
${COMPILER_RT_UNITTEST_LINK_FLAGS}
|
||||||
${COMPILER_RT_UNWINDER_LINK_LIBS}
|
${COMPILER_RT_UNWINDER_LINK_LIBS}
|
||||||
${SANITIZER_TEST_CXX_LIBRARIES})
|
${SANITIZER_TEST_CXX_LIBRARIES})
|
||||||
|
set(NSAN_UNITTEST_INSTRUMENTED_LINK_FLAGS ${NSAN_UNITTEST_LINK_FLAGS})
|
||||||
|
list(APPEND NSAN_UNITTEST_INSTRUMENTED_LINK_FLAGS -fsanitize=numerical)
|
||||||
|
|
||||||
file(GLOB NSAN_HEADERS ../*.h)
|
file(GLOB NSAN_HEADERS ../*.h)
|
||||||
set(NSAN_UNITTESTS
|
set(NSAN_UNITTESTS
|
||||||
@ -27,30 +29,13 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST NSAN_SUPPORTED_ARCH)
|
|||||||
# NSan unit tests are only run on the host machine.
|
# NSan unit tests are only run on the host machine.
|
||||||
set(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH})
|
set(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH})
|
||||||
|
|
||||||
set(NSAN_TEST_RUNTIME RTNsanTest.${arch})
|
|
||||||
|
|
||||||
set(NSAN_TEST_RUNTIME_OBJECTS
|
|
||||||
$<TARGET_OBJECTS:RTNsan.${arch}>
|
|
||||||
$<TARGET_OBJECTS:RTInterception.${arch}>
|
|
||||||
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
|
|
||||||
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
|
|
||||||
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
|
|
||||||
|
|
||||||
add_library(${NSAN_TEST_RUNTIME} STATIC
|
|
||||||
${NSAN_TEST_RUNTIME_OBJECTS})
|
|
||||||
|
|
||||||
set_target_properties(${NSAN_TEST_RUNTIME} PROPERTIES
|
|
||||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
FOLDER "Compiler-RT Runtime tests")
|
|
||||||
|
|
||||||
set(NsanTestObjects)
|
set(NsanTestObjects)
|
||||||
generate_compiler_rt_tests(NsanTestObjects
|
generate_compiler_rt_tests(NsanTestObjects
|
||||||
NsanUnitTests "Nsan-${arch}-Test" ${arch}
|
NsanUnitTests "Nsan-${arch}-Test" ${arch}
|
||||||
SOURCES ${NSAN_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE}
|
SOURCES ${NSAN_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE}
|
||||||
RUNTIME ${NSAN_TEST_RUNTIME}
|
|
||||||
DEPS ${NSAN_UNIT_TEST_HEADERS}
|
DEPS ${NSAN_UNIT_TEST_HEADERS}
|
||||||
CFLAGS ${NSAN_UNITTEST_CFLAGS}
|
CFLAGS ${NSAN_UNITTEST_CFLAGS}
|
||||||
LINK_FLAGS ${NSAN_UNITTEST_LINK_FLAGS})
|
LINK_FLAGS ${NSAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
|
||||||
set_target_properties(NsanUnitTests PROPERTIES
|
set_target_properties(NsanUnitTests PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user