merge bitcoin#20560: Link all targets once

This commit is contained in:
Kittywhiskers Van Gogh 2022-09-19 12:33:12 +05:30
parent 2b90cb728b
commit c52700f2ef
95 changed files with 472 additions and 1262 deletions

View File

@ -7,7 +7,7 @@ setup:
- sudo apt-get update - sudo apt-get update
- sudo apt-get install -y autoconf bsdmainutils clang git libboost-all-dev libc++1 libc++abi1 libc++abi-dev libc++-dev libclang1 libclang-dev libdb5.3++ libevent-dev libllvm-ocaml-dev libomp5 libomp-dev libqt5core5a libqt5dbus5 libqt5gui5 libtool llvm llvm-dev llvm-runtime pkg-config qttools5-dev qttools5-dev-tools software-properties-common - sudo apt-get install -y autoconf bsdmainutils clang git libboost-all-dev libc++1 libc++abi1 libc++abi-dev libc++-dev libclang1 libclang-dev libdb5.3++ libevent-dev libllvm-ocaml-dev libomp5 libomp-dev libqt5core5a libqt5dbus5 libqt5gui5 libtool llvm llvm-dev llvm-runtime pkg-config qttools5-dev qttools5-dev-tools software-properties-common
- ./autogen.sh - ./autogen.sh
- CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined - CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined --enable-danger-fuzz-link-all
- make - make
- git clone https://github.com/bitcoin-core/qa-assets - git clone https://github.com/bitcoin-core/qa-assets
auto_targets: auto_targets:

View File

@ -171,6 +171,12 @@ AC_ARG_ENABLE([fuzz],
[enable_fuzz=$enableval], [enable_fuzz=$enableval],
[enable_fuzz=no]) [enable_fuzz=no])
AC_ARG_ENABLE([danger_fuzz_link_all],
AS_HELP_STRING([--enable-danger-fuzz-link-all],
[Danger! Modifies source code. Needs git and gnu sed installed. Link each fuzz target (default no).]),
[enable_danger_fuzz_link_all=$enableval],
[enable_danger_fuzz_link_all=no])
AC_ARG_WITH([qrencode], AC_ARG_WITH([qrencode],
[AS_HELP_STRING([--with-qrencode], [AS_HELP_STRING([--with-qrencode],
[enable QR code support (default is yes if qt is enabled and libqrencode is found)])], [enable QR code support (default is yes if qt is enabled and libqrencode is found)])],
@ -1707,6 +1713,7 @@ AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes])
AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes])
AM_CONDITIONAL([ENABLE_FUZZ],[test x$enable_fuzz = xyes]) AM_CONDITIONAL([ENABLE_FUZZ],[test x$enable_fuzz = xyes])
AM_CONDITIONAL([ENABLE_FUZZ_LINK_ALL],[test x$enable_danger_fuzz_link_all = xyes])
AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes])
AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes])
AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes])

View File

