Skip to content

Commit 090d877

Browse files
author
MarcoFalke
committed
Merge #19143: tests: Add fuzzing harnesses for CAutoFile, CBufferedFile, LoadExternalBlockFile and other FILE* consumers
ad6c348 tests: Add fuzzing harness for CBlockPolicyEstimator::{Read,Write} (policy/fees.h) (practicalswift) 614e080 tests: Add fuzzing harness for CBufferedFile::{SetPos,GetPos,GetType,GetVersion} (stream.h) (practicalswift) 7bcc71e tests: Add fuzzing harness for LoadExternalBlockFile(...) (validation.h) (practicalswift) 9823376 tests: Add fuzzing harness for CBufferedFile (streams.h) (practicalswift) f3aa659 tests: Add fuzzing harness for CAutoFile (streams.h) (practicalswift) e507c07 tests: Add serialization/deserialization fuzzing helpers WriteToStream(…)/ReadFromStream(…) (practicalswift) e48094a tests: Add FuzzedAutoFileProvider which provides a CAutoFile interface to FuzzedDataProvider (practicalswift) 9dbcd68 tests: Add FuzzedFileProvider which provides a FILE* interface to FuzzedDataProvider using fopencookie (practicalswift) Pull request description: Add fuzzing harnesses for `CAutoFile`, `CBufferedFile`, `LoadExternalBlockFile` and other `FILE*` consumers: * Add `FuzzedFileProvider` which provides a `FILE*` interface to `FuzzedDataProvider` using `fopencookie` * Add `FuzzedAutoFileProvider` which provides a `CAutoFile` interface to `FuzzedDataProvider` * Add serialization/deserialization fuzzing helpers `WriteToStream(…)`/`ReadFromStream(…)` * Add fuzzing harness for `CAutoFile` (`streams.h`) * Add fuzzing harness for `CBufferedFile` (`streams.h`) * Add fuzzing harness for `LoadExternalBlockFile(...)` (`validation.h`) * Add fuzzing harness for `CBlockPolicyEstimator::Read` and `CBlockPolicyEstimator::Write` (`policy/fees.h`) See [`doc/fuzzing.md`](https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md) for information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the [Bitcoin Core fuzzing corpus repo](https://github.com/bitcoin-core/qa-assets). Happy fuzzing :) ACKs for top commit: Crypt-iQ: Tested ACK ad6c348 Tree-SHA512: a38e142608218496796a527d7e59b74e30279a2815450408b7c27a76ed600cebc6b88491e831665a0639671e2d212453fcdca558500bbadbeb32b267751f8f72
2 parents fd59670 + ad6c348 commit 090d877

File tree

7 files changed

+454
-0
lines changed

7 files changed

+454
-0
lines changed

src/Makefile.test.include

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ FUZZ_TARGETS = \
1010
test/fuzz/addrman_deserialize \
1111
test/fuzz/asmap \
1212
test/fuzz/asmap_direct \
13+
test/fuzz/autofile \
1314
test/fuzz/banentry_deserialize \
1415
test/fuzz/banman \
1516
test/fuzz/base_encode_decode \
@@ -29,6 +30,7 @@ FUZZ_TARGETS = \
2930
test/fuzz/blockundo_deserialize \
3031
test/fuzz/bloom_filter \
3132
test/fuzz/bloomfilter_deserialize \
33+
test/fuzz/buffered_file \
3234
test/fuzz/chain \
3335
test/fuzz/checkqueue \
3436
test/fuzz/coins_deserialize \
@@ -61,6 +63,7 @@ FUZZ_TARGETS = \
6163
test/fuzz/key_io \
6264
test/fuzz/key_origin_info_deserialize \
6365
test/fuzz/kitchen_sink \
66+
test/fuzz/load_external_block_file \
6467
test/fuzz/locale \
6568
test/fuzz/merkle_block_deserialize \
6669
test/fuzz/merkleblock \
@@ -80,6 +83,7 @@ FUZZ_TARGETS = \
8083
test/fuzz/partial_merkle_tree_deserialize \
8184
test/fuzz/partially_signed_transaction_deserialize \
8285
test/fuzz/policy_estimator \
86+
test/fuzz/policy_estimator_io \
8387
test/fuzz/pow \
8488
test/fuzz/prefilled_transaction_deserialize \
8589
test/fuzz/prevector \
@@ -356,6 +360,12 @@ test_fuzz_asmap_direct_LDADD = $(FUZZ_SUITE_LD_COMMON)
356360
test_fuzz_asmap_direct_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
357361
test_fuzz_asmap_direct_SOURCES = test/fuzz/asmap_direct.cpp
358362

363+
test_fuzz_autofile_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
364+
test_fuzz_autofile_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
365+
test_fuzz_autofile_LDADD = $(FUZZ_SUITE_LD_COMMON)
366+
test_fuzz_autofile_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
367+
test_fuzz_autofile_SOURCES = test/fuzz/autofile.cpp
368+
359369
test_fuzz_banentry_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBANENTRY_DESERIALIZE=1
360370
test_fuzz_banentry_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
361371
test_fuzz_banentry_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
@@ -470,6 +480,12 @@ test_fuzz_bloomfilter_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
470480
test_fuzz_bloomfilter_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
471481
test_fuzz_bloomfilter_deserialize_SOURCES = test/fuzz/deserialize.cpp
472482

483+
test_fuzz_buffered_file_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
484+
test_fuzz_buffered_file_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
485+
test_fuzz_buffered_file_LDADD = $(FUZZ_SUITE_LD_COMMON)
486+
test_fuzz_buffered_file_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
487+
test_fuzz_buffered_file_SOURCES = test/fuzz/buffered_file.cpp
488+
473489
test_fuzz_chain_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
474490
test_fuzz_chain_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
475491
test_fuzz_chain_LDADD = $(FUZZ_SUITE_LD_COMMON)
@@ -662,6 +678,12 @@ test_fuzz_kitchen_sink_LDADD = $(FUZZ_SUITE_LD_COMMON)
662678
test_fuzz_kitchen_sink_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
663679
test_fuzz_kitchen_sink_SOURCES = test/fuzz/kitchen_sink.cpp
664680

681+
test_fuzz_load_external_block_file_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
682+
test_fuzz_load_external_block_file_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
683+
test_fuzz_load_external_block_file_LDADD = $(FUZZ_SUITE_LD_COMMON)
684+
test_fuzz_load_external_block_file_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
685+
test_fuzz_load_external_block_file_SOURCES = test/fuzz/load_external_block_file.cpp
686+
665687
test_fuzz_locale_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
666688
test_fuzz_locale_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
667689
test_fuzz_locale_LDADD = $(FUZZ_SUITE_LD_COMMON)
@@ -782,6 +804,12 @@ test_fuzz_policy_estimator_LDADD = $(FUZZ_SUITE_LD_COMMON)
782804
test_fuzz_policy_estimator_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
783805
test_fuzz_policy_estimator_SOURCES = test/fuzz/policy_estimator.cpp
784806

807+
test_fuzz_policy_estimator_io_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
808+
test_fuzz_policy_estimator_io_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
809+
test_fuzz_policy_estimator_io_LDADD = $(FUZZ_SUITE_LD_COMMON)
810+
test_fuzz_policy_estimator_io_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
811+
test_fuzz_policy_estimator_io_SOURCES = test/fuzz/policy_estimator_io.cpp
812+
785813
test_fuzz_pow_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
786814
test_fuzz_pow_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
787815
test_fuzz_pow_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/autofile.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <optional.h>
6+
#include <streams.h>
7+
#include <test/fuzz/FuzzedDataProvider.h>
8+
#include <test/fuzz/fuzz.h>
9+
#include <test/fuzz/util.h>
10+
11+
#include <array>
12+
#include <cstdint>
13+
#include <iostream>
14+
#include <optional>
15+
#include <string>
16+
#include <vector>
17+
18+
void test_one_input(const std::vector<uint8_t>& buffer)
19+
{
20+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
21+
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
22+
CAutoFile auto_file = fuzzed_auto_file_provider.open();
23+
while (fuzzed_data_provider.ConsumeBool()) {
24+
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
25+
case 0: {
26+
std::array<uint8_t, 4096> arr{};
27+
try {
28+
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
29+
} catch (const std::ios_base::failure&) {
30+
}
31+
break;
32+
}
33+
case 1: {
34+
const std::array<uint8_t, 4096> arr{};
35+
try {
36+
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
37+
} catch (const std::ios_base::failure&) {
38+
}
39+
break;
40+
}
41+
case 2: {
42+
try {
43+
auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
44+
} catch (const std::ios_base::failure&) {
45+
}
46+
break;
47+
}
48+
case 3: {
49+
auto_file.fclose();
50+
break;
51+
}
52+
case 4: {
53+
ReadFromStream(fuzzed_data_provider, auto_file);
54+
break;
55+
}
56+
case 5: {
57+
WriteToStream(fuzzed_data_provider, auto_file);
58+
break;
59+
}
60+
}
61+
}
62+
(void)auto_file.Get();
63+
(void)auto_file.GetType();
64+
(void)auto_file.GetVersion();
65+
(void)auto_file.IsNull();
66+
if (fuzzed_data_provider.ConsumeBool()) {
67+
FILE* f = auto_file.release();
68+
if (f != nullptr) {
69+
fclose(f);
70+
}
71+
}
72+
}

