Add fuzzing harnesses for DecodeRawPSBT(...)
, ParseHDKeypath(...)
, ParseScript(...)
, various number parsing functions and various JSON/univalue parsing functions.
Testing this PR
As usual the best way to test proposed fuzzing harnesses is to use test_fuzzing_harnesses.sh
(#17000) to quickly verify that the relevant code regions are triggered, that the fuzzing throughput seems reasonable, etc.
test_fuzzing_harnesses.sh 'psbt|hd_keypath|numbers|parse_script|univalue' 10
runs all fuzzers matching the regexp and gives them ten seconds of runtime each.
0$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
1$ make
2$ contrib/devtools/test_fuzzing_harnesses.sh 'psbt|hd_keypath|numbers|parse_script|univalue' 10
3Testing fuzzer parse_hd_keypath during 10 second(s)
4A subset of reached functions:
5 NEW_FUNC[0/2]: 0x55bc23a76940 in ParsePrechecks(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) src/util/strencodings.cpp:267
6 NEW_FUNC[1/2]: 0x55bc23a77300 in ParseUInt32(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int*) src/util/strencodings.cpp:309
7stat::number_of_executed_units: 34237
8stat::average_exec_per_sec: 3112
9stat::new_units_added: 113
10stat::slowest_unit_time_sec: 0
11stat::peak_rss_mb: 282
12Number of unique code paths taken during fuzzing round: 30
13
14Testing fuzzer parse_numbers during 10 second(s)
15A subset of reached functions:
16stat::number_of_executed_units: 31309
17stat::average_exec_per_sec: 2846
18stat::new_units_added: 688
19stat::slowest_unit_time_sec: 0
20stat::peak_rss_mb: 234
21Number of unique code paths taken during fuzzing round: 149
22
23Testing fuzzer parse_script during 10 second(s)
24A subset of reached functions:
25 NEW_FUNC[1/11]: 0x5636ff61ba00 in IsDigit(char) src/./util/strencodings.h:70
26 NEW_FUNC[0/14]: 0x5636fe6c6280 in CScript::operator<<(opcodetype) src/./script/script.h:448
27 NEW_FUNC[1/14]: 0x5636fe6e0290 in prevector<28u, unsigned char, unsigned int, int>::insert(prevector<28u, unsigned char, unsigned int, int>::iterator, unsigned char const&) src/./prevector.h:342
28 NEW_FUNC[2/14]: 0x5636fe6e1040 in prevector<28u, unsigned char, unsigned int, int>::size() const src/./prevector.h:277
29 NEW_FUNC[3/14]: 0x5636fe6e1250 in prevector<28u, unsigned char, unsigned int, int>::capacity() const src/./prevector.h:295
30 NEW_FUNC[4/14]: 0x5636fe6e1cb0 in prevector<28u, unsigned char, unsigned int, int>::item_ptr(int) src/./prevector.h:196
31 NEW_FUNC[0/10]: 0x5636fe6c5650 in CScript::operator<<(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/./script/script.h:462
32 NEW_FUNC[2/10]: 0x5636fe6e0a20 in void prevector<28u, unsigned char, unsigned int, int>::insert<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > >(prevector<28u, unsigned char, unsigned int, int>::iterator, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<[32/1902]
33char> > >, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >) src/./prevector.h:368
34 NEW_FUNC[5/10]: 0x5636fe6e2350 in void prevector<28u, unsigned char, unsigned int, int>::fill<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > >(unsigned char*, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, __gnu_cxx::__normal_iterator<unsign
35ed char const*, std::vector<unsigned char, std::allocator<unsigned char> > >) src/./prevector.h:204
36 NEW_FUNC[0/1]: 0x5636ff8e48b0 in IsHex(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) src/util/strencodings.cpp:61
37 NEW_FUNC[0/2]: 0x5636fe6e1410 in prevector<28u, unsigned char, unsigned int, int>::change_capacity(unsigned int) src/./prevector.h:165
38 NEW_FUNC[1/2]: 0x5636fe6e1f00 in prevector<28u, unsigned char, unsigned int, int>::indirect_ptr(int) src/./prevector.h:161
39 NEW_FUNC[0/1]: 0x5636fe6e0580 in void prevector<28u, unsigned char, unsigned int, int>::insert<unsigned char*>(prevector<28u, unsigned char, unsigned int, int>::iterator, unsigned char*, unsigned char*) src/./prevector.h:368
40 NEW_FUNC[0/3]: 0x5636fe85f0d0 in CScript::push_int64(long) src/./script/script.h:394
41 NEW_FUNC[1/3]: 0x5636fe85f520 in prevector<28u, unsigned char, unsigned int, int>::push_back(unsigned char const&) src/./prevector.h:422
42 NEW_FUNC[2/3]: 0x5636ff8ed730 in atoi64(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) src/util/strencodings.cpp:417
43stat::number_of_executed_units: 8153
44stat::average_exec_per_sec: 741
45stat::new_units_added: 296
46stat::slowest_unit_time_sec: 0
47stat::peak_rss_mb: 237
48Number of unique code paths taken during fuzzing round: 98
49
50Testing fuzzer parse_univalue during 10 second(s)
51A subset of reached functions:
52 NEW_FUNC[0/19]: 0x560db8655950 in tinyformat::detail::formatImpl(std::ostream&, char const*, tinyformat::detail::FormatArg const*, int) src/./tinyformat.h:791
53 NEW_FUNC[4/19]: 0x560db86582b0 in tinyformat::detail::printFormatStringLiteral(std::ostream&, char const*) src/./tinyformat.h:564
54 NEW_FUNC[5/19]: 0x560db8658690 in tinyformat::detail::streamStateFromFormat(std::ostream&, bool&, int&, char const*, tinyformat::detail::FormatArg const*, int&, int) src/./tinyformat.h:601
55 NEW_FUNC[6/19]: 0x560db865f090 in tinyformat::detail::FormatArg::format(std::ostream&, char const*, char const*, int) const src/./tinyformat.h:513
56 NEW_FUNC[12/19]: 0x560db8661ba0 in void tinyformat::detail::FormatArg::formatImpl<int>(std::ostream&, char const*, char const*, int, void const*) src/./tinyformat.h:530
57 NEW_FUNC[13/19]: 0x560db8661d90 in void tinyformat::formatValue<int>(std::ostream&, char const*, char const*, int, int const&) src/./tinyformat.h:317
58 NEW_FUNC[14/19]: 0x560db875c8b0 in void tinyformat::detail::FormatArg::formatImpl<unsigned int>(std::ostream&, char const*, char const*, int, void const*) src/./tinyformat.h:530
59 NEW_FUNC[15/19]: 0x560db875caa0 in void tinyformat::formatValue<unsigned int>(std::ostream&, char const*, char const*, int, unsigned int const&) src/./tinyformat.h:317
60 NEW_FUNC[16/19]: 0x560db9473ef0 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > tinyformat::format<int, unsigned int>(char const*, int const&, unsigned int const&) src/./tinyformat.h:976
61 NEW_FUNC[17/19]: 0x560db94749a0 in void tinyformat::format<int, unsigned int>(std::ostream&, char const*, int const&, unsigned int const&) src/./tinyformat.h:968
62 NEW_FUNC[18/19]: 0x560db9474cf0 in tinyformat::detail::FormatListN<2>::FormatListN<int, unsigned int>(int const&, unsigned int const&) src/./tinyformat.h:885
63stat::number_of_executed_units: 14089
64stat::average_exec_per_sec: 1280
65stat::new_units_added: 135
66stat::slowest_unit_time_sec: 0
67stat::peak_rss_mb: 356
68Number of unique code paths taken during fuzzing round: 62
69
70Testing fuzzer psbt_input_deserialize during 10 second(s)
71A subset of reached functions:
72 NEW_FUNC[0/46]: 0x557847ce3530 in prevector<28u, unsigned char, unsigned int, int>::~prevector() src/./prevector.h:456
73 NEW_FUNC[3/46]: 0x557847cfdcf0 in prevector<28u, unsigned char, unsigned int, int>::size() const src/./prevector.h:277
74 NEW_FUNC[4/46]: 0x557847cfe0c0 in prevector<28u, unsigned char, unsigned int, int>::change_capacity(unsigned int) src/./prevector.h:165
75 NEW_FUNC[13/46]: 0x557847d3c890 in unsigned long ReadCompactSize<CDataStream>(CDataStream&) src/./serialize.h:290
76 NEW_FUNC[14/46]: 0x557847d47b60 in prevector<28u, unsigned char, unsigned int, int>::resize(unsigned int) src/./prevector.h:311
77 NEW_FUNC[16/46]: 0x557847d48800 in CTxOut::CTxOut() src/./primitives/transaction.h:140
78 NEW_FUNC[17/46]: 0x557847d4b050 in CTxOut::SetNull() src/./primitives/transaction.h:155
79 NEW_FUNC[18/46]: 0x557847d4b140 in CScript::clear() src/./script/script.h:563
80 NEW_FUNC[19/46]: 0x557847d4ead0 in void Unserialize_impl<CDataStream, unsigned char, std::allocator<unsigned char> >(CDataStream&, std::vector<unsigned char, std::allocator<unsigned char> >&, unsigned char const&) src/./serialize.h:746
81 NEW_FUNC[0/58]: 0x557847cfdf00 in prevector<28u, unsigned char, unsigned int, int>::capacity() const src/./prevector.h:295
82 NEW_FUNC[1/58]: 0x557847cfe960 in prevector<28u, unsigned char, unsigned int, int>::item_ptr(int) src/./prevector.h:196
83 NEW_FUNC[2/58]: 0x557847cfebb0 in prevector<28u, unsigned char, unsigned int, int>::indirect_ptr(int) src/./prevector.h:161
84 NEW_FUNC[3/58]: 0x557847d03990 in uint256::uint256() src/./uint256.h:123
85 NEW_FUNC[0/3]: 0x557847d47430 in void CScript::SerializationOp<CDataStream, CSerActionUnserialize>(CDataStream&, CSerActionUnserialize) src/./script/script.h:418
86 NEW_FUNC[1/3]: 0x557847d47730 in void Unserialize_impl<CDataStream, 28u, unsigned char>(CDataStream&, prevector<28u, unsigned char, unsigned int, int>&, unsigned char const&) src/./serialize.h:666
87 NEW_FUNC[2/3]: 0x557847d60dd0 in CDataStream& CDataStream::operator>><CScript&>(CScript&) src/./streams.h:460
88 NEW_FUNC[1/78]: 0x557847cffae0 in prevector<28u, unsigned char, unsigned int, int>::item_ptr(int) const src/./prevector.h:197
89 NEW_FUNC[2/78]: 0x557847cffd30 in prevector<28u, unsigned char, unsigned int, int>::indirect_ptr(int) const src/./prevector.h:162
90 NEW_FUNC[0/1]: 0x557847d65f90 in OverrideStream<CDataStream>& OverrideStream<CDataStream>::operator>><unsigned char&>(unsigned char&) src/./streams.h:46
91 NEW_FUNC[0/3]: 0x557847d470e0 in void SerReadWriteMany<CDataStream, CScript&>(CDataStream&, CSerActionUnserialize, CScript&) src/./serialize.h:989
92 NEW_FUNC[1/3]: 0x557847d4ac50 in void CTxOut::SerializationOp<CDataStream, CSerActionUnserialize>(CDataStream&, CSerActionUnserialize) src/./primitives/transaction.h:149
93 NEW_FUNC[2/3]: 0x557847d5f860 in void UnserializeFromVector<CDataStream, CTxOut>(CDataStream&, CTxOut&) src/./script/sign.h:90
94 NEW_FUNC[0/1]: 0x557847d60840 in void UnserializeFromVector<CDataStream, int>(CDataStream&, int&) src/./script/sign.h:90
95 NEW_FUNC[0/1]: 0x557847d41010 in CMutableTransaction::HasWitness() const src/./primitives/transaction.h:398
96stat::number_of_executed_units: 13615
97stat::average_exec_per_sec: 1237
98stat::new_units_added: 357
99stat::slowest_unit_time_sec: 0
100stat::peak_rss_mb: 446
101Number of unique code paths taken during fuzzing round: 152
102
103Testing fuzzer psbt_output_deserialize during 10 second(s)
104A subset of reached functions:
105 NEW_FUNC[0/27]: 0x55c9347e5940 in prevector<28u, unsigned char, unsigned int, int>::~prevector() src/./prevector.h:456
106 NEW_FUNC[5/27]: 0x55c93483eca0 in unsigned long ReadCompactSize<CDataStream>(CDataStream&) src/./serialize.h:290
107 NEW_FUNC[6/27]: 0x55c934850ee0 in void Unserialize_impl<CDataStream, unsigned char, std::allocator<unsigned char> >(CDataStream&, std::vector<unsigned char, std::allocator<unsigned char> >&, unsigned char const&) src/./serialize.h:746
108 NEW_FUNC[14/27]: 0x55c934858500 in PSBTOutput::PSBTOutput() src/./psbt.h:281
109 NEW_FUNC[15/27]: 0x55c934858870 in CDataStream& CDataStream::operator>><PSBTOutput&>(PSBTOutput&) src/./streams.h:460
110 NEW_FUNC[0/1]: 0x55c934800100 in prevector<28u, unsigned char, unsigned int, int>::size() const src/./prevector.h:277
111 NEW_FUNC[0/4]: 0x55c934849840 in void CScript::SerializationOp<CDataStream, CSerActionUnserialize>(CDataStream&, CSerActionUnserialize) src/./script/script.h:418
112 NEW_FUNC[1/4]: 0x55c934849b40 in void Unserialize_impl<CDataStream, 28u, unsigned char>(CDataStream&, prevector<28u, unsigned char, unsigned int, int>&, unsigned char const&) src/./serialize.h:666
113 NEW_FUNC[2/4]: 0x55c934849f70 in prevector<28u, unsigned char, unsigned int, int>::resize(unsigned int) src/./prevector.h:311
114 NEW_FUNC[3/4]: 0x55c93485dc60 in CDataStream& CDataStream::operator>><CScript&>(CScript&) src/./streams.h:460
115 NEW_FUNC[0/3]: 0x55c934800310 in prevector<28u, unsigned char, unsigned int, int>::capacity() const src/./prevector.h:295
116 NEW_FUNC[1/3]: 0x55c934800d70 in prevector<28u, unsigned char, unsigned int, int>::item_ptr(int) src/./prevector.h:196
117 NEW_FUNC[2/3]: 0x55c934849d40 in prevector<28u, unsigned char, unsigned int, int>::resize_uninitialized(unsigned int) src/./prevector.h:381
118 NEW_FUNC[0/1]: 0x55c93485ddd0 in void DeserializeHDKeypaths<CDataStream>(CDataStream&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::map<CPubKey, KeyOriginInfo, std::less<CPubKey>, std::allocator<std::pair<CPubKey const, KeyOriginInfo> > >&) src/./script/sign.h:103
119stat::number_of_executed_units: 19130
120stat::average_exec_per_sec: 1739
121stat::new_units_added: 195
122stat::slowest_unit_time_sec: 0
123stat::peak_rss_mb: 411
124Number of unique code paths taken during fuzzing round: 64
125
126Tested fuzz harnesses seem to work as expected.