Skip to content

Commit 3659fca

Browse files
committed
Merge #43: cmake: Add fuzzing facilities
9b9f562 cmake: Add fuzzing options (Hennadii Stepanov) ea7861e cmake: Add `SANITIZERS` option (Hennadii Stepanov) Pull request description: New CMake variables that affect the build system configuration: - `SANITIZERS` - `BUILD_FUZZ_BINARY` - `FUZZ` In the light of bitcoin#29189, this PR is no longer based on #41. However, the `test/fuzz/script_bitcoin_consensus.cpp` might be easily added anytime. For OSS-Fuzz integration, please refer to hebasto/oss-fuzz#1. ACKs for top commit: theuni: Lightly tested ACK 9b9f562. Tree-SHA512: f762d1218f2f8bfe26bdd43f431cb37a26093a6899db7120b50df3083f81d6ad6aa867937e69930faff6ab4519532cfaca48aaf97831d4c2593b93423cb6d41a
2 parents 42c0d4f + 9b9f562 commit 3659fca

File tree

5 files changed

+235
-0
lines changed

5 files changed

+235
-0
lines changed

CMakeLists.txt

+55
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ tristate_option(WITH_USDT
7272

7373
option(BUILD_TESTS "Build test_bitcoin executable." ON)
7474
option(BUILD_BENCH "Build bench_bitcoin executable." ON)
75+
cmake_dependent_option(BUILD_FUZZ_BINARY "Build fuzz binary." ON "NOT MSVC" OFF)
76+
cmake_dependent_option(FUZZ "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF "NOT MSVC" OFF)
77+
78+
if(FUZZ)
79+
message(WARNING "FUZZ=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.")
80+
set(BUILD_DAEMON OFF)
81+
set(BUILD_CLI OFF)
82+
set(BUILD_TX OFF)
83+
set(BUILD_UTIL OFF)
84+
set(BUILD_UTIL_CHAINSTATE OFF)
85+
set(BUILD_SHARED_LIBS OFF)
86+
set(BUILD_WALLET_TOOL OFF)
87+
set(WITH_NATPMP OFF)
88+
set(WITH_MINIUPNPC OFF)
89+
set(WITH_ZMQ OFF)
90+
set(BUILD_TESTS OFF)
91+
set(BUILD_BENCH OFF)
92+
set(BUILD_FUZZ_BINARY ON)
93+
endif()
94+
7595
option(INSTALL_MAN "Install man pages." ON)
7696

7797
set(configure_warnings)
@@ -188,6 +208,40 @@ endif()
188208
include(AddThreadsIfNeeded)
189209
add_threads_if_needed()
190210

211+
add_library(sanitizing_interface INTERFACE)
212+
target_link_libraries(core_interface INTERFACE sanitizing_interface)
213+
if(SANITIZERS)
214+
# First check if the compiler accepts flags. If an incompatible pair like
215+
# -fsanitize=address,thread is used here, this check will fail. This will also
216+
# fail if a bad argument is passed, e.g. -fsanitize=undfeined
217+
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitizing_interface
218+
RESULT_VAR cxx_supports_sanitizers
219+
)
220+
if(NOT cxx_supports_sanitizers)
221+
message(FATAL_ERROR "Compiler did not accept requested flags.")
222+
endif()
223+
224+
# Some compilers (e.g. GCC) require additional libraries like libasan,
225+
# libtsan, libubsan, etc. Make sure linking still works with the sanitize
226+
# flag. This is a separate check so we can give a better error message when
227+
# the sanitize flags are supported by the compiler but the actual sanitizer
228+
# libs are missing.
229+
try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS
230+
SOURCE "
231+
#include <cstdint>
232+
#include <cstddef>
233+
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
234+
__attribute__((weak)) // allow for libFuzzer linking
235+
int main() { return 0; }
236+
"
237+
RESULT_VAR linker_supports_sanitizers
238+
)
239+
if(NOT linker_supports_sanitizers)
240+
message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.")
241+
endif()
242+
endif()
243+
target_link_options(sanitizing_interface INTERFACE ${SANITIZER_LDFLAGS})
244+
191245
include(AddBoostIfNeeded)
192246
add_boost_if_needed()
193247

@@ -349,6 +403,7 @@ message(" USDT tracing ........................ ${WITH_USDT}")
349403
message("Tests:")
350404
message(" test_bitcoin ........................ ${BUILD_TESTS}")
351405
message(" bench_bitcoin ....................... ${BUILD_BENCH}")
406+
message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}")
352407
message("")
353408
if(CMAKE_CROSSCOMPILING)
354409
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")

src/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ if(BUILD_TESTS)
336336
add_subdirectory(test)
337337
endif()
338338

339+
if(BUILD_FUZZ_BINARY)
340+
add_subdirectory(test/fuzz)
341+
endif()
342+
339343

340344
install(TARGETS ${installable_targets}
341345
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}

