Merge #18314: tests: Add deserialization fuzzing of SnapshotMetadata (utxo_snapshot). Increase fuzzing coverage.

08eab0f599 tests: Add fuzzing of CSubNet, CNetAddr and CService related functions (practicalswift)
7a861a62c1 tests: Fuzz HasAllDesirableServiceFlags(...) and MayHaveUsefulAddressDB(...) (practicalswift)
47a263108b tests: Fuzz DecodeBase64PSBT(...) (practicalswift)
d3d4892ef4 tests: Simplify code by removing unwarranted use of unique_ptr:s (practicalswift)
e57e67057a tests: Fuzz DecodeHexBlk(...) (practicalswift)
117a706fab tests: Fuzz RecursiveDynamicUsage(const std::shared_ptr<X>& p) (practicalswift)
81b58a3161 tests: Fuzz operator!= of CService (practicalswift)
c2c58f6f59 tests: Increase fuzzing coverage of DecompressScript(...) (practicalswift)
9f8d74a8c7 tests: Fuzz currently uncovered code path in TxToUniv(...) (practicalswift)
46ef4cfe5f tests: Re-arrange test cases in parse_univalue to increase coverage (practicalswift)
516cc6fc78 tests: Remove unit test from fuzzing harness (practicalswift)
7b169cae20 tests: Add deserialization fuzzing of SnapshotMetadata (utxo_snapshot), uint160 and uint256 (practicalswift)

Pull request description:

  Add deserialization fuzzing of `SnapshotMetadata` (`utxo_snapshot`).

  Increase fuzzing coverage.

ACKs for top commit:
  MarcoFalke:
    ACK 08eab0f599 🗾

Tree-SHA512: 5dca2316d64b9eb1da9bbbb3831de285b1524cbe815e3dba0f9c4eac7f39b403eb26ee0bdd3d9409a1838e7226d783946ec0d251e514a99f68267a95ac56d416
This commit is contained in:
MarcoFalke 2020-03-11 13:02:37 -04:00
commit 249114b1a6
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
14 changed files with 108 additions and 18 deletions

View file

@ -88,6 +88,7 @@ FUZZ_TARGETS = \
test/fuzz/script_ops \
test/fuzz/scriptnum_ops \
test/fuzz/service_deserialize \
test/fuzz/snapshotmetadata_deserialize \
test/fuzz/spanparsing \
test/fuzz/strprintf \
test/fuzz/sub_net_deserialize \
@ -96,7 +97,9 @@ FUZZ_TARGETS = \
test/fuzz/tx_in_deserialize \
test/fuzz/tx_out \
test/fuzz/txoutcompressor_deserialize \
test/fuzz/txundo_deserialize
test/fuzz/txundo_deserialize \
test/fuzz/uint160_deserialize \
test/fuzz/uint256_deserialize
if ENABLE_FUZZ
noinst_PROGRAMS += $(FUZZ_TARGETS:=)
@ -802,6 +805,12 @@ test_fuzz_sub_net_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_sub_net_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_sub_net_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_snapshotmetadata_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSNAPSHOTMETADATA_DESERIALIZE=1
test_fuzz_snapshotmetadata_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_snapshotmetadata_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_snapshotmetadata_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_snapshotmetadata_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_transaction_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_transaction_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_transaction_LDADD = $(FUZZ_SUITE_LD_COMMON)
@ -838,6 +847,18 @@ test_fuzz_txundo_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_txundo_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_txundo_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_uint160_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DUINT160_DESERIALIZE=1
test_fuzz_uint160_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_uint160_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_uint160_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_uint160_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_uint256_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DUINT256_DESERIALIZE=1
test_fuzz_uint256_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_uint256_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_uint256_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_uint256_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
endif # ENABLE_FUZZ
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)

View file

@ -5,6 +5,7 @@
#include <test/fuzz/fuzz.h>
#include <base58.h>
#include <psbt.h>
#include <util/string.h>
#include <util/strencodings.h>
@ -44,4 +45,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(encoded_string == TrimString(encoded_string));
assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
}
PartiallySignedTransaction psbt;
std::string error;
(void)DecodeBase64PSBT(psbt, random_encoded_string, error);
}

View file

@ -19,7 +19,7 @@
void initialize()
{
const static auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}
@ -59,5 +59,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
(void)GetBlockWeight(block);
(void)GetWitnessCommitmentIndex(block);
(void)RecursiveDynamicUsage(block);
const size_t raw_memory_size = RecursiveDynamicUsage(block);
const size_t raw_memory_size_as_shared_ptr = RecursiveDynamicUsage(std::make_shared<CBlock>(block));
assert(raw_memory_size_as_shared_ptr > raw_memory_size);
}

View file

@ -10,7 +10,7 @@
void initialize()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}

View file