src/test/fuzz/buffered_file.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <optional.h>
6+
#include <streams.h>
7+
#include <test/fuzz/FuzzedDataProvider.h>
8+
#include <test/fuzz/fuzz.h>
9+
#include <test/fuzz/util.h>
10+
11+
#include <array>
12+
#include <cstdint>
13+
#include <iostream>
14+
#include <optional>
15+
#include <string>
16+
#include <vector>
17+
18+
void test_one_input(const std::vector<uint8_t>& buffer)
19+
{
20+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
21+
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
22+
std::optional<CBufferedFile> opt_buffered_file;
23+
FILE* fuzzed_file = fuzzed_file_provider.open();
24+
try {
25+
opt_buffered_file.emplace(fuzzed_file, fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeIntegral<int>());
26+
} catch (const std::ios_base::failure&) {
27+
if (fuzzed_file != nullptr) {
28+
fclose(fuzzed_file);
29+
}
30+
}
31+
if (opt_buffered_file && fuzzed_file != nullptr) {
32+
bool setpos_fail = false;
33+
while (fuzzed_data_provider.ConsumeBool()) {
34+
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
35+
case 0: {
36+
std::array<uint8_t, 4096> arr{};
37+
try {
38+
opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
39+
} catch (const std::ios_base::failure&) {
40+
}
41+
break;
42+
}
43+
case 1: {
44+
opt_buffered_file->Seek(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
45+
break;
46+
}
47+
case 2: {
48+
opt_buffered_file->SetLimit(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
49+
break;
50+
}
51+
case 3: {
52+
if (!opt_buffered_file->SetPos(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096))) {
53+
setpos_fail = true;
54+
}
55+
break;
56+
}
57+
case 4: {
58+
if (setpos_fail) {
59+
// Calling FindByte(...) after a failed SetPos(...) call may result in an infinite loop.
60+
break;
61+
}
62+
try {
63+
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>());
64+
} catch (const std::ios_base::failure&) {
65+
}
66+
break;
67+
}
68+
case 5: {
69+
ReadFromStream(fuzzed_data_provider, *opt_buffered_file);
70+
break;
71+
}
72+
}
73+
}
74+
opt_buffered_file->GetPos();
75+
opt_buffered_file->GetType();
76+
opt_buffered_file->GetVersion();
77+
}
78+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <chainparams.h>
6+
#include <flatfile.h>
7+
#include <test/fuzz/FuzzedDataProvider.h>
8+
#include <test/fuzz/fuzz.h>
9+
#include <test/fuzz/util.h>
10+
#include <test/util/setup_common.h>
11+
#include <validation.h>
12+
13+
#include <cstdint>
14+
#include <vector>
15+
16+
void initialize()
17+
{
18+
InitializeFuzzingContext();
19+
}
20+
21+
void test_one_input(const std::vector<uint8_t>& buffer)
22+
{
23+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
24+
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
25+
FILE* fuzzed_block_file = fuzzed_file_provider.open();
26+
if (fuzzed_block_file == nullptr) {
27+
return;
28+
}
29+
FlatFilePos flat_file_pos;
30+
LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
31+
}

