Merge 34aeb70748ef8ee186fe53f0db2580a445452dc2 into 5f4422d68dc3530c353af1f87499de1c864b60ad

This commit is contained in:
Ryan Ofsky 2025-03-17 03:51:35 +01:00 committed by GitHub
commit d74805c1c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 4 deletions

View File

@ -346,13 +346,35 @@ target_link_libraries(core_interface INTERFACE
Threads::Threads Threads::Threads
) )
# Define "sanitize_interface" with flags intended to apply to all libraries and
# executables to support sanitizers and fuzzing, and a separate
# "fuzzer_interface" with flags specifically intended to apply to the fuzz test
# binary. Reason these are separate interfaces is that if -DSANITIZERS=fuzzer is
# specified, the fuzz test binary should be built with -fsanitize=fuzzer (so it
# can use libFuzzer's main function), but libraries should be built with
# -fsanitize=fuzzer-no-link (so they can be linked into other executables that
# have their own main functions).
add_library(sanitize_interface INTERFACE) add_library(sanitize_interface INTERFACE)
add_library(fuzzer_interface INTERFACE)
target_link_libraries(core_interface INTERFACE sanitize_interface) target_link_libraries(core_interface INTERFACE sanitize_interface)
if(SANITIZERS) if(SANITIZERS)
# Transform list of sanitizers into -fsanitize flags, replacing "fuzzer" with
# "fuzzer-no-link" in sanitize_interface flags, and moving "fuzzer" to
# fuzzer_interface flags.
string(REGEX REPLACE "(^|,)fuzzer($|,)" "\\1fuzzer-no-link\\2" SANITIZE_FLAG "${SANITIZERS}")
set(FUZZ_FLAG "")
if (NOT "${SANITIZE_FLAG}" STREQUAL "${SANITIZERS}")
set(FUZZ_FLAG "-fsanitize=fuzzer")
if(NOT BUILD_FOR_FUZZING)
message(FATAL_ERROR "Error: Enabling -DSANITIZERS=fuzzer without -DBUILD_FOR_FUZZING=ON is not supported.")
endif()
endif()
set(SANITIZE_FLAG "-fsanitize=${SANITIZE_FLAG}")
# First check if the compiler accepts flags. If an incompatible pair like # First check if the compiler accepts flags. If an incompatible pair like
# -fsanitize=address,thread is used here, this check will fail. This will also # -fsanitize=address,thread is used here, this check will fail. This will also
# fail if a bad argument is passed, e.g. -fsanitize=undfeined # fail if a bad argument is passed, e.g. -fsanitize=undfeined
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitize_interface try_append_cxx_flags("${SANITIZE_FLAG}" TARGET sanitize_interface
RESULT_VAR cxx_supports_sanitizers RESULT_VAR cxx_supports_sanitizers
SKIP_LINK SKIP_LINK
) )
@ -365,12 +387,11 @@ if(SANITIZERS)
# flag. This is a separate check so we can give a better error message when # flag. This is a separate check so we can give a better error message when
# the sanitize flags are supported by the compiler but the actual sanitizer # the sanitize flags are supported by the compiler but the actual sanitizer
# libs are missing. # libs are missing.
try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS try_append_linker_flag("${SANITIZE_FLAG}" VAR SANITIZER_LDFLAGS
SOURCE " SOURCE "
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
__attribute__((weak)) // allow for libFuzzer linking
int main() { return 0; } int main() { return 0; }
" "
RESULT_VAR linker_supports_sanitizers RESULT_VAR linker_supports_sanitizers
@ -380,6 +401,7 @@ if(SANITIZERS)
endif() endif()
endif() endif()
target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS}) target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS})
target_link_options(fuzzer_interface INTERFACE ${FUZZ_FLAG})
if(BUILD_FUZZ_BINARY) if(BUILD_FUZZ_BINARY)
target_link_libraries(core_interface INTERFACE ${FUZZ_LIBS}) target_link_libraries(core_interface INTERFACE ${FUZZ_LIBS})
@ -390,7 +412,7 @@ if(BUILD_FUZZ_BINARY)
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
// No main() function. // No main() function.
" FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION " FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION
LDFLAGS ${SANITIZER_LDFLAGS} LDFLAGS ${SANITIZER_LDFLAGS} ${FUZZ_FLAG}
LINK_LIBRARIES ${FUZZ_LIBS} LINK_LIBRARIES ${FUZZ_LIBS}
) )
endif() endif()

View File

@ -137,6 +137,7 @@ add_executable(fuzz
) )
target_link_libraries(fuzz target_link_libraries(fuzz
core_interface core_interface
fuzzer_interface
test_fuzz test_fuzz
bitcoin_cli bitcoin_cli
bitcoin_common bitcoin_common