diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-12-06 09:45:19 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-12-06 09:45:26 +0100 |
commit | cb11324a63ef10475bfc4d8e45148d5ae6f3e71e (patch) | |
tree | 114db5aa0e4c7b3703208c67d3347964634b063d /src/test/fuzz | |
parent | c7c9c44278471228376ee29f2852dcfc6b58cb93 (diff) | |
parent | 897849d8c225045f0dd3a2fe99b5d69bdf84b4e2 (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.cpp | 318 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 22 |
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; } |