diff options
author | MarcoFalke <falke.marco@gmail.com> | 2020-03-11 13:02:37 -0400 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2020-03-11 13:02:43 -0400 |
commit | 249114b1a6a4a10f8cfa61cafd01c391991a750f (patch) | |
tree | 90298b9af647f9e00ed34012cd4164f8a21926f2 | |
parent | 0eebe45cf7c63f55af0116c25cf0824ef31b9e33 (diff) | |
parent | 08eab0f599a7be7b9b0256bfe9e3a793fe7450db (diff) |
Merge #18314: tests: Add deserialization fuzzing of SnapshotMetadata (utxo_snapshot). Increase fuzzing coverage.
08eab0f599a7be7b9b0256bfe9e3a793fe7450db tests: Add fuzzing of CSubNet, CNetAddr and CService related functions (practicalswift)
7a861a62c164ab9b07d6fca09b6a8176e688f1f6 tests: Fuzz HasAllDesirableServiceFlags(...) and MayHaveUsefulAddressDB(...) (practicalswift)
47a263108b05c7039baba5618656898312a7a5ef tests: Fuzz DecodeBase64PSBT(...) (practicalswift)
d3d4892ef45d09edbbe4672b112100743970b2a5 tests: Simplify code by removing unwarranted use of unique_ptr:s (practicalswift)
e57e67057ae76db73f52ddd5480a4ea5b4bf1636 tests: Fuzz DecodeHexBlk(...) (practicalswift)
117a706faba586f2095f97cf630b709b3e29a947 tests: Fuzz RecursiveDynamicUsage(const std::shared_ptr<X>& p) (practicalswift)
81b58a3161c5d558dadd2b7093e4fc9687844cd9 tests: Fuzz operator!= of CService (practicalswift)
c2c58f6f59d38e3d60fe0a8fa45b2a45deee84cc tests: Increase fuzzing coverage of DecompressScript(...) (practicalswift)
9f8d74a8c78457ed49c7ff81bae909c8e003670b tests: Fuzz currently uncovered code path in TxToUniv(...) (practicalswift)
46ef4cfe5f416cb34e889646df3ee241b1d5ae5a tests: Re-arrange test cases in parse_univalue to increase coverage (practicalswift)
516cc6fc7842c13a1d54c6ea2b9e3d335a872125 tests: Remove unit test from fuzzing harness (practicalswift)
7b169cae207ad1301c4edf7d623407d1f377169d 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
-rw-r--r-- | src/Makefile.test.include | 23 | ||||
-rw-r--r-- | src/test/fuzz/base_encode_decode.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/block.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/descriptor_parse.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/deserialize.cpp | 18 | ||||
-rw-r--r-- | src/test/fuzz/eval_script.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/hex.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/integer.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/netaddress.cpp | 11 | ||||
-rw-r--r-- | src/test/fuzz/parse_univalue.cpp | 18 | ||||
-rw-r--r-- | src/test/fuzz/psbt.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/script.cpp | 21 | ||||
-rw-r--r-- | src/test/fuzz/script_flags.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 2 |
14 files changed, 108 insertions, 18 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 5a2ecff651..161c925a53 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -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) diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp index cb0fbdf76f..adad6b3f96 100644 --- a/src/test/fuzz/base_encode_decode.cpp +++ b/src/test/fuzz/base_encode_decode.cpp @@ -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); } diff --git a/src/test/fuzz/block.cpp b/src/test/fuzz/block.cpp index 431248de4a..9d0ad369a2 100644 --- a/src/test/fuzz/block.cpp +++ b/src/test/fuzz/block.cpp @@ -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); } diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp index 47d5038c26..a0ef08cca6 100644 --- a/src/test/fuzz/descriptor_parse.cpp +++ b/src/test/fuzz/descriptor_parse.cpp @@ -10,7 +10,7 @@ void initialize() { - static const auto verify_handle = MakeUnique<ECCVerifyHandle>(); + static const ECCVerifyHandle verify_handle; SelectParams(CBaseChainParams::REGTEST); } diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index f06f339b9d..964fc85302 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -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&) { } } diff --git a/src/test/fuzz/eval_script.cpp b/src/test/fuzz/eval_script.cpp index 7acdd76857..6a1b037630 100644 --- a/src/test/fuzz/eval_script.cpp +++ b/src/test/fuzz/eval_script.cpp @@ -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) diff --git a/src/test/fuzz/hex.cpp b/src/test/fuzz/hex.cpp index 2de6100d7b..3bbf0084c2 100644 --- a/src/test/fuzz/hex.cpp +++ b/src/test/fuzz/hex.cpp @@ -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); } diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 350d3d3331..980042e811 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -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); + } } diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp index 7d87ebc214..d8d53566c7 100644 --- a/src/test/fuzz/netaddress.cpp +++ b/src/test/fuzz/netaddress.cpp @@ -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); } diff --git a/src/test/fuzz/parse_univalue.cpp b/src/test/fuzz/parse_univalue.cpp index 3ad112dbad..571364aaa6 100644 --- a/src/test/fuzz/parse_univalue.cpp +++ b/src/test/fuzz/parse_univalue.cpp @@ -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&) { diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp index 1ce28f9a6d..ca3e0b8586 100644 --- a/src/test/fuzz/psbt.cpp +++ b/src/test/fuzz/psbt.cpp @@ -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) diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index 0d18784302..2f50f1b838 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -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); + } + } } diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp index 08622d0979..3d8ece7c61 100644 --- a/src/test/fuzz/script_flags.cpp +++ b/src/test/fuzz/script_flags.cpp @@ -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) diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 1ec69cc23d..d8e84f1a0f 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -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); } } |