From 7b169cae207ad1301c4edf7d623407d1f377169d Mon Sep 17 00:00:00 2001 From: practicalswift Date: Mon, 9 Mar 2020 12:14:01 +0000 Subject: [PATCH 01/12] tests: Add deserialization fuzzing of SnapshotMetadata (utxo_snapshot), uint160 and uint256 --- src/Makefile.test.include | 23 ++++++++++++++++++++++- src/test/fuzz/deserialize.cpp | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 669ebcbc485..7eb465c1066 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -64,6 +64,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 \ @@ -72,7 +73,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:=) @@ -628,6 +631,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) @@ -664,6 +673,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/deserialize.cpp b/src/test/fuzz/deserialize.cpp index f06f339b9d0..e90e7e90119 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -214,9 +215,24 @@ void test_one_input(const std::vector& 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&) { } } From 516cc6fc7842c13a1d54c6ea2b9e3d335a872125 Mon Sep 17 00:00:00 2001 From: practicalswift Date: Mon, 9 Mar 2020 15:34:20 +0000 Subject: [PATCH 02/12] tests: Remove unit test from fuzzing harness --- src/test/fuzz/script.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index 0d18784302f..ca8b136c2dd 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -41,13 +41,6 @@ void test_one_input(const std::vector& buffer) assert(script == decompressed_script); } - for (unsigned int size = 0; size < 6; ++size) { - std::vector 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); From 46ef4cfe5f416cb34e889646df3ee241b1d5ae5a Mon Sep 17 00:00:00 2001 From: practicalswift Date: Tue, 10 Mar 2020 11:22:48 +0000 Subject: [PATCH 03/12] tests: Re-arrange test cases in parse_univalue to increase coverage --- src/test/fuzz/parse_univalue.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/test/fuzz/parse_univalue.cpp b/src/test/fuzz/parse_univalue.cpp index 3ad112dbad5..73547cda3ba 100644 --- a/src/test/fuzz/parse_univalue.cpp +++ b/src/test/fuzz/parse_univalue.cpp @@ -35,21 +35,31 @@ void test_one_input(const std::vector& 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& 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&) { From 9f8d74a8c78457ed49c7ff81bae909c8e003670b Mon Sep 17 00:00:00 2001 From: practicalswift Date: Tue, 10 Mar 2020 11:28:10 +0000 Subject: [PATCH 04/12] tests: Fuzz currently uncovered code path in TxToUniv(...) --- src/test/fuzz/transaction.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 1ec69cc23d5..d8e84f1a0fd 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -108,5 +108,7 @@ void test_one_input(const std::vector& buffer) } if (!skip_tx_to_univ) { TxToUniv(tx, /* hashBlock */ {}, u); + static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + TxToUniv(tx, u256_max, u); } } From c2c58f6f59d38e3d60fe0a8fa45b2a45deee84cc Mon Sep 17 00:00:00 2001 From: practicalswift Date: Tue, 10 Mar 2020 11:58:30 +0000 Subject: [PATCH 05/12] tests: Increase fuzzing coverage of DecompressScript(...) --- src/test/fuzz/script.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index ca8b136c2dd..4961bba4776 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -14,7 +14,9 @@ #include