@ -12,7 +12,7 @@ $ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzze
# macOS users: If you have problem with this step then make sure to read "macOS hints for # macOS users: If you have problem with this step then make sure to read "macOS hints for
# libFuzzer" on https://github.com/dashpay/dash/blob/develop/doc/fuzzing.md#macos-hints-for-libfuzzer # libFuzzer" on https://github.com/dashpay/dash/blob/develop/doc/fuzzing.md#macos-hints-for-libfuzzer
$ make $ make
$ src/test/fuzz/process_message $ FUZZ=process_message src/test/fuzz/fuzz
# abort fuzzing using ctrl-c # abort fuzzing using ctrl-c
``` ```
@ -26,7 +26,7 @@ If you specify a corpus directory then any new coverage increasing inputs will b
```sh ```sh
$ mkdir -p process_message-seeded-from-thin-air/ $ mkdir -p process_message-seeded-from-thin-air/
$ src/test/fuzz/process_message process_message-seeded-from-thin-air/ $ FUZZ=process_message src/test/fuzz/fuzz process_message-seeded-from-thin-air/
INFO: Seed: 840522292 INFO: Seed: 840522292
INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55e121ef9ab8, 0x55e121f613a6), INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55e121ef9ab8, 0x55e121f613a6),
INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55e121f613a8,0x55e1225da288), INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55e121f613a8,0x55e1225da288),
@ -70,7 +70,7 @@ To fuzz `process_message` using the [`bitcoin-core/qa-assets`](https://github.co
```sh ```sh
$ git clone https://github.com/bitcoin-core/qa-assets $ git clone https://github.com/bitcoin-core/qa-assets
$ src/test/fuzz/process_message qa-assets/fuzz_seed_corpus/process_message/ $ FUZZ=process_message src/test/fuzz/fuzz qa-assets/fuzz_seed_corpus/process_message/
INFO: Seed: 1346407872 INFO: Seed: 1346407872
INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55d8a9004ab8, 0x55d8a906c3a6), INFO: Loaded 1 modules (424174 inline 8-bit counters): 424174 [0x55d8a9004ab8, 0x55d8a906c3a6),
INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55d8a906c3a8,0x55d8a96e5288), INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55d8a906c3a8,0x55d8a96e5288),
@ -127,7 +127,7 @@ $ make
# try compiling using: AFL_NO_X86=1 make # try compiling using: AFL_NO_X86=1 make
$ mkdir -p inputs/ outputs/ $ mkdir -p inputs/ outputs/
$ echo A > inputs/thin-air-input $ echo A > inputs/thin-air-input
$ afl/afl-fuzz -i inputs/ -o outputs/ -- src/test/fuzz/bech32 $ FUZZ=bech32 afl/afl-fuzz -i inputs/ -o outputs/ -- src/test/fuzz/fuzz
# You may have to change a few kernel parameters to test optimally - afl-fuzz # You may have to change a few kernel parameters to test optimally - afl-fuzz
# will print an error and suggestion if so. # will print an error and suggestion if so.
``` ```
@ -151,7 +151,7 @@ $ cd ..
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined $ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined
$ make $ make
$ mkdir -p inputs/ $ mkdir -p inputs/
$ honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/process_message $ FUZZ=process_message honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/fuzz
``` ```
Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information. Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information.

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ void TestAdditionOverflow(FuzzedDataProvider& fuzzed_data_provider)
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(addition_overflow)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
TestAdditionOverflow<int64_t>(fuzzed_data_provider); TestAdditionOverflow<int64_t>(fuzzed_data_provider);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(addrdb)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -17,12 +17,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_addrman()
{ {
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(addrman, initialize_addrman)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -28,7 +28,7 @@ static const std::vector<bool> IPV4_PREFIX_ASMAP = {
true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true // Match 0xFF true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true // Match 0xFF
}; };
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(asmap)
{ {
// Encoding: [7 bits: asmap size] [1 bit: ipv6?] [3-130 bytes: asmap] [4 or 16 bytes: addr] // Encoding: [7 bits: asmap size] [1 bit: ipv6?] [3-130 bytes: asmap] [4 or 16 bytes: addr]
if (buffer.size() < 1 + 3 + 4) return; if (buffer.size() < 1 + 3 + 4) return;

View File

@ -10,7 +10,7 @@
#include <assert.h> #include <assert.h>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(asmap_direct)
{ {
// Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte] // Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
bool have_sep = false; bool have_sep = false;

View File

@ -15,7 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(autofile)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider); FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);

View File

@ -24,12 +24,12 @@ int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
} }
} // namespace } // namespace
void initialize() void initialize_banman()
{ {
InitializeFuzzingContext(); InitializeFuzzingContext();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(banman, initialize_banman)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat"; const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat";

View File

@ -15,7 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(base_encode_decode)
{ {
const std::string random_encoded_string(buffer.begin(), buffer.end()); const std::string random_encoded_string(buffer.begin(), buffer.end());

View File

@ -13,7 +13,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(bech32)
{ {
const std::string random_string(buffer.begin(), buffer.end()); const std::string random_string(buffer.begin(), buffer.end());
const std::pair<std::string, std::vector<uint8_t>> r1 = bech32::Decode(random_string); const std::pair<std::string, std::vector<uint8_t>> r1 = bech32::Decode(random_string);

View File

@ -17,13 +17,13 @@
#include <cassert> #include <cassert>
#include <string> #include <string>
void initialize() void initialize_block()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(block, initialize_block)
{ {
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CBlock block; CBlock block;

View File

@ -14,7 +14,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(block_header)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider); const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(blockfilter)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider); const std::optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider);

View File

@ -15,7 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(bloom_filter)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -15,7 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(buffered_file)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider); FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);

View File

@ -11,7 +11,7 @@
#include <optional> #include <optional>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(chain)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::optional<CDiskBlockIndex> disk_block_index = ConsumeDeserializable<CDiskBlockIndex>(fuzzed_data_provider); std::optional<CDiskBlockIndex> disk_block_index = ConsumeDeserializable<CDiskBlockIndex>(fuzzed_data_provider);

View File

@ -32,7 +32,7 @@ struct DumbCheck {
}; };
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(checkqueue)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -35,14 +35,14 @@ bool operator==(const Coin& a, const Coin& b)
} }
} // namespace } // namespace
void initialize() void initialize_coins_view()
{ {
static const ECCVerifyHandle ecc_verify_handle; static const ECCVerifyHandle ecc_verify_handle;
ECC_Start(); ECC_Start();
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
CCoinsView backend_coins_view; CCoinsView backend_coins_view;

View File

@ -15,12 +15,12 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void initialize() void initialize_connman()
{ {
InitializeFuzzingContext(); InitializeFuzzingContext();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(connman, initialize_connman)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()}; CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()};

View File

@ -17,7 +17,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider); std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);

View File

@ -11,7 +11,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_aes256)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE); const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);

View File

@ -11,7 +11,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_aes256cbc)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE); const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);

View File

@ -10,7 +10,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_chacha20)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};

View File

@ -13,7 +13,7 @@
#include <limits> #include <limits>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_chacha20_poly1305_aead)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};

View File

@ -13,7 +13,7 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_common)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const uint16_t random_u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>(); const uint16_t random_u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();

View File

@ -11,7 +11,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_hkdf_hmac_sha256_l32)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};

View File

@ -10,7 +10,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(crypto_poly1305)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};

View File

@ -26,7 +26,7 @@ struct RandomHasher {
}; };
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(cuckoocache)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
fuzzed_data_provider_ptr = &fuzzed_data_provider; fuzzed_data_provider_ptr = &fuzzed_data_provider;

