diff --git a/src/Makefile.test.include b/src/Makefile.test.include index b7715b03a9..f4ed000f8b 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -37,6 +37,7 @@ FUZZ_TARGETS = \ test/fuzz/fee_rate \ test/fuzz/fee_rate_deserialize \ test/fuzz/flat_file_pos_deserialize \ + test/fuzz/flatfile \ test/fuzz/float \ test/fuzz/hex \ test/fuzz/integer \ @@ -46,6 +47,7 @@ FUZZ_TARGETS = \ test/fuzz/key_origin_info_deserialize \ test/fuzz/locale \ test/fuzz/merkle_block_deserialize \ + test/fuzz/merkleblock \ test/fuzz/messageheader_deserialize \ test/fuzz/multiplication_overflow \ test/fuzz/net_permissions \ @@ -67,6 +69,7 @@ FUZZ_TARGETS = \ test/fuzz/psbt_input_deserialize \ test/fuzz/psbt_output_deserialize \ test/fuzz/pub_key_deserialize \ + test/fuzz/random \ test/fuzz/rolling_bloom_filter \ test/fuzz/script \ test/fuzz/script_deserialize \ @@ -74,6 +77,7 @@ FUZZ_TARGETS = \ test/fuzz/script_ops \ test/fuzz/scriptnum_ops \ test/fuzz/service_deserialize \ + test/fuzz/span \ test/fuzz/spanparsing \ test/fuzz/string \ test/fuzz/strprintf \ @@ -477,6 +481,12 @@ test_fuzz_flat_file_pos_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_flat_file_pos_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) test_fuzz_flat_file_pos_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp +test_fuzz_flatfile_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_flatfile_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_flatfile_LDADD = $(FUZZ_SUITE_LD_COMMON) +test_fuzz_flatfile_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) +test_fuzz_flatfile_SOURCES = $(FUZZ_SUITE) test/fuzz/flatfile.cpp + test_fuzz_float_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) test_fuzz_float_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_float_LDADD = $(FUZZ_SUITE_LD_COMMON) @@ -531,6 +541,12 @@ test_fuzz_merkle_block_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_merkle_block_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) test_fuzz_merkle_block_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp +test_fuzz_merkleblock_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_merkleblock_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_merkleblock_LDADD = $(FUZZ_SUITE_LD_COMMON) +test_fuzz_merkleblock_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) +test_fuzz_merkleblock_SOURCES = $(FUZZ_SUITE) test/fuzz/merkleblock.cpp + test_fuzz_messageheader_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DMESSAGEHEADER_DESERIALIZE=1 test_fuzz_messageheader_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_messageheader_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) @@ -657,6 +673,12 @@ test_fuzz_pub_key_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_pub_key_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) test_fuzz_pub_key_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp +test_fuzz_random_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_random_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_random_LDADD = $(FUZZ_SUITE_LD_COMMON) +test_fuzz_random_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) +test_fuzz_random_SOURCES = $(FUZZ_SUITE) test/fuzz/random.cpp + test_fuzz_rolling_bloom_filter_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) test_fuzz_rolling_bloom_filter_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_rolling_bloom_filter_LDADD = $(FUZZ_SUITE_LD_COMMON) @@ -699,6 +721,12 @@ test_fuzz_service_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_service_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) test_fuzz_service_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp +test_fuzz_span_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_span_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_span_LDADD = $(FUZZ_SUITE_LD_COMMON) +test_fuzz_span_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(LDFLAGS_WRAP_EXCEPTIONS) +test_fuzz_span_SOURCES = $(FUZZ_SUITE) test/fuzz/span.cpp + test_fuzz_spanparsing_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) test_fuzz_spanparsing_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_spanparsing_LDADD = $(FUZZ_SUITE_LD_COMMON) diff --git a/src/random.h b/src/random.h index 648aa16e23..cd61693b65 100644 --- a/src/random.h +++ b/src/random.h @@ -106,7 +106,8 @@ void RandAddEvent(const uint32_t event_info) noexcept; * * This class is not thread-safe. */ -class FastRandomContext { +class FastRandomContext +{ private: bool requires_seed; ChaCha20 rng; @@ -158,7 +159,8 @@ public: } /** Generate a random (bits)-bit integer. */ - uint64_t randbits(int bits) noexcept { + uint64_t randbits(int bits) noexcept + { if (bits == 0) { return 0; } else if (bits > 32) { @@ -172,7 +174,9 @@ public: } } - /** Generate a random integer in the range [0..range). */ + /** Generate a random integer in the range [0..range). + * Precondition: range > 0. + */ uint64_t randrange(uint64_t range) noexcept { assert(range); @@ -221,7 +225,7 @@ public: * debug mode detects and panics on. This is a known issue, see * https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle */ -template +template void Shuffle(I first, I last, R&& rng) { while (first != last) { @@ -244,7 +248,7 @@ static const int NUM_OS_RANDOM_BYTES = 32; /** Get 32 bytes of system entropy. Do not use this in application code: use * GetStrongRandBytes instead. */ -void GetOSRand(unsigned char *ent32); +void GetOSRand(unsigned char* ent32); /** Check that OS randomness is available and returning the requested number * of bytes. diff --git a/src/test/fuzz/flatfile.cpp b/src/test/fuzz/flatfile.cpp new file mode 100644 index 0000000000..a55de77df7 --- /dev/null +++ b/src/test/fuzz/flatfile.cpp @@ -0,0 +1,30 @@ +// 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +void test_one_input(const std::vector& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + Optional flat_file_pos = ConsumeDeserializable(fuzzed_data_provider); + if (!flat_file_pos) { + return; + } + Optional another_flat_file_pos = ConsumeDeserializable(fuzzed_data_provider); + if (another_flat_file_pos) { + assert((*flat_file_pos == *another_flat_file_pos) != (*flat_file_pos != *another_flat_file_pos)); + } + (void)flat_file_pos->ToString(); + flat_file_pos->SetNull(); + assert(flat_file_pos->IsNull()); +} diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp new file mode 100644 index 0000000000..eb8fa1d421 --- /dev/null +++ b/src/test/fuzz/merkleblock.cpp @@ -0,0 +1,27 @@ +// 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 +#include +#include +#include +#include +#include + +#include +#include +#include + +void test_one_input(const std::vector& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + Optional partial_merkle_tree = ConsumeDeserializable(fuzzed_data_provider); + if (!partial_merkle_tree) { + return; + } + (void)partial_merkle_tree->GetNumTransactions(); + std::vector matches; + std::vector indices; + (void)partial_merkle_tree->ExtractMatches(matches, indices); +} diff --git a/src/test/fuzz/random.cpp b/src/test/fuzz/random.cpp new file mode 100644 index 0000000000..7df6594ad6 --- /dev/null +++ b/src/test/fuzz/random.cpp @@ -0,0 +1,31 @@ +// 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 +#include +#include +#include + +#include +#include +#include +#include + +void test_one_input(const std::vector& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)}; + (void)fast_random_context.rand64(); + (void)fast_random_context.randbits(fuzzed_data_provider.ConsumeIntegralInRange(0, 64)); + (void)fast_random_context.randrange(fuzzed_data_provider.ConsumeIntegralInRange(FastRandomContext::min() + 1, FastRandomContext::max())); + (void)fast_random_context.randbytes(fuzzed_data_provider.ConsumeIntegralInRange(0, 1024)); + (void)fast_random_context.rand32(); + (void)fast_random_context.rand256(); + (void)fast_random_context.randbool(); + (void)fast_random_context(); + + std::vector integrals = ConsumeRandomLengthIntegralVector(fuzzed_data_provider); + Shuffle(integrals.begin(), integrals.end(), fast_random_context); + std::shuffle(integrals.begin(), integrals.end(), fast_random_context); +} diff --git a/src/test/fuzz/span.cpp b/src/test/fuzz/span.cpp new file mode 100644 index 0000000000..4aea530ef2 --- /dev/null +++ b/src/test/fuzz/span.cpp @@ -0,0 +1,39 @@ +// 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +void test_one_input(const std::vector& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + std::string str = fuzzed_data_provider.ConsumeBytesAsString(32); + const Span span = MakeSpan(str); + (void)span.data(); + (void)span.begin(); + (void)span.end(); + if (span.size() > 0) { + const std::ptrdiff_t idx = fuzzed_data_provider.ConsumeIntegralInRange(0U, span.size() - 1U); + (void)span.first(idx); + (void)span.last(idx); + (void)span.subspan(idx); + (void)span.subspan(idx, span.size() - idx); + (void)span[idx]; + } + + std::string another_str = fuzzed_data_provider.ConsumeBytesAsString(32); + const Span another_span = MakeSpan(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/string.cpp b/src/test/fuzz/string.cpp index a7bc2cb440..0a333f1a69 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -11,6 +11,8 @@ #include #include #include