src/test/fuzz/CMakeLists.txt

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Copyright (c) 2023-present The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit/.
4+
5+
add_subdirectory(util)
6+
7+
add_executable(fuzz
8+
addition_overflow.cpp
9+
addrman.cpp
10+
asmap.cpp
11+
asmap_direct.cpp
12+
autofile.cpp
13+
banman.cpp
14+
base_encode_decode.cpp
15+
bech32.cpp
16+
bip324.cpp
17+
bitdeque.cpp
18+
block.cpp
19+
block_header.cpp
20+
blockfilter.cpp
21+
bloom_filter.cpp
22+
buffered_file.cpp
23+
chain.cpp
24+
checkqueue.cpp
25+
coins_view.cpp
26+
coinscache_sim.cpp
27+
connman.cpp
28+
crypto.cpp
29+
crypto_aes256.cpp
30+
crypto_aes256cbc.cpp
31+
crypto_chacha20.cpp
32+
crypto_common.cpp
33+
crypto_diff_fuzz_chacha20.cpp
34+
crypto_hkdf_hmac_sha256_l32.cpp
35+
crypto_poly1305.cpp
36+
cuckoocache.cpp
37+
decode_tx.cpp
38+
descriptor_parse.cpp
39+
deserialize.cpp
40+
eval_script.cpp
41+
fee_rate.cpp
42+
fees.cpp
43+
flatfile.cpp
44+
float.cpp
45+
golomb_rice.cpp
46+
headerssync.cpp
47+
hex.cpp
48+
http_request.cpp
49+
integer.cpp
50+
key.cpp
51+
key_io.cpp
52+
kitchen_sink.cpp
53+
load_external_block_file.cpp
54+
locale.cpp
55+
merkleblock.cpp
56+
message.cpp
57+
miniscript.cpp
58+
minisketch.cpp
59+
mini_miner.cpp
60+
muhash.cpp
61+
multiplication_overflow.cpp
62+
net.cpp
63+
net_permissions.cpp
64+
netaddress.cpp
65+
netbase_dns_lookup.cpp
66+
node_eviction.cpp
67+
p2p_transport_serialization.cpp
68+
package_eval.cpp
69+
parse_hd_keypath.cpp
70+
parse_numbers.cpp
71+
parse_script.cpp
72+
parse_univalue.cpp
73+
partially_downloaded_block.cpp
74+
policy_estimator.cpp
75+
policy_estimator_io.cpp
76+
poolresource.cpp
77+
pow.cpp
78+
prevector.cpp
79+
primitives_transaction.cpp
80+
process_message.cpp
81+
process_messages.cpp
82+
protocol.cpp
83+
psbt.cpp
84+
random.cpp
85+
rbf.cpp
86+
rolling_bloom_filter.cpp
87+
rpc.cpp
88+
script.cpp
89+
script_assets_test_minimizer.cpp
90+
script_descriptor_cache.cpp
91+
script_flags.cpp
92+
script_format.cpp
93+
script_interpreter.cpp
94+
script_ops.cpp
95+
script_sigcache.cpp
96+
script_sign.cpp
97+
scriptnum_ops.cpp
98+
secp256k1_ec_seckey_import_export_der.cpp
99+
secp256k1_ecdsa_signature_parse_der_lax.cpp
100+
signature_checker.cpp
101+
signet.cpp
102+
socks5.cpp
103+
span.cpp
104+
spanparsing.cpp
105+
string.cpp
106+
strprintf.cpp
107+
system.cpp
108+
timedata.cpp
109+
torcontrol.cpp
110+
transaction.cpp
111+
tx_in.cpp
112+
tx_out.cpp
113+
tx_pool.cpp
114+
txorphan.cpp
115+
txrequest.cpp
116+
utxo_snapshot.cpp
117+
utxo_total_supply.cpp
118+
validation_load_mempool.cpp
119+
versionbits.cpp
120+
)
121+
target_link_libraries(fuzz
122+
core_interface
123+
test_fuzz
124+
bitcoin_cli
125+
bitcoin_common
126+
minisketch
127+
leveldb
128+
univalue
129+
secp256k1
130+
Boost::headers
131+
libevent::libevent
132+
)
133+
134+
if(ENABLE_WALLET)
135+
target_sources(fuzz
136+
PRIVATE
137+
${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/coincontrol.cpp
138+
${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/coinselection.cpp
139+
${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/fees.cpp
140+
${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/parse_iso8601.cpp
141+
$<$<BOOL:${USE_SQLITE}>:${CMAKE_SOURCE_DIR}/src/wallet/test/fuzz/notifications.cpp>
142+
)
143+
target_link_libraries(fuzz bitcoin_wallet)
144+
endif()

src/test/fuzz/util/CMakeLists.txt

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright (c) 2023-present The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit/.
4+
5+
add_library(test_fuzz STATIC EXCLUDE_FROM_ALL
6+
descriptor.cpp
7+
mempool.cpp
8+
net.cpp
9+
../fuzz.cpp
10+
../util.cpp
11+
)
12+
13+
target_link_libraries(test_fuzz
14+
PRIVATE
15+
core_interface
16+
test_util
17+
bitcoin_node
18+
Boost::headers
19+
)
20+
21+
include(CheckSourceCompilesAndLinks)
22+
check_cxx_source_links_with_flags("${SANITIZER_LDFLAGS}" "
23+
#include <cstdint>
24+
#include <cstddef>
25+
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
26+
// No main() function.
27+
" BINARY_LINKS_WITHOUT_MAIN_FUNCTION
28+
)
29+
if(NOT BINARY_LINKS_WITHOUT_MAIN_FUNCTION)
30+
target_compile_definitions(test_fuzz PRIVATE PROVIDE_FUZZ_MAIN_FUNCTION)
31+
endif()

test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function(create_test_config)
2222
set_configure_variable(BUILD_UTIL BUILD_BITCOIN_UTIL)
2323
set_configure_variable(BUILD_WALLET_TOOL BUILD_BITCOIN_WALLET)
2424
set_configure_variable(BUILD_DAEMON BUILD_BITCOIND_TRUE)
25+
set_configure_variable(FUZZ ENABLE_FUZZ)
2526
set_configure_variable(WITH_ZMQ ENABLE_ZMQ)
2627
set_configure_variable(ENABLE_EXTERNAL_SIGNER ENABLE_EXTERNAL_SIGNER)
2728
set_configure_variable(ENABLE_TRACING ENABLE_USDT_TRACEPOINTS)

0 commit comments

Comments
 (0)