aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/crypto.cpp124
-rw-r--r--src/test/fuzz/decode_tx.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp16
-rw-r--r--src/test/fuzz/key.cpp18
-rw-r--r--src/test/fuzz/process_message.cpp17
-rw-r--r--src/test/fuzz/process_messages.cpp2
-rw-r--r--src/test/fuzz/psbt.cpp2
-rw-r--r--src/test/fuzz/script.cpp4
-rw-r--r--src/test/fuzz/span.cpp4
-rw-r--r--src/test/fuzz/spanparsing.cpp2
10 files changed, 167 insertions, 24 deletions
diff --git a/src/test/fuzz/crypto.cpp b/src/test/fuzz/crypto.cpp
new file mode 100644
index 0000000000..595cdf9abb
--- /dev/null
+++ b/src/test/fuzz/crypto.cpp
@@ -0,0 +1,124 @@
+// 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.
+
+#include <crypto/hmac_sha256.h>
+#include <crypto/hmac_sha512.h>
+#include <crypto/ripemd160.h>
+#include <crypto/sha1.h>
+#include <crypto/sha256.h>
+#include <crypto/sha512.h>
+#include <hash.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+
+ CHash160 hash160;
+ CHash256 hash256;
+ CHMAC_SHA256 hmac_sha256{data.data(), data.size()};
+ CHMAC_SHA512 hmac_sha512{data.data(), data.size()};
+ CRIPEMD160 ripemd160;
+ CSHA1 sha1;
+ CSHA256 sha256;
+ CSHA512 sha512;
+ CSipHasher sip_hasher{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
+ case 0: {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+ }
+
+ (void)hash160.Write(data.data(), data.size());
+ (void)hash256.Write(data.data(), data.size());
+ (void)hmac_sha256.Write(data.data(), data.size());
+ (void)hmac_sha512.Write(data.data(), data.size());
+ (void)ripemd160.Write(data.data(), data.size());
+ (void)sha1.Write(data.data(), data.size());
+ (void)sha256.Write(data.data(), data.size());
+ (void)sha512.Write(data.data(), data.size());
+ (void)sip_hasher.Write(data.data(), data.size());
+
+ (void)Hash(data.begin(), data.end());
+ (void)Hash160(data);
+ (void)Hash160(data.begin(), data.end());
+ (void)sha512.Size();
+ break;
+ }
+ case 1: {
+ (void)hash160.Reset();
+ (void)hash256.Reset();
+ (void)ripemd160.Reset();
+ (void)sha1.Reset();
+ (void)sha256.Reset();
+ (void)sha512.Reset();
+ break;
+ }
+ case 2: {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 8)) {
+ case 0: {
+ data.resize(CHash160::OUTPUT_SIZE);
+ hash160.Finalize(data.data());
+ break;
+ }
+ case 1: {
+ data.resize(CHash256::OUTPUT_SIZE);
+ hash256.Finalize(data.data());
+ break;
+ }
+ case 2: {
+ data.resize(CHMAC_SHA256::OUTPUT_SIZE);
+ hmac_sha256.Finalize(data.data());
+ break;
+ }
+ case 3: {
+ data.resize(CHMAC_SHA512::OUTPUT_SIZE);
+ hmac_sha512.Finalize(data.data());
+ break;
+ }
+ case 4: {
+ data.resize(CRIPEMD160::OUTPUT_SIZE);
+ ripemd160.Finalize(data.data());
+ break;
+ }
+ case 5: {
+ data.resize(CSHA1::OUTPUT_SIZE);
+ sha1.Finalize(data.data());
+ break;
+ }
+ case 6: {
+ data.resize(CSHA256::OUTPUT_SIZE);
+ sha256.Finalize(data.data());
+ break;
+ }
+ case 7: {
+ data.resize(CSHA512::OUTPUT_SIZE);
+ sha512.Finalize(data.data());
+ break;
+ }
+ case 8: {
+ data.resize(1);
+ data[0] = sip_hasher.Finalize() % 256;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/src/test/fuzz/decode_tx.cpp b/src/test/fuzz/decode_tx.cpp
index 09c4ff05df..0d89d4228a 100644
--- a/src/test/fuzz/decode_tx.cpp
+++ b/src/test/fuzz/decode_tx.cpp
@@ -14,7 +14,7 @@
void test_one_input(const std::vector<uint8_t>& buffer)
{
- const std::string tx_hex = HexStr(std::string{buffer.begin(), buffer.end()});
+ const std::string tx_hex = HexStr(buffer);
CMutableTransaction mtx;
const bool result_none = DecodeHexTx(mtx, tx_hex, false, false);
const bool result_try_witness = DecodeHexTx(mtx, tx_hex, false, true);
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 82e1d55c0b..1e1807d734 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -12,7 +12,16 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
-#if defined(__AFL_COMPILER)
+// Decide if main(...) should be provided:
+// * AFL needs main(...) regardless of platform.
+// * macOS handles __attribute__((weak)) main(...) poorly when linking
+// against libFuzzer. See https://github.com/bitcoin/bitcoin/pull/18008
+// for details.
+#if defined(__AFL_COMPILER) || !defined(MAC_OSX)
+#define PROVIDE_MAIN_FUNCTION
+#endif
+
+#if defined(PROVIDE_MAIN_FUNCTION)
static bool read_stdin(std::vector<uint8_t>& data)
{
uint8_t buffer[1024];
@@ -44,9 +53,8 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
return 0;
}
-// Generally, the fuzzer will provide main(), except for AFL
-#if defined(__AFL_COMPILER)
-int main(int argc, char** argv)
+#if defined(PROVIDE_MAIN_FUNCTION)
+__attribute__((weak)) int main(int argc, char** argv)
{
initialize();
#ifdef __AFL_INIT
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp
index 1919a5f881..c746374c61 100644
--- a/src/test/fuzz/key.cpp
+++ b/src/test/fuzz/key.cpp
@@ -108,7 +108,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(pubkey.IsCompressed());
assert(pubkey.IsValid());
assert(pubkey.IsFullyValid());
- assert(HexToPubKey(HexStr(pubkey.begin(), pubkey.end())) == pubkey);
+ assert(HexToPubKey(HexStr(pubkey)) == pubkey);
assert(GetAllDestinationsForKey(pubkey).size() == 3);
}
@@ -157,25 +157,25 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(ok_add_key_pubkey);
assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID()));
- txnouttype which_type_tx_pubkey;
+ TxoutType which_type_tx_pubkey;
const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, which_type_tx_pubkey);
assert(is_standard_tx_pubkey);
- assert(which_type_tx_pubkey == txnouttype::TX_PUBKEY);
+ assert(which_type_tx_pubkey == TxoutType::PUBKEY);
- txnouttype which_type_tx_multisig;
+ TxoutType which_type_tx_multisig;
const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, which_type_tx_multisig);
assert(is_standard_tx_multisig);
- assert(which_type_tx_multisig == txnouttype::TX_MULTISIG);
+ assert(which_type_tx_multisig == TxoutType::MULTISIG);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey;
- const txnouttype outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
- assert(outtype_tx_pubkey == txnouttype::TX_PUBKEY);
+ const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
+ assert(outtype_tx_pubkey == TxoutType::PUBKEY);
assert(v_solutions_ret_tx_pubkey.size() == 1);
assert(v_solutions_ret_tx_pubkey[0].size() == 33);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig;
- const txnouttype outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
- assert(outtype_tx_multisig == txnouttype::TX_MULTISIG);
+ const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
+ assert(outtype_tx_multisig == TxoutType::MULTISIG);
assert(v_solutions_ret_tx_multisig.size() == 3);
assert(v_solutions_ret_tx_multisig[0].size() == 1);
assert(v_solutions_ret_tx_multisig[1].size() == 33);
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index 211a84b5f2..2fa751b987 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -30,7 +30,17 @@
#include <string>
#include <vector>
-bool ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc);
+void ProcessMessage(
+ CNode& pfrom,
+ const std::string& msg_type,
+ CDataStream& vRecv,
+ int64_t nTimeReceived,
+ const CChainParams& chainparams,
+ ChainstateManager& chainman,
+ CTxMemPool& mempool,
+ CConnman* connman,
+ BanMan* banman,
+ const std::atomic<bool>& interruptMsgProc);
namespace {
@@ -77,7 +87,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
connman.AddTestNode(p2p_node);
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
try {
- (void)ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false});
+ ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(),
+ Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool,
+ g_setup->m_node.connman.get(), g_setup->m_node.banman.get(),
+ std::atomic<bool>{false});
} catch (const std::ios_base::failure&) {
}
SyncWithValidationInterfaceQueue();
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp
index ad6c115a49..91ebf9fb1b 100644
--- a/src/test/fuzz/process_messages.cpp
+++ b/src/test/fuzz/process_messages.cpp
@@ -62,7 +62,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
CSerializedNetMsg net_msg;
- net_msg.command = random_message_type;
+ net_msg.m_type = random_message_type;
net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
CNode& random_node = *peers.at(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, peers.size() - 1));
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
index 64328fb66e..908e2b16f2 100644
--- a/src/test/fuzz/psbt.cpp
+++ b/src/test/fuzz/psbt.cpp
@@ -39,7 +39,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
(void)psbt.IsNull();
- (void)psbt.IsSane();
Optional<CMutableTransaction> tx = psbt.tx;
if (tx) {
@@ -50,7 +49,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
for (const PSBTInput& input : psbt.inputs) {
(void)PSBTInputSigned(input);
(void)input.IsNull();
- (void)input.IsSane();
}
for (const PSBTOutput& output : psbt.outputs) {
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index 933cf9049d..cad548178d 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -58,7 +58,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CTxDestination address;
(void)ExtractDestination(script, address);
- txnouttype type_ret;
+ TxoutType type_ret;
std::vector<CTxDestination> addresses;
int required_ret;
(void)ExtractDestinations(script, type_ret, addresses, required_ret);
@@ -72,7 +72,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)IsSolvable(signing_provider, script);
- txnouttype which_type;
+ TxoutType which_type;
(void)IsStandard(script, which_type);
(void)RecursiveDynamicUsage(script);
diff --git a/src/test/fuzz/span.cpp b/src/test/fuzz/span.cpp
index 4aea530ef2..f6b6e8f6f0 100644
--- a/src/test/fuzz/span.cpp
+++ b/src/test/fuzz/span.cpp
@@ -18,7 +18,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::string str = fuzzed_data_provider.ConsumeBytesAsString(32);
- const Span<const char> span = MakeSpan(str);
+ const Span<const char> span{str};
(void)span.data();
(void)span.begin();
(void)span.end();
@@ -32,7 +32,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
std::string another_str = fuzzed_data_provider.ConsumeBytesAsString(32);
- const Span<const char> another_span = MakeSpan(another_str);
+ const Span<const char> another_span{another_str};
assert((span <= another_span) != (span > another_span));
assert((span == another_span) != (span != another_span));
assert((span >= another_span) != (span < another_span));
diff --git a/src/test/fuzz/spanparsing.cpp b/src/test/fuzz/spanparsing.cpp
index 8e5e7dad11..e5bf5dd608 100644
--- a/src/test/fuzz/spanparsing.cpp
+++ b/src/test/fuzz/spanparsing.cpp
@@ -12,7 +12,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>();
const std::string query = fuzzed_data_provider.ConsumeBytesAsString(std::min<size_t>(query_size, 1024 * 1024));
const std::string span_str = fuzzed_data_provider.ConsumeRemainingBytesAsString();
- const Span<const char> const_span = MakeSpan(span_str);
+ const Span<const char> const_span{span_str};
Span<const char> mut_span = const_span;
(void)spanparsing::Const(query, mut_span);