diff --git a/CMakeLists.txt b/CMakeLists.txt index 1154da09114ca..e9426fdad42bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,26 @@ tristate_option(WITH_USDT option(BUILD_TESTS "Build test_bitcoin executable." ON) option(BUILD_BENCH "Build bench_bitcoin executable." ON) +cmake_dependent_option(BUILD_FUZZ_BINARY "Build fuzz binary." ON "NOT MSVC" OFF) +cmake_dependent_option(FUZZ "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF "NOT MSVC" OFF) + +if(FUZZ) + message(WARNING "FUZZ=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.") + set(BUILD_DAEMON OFF) + set(BUILD_CLI OFF) + set(BUILD_TX OFF) + set(BUILD_UTIL OFF) + set(BUILD_UTIL_CHAINSTATE OFF) + set(BUILD_SHARED_LIBS OFF) + set(BUILD_WALLET_TOOL OFF) + set(WITH_NATPMP OFF) + set(WITH_MINIUPNPC OFF) + set(WITH_ZMQ OFF) + set(BUILD_TESTS OFF) + set(BUILD_BENCH OFF) + set(BUILD_FUZZ_BINARY ON) +endif() + option(INSTALL_MAN "Install man pages." ON) set(configure_warnings) @@ -384,6 +404,7 @@ message(" USDT tracing ........................ ${WITH_USDT}") message("Tests:") message(" test_bitcoin ........................ ${BUILD_TESTS}") message(" bench_bitcoin ....................... ${BUILD_BENCH}") +message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 03e557991b4b7..d318ad457d694 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -333,6 +333,10 @@ if(BUILD_TESTS) add_subdirectory(test) endif() +if(BUILD_FUZZ_BINARY) + add_subdirectory(test/fuzz) +endif() + install(TARGETS ${installable_targets} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt new file mode 100644 index 0000000000000..746d6b682e340 --- /dev/null +++ b/src/test/fuzz/CMakeLists.txt @@ -0,0 +1,168 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_subdirectory(util) + +add_executable(fuzz + addition_overflow.cpp + addrman.cpp + asmap.cpp + asmap_direct.cpp + autofile.cpp + banman.cpp + base_encode_decode.cpp + bech32.cpp + bip324.cpp + bitdeque.cpp + block.cpp + block_header.cpp + blockfilter.cpp + bloom_filter.cpp + buffered_file.cpp + chain.cpp + checkqueue.cpp + coins_view.cpp + coinscache_sim.cpp + connman.cpp + crypto.cpp + crypto_aes256.cpp + crypto_aes256cbc.cpp + crypto_chacha20.cpp + crypto_common.cpp + crypto_diff_fuzz_chacha20.cpp + crypto_hkdf_hmac_sha256_l32.cpp + crypto_poly1305.cpp + cuckoocache.cpp + decode_tx.cpp + descriptor_parse.cpp + deserialize.cpp + eval_script.cpp + fee_rate.cpp + fees.cpp + flatfile.cpp + float.cpp + golomb_rice.cpp + headerssync.cpp + hex.cpp + http_request.cpp + integer.cpp + key.cpp + key_io.cpp + kitchen_sink.cpp + load_external_block_file.cpp + locale.cpp + merkleblock.cpp + message.cpp + miniscript.cpp + minisketch.cpp + mini_miner.cpp + muhash.cpp + multiplication_overflow.cpp + net.cpp + net_permissions.cpp + netaddress.cpp + netbase_dns_lookup.cpp + node_eviction.cpp + p2p_transport_serialization.cpp + package_eval.cpp + parse_hd_keypath.cpp + parse_numbers.cpp + parse_script.cpp + parse_univalue.cpp + partially_downloaded_block.cpp + policy_estimator.cpp + policy_estimator_io.cpp + poolresource.cpp + pow.cpp + prevector.cpp + primitives_transaction.cpp + process_message.cpp + process_messages.cpp + protocol.cpp + psbt.cpp + random.cpp + rbf.cpp + rolling_bloom_filter.cpp + rpc.cpp + script.cpp + script_assets_test_minimizer.cpp + script_descriptor_cache.cpp + script_flags.cpp + script_format.cpp + script_interpreter.cpp + script_ops.cpp + script_sigcache.cpp + script_sign.cpp + scriptnum_ops.cpp + secp256k1_ec_seckey_import_export_der.cpp + secp256k1_ecdsa_signature_parse_der_lax.cpp + signature_checker.cpp + signet.cpp + socks5.cpp + span.cpp + spanparsing.cpp + string.cpp + strprintf.cpp + system.cpp + timedata.cpp + torcontrol.cpp + transaction.cpp + tx_in.cpp + tx_out.cpp + tx_pool.cpp + txorphan.cpp + txrequest.cpp + utxo_snapshot.cpp + utxo_total_supply.cpp + validation_load_mempool.cpp + versionbits.cpp +) +target_link_libraries(fuzz + core + test_fuzz + bitcoin_cli + bitcoin_common + minisketch + leveldb + univalue + secp256k1 + Boost::headers + libevent::libevent +) + +if(ENABLE_WALLET) + target_sources(fuzz + PRIVATE + ${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/coincontrol.cpp + ${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/coinselection.cpp + ${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/fees.cpp + ${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/parse_iso8601.cpp + $<$:${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/notifications.cpp> + ) + target_link_libraries(fuzz bitcoin_wallet) +endif() + +set(builtin_mul_overflow_source " + bool f(long long x, long long y, long long* p) + { + return __builtin_mul_overflow(x, y, p); + } + int main() { return 0; } +") +include(CheckCXXSourceCompiles) +check_cxx_source_compiles("${builtin_mul_overflow_source}" HAVE_BUILTIN_MUL_OVERFLOW) +if(HAVE_BUILTIN_MUL_OVERFLOW) + target_compile_definitions(fuzz PRIVATE HAVE_BUILTIN_MUL_OVERFLOW) +else() + set(CMAKE_REQUIRED_LINK_OPTIONS rtlib=compiler-rt) + set(CMAKE_REQUIRED_LIBRARIES gcc_s) + check_cxx_source_compiles("${builtin_mul_overflow_source}" HAVE_BUILTIN_MUL_OVERFLOW_NEEDS_LINK_TO_RT) + if(HAVE_BUILTIN_MUL_OVERFLOW_NEEDS_LINK_TO_RT) + target_compile_definitions(fuzz PRIVATE HAVE_BUILTIN_MUL_OVERFLOW) + target_link_options(fuzz PRIVATE ${CMAKE_REQUIRED_LINK_OPTIONS}) + target_link_libraries(fuzz PRIVATE ${CMAKE_REQUIRED_LIBRARIES}) + endif() + set(CMAKE_REQUIRED_LINK_OPTIONS) + set(CMAKE_REQUIRED_LIBRARIES) +endif() diff --git a/src/test/fuzz/util/CMakeLists.txt b/src/test/fuzz/util/CMakeLists.txt new file mode 100644 index 0000000000000..26e4956a0a231 --- /dev/null +++ b/src/test/fuzz/util/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +add_library(test_fuzz STATIC EXCLUDE_FROM_ALL + descriptor.cpp + mempool.cpp + net.cpp + ../fuzz.cpp + ../util.cpp +) + +target_link_libraries(test_fuzz + PRIVATE + core + test_util + bitcoin_node + Boost::headers +) + +include(CheckSourceCompilesAndLinks) +check_cxx_source_links_with_flags("${SANITIZER_LDFLAGS}" " + #include + #include + extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + // No main() function. + " BINARY_LINKS_WITHOUT_MAIN_FUNCTION +) +if(NOT BINARY_LINKS_WITHOUT_MAIN_FUNCTION) + target_compile_definitions(test_fuzz PRIVATE PROVIDE_FUZZ_MAIN_FUNCTION) +endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe832a92f26ba..3b7eeb93036c1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,6 +22,7 @@ function(create_test_config) set_configure_variable(BUILD_UTIL BUILD_BITCOIN_UTIL) set_configure_variable(BUILD_WALLET_TOOL BUILD_BITCOIN_WALLET) set_configure_variable(BUILD_DAEMON BUILD_BITCOIND_TRUE) + set_configure_variable(FUZZ ENABLE_FUZZ) set_configure_variable(WITH_ZMQ ENABLE_ZMQ) set_configure_variable(ENABLE_EXTERNAL_SIGNER ENABLE_EXTERNAL_SIGNER) set_configure_variable(ENABLE_TRACING ENABLE_USDT_TRACEPOINTS)