src/test/fuzz/policy_estimator.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
#include <string>
1515
#include <vector>
1616

17+
void initialize()
18+
{
19+
InitializeFuzzingContext();
20+
}
21+
1722
void test_one_input(const std::vector<uint8_t>& buffer)
1823
{
1924
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@@ -66,4 +71,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
6671
(void)block_policy_estimator.estimateSmartFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr, fuzzed_data_provider.ConsumeBool());
6772
(void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}));
6873
}
74+
{
75+
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
76+
CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
77+
block_policy_estimator.Write(fuzzed_auto_file);
78+
block_policy_estimator.Read(fuzzed_auto_file);
79+
}
6980
}

src/test/fuzz/policy_estimator_io.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <policy/fees.h>
6+
#include <test/fuzz/FuzzedDataProvider.h>
7+
#include <test/fuzz/fuzz.h>
8+
#include <test/fuzz/util.h>
9+
10+
#include <cstdint>
11+
#include <vector>
12+
13+
void initialize()
14+
{
15+
InitializeFuzzingContext();
16+
}
17+
18+
void test_one_input(const std::vector<uint8_t>& buffer)
19+
{
20+
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
21+
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
22+
CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
23+
// Re-using block_policy_estimator across runs to avoid costly creation of CBlockPolicyEstimator object.
24+
static CBlockPolicyEstimator block_policy_estimator;
25+
if (block_policy_estimator.Read(fuzzed_auto_file)) {
26+
block_policy_estimator.Write(fuzzed_auto_file);
27+
}
28+
}

0 commit comments

Comments
 (0)