@ -13,6 +13,7 @@
#include <key.h>
#include <merkleblock.h>
#include <net.h>
#include <node/utxo_snapshot.h>
#include <primitives/block.h>
#include <protocol.h>
#include <psbt.h>
@ -34,7 +35,7 @@
void initialize()
{
// Fuzzers using pubkey must hold an ECCVerifyHandle.
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
}
namespace {
@ -214,9 +215,24 @@ void test_one_input(const std::vector<uint8_t>& buffer)
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
BlockTransactionsRequest btr;
DeserializeFromFuzzingInput(buffer, btr);
#elif SNAPSHOTMETADATA_DESERIALIZE
SnapshotMetadata snapshot_metadata;
DeserializeFromFuzzingInput(buffer, snapshot_metadata);
#elif UINT160_DESERIALIZE
uint160 u160;
DeserializeFromFuzzingInput(buffer, u160);
AssertEqualAfterSerializeDeserialize(u160);
#elif UINT256_DESERIALIZE
uint256 u256;
DeserializeFromFuzzingInput(buffer, 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
// fuzzed elsewhere:
// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
} catch (const invalid_fuzzing_input_exception&) {
}
}

View file

@ -12,7 +12,7 @@
void initialize()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
}
void test_one_input(const std::vector<uint8_t>& buffer)

View file

@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <core_io.h>
#include <pubkey.h>
#include <primitives/block.h>
#include <rpc/util.h>
#include <test/fuzz/fuzz.h>
@ -15,6 +16,10 @@
#include <string>
#include <vector>
void initialize() {
static const ECCVerifyHandle verify_handle;
}
void test_one_input(const std::vector<uint8_t>& buffer)
{
const std::string random_hex_string(buffer.begin(), buffer.end());
@ -33,4 +38,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
CBlockHeader block_header;
(void)DecodeHexBlockHeader(block_header, random_hex_string);
CBlock block;
(void)DecodeHexBlk(block, random_hex_string);
}

View file

@ -14,6 +14,7 @@
#include <netbase.h>
#include <policy/settings.h>
#include <pow.h>
#include <protocol.h>
#include <pubkey.h>
#include <rpc/util.h>
#include <script/signingprovider.h>
@ -216,4 +217,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
stream >> deserialized_b;
assert(b == deserialized_b && stream.empty());
}
{
const ServiceFlags service_flags = (ServiceFlags)u64;
(void)HasAllDesirableServiceFlags(service_flags);
(void)MayHaveUsefulAddressDB(service_flags);
}
}

View file

@ -120,4 +120,15 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const CNetAddr other_net_addr = ConsumeNetAddr(fuzzed_data_provider);
(void)net_addr.GetReachabilityFrom(&other_net_addr);
(void)sub_net.Match(other_net_addr);
const CService other_service{net_addr, fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
assert((service == other_service) != (service != other_service));
(void)(service < other_service);
const CSubNet sub_net_copy_1{net_addr, other_net_addr};
const CSubNet sub_net_copy_2{net_addr};
CNetAddr mutable_net_addr;
mutable_net_addr.SetIP(net_addr);
assert(net_addr == mutable_net_addr);
}

View file

@ -14,7 +14,7 @@
void initialize()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}
@ -35,21 +35,31 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
try {
(void)ParseHashO(univalue, "A");
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHashO(univalue, random_string);
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHashV(univalue, "A");
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHashV(univalue, random_string);
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHexO(univalue, "A");
} catch (const UniValue&) {
}
try {
(void)ParseHexO(univalue, random_string);
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHexUV(univalue, "A");
@ -59,6 +69,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
try {
(void)ParseHexV(univalue, "A");
} catch (const UniValue&) {
} catch (const std::runtime_error&) {
}
try {
(void)ParseHexV(univalue, random_string);
} catch (const UniValue&) {
} catch (const std::runtime_error&) {

View file

@ -19,7 +19,7 @@
void initialize()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
}
void test_one_input(const std::vector<uint8_t>& buffer)

View file

@ -14,14 +14,16 @@
#include <script/signingprovider.h>
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <univalue.h>
#include <util/memory.h>
void initialize()
{
// Fuzzers using pubkey must hold an ECCVerifyHandle.
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}
@ -41,13 +43,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(script == decompressed_script);
}
for (unsigned int size = 0; size < 6; ++size) {
std::vector<unsigned char> vch(GetSpecialScriptSize(size), 0x00);
vch.insert(vch.end(), buffer.begin(), buffer.end());
CScript decompressed_script;
(void)DecompressScript(decompressed_script, size, vch);
}
CTxDestination address;
(void)ExtractDestination(script, address);
@ -92,4 +87,14 @@ void test_one_input(const std::vector<uint8_t>& buffer)
ScriptToUniv(script, o3, true);
UniValue o4(UniValue::VOBJ);
ScriptToUniv(script, o4, false);
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
// DecompressScript(..., ..., bytes) is not guaranteed to be defined if bytes.size() <= 23.
if (bytes.size() >= 24) {
CScript decompressed_script;
DecompressScript(decompressed_script, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), bytes);
}
}
}

View file

@ -15,7 +15,7 @@ static bool IsValidFlagCombination(unsigned flags);
void initialize()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
}
void test_one_input(const std::vector<uint8_t>& buffer)

View file

@ -108,5 +108,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
if (!skip_tx_to_univ) {
TxToUniv(tx, /* hashBlock */ {}, u);
static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
TxToUniv(tx, u256_max, u);
}
}