View File

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Copyright (c) 2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
set -e
ROOT_DIR="$(git rev-parse --show-toplevel)"
# Run only once (break make recursion)
if [ -d "${ROOT_DIR}/lock_fuzz_link_all" ]; then
exit
fi
mkdir "${ROOT_DIR}/lock_fuzz_link_all"
echo "Linking each fuzz target separately."
for FUZZING_HARNESS in $(PRINT_ALL_FUZZ_TARGETS_AND_ABORT=1 "${ROOT_DIR}/src/test/fuzz/fuzz" | sort -u); do
echo "Building src/test/fuzz/${FUZZING_HARNESS} ..."
git checkout -- "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
sed -i "s/std::getenv(\"FUZZ\")/\"${FUZZING_HARNESS}\"/g" "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
make
mv "${ROOT_DIR}/src/test/fuzz/fuzz" "${ROOT_DIR}/src/test/fuzz/${FUZZING_HARNESS}"
done
git checkout -- "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
rmdir "${ROOT_DIR}/lock_fuzz_link_all"
echo "Successfully built all fuzz targets."

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(decode_tx)
{ {
const std::string tx_hex = HexStr(std::string{buffer.begin(), buffer.end()}); const std::string tx_hex = HexStr(std::string{buffer.begin(), buffer.end()});
CMutableTransaction mtx; CMutableTransaction mtx;

View File

@ -10,13 +10,13 @@
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <util/memory.h> #include <util/memory.h>
void initialize() void initialize_descriptor_parse()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(descriptor_parse, initialize_descriptor_parse)
{ {
const std::string descriptor(buffer.begin(), buffer.end()); const std::string descriptor(buffer.begin(), buffer.end());
FlatSigningProvider signing_provider; FlatSigningProvider signing_provider;

View File

@ -31,12 +31,21 @@
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
void initialize() void initialize_deserialize()
{ {
// Fuzzers using pubkey must hold an ECCVerifyHandle. // Fuzzers using pubkey must hold an ECCVerifyHandle.
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
} }
#define FUZZ_TARGET_DESERIALIZE(name, code) \
FUZZ_TARGET_INIT(name, initialize_deserialize) \
{ \
try { \
code \
} catch (const invalid_fuzzing_input_exception&) { \
} \
}
namespace { namespace {
struct invalid_fuzzing_input_exception : public std::exception { struct invalid_fuzzing_input_exception : public std::exception {
@ -85,155 +94,189 @@ void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) /*
{ FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
try { BlockFilter block_filter;
#if BLOCK_FILTER_DESERIALIZE DeserializeFromFuzzingInput(buffer, block_filter);
// BlockFilter block_filter; })
// DeserializeFromFuzzingInput(buffer, block_filter); */
#elif ADDR_INFO_DESERIALIZE FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
CAddrInfo addr_info; CAddrInfo addr_info;
DeserializeFromFuzzingInput(buffer, addr_info); DeserializeFromFuzzingInput(buffer, addr_info);
#elif BLOCK_FILE_INFO_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
CBlockFileInfo block_file_info; CBlockFileInfo block_file_info;
DeserializeFromFuzzingInput(buffer, block_file_info); DeserializeFromFuzzingInput(buffer, block_file_info);
#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
CBlockHeaderAndShortTxIDs block_header_and_short_txids; CBlockHeaderAndShortTxIDs block_header_and_short_txids;
DeserializeFromFuzzingInput(buffer, block_header_and_short_txids); DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
#elif FEE_RATE_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
CFeeRate fee_rate; CFeeRate fee_rate;
DeserializeFromFuzzingInput(buffer, fee_rate); DeserializeFromFuzzingInput(buffer, fee_rate);
AssertEqualAfterSerializeDeserialize(fee_rate); AssertEqualAfterSerializeDeserialize(fee_rate);
#elif MERKLE_BLOCK_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
CMerkleBlock merkle_block; CMerkleBlock merkle_block;
DeserializeFromFuzzingInput(buffer, merkle_block); DeserializeFromFuzzingInput(buffer, merkle_block);
#elif OUT_POINT_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
COutPoint out_point; COutPoint out_point;
DeserializeFromFuzzingInput(buffer, out_point); DeserializeFromFuzzingInput(buffer, out_point);
AssertEqualAfterSerializeDeserialize(out_point); AssertEqualAfterSerializeDeserialize(out_point);
#elif PARTIAL_MERKLE_TREE_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
CPartialMerkleTree partial_merkle_tree; CPartialMerkleTree partial_merkle_tree;
DeserializeFromFuzzingInput(buffer, partial_merkle_tree); DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
#elif PUB_KEY_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
CPubKey pub_key; CPubKey pub_key;
DeserializeFromFuzzingInput(buffer, pub_key); DeserializeFromFuzzingInput(buffer, pub_key);
// TODO: The following equivalence should hold for CPubKey? Fix. // TODO: The following equivalence should hold for CPubKey? Fix.
// AssertEqualAfterSerializeDeserialize(pub_key); // AssertEqualAfterSerializeDeserialize(pub_key);
#elif SCRIPT_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(script_deserialize, {
CScript script; CScript script;
DeserializeFromFuzzingInput(buffer, script); DeserializeFromFuzzingInput(buffer, script);
#elif SUB_NET_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, {
CSubNet sub_net; CSubNet sub_net;
DeserializeFromFuzzingInput(buffer, sub_net); DeserializeFromFuzzingInput(buffer, sub_net);
AssertEqualAfterSerializeDeserialize(sub_net); AssertEqualAfterSerializeDeserialize(sub_net);
#elif TX_IN_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
CTxIn tx_in; CTxIn tx_in;
DeserializeFromFuzzingInput(buffer, tx_in); DeserializeFromFuzzingInput(buffer, tx_in);
AssertEqualAfterSerializeDeserialize(tx_in); AssertEqualAfterSerializeDeserialize(tx_in);
#elif FLAT_FILE_POS_DESERIALIZE })
// FlatFilePos flat_file_pos; /*
// DeserializeFromFuzzingInput(buffer, flat_file_pos); FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
// AssertEqualAfterSerializeDeserialize(flat_file_pos); FlatFilePos flat_file_pos;
#elif KEY_ORIGIN_INFO_DESERIALIZE DeserializeFromFuzzingInput(buffer, flat_file_pos);
// KeyOriginInfo key_origin_info; AssertEqualAfterSerializeDeserialize(flat_file_pos);
// DeserializeFromFuzzingInput(buffer, key_origin_info); })
// AssertEqualAfterSerializeDeserialize(key_origin_info); FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE KeyOriginInfo key_origin_info;
DeserializeFromFuzzingInput(buffer, key_origin_info);
AssertEqualAfterSerializeDeserialize(key_origin_info);
})
*/
FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
PartiallySignedTransaction partially_signed_transaction; PartiallySignedTransaction partially_signed_transaction;
DeserializeFromFuzzingInput(buffer, partially_signed_transaction); DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
#elif PREFILLED_TRANSACTION_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
PrefilledTransaction prefilled_transaction; PrefilledTransaction prefilled_transaction;
DeserializeFromFuzzingInput(buffer, prefilled_transaction); DeserializeFromFuzzingInput(buffer, prefilled_transaction);
#elif PSBT_INPUT_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
PSBTInput psbt_input; PSBTInput psbt_input;
DeserializeFromFuzzingInput(buffer, psbt_input); DeserializeFromFuzzingInput(buffer, psbt_input);
#elif PSBT_OUTPUT_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
PSBTOutput psbt_output; PSBTOutput psbt_output;
DeserializeFromFuzzingInput(buffer, psbt_output); DeserializeFromFuzzingInput(buffer, psbt_output);
#elif BLOCK_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(block_deserialize, {
CBlock block; CBlock block;
DeserializeFromFuzzingInput(buffer, block); DeserializeFromFuzzingInput(buffer, block);
#elif BLOCKLOCATOR_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
CBlockLocator bl; CBlockLocator bl;
DeserializeFromFuzzingInput(buffer, bl); DeserializeFromFuzzingInput(buffer, bl);
#elif BLOCKMERKLEROOT })
FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
CBlock block; CBlock block;
DeserializeFromFuzzingInput(buffer, block); DeserializeFromFuzzingInput(buffer, block);
bool mutated; bool mutated;
BlockMerkleRoot(block, &mutated); BlockMerkleRoot(block, &mutated);
#elif ADDRMAN_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
CAddrMan am; CAddrMan am;
DeserializeFromFuzzingInput(buffer, am); DeserializeFromFuzzingInput(buffer, am);
#elif BLOCKHEADER_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
CBlockHeader bh; CBlockHeader bh;
DeserializeFromFuzzingInput(buffer, bh); DeserializeFromFuzzingInput(buffer, bh);
#elif BANENTRY_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(banentry_deserialize, {
CBanEntry be; CBanEntry be;
DeserializeFromFuzzingInput(buffer, be); DeserializeFromFuzzingInput(buffer, be);
#elif TXUNDO_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
CTxUndo tu; CTxUndo tu;
DeserializeFromFuzzingInput(buffer, tu); DeserializeFromFuzzingInput(buffer, tu);
#elif BLOCKUNDO_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
CBlockUndo bu; CBlockUndo bu;
DeserializeFromFuzzingInput(buffer, bu); DeserializeFromFuzzingInput(buffer, bu);
#elif COINS_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
Coin coin; Coin coin;
DeserializeFromFuzzingInput(buffer, coin); DeserializeFromFuzzingInput(buffer, coin);
#elif NETADDR_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
CNetAddr na; CNetAddr na;
DeserializeFromFuzzingInput(buffer, na); DeserializeFromFuzzingInput(buffer, na);
if (na.IsAddrV1Compatible()) { if (na.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(na); AssertEqualAfterSerializeDeserialize(na);
} }
AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
#elif SERVICE_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(service_deserialize, {
CService s; CService s;
DeserializeFromFuzzingInput(buffer, s); DeserializeFromFuzzingInput(buffer, s);
if (s.IsAddrV1Compatible()) { if (s.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(s); AssertEqualAfterSerializeDeserialize(s);
} }
AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT); AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
#elif MESSAGEHEADER_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
CMessageHeader mh; CMessageHeader mh;
DeserializeFromFuzzingInput(buffer, mh); DeserializeFromFuzzingInput(buffer, mh);
(void)mh.IsCommandValid(); (void)mh.IsCommandValid();
#elif ADDRESS_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(address_deserialize, {
CAddress a; CAddress a;
DeserializeFromFuzzingInput(buffer, a); DeserializeFromFuzzingInput(buffer, a);
#elif INV_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
CInv i; CInv i;
DeserializeFromFuzzingInput(buffer, i); DeserializeFromFuzzingInput(buffer, i);
#elif BLOOMFILTER_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
CBloomFilter bf; CBloomFilter bf;
DeserializeFromFuzzingInput(buffer, bf); DeserializeFromFuzzingInput(buffer, bf);
#elif DISKBLOCKINDEX_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
CDiskBlockIndex dbi; CDiskBlockIndex dbi;
DeserializeFromFuzzingInput(buffer, dbi); DeserializeFromFuzzingInput(buffer, dbi);
#elif TXOUTCOMPRESSOR_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
CTxOut to; CTxOut to;
auto toc = Using<TxOutCompression>(to); auto toc = Using<TxOutCompression>(to);
DeserializeFromFuzzingInput(buffer, toc); DeserializeFromFuzzingInput(buffer, toc);
#elif BLOCKTRANSACTIONS_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
BlockTransactions bt; BlockTransactions bt;
DeserializeFromFuzzingInput(buffer, bt); DeserializeFromFuzzingInput(buffer, bt);
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
BlockTransactionsRequest btr; BlockTransactionsRequest btr;
DeserializeFromFuzzingInput(buffer, btr); DeserializeFromFuzzingInput(buffer, btr);
#elif UINT160_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
uint160 u160; uint160 u160;
DeserializeFromFuzzingInput(buffer, u160); DeserializeFromFuzzingInput(buffer, u160);
AssertEqualAfterSerializeDeserialize(u160); AssertEqualAfterSerializeDeserialize(u160);
#elif UINT256_DESERIALIZE })
FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
uint256 u256; uint256 u256;
DeserializeFromFuzzingInput(buffer, u256); DeserializeFromFuzzingInput(buffer, u256);
AssertEqualAfterSerializeDeserialize(u256); AssertEqualAfterSerializeDeserialize(u256);
#else })
#error Need at least one fuzz target to compile
#endif
// Classes intentionally not covered in this file since their deserialization code is // Classes intentionally not covered in this file since their deserialization code is
// fuzzed elsewhere: // fuzzed elsewhere:
// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp // * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp // * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
} catch (const invalid_fuzzing_input_exception&) {
}
}

View File

@ -10,12 +10,12 @@
#include <limits> #include <limits>
void initialize() void initialize_eval_script()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(eval_script, initialize_eval_script)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(fee_rate)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const CAmount satoshis_per_k = ConsumeMoney(fuzzed_data_provider); const CAmount satoshis_per_k = ConsumeMoney(fuzzed_data_provider);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(fees)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED}); const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(flatfile)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::optional<FlatFilePos> flat_file_pos = ConsumeDeserializable<FlatFilePos>(fuzzed_data_provider); std::optional<FlatFilePos> flat_file_pos = ConsumeDeserializable<FlatFilePos>(fuzzed_data_provider);

