aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-03-11 13:02:37 -0400
committerMarcoFalke <falke.marco@gmail.com>2020-03-11 13:02:43 -0400
commit249114b1a6a4a10f8cfa61cafd01c391991a750f (patch)
tree90298b9af647f9e00ed34012cd4164f8a21926f2
parent0eebe45cf7c63f55af0116c25cf0824ef31b9e33 (diff)
parent08eab0f599a7be7b9b0256bfe9e3a793fe7450db (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.include23
-rw-r--r--src/test/fuzz/base_encode_decode.cpp5
-rw-r--r--src/test/fuzz/block.cpp6
-rw-r--r--src/test/fuzz/descriptor_parse.cpp2
-rw-r--r--src/test/fuzz/deserialize.cpp18
-rw-r--r--src/test/fuzz/eval_script.cpp2
-rw-r--r--src/test/fuzz/hex.cpp7
-rw-r--r--src/test/fuzz/integer.cpp7
-rw-r--r--src/test/fuzz/netaddress.cpp11
-rw-r--r--src/test/fuzz/parse_univalue.cpp18
-rw-r--r--src/test/fuzz/psbt.cpp2
-rw-r--r--src/test/fuzz/script.cpp21
-rw-r--r--src/test/fuzz/script_flags.cpp2
-rw-r--r--src/test/fuzz/transaction.cpp2
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);
}
}