aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2019-12-06 09:45:19 +0100
committerWladimir J. van der Laan <laanwj@protonmail.com>2019-12-06 09:45:26 +0100
commitcb11324a63ef10475bfc4d8e45148d5ae6f3e71e (patch)
tree114db5aa0e4c7b3703208c67d3347964634b063d /src/test/fuzz
parentc7c9c44278471228376ee29f2852dcfc6b58cb93 (diff)
parent897849d8c225045f0dd3a2fe99b5d69bdf84b4e2 (diff)
Merge #17051: tests: Add deserialization fuzzing harnesses
897849d8c225045f0dd3a2fe99b5d69bdf84b4e2 tests: Add deserialization fuzzing harnesses (practicalswift) 16f0a186dcee563bb1000e1ffc51da87e7623bc6 tests: Add corpora suppression (FUZZERS_MISSING_CORPORA) for fuzzers missing in https://github.com/bitcoin-core/qa-assets/tree/master/fuzz_seed_corpus (practicalswift) Pull request description: Add deserialization fuzzing harnesses. **Testing this PR** Run: ``` $ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined $ make $ contrib/devtools/test_fuzzing_harnesses.sh 'addr_info|block_file_info|block_filter|block_header|ext_key|ext_pub_key|fee_rate|flat_file|key_origin|merkle_block|mutable_transaction|out_point|partial_merkle_tree|partially_signed_transaction|prefilled_transaction|psbt_input|psbt_output|pub_key|script_deserialize|sub_net|tx_in' 10 ``` `test_fuzzing_harnesses.sh` can be found in PR #17000. ACKs for top commit: laanwj: thanks, ACK 897849d8c225045f0dd3a2fe99b5d69bdf84b4e2 Tree-SHA512: 5a270a3002cc23b725f7b35476a43777b2b00b4d089cc006372e2fcc7afa430afaa3c1430f778ae08fc53dd85a13e7bd2fab0449c319f676423226e189a417f6
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/deserialize.cpp318
-rw-r--r--src/test/fuzz/transaction.cpp22
2 files changed, 233 insertions, 107 deletions
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index bcd8691359..46bc38fdab 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -5,18 +5,24 @@
#include <addrdb.h>
#include <addrman.h>
#include <blockencodings.h>
+#include <blockfilter.h>
#include <chain.h>
#include <coins.h>
#include <compressor.h>
#include <consensus/merkle.h>
+#include <key.h>
+#include <merkleblock.h>
#include <net.h>
#include <primitives/block.h>
#include <protocol.h>
+#include <psbt.h>
#include <pubkey.h>
+#include <script/keyorigin.h>
#include <streams.h>
#include <undo.h>
#include <version.h>
+#include <stdexcept>
#include <stdint.h>
#include <unistd.h>
@@ -37,129 +43,237 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
-#if BLOCK_DESERIALIZE
- try
- {
- CBlock block;
- ds >> block;
- } catch (const std::ios_base::failure& e) {return;}
+#if BLOCK_FILTER_DESERIALIZE
+ try {
+ BlockFilter block_filter;
+ ds >> block_filter;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif ADDR_INFO_DESERIALIZE
+ try {
+ CAddrInfo addr_info;
+ ds >> addr_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_FILE_INFO_DESERIALIZE
+ try {
+ CBlockFileInfo block_file_info;
+ ds >> block_file_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE
+ try {
+ CBlockHeaderAndShortTxIDs block_header_and_short_txids;
+ ds >> block_header_and_short_txids;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FEE_RATE_DESERIALIZE
+ try {
+ CFeeRate fee_rate;
+ ds >> fee_rate;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif MERKLE_BLOCK_DESERIALIZE
+ try {
+ CMerkleBlock merkle_block;
+ ds >> merkle_block;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif OUT_POINT_DESERIALIZE
+ try {
+ COutPoint out_point;
+ ds >> out_point;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIAL_MERKLE_TREE_DESERIALIZE
+ try {
+ CPartialMerkleTree partial_merkle_tree;
+ ds >> partial_merkle_tree;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PUB_KEY_DESERIALIZE
+ try {
+ CPubKey pub_key;
+ ds >> pub_key;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SCRIPT_DESERIALIZE
+ try {
+ CScript script;
+ ds >> script;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SUB_NET_DESERIALIZE
+ try {
+ CSubNet sub_net;
+ ds >> sub_net;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif TX_IN_DESERIALIZE
+ try {
+ CTxIn tx_in;
+ ds >> tx_in;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FLAT_FILE_POS_DESERIALIZE
+ try {
+ FlatFilePos flat_file_pos;
+ ds >> flat_file_pos;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif KEY_ORIGIN_INFO_DESERIALIZE
+ try {
+ KeyOriginInfo key_origin_info;
+ ds >> key_origin_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE
+ try {
+ PartiallySignedTransaction partially_signed_transaction;
+ ds >> partially_signed_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PREFILLED_TRANSACTION_DESERIALIZE
+ try {
+ PrefilledTransaction prefilled_transaction;
+ ds >> prefilled_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_INPUT_DESERIALIZE
+ try {
+ PSBTInput psbt_input;
+ ds >> psbt_input;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_OUTPUT_DESERIALIZE
+ try {
+ PSBTOutput psbt_output;
+ ds >> psbt_output;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_DESERIALIZE
+ try {
+ CBlock block;
+ ds >> block;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKLOCATOR_DESERIALIZE
- try
- {
- CBlockLocator bl;
- ds >> bl;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockLocator bl;
+ ds >> bl;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKMERKLEROOT
- try
- {
- CBlock block;
- ds >> block;
- bool mutated;
- BlockMerkleRoot(block, &mutated);
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlock block;
+ ds >> block;
+ bool mutated;
+ BlockMerkleRoot(block, &mutated);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRMAN_DESERIALIZE
- try
- {
- CAddrMan am;
- ds >> am;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddrMan am;
+ ds >> am;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKHEADER_DESERIALIZE
- try
- {
- CBlockHeader bh;
- ds >> bh;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockHeader bh;
+ ds >> bh;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BANENTRY_DESERIALIZE
- try
- {
- CBanEntry be;
- ds >> be;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBanEntry be;
+ ds >> be;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXUNDO_DESERIALIZE
- try
- {
- CTxUndo tu;
- ds >> tu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CTxUndo tu;
+ ds >> tu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKUNDO_DESERIALIZE
- try
- {
- CBlockUndo bu;
- ds >> bu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockUndo bu;
+ ds >> bu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif COINS_DESERIALIZE
- try
- {
- Coin coin;
- ds >> coin;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ Coin coin;
+ ds >> coin;
+ } catch (const std::ios_base::failure&) {
+ }
#elif NETADDR_DESERIALIZE
- try
- {
- CNetAddr na;
- ds >> na;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CNetAddr na;
+ ds >> na;
+ } catch (const std::ios_base::failure&) {
+ }
#elif SERVICE_DESERIALIZE
- try
- {
- CService s;
- ds >> s;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CService s;
+ ds >> s;
+ } catch (const std::ios_base::failure&) {
+ }
#elif MESSAGEHEADER_DESERIALIZE
- CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
- try
- {
- CMessageHeader mh(pchMessageStart);
- ds >> mh;
- if (!mh.IsValid(pchMessageStart)) {return;}
- } catch (const std::ios_base::failure& e) {return;}
+ CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
+ try {
+ CMessageHeader mh(pchMessageStart);
+ ds >> mh;
+ (void)mh.IsValid(pchMessageStart);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRESS_DESERIALIZE
- try
- {
- CAddress a;
- ds >> a;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddress a;
+ ds >> a;
+ } catch (const std::ios_base::failure&) {
+ }
#elif INV_DESERIALIZE
- try
- {
- CInv i;
- ds >> i;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CInv i;
+ ds >> i;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOOMFILTER_DESERIALIZE
- try
- {
- CBloomFilter bf;
- ds >> bf;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBloomFilter bf;
+ ds >> bf;
+ } catch (const std::ios_base::failure&) {
+ }
#elif DISKBLOCKINDEX_DESERIALIZE
- try
- {
- CDiskBlockIndex dbi;
- ds >> dbi;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CDiskBlockIndex dbi;
+ ds >> dbi;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXOUTCOMPRESSOR_DESERIALIZE
- CTxOut to;
- CTxOutCompressor toc(to);
- try
- {
- ds >> toc;
- } catch (const std::ios_base::failure& e) {return;}
+ CTxOut to;
+ CTxOutCompressor toc(to);
+ try {
+ ds >> toc;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONS_DESERIALIZE
- try
- {
- BlockTransactions bt;
- ds >> bt;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactions bt;
+ ds >> bt;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
- try
- {
- BlockTransactionsRequest btr;
- ds >> btr;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactionsRequest btr;
+ ds >> btr;
+ } catch (const std::ios_base::failure&) {
+ }
#else
#error Need at least one fuzz target to compile
#endif
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 76b230ef3c..fefafda36b 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -26,19 +26,31 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
- bool valid = true;
+ bool valid_tx = true;
const CTransaction tx = [&] {
try {
return CTransaction(deserialize, ds);
- } catch (const std::ios_base::failure& e) {
- valid = false;
+ } catch (const std::ios_base::failure&) {
+ valid_tx = false;
return CTransaction();
}
}();
- if (!valid) {
+ bool valid_mutable_tx = true;
+ CDataStream ds_mtx(buffer, SER_NETWORK, INIT_PROTO_VERSION);
+ CMutableTransaction mutable_tx;
+ try {
+ int nVersion;
+ ds_mtx >> nVersion;
+ ds_mtx.SetVersion(nVersion);
+ ds_mtx >> mutable_tx;
+ } catch (const std::ios_base::failure&) {
+ valid_mutable_tx = false;
+ }
+ assert(valid_tx == valid_mutable_tx);
+ if (!valid_tx) {
return;
}