View File

@ -12,7 +12,7 @@
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(float)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -5,6 +5,7 @@
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <util/check.h>
#include <cstdint> #include <cstdint>
#include <unistd.h> #include <unistd.h>
@ -12,6 +13,36 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>>& FuzzTargets()
{
static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>> g_fuzz_targets;
return g_fuzz_targets;
}
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init)
{
const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init));
Assert(it_ins.second);
}
static TypeTestOneInput* g_test_one_input{nullptr};
void initialize()
{
if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) {
for (const auto& t : FuzzTargets()) {
std::cout << t.first << std::endl;
}
Assert(false);
}
std::string_view fuzz_target{Assert(std::getenv("FUZZ"))};
const auto it = FuzzTargets().find(fuzz_target);
Assert(it != FuzzTargets().end());
Assert(!g_test_one_input);
g_test_one_input = &std::get<0>(it->second);
std::get<1>(it->second)();
}
#if defined(PROVIDE_MAIN_FUNCTION) #if defined(PROVIDE_MAIN_FUNCTION)
static bool read_stdin(std::vector<uint8_t>& data) static bool read_stdin(std::vector<uint8_t>& data)
{ {
@ -24,14 +55,10 @@ static bool read_stdin(std::vector<uint8_t>& data)
} }
#endif #endif
// Default initialization: Override using a non-weak initialize().
__attribute__((weak)) void initialize()
{
}
// This function is used by libFuzzer // This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{ {
static const auto& test_one_input = *Assert(g_test_one_input);
const std::vector<uint8_t> input(data, data + size); const std::vector<uint8_t> input(data, data + size);
test_one_input(input); test_one_input(input);
return 0; return 0;
@ -48,6 +75,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
__attribute__((weak)) int main(int argc, char** argv) __attribute__((weak)) int main(int argc, char** argv)
{ {
initialize(); initialize();
static const auto& test_one_input = *Assert(g_test_one_input);
#ifdef __AFL_INIT #ifdef __AFL_INIT
// Enable AFL deferred forkserver mode. Requires compilation using // Enable AFL deferred forkserver mode. Requires compilation using
// afl-clang-fast++. See fuzzing.md for details. // afl-clang-fast++. See fuzzing.md for details.

View File

@ -5,10 +5,29 @@
#ifndef BITCOIN_TEST_FUZZ_FUZZ_H #ifndef BITCOIN_TEST_FUZZ_FUZZ_H
#define BITCOIN_TEST_FUZZ_FUZZ_H #define BITCOIN_TEST_FUZZ_FUZZ_H
#include <stdint.h> #include <cstdint>
#include <functional>
#include <string_view>
#include <vector> #include <vector>
void initialize(); using TypeTestOneInput = std::function<void(const std::vector<uint8_t>&)>;
void test_one_input(const std::vector<uint8_t>& buffer); using TypeInitialize = std::function<void()>;
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init);
void FuzzFrameworkEmptyFun() {}
#define FUZZ_TARGET(name) \
FUZZ_TARGET_INIT(name, FuzzFrameworkEmptyFun)
#define FUZZ_TARGET_INIT(name, init_fun) \
void name##_fuzz_target(const std::vector<uint8_t>&); \
struct name##_Before_Main { \
name##_Before_Main() \
{ \
FuzzFrameworkRegisterTarget(#name, name##_fuzz_target, init_fun); \
} \
} const static g_##name##_before_main; \
void name##_fuzz_target(const std::vector<uint8_t>& buffer)
#endif // BITCOIN_TEST_FUZZ_FUZZ_H #endif // BITCOIN_TEST_FUZZ_FUZZ_H

View File

@ -54,7 +54,7 @@ std::vector<uint64_t> BuildHashedSet(const std::unordered_set<std::vector<uint8_
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(golomb_rice)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::vector<uint8_t> golomb_rice_data; std::vector<uint8_t> golomb_rice_data;

View File

@ -16,12 +16,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_hex()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(hex, initialize_hex)
{ {
const std::string random_hex_string(buffer.begin(), buffer.end()); const std::string random_hex_string(buffer.begin(), buffer.end());
const std::vector<unsigned char> data = ParseHex(random_hex_string); const std::vector<unsigned char> data = ParseHex(random_hex_string);

View File

@ -22,7 +22,7 @@ extern "C" int evhttp_parse_firstline_(struct evhttp_request*, struct evbuffer*)
extern "C" int evhttp_parse_headers_(struct evhttp_request*, struct evbuffer*); extern "C" int evhttp_parse_headers_(struct evhttp_request*, struct evbuffer*);
std::string RequestMethodString(HTTPRequest::RequestMethod m); std::string RequestMethodString(HTTPRequest::RequestMethod m);
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(http_request)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
evhttp_request* evreq = evhttp_request_new(nullptr, nullptr); evhttp_request* evreq = evhttp_request_new(nullptr, nullptr);

View File

@ -39,12 +39,12 @@
#include <set> #include <set>
#include <vector> #include <vector>
void initialize() void initialize_integer()
{ {
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(integer, initialize_integer)
{ {
if (buffer.size() < sizeof(uint256) + sizeof(uint160)) { if (buffer.size() < sizeof(uint256) + sizeof(uint160)) {
return; return;

View File

@ -23,14 +23,14 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_key()
{ {
static const ECCVerifyHandle ecc_verify_handle; static const ECCVerifyHandle ecc_verify_handle;
ECC_Start(); ECC_Start();
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(key, initialize_key)
{ {
const CKey key = [&] { const CKey key = [&] {
CKey k; CKey k;

View File

@ -13,12 +13,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_key_io()
{ {
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(key_io, initialize_key_io)
{ {
const std::string random_string(buffer.begin(), buffer.end()); const std::string random_string(buffer.begin(), buffer.end());

View File

@ -15,7 +15,7 @@
// The fuzzing kitchen sink: Fuzzing harness for functions that need to be // The fuzzing kitchen sink: Fuzzing harness for functions that need to be
// fuzzed but a.) don't belong in any existing fuzzing harness file, and // fuzzed but a.) don't belong in any existing fuzzing harness file, and
// b.) are not important enough to warrant their own fuzzing harness file. // b.) are not important enough to warrant their own fuzzing harness file.
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(kitchen_sink)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -13,12 +13,12 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void initialize() void initialize_load_external_block_file()
{ {
InitializeFuzzingContext(); InitializeFuzzingContext();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider); FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);

View File

@ -35,7 +35,7 @@ bool IsAvailableLocale(const std::string& locale_identifier)
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(locale)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string locale_identifier = ConsumeLocaleIdentifier(fuzzed_data_provider); const std::string locale_identifier = ConsumeLocaleIdentifier(fuzzed_data_provider);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(merkleblock)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::optional<CPartialMerkleTree> partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider); std::optional<CPartialMerkleTree> partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider);

View File

@ -16,14 +16,14 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_message()
{ {
static const ECCVerifyHandle ecc_verify_handle; static const ECCVerifyHandle ecc_verify_handle;
ECC_Start(); ECC_Start();
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(message, initialize_message)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string random_message = fuzzed_data_provider.ConsumeRandomLengthString(1024); const std::string random_message = fuzzed_data_provider.ConsumeRandomLengthString(1024);

View File

@ -40,7 +40,7 @@ void TestMultiplicationOverflow(FuzzedDataProvider& fuzzed_data_provider)
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(multiplication_overflow)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
TestMultiplicationOverflow<int64_t>(fuzzed_data_provider); TestMultiplicationOverflow<int64_t>(fuzzed_data_provider);

View File

@ -19,12 +19,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_net()
{ {
static const BasicTestingSetup basic_testing_setup; static const BasicTestingSetup basic_testing_setup;
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(net, initialize_net)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(net_permissions)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(32); const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(32);

View File

@ -12,7 +12,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(netaddress)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -12,12 +12,12 @@
#include <limits> #include <limits>
#include <vector> #include <vector>
void initialize() void initialize_p2p_transport_deserializer()
{ {
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(p2p_transport_deserializer, initialize_p2p_transport_deserializer)
{ {
// Construct deserializer, with a dummy NodeId // Construct deserializer, with a dummy NodeId
V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION}; V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION};

View File

@ -10,7 +10,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(parse_hd_keypath)
{ {
const std::string keypath_str(buffer.begin(), buffer.end()); const std::string keypath_str(buffer.begin(), buffer.end());
std::vector<uint32_t> keypath; std::vector<uint32_t> keypath;

View File

@ -11,7 +11,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(parse_iso8601)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -8,7 +8,7 @@
#include <string> #include <string>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(parse_numbers)
{ {
const std::string random_string(buffer.begin(), buffer.end()); const std::string random_string(buffer.begin(), buffer.end());

View File

@ -6,7 +6,7 @@
#include <script/script.h> #include <script/script.h>
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(parse_script)
{ {
const std::string script_string(buffer.begin(), buffer.end()); const std::string script_string(buffer.begin(), buffer.end());
try { try {

View File

@ -14,13 +14,13 @@
#include <limits> #include <limits>
#include <string> #include <string>
void initialize() void initialize_parse_univalue()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(parse_univalue, initialize_parse_univalue)
{ {
const std::string random_string(buffer.begin(), buffer.end()); const std::string random_string(buffer.begin(), buffer.end());
bool valid = true; bool valid = true;

View File

@ -14,7 +14,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(policy_estimator)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CBlockPolicyEstimator block_policy_estimator; CBlockPolicyEstimator block_policy_estimator;

View File

@ -15,12 +15,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_pow()
{ {
SelectParams(CBaseChainParams::MAIN); SelectParams(CBaseChainParams::MAIN);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(pow, initialize_pow)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const Consensus::Params& consensus_params = Params().GetConsensus(); const Consensus::Params& consensus_params = Params().GetConsensus();

View File

@ -204,7 +204,7 @@ public:
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(prevector)
{ {
FuzzedDataProvider prov(buffer.data(), buffer.size()); FuzzedDataProvider prov(buffer.data(), buffer.size());
prevector_tester<8, int> test; prevector_tester<8, int> test;

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(primitives_transaction)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const CScript script = ConsumeScript(fuzzed_data_provider); const CScript script = ConsumeScript(fuzzed_data_provider);

View File

@ -40,19 +40,10 @@
bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CDKGSessionManager& qdkgsman, llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61); bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CDKGSessionManager& qdkgsman, llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61);
namespace { namespace {
#ifdef MESSAGE_TYPE
#define TO_STRING_(s) #s
#define TO_STRING(s) TO_STRING_(s)
const std::string LIMIT_TO_MESSAGE_TYPE{TO_STRING(MESSAGE_TYPE)};
#else
const std::string LIMIT_TO_MESSAGE_TYPE;
#endif
const TestingSetup* g_setup; const TestingSetup* g_setup;
} // namespace } // namespace
void initialize() void initialize_process_message()
{ {
static TestingSetup setup{ static TestingSetup setup{
CBaseChainParams::REGTEST, CBaseChainParams::REGTEST,
@ -68,7 +59,7 @@ void initialize()
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();
} }
void test_one_input(const std::vector<uint8_t>& buffer) void fuzz_target(const std::vector<uint8_t>& buffer, const std::string& LIMIT_TO_MESSAGE_TYPE)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
@ -87,3 +78,29 @@ void test_one_input(const std::vector<uint8_t>& buffer)
} }
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();
} }
FUZZ_TARGET_INIT(process_message, initialize_process_message) { fuzz_target(buffer, ""); }
FUZZ_TARGET_INIT(process_message_addr, initialize_process_message) { fuzz_target(buffer, "addr"); }
FUZZ_TARGET_INIT(process_message_block, initialize_process_message) { fuzz_target(buffer, "block"); }
FUZZ_TARGET_INIT(process_message_blocktxn, initialize_process_message) { fuzz_target(buffer, "blocktxn"); }
FUZZ_TARGET_INIT(process_message_cmpctblock, initialize_process_message) { fuzz_target(buffer, "cmpctblock"); }
FUZZ_TARGET_INIT(process_message_feefilter, initialize_process_message) { fuzz_target(buffer, "feefilter"); }
FUZZ_TARGET_INIT(process_message_filteradd, initialize_process_message) { fuzz_target(buffer, "filteradd"); }
FUZZ_TARGET_INIT(process_message_filterclear, initialize_process_message) { fuzz_target(buffer, "filterclear"); }
FUZZ_TARGET_INIT(process_message_filterload, initialize_process_message) { fuzz_target(buffer, "filterload"); }
FUZZ_TARGET_INIT(process_message_getaddr, initialize_process_message) { fuzz_target(buffer, "getaddr"); }
FUZZ_TARGET_INIT(process_message_getblocks, initialize_process_message) { fuzz_target(buffer, "getblocks"); }
FUZZ_TARGET_INIT(process_message_getblocktxn, initialize_process_message) { fuzz_target(buffer, "getblocktxn"); }
FUZZ_TARGET_INIT(process_message_getdata, initialize_process_message) { fuzz_target(buffer, "getdata"); }
FUZZ_TARGET_INIT(process_message_getheaders, initialize_process_message) { fuzz_target(buffer, "getheaders"); }
FUZZ_TARGET_INIT(process_message_headers, initialize_process_message) { fuzz_target(buffer, "headers"); }
FUZZ_TARGET_INIT(process_message_inv, initialize_process_message) { fuzz_target(buffer, "inv"); }
FUZZ_TARGET_INIT(process_message_mempool, initialize_process_message) { fuzz_target(buffer, "mempool"); }
FUZZ_TARGET_INIT(process_message_notfound, initialize_process_message) { fuzz_target(buffer, "notfound"); }
FUZZ_TARGET_INIT(process_message_ping, initialize_process_message) { fuzz_target(buffer, "ping"); }
FUZZ_TARGET_INIT(process_message_pong, initialize_process_message) { fuzz_target(buffer, "pong"); }
FUZZ_TARGET_INIT(process_message_sendcmpct, initialize_process_message) { fuzz_target(buffer, "sendcmpct"); }
FUZZ_TARGET_INIT(process_message_sendheaders, initialize_process_message) { fuzz_target(buffer, "sendheaders"); }
FUZZ_TARGET_INIT(process_message_tx, initialize_process_message) { fuzz_target(buffer, "tx"); }
FUZZ_TARGET_INIT(process_message_verack, initialize_process_message) { fuzz_target(buffer, "verack"); }
FUZZ_TARGET_INIT(process_message_version, initialize_process_message) { fuzz_target(buffer, "version"); }

View File

@ -18,7 +18,7 @@
const TestingSetup* g_setup; const TestingSetup* g_setup;
void initialize() void initialize_process_messages()
{ {
static TestingSetup setup{ static TestingSetup setup{
CBaseChainParams::REGTEST, CBaseChainParams::REGTEST,
@ -34,7 +34,7 @@ void initialize()
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(process_messages, initialize_process_messages)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -12,7 +12,7 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(protocol)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CInv> inv = ConsumeDeserializable<CInv>(fuzzed_data_provider); const std::optional<CInv> inv = ConsumeDeserializable<CInv>(fuzzed_data_provider);

View File

@ -16,12 +16,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_psbt()
{ {
static const auto verify_handle = MakeUnique<ECCVerifyHandle>(); static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(psbt, initialize_psbt)
{ {
PartiallySignedTransaction psbt_mut; PartiallySignedTransaction psbt_mut;
const std::string raw_psbt{buffer.begin(), buffer.end()}; const std::string raw_psbt{buffer.begin(), buffer.end()};

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(random)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)}; FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};

View File

@ -14,7 +14,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(rolling_bloom_filter)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -29,7 +29,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_script()
{ {
// Fuzzers using pubkey must hold an ECCVerifyHandle. // Fuzzers using pubkey must hold an ECCVerifyHandle.
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
@ -37,7 +37,7 @@ void initialize()
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(script, initialize_script)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CScript> script_opt = ConsumeDeserializable<CScript>(fuzzed_data_provider); const std::optional<CScript> script_opt = ConsumeDeserializable<CScript>(fuzzed_data_provider);

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(script_bitcoin_consensus)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider); const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(script_descriptor_cache)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
DescriptorCache descriptor_cache; DescriptorCache descriptor_cache;

View File

@ -13,12 +13,12 @@
/** Flags that are not forbidden by an assert */ /** Flags that are not forbidden by an assert */
static bool IsValidFlagCombination(unsigned flags); static bool IsValidFlagCombination(unsigned flags);
void initialize() void initialize_script_flags()
{ {
static const ECCVerifyHandle verify_handle; static const ECCVerifyHandle verify_handle;
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(script_flags, initialize_script_flags)
{ {
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
try { try {

View File

@ -15,7 +15,7 @@
bool CastToBool(const std::vector<unsigned char>& vch); bool CastToBool(const std::vector<unsigned char>& vch);
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(script_interpreter)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
{ {

View File

@ -11,7 +11,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(script_ops)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CScript script = ConsumeScript(fuzzed_data_provider); CScript script = ConsumeScript(fuzzed_data_provider);

View File

@ -16,7 +16,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_script_sigcache()
{ {
static const ECCVerifyHandle ecc_verify_handle; static const ECCVerifyHandle ecc_verify_handle;
ECC_Start(); ECC_Start();
@ -24,7 +24,7 @@ void initialize()
InitSignatureCache(); InitSignatureCache();
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(script_sigcache, initialize_script_sigcache)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -22,14 +22,14 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_script_sign()
{ {
static const ECCVerifyHandle ecc_verify_handle; static const ECCVerifyHandle ecc_verify_handle;
ECC_Start(); ECC_Start();
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128); const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128);

View File

@ -24,7 +24,7 @@ bool IsValidSubtraction(const CScriptNum& lhs, const CScriptNum& rhs)
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(scriptnum_ops)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CScriptNum script_num = ConsumeScriptNum(fuzzed_data_provider); CScriptNum script_num = ConsumeScriptNum(fuzzed_data_provider);

View File

@ -14,7 +14,7 @@
int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char* out32, const unsigned char* seckey, size_t seckeylen); int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char* out32, const unsigned char* seckey, size_t seckeylen);
int ec_seckey_export_der(const secp256k1_context* ctx, unsigned char* seckey, size_t* seckeylen, const unsigned char* key32, bool compressed); int ec_seckey_export_der(const secp256k1_context* ctx, unsigned char* seckey, size_t* seckeylen, const unsigned char* key32, bool compressed);
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(secp256k1_ec_seckey_import_export_der)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);

View File

@ -14,7 +14,7 @@
bool SigHasLowR(const secp256k1_ecdsa_signature* sig); bool SigHasLowR(const secp256k1_ecdsa_signature* sig);
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char* input, size_t inputlen); int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char* input, size_t inputlen);
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> signature_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider); const std::vector<uint8_t> signature_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void initialize() void initialize_signature_checker()
{ {
static const auto verify_handle = MakeUnique<ECCVerifyHandle>(); static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
} }
@ -47,7 +47,7 @@ public:
}; };
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(signature_checker, initialize_signature_checker)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(span)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

View File

@ -6,7 +6,7 @@
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <util/spanparsing.h> #include <util/spanparsing.h>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(spanparsing)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>(); const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>();

View File

@ -31,7 +31,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(string)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string random_string_1 = fuzzed_data_provider.ConsumeRandomLengthString(32); const std::string random_string_1 = fuzzed_data_provider.ConsumeRandomLengthString(32);

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(str_printf)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string format_string = fuzzed_data_provider.ConsumeRandomLengthString(64); const std::string format_string = fuzzed_data_provider.ConsumeRandomLengthString(64);

View File

@ -22,7 +22,7 @@ std::string GetArgumentName(const std::string& name)
} }
} // namespace } // namespace
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(system)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
ArgsManager args_manager{}; ArgsManager args_manager{};

View File

@ -11,7 +11,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(timedata)
{ {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000); const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000);

View File

@ -20,12 +20,12 @@
#include <cassert> #include <cassert>
void initialize() void initialize_transaction()
{ {
SelectParams(CBaseChainParams::REGTEST); SelectParams(CBaseChainParams::REGTEST);
} }
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET_INIT(transaction, initialize_transaction)
{ {
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
try { try {

View File

@ -12,7 +12,7 @@
#include <cassert> #include <cassert>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(tx_in)
{ {
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CTxIn tx_in; CTxIn tx_in;

View File

@ -9,7 +9,7 @@
#include <test/fuzz/fuzz.h> #include <test/fuzz/fuzz.h>
#include <version.h> #include <version.h>
void test_one_input(const std::vector<uint8_t>& buffer) FUZZ_TARGET(tx_out)
{ {
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CTxOut tx_out; CTxOut tx_out;

View File

@ -82,7 +82,7 @@ def main():
sys.exit(1) sys.exit(1)
# Build list of tests # Build list of tests
test_list_all = parse_test_list(makefile=os.path.join(config["environment"]["SRCDIR"], 'src', 'Makefile.test.include')) test_list_all = parse_test_list(fuzz_bin=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'))
if not test_list_all: if not test_list_all:
logging.error("No fuzz targets found") logging.error("No fuzz targets found")
@ -125,9 +125,12 @@ def main():
try: try:
help_output = subprocess.run( help_output = subprocess.run(
args=[ args=[
os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', test_list_selection[0]), os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'),
'-help=1', '-help=1',
], ],
env={
'FUZZ': test_list_selection[0]
},
timeout=20, timeout=20,
check=True, check=True,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
@ -176,24 +179,30 @@ def generate_corpus_seeds(*, fuzz_pool, build_dir, seed_dir, targets):
""" """
logging.info("Generating corpus seeds to {}".format(seed_dir)) logging.info("Generating corpus seeds to {}".format(seed_dir))
def job(command): def job(command, t):
logging.debug("Running '{}'\n".format(" ".join(command))) logging.debug("Running '{}'\n".format(" ".join(command)))
logging.debug("Command '{}' output:\n'{}'\n".format( logging.debug("Command '{}' output:\n'{}'\n".format(
' '.join(command), ' '.join(command),
subprocess.run(command, check=True, stderr=subprocess.PIPE, subprocess.run(
universal_newlines=True).stderr command,
)) env={
'FUZZ': t
},
check=True,
stderr=subprocess.PIPE,
universal_newlines=True,
).stderr))
futures = [] futures = []
for target in targets: for target in targets:
target_seed_dir = os.path.join(seed_dir, target) target_seed_dir = os.path.join(seed_dir, target)
os.makedirs(target_seed_dir, exist_ok=True) os.makedirs(target_seed_dir, exist_ok=True)
command = [ command = [
os.path.join(build_dir, "src", "test", "fuzz", target), os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
"-runs=100000", "-runs=100000",
target_seed_dir, target_seed_dir,
] ]
futures.append(fuzz_pool.submit(job, command)) futures.append(fuzz_pool.submit(job, command, target))
for future in as_completed(futures): for future in as_completed(futures):
future.result() future.result()
@ -204,7 +213,7 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, build_dir, merge_dir):
jobs = [] jobs = []
for t in test_list: for t in test_list:
args = [ args = [
os.path.join(build_dir, 'src', 'test', 'fuzz', t), os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
'-merge=1', '-merge=1',
'-use_value_profile=1', # Also done by oss-fuzz https://github.com/google/oss-fuzz/issues/1406#issuecomment-387790487 '-use_value_profile=1', # Also done by oss-fuzz https://github.com/google/oss-fuzz/issues/1406#issuecomment-387790487
os.path.join(corpus, t), os.path.join(corpus, t),
@ -215,7 +224,15 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, build_dir, merge_dir):
def job(t, args): def job(t, args):
output = 'Run {} with args {}\n'.format(t, " ".join(args)) output = 'Run {} with args {}\n'.format(t, " ".join(args))
output += subprocess.run(args, check=True, stderr=subprocess.PIPE, universal_newlines=True).stderr output += subprocess.run(
args,
env={
'FUZZ': t
},
check=True,
stderr=subprocess.PIPE,
universal_newlines=True,
).stderr
logging.debug(output) logging.debug(output)
jobs.append(fuzz_pool.submit(job, t, args)) jobs.append(fuzz_pool.submit(job, t, args))
@ -230,7 +247,7 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
corpus_path = os.path.join(corpus, t) corpus_path = os.path.join(corpus, t)
os.makedirs(corpus_path, exist_ok=True) os.makedirs(corpus_path, exist_ok=True)
args = [ args = [
os.path.join(build_dir, 'src', 'test', 'fuzz', t), os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
'-runs=1', '-runs=1',
corpus_path, corpus_path,
] ]
@ -239,7 +256,7 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
def job(t, args): def job(t, args):
output = 'Run {} with args {}'.format(t, args) output = 'Run {} with args {}'.format(t, args)
result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True) result = subprocess.run(args, env={'FUZZ': t}, stderr=subprocess.PIPE, universal_newlines=True)
output += result.stderr output += result.stderr
return output, result return output, result
@ -259,20 +276,16 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
sys.exit(1) sys.exit(1)
def parse_test_list(makefile): def parse_test_list(*, fuzz_bin):
with open(makefile, encoding='utf-8') as makefile_test: test_list_all = subprocess.run(
test_list_all = [] fuzz_bin,
read_targets = False env={
for line in makefile_test.readlines(): 'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': ''
line = line.strip().replace('test/fuzz/', '').replace(' \\', '') },
if read_targets: stdout=subprocess.PIPE,
if not line: stderr=subprocess.DEVNULL,
break universal_newlines=True,
test_list_all.append(line) ).stdout.splitlines()
continue
if line == 'FUZZ_TARGETS =':
read_targets = True
return test_list_all return test_list_all