Skip to content

Commit 28cb616

Browse files
author
MarcoFalke
committed
Merge #19065: tests: Add fuzzing harness for CAddrMan
d04a17a fuzz: Use ConsumeRandomLengthBitVector(...) in src/test/fuzz/connman and src/test/fuzz/net (practicalswift) e6bb9fd tests: Add fuzzing harness for CAddrMan (practicalswift) Pull request description: Add fuzzing harness for `CAddrMan`. ~~Fill some fuzzing coverage gaps for functions in `addrdb.h`, `merkleblock.h` and `outputtype.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: MarcoFalke: review ACK d04a17a Tree-SHA512: a6b627e3a0cb51e3a8cb02ad0f19088fc0e965ca34ab110b68d5822d0ea7f473207ae312b49fb217cb6cf2f9f211d00bb69c83bac9f50d79c9ed1e157e85775d
2 parents 99fcc2b + d04a17a commit 28cb616

File tree

5 files changed

+142
-2
lines changed

5 files changed

+142
-2
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ FUZZ_TARGETS = \
77
test/fuzz/addr_info_deserialize \
88
test/fuzz/addrdb \
99
test/fuzz/address_deserialize \
10+
test/fuzz/addrman \
1011
test/fuzz/addrman_deserialize \
1112
test/fuzz/asmap \
1213
test/fuzz/asmap_direct \
@@ -353,6 +354,12 @@ test_fuzz_address_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
353354
test_fuzz_address_deserialize_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
354355
test_fuzz_address_deserialize_SOURCES = test/fuzz/deserialize.cpp
355356

357+
test_fuzz_addrman_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
358+
test_fuzz_addrman_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
359+
test_fuzz_addrman_LDADD = $(FUZZ_SUITE_LD_COMMON)
360+
test_fuzz_addrman_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
361+
test_fuzz_addrman_SOURCES = test/fuzz/addrman.cpp
362+
356363
test_fuzz_addrman_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DADDRMAN_DESERIALIZE=1
357364
test_fuzz_addrman_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
358365
test_fuzz_addrman_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/addrman.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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 <addrdb.h>
6+
#include <addrman.h>
7+
#include <chainparams.h>
8+
#include <merkleblock.h>
9+
#include <test/fuzz/FuzzedDataProvider.h>
10+
#include <test/fuzz/fuzz.h>
11+
#include <test/fuzz/util.h>
12+
#include <time.h>
13+
#include <util/asmap.h>
14+
15+
#include <cstdint>
16+
#include <optional>
17+
#include <string>
18+
#include <vector>
19+
20+
void initialize()
21+
{
22+
SelectParams(CBaseChainParams::REGTEST);
23+
}
24+
25+
void test_one_input(const std::vector<uint8_t>& buffer)
26+
{
27+
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
28+
29+
SetMockTime(ConsumeTime(fuzzed_data_provider));
30+
CAddrMan addr_man;
31+
if (fuzzed_data_provider.ConsumeBool()) {
32+
addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
33+
if (!SanityCheckASMap(addr_man.m_asmap)) {
34+
addr_man.m_asmap.clear();
35+
}
36+
}
37+
while (fuzzed_data_provider.ConsumeBool()) {
38+
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
39+
case 0: {
40+
addr_man.Clear();
41+
break;
42+
}
43+
case 1: {
44+
addr_man.ResolveCollisions();
45+
break;
46+
}
47+
case 2: {
48+
(void)addr_man.SelectTriedCollision();
49+
break;
50+
}
51+
case 3: {
52+
(void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
53+
break;
54+
}
55+
case 4: {
56+
(void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
57+
break;
58+
}
59+
case 5: {
60+
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
61+
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
62+
if (opt_address && opt_net_addr) {
63+
addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
64+
}
65+
break;
66+
}
67+
case 6: {
68+
std::vector<CAddress> addresses;
69+
while (fuzzed_data_provider.ConsumeBool()) {
70+
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
71+
if (!opt_address) {
72+
break;
73+
}
74+
addresses.push_back(*opt_address);
75+
}
76+
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
77+
if (opt_net_addr) {
78+
addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
79+
}
80+
break;
81+
}
82+
case 7: {
83+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
84+
if (opt_service) {
85+
addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
86+
}
87+
break;
88+
}
89+
case 8: {
90+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
91+
if (opt_service) {
92+
addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
93+
}
94+
break;
95+
}
96+
case 9: {
97+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
98+
if (opt_service) {
99+
addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
100+
}
101+
break;
102+
}
103+
case 10: {
104+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
105+
if (opt_service) {
106+
addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
107+
}
108+
break;
109+
}
110+
case 11: {
111+
(void)addr_man.Check();
112+
break;
113+
}
114+
}
115+
}
116+
(void)addr_man.size();
117+
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
118+
data_stream << addr_man;
119+
}

src/test/fuzz/connman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
117117
connman.RemoveAddedNode(random_string);
118118
break;
119119
case 24: {
120-
const std::vector<bool> asmap = ConsumeRandomLengthIntegralVector<bool>(fuzzed_data_provider, 512);
120+
const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
121121
if (SanityCheckASMap(asmap)) {
122122
connman.SetAsmap(asmap);
123123
}

src/test/fuzz/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
6363
break;
6464
}
6565
case 3: {
66-
const std::vector<bool> asmap = ConsumeRandomLengthIntegralVector<bool>(fuzzed_data_provider, 128);
66+
const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
6767
if (!SanityCheckASMap(asmap)) {
6868
break;
6969
}

src/test/fuzz/util.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <chainparamsbase.h>
1212
#include <coins.h>
1313
#include <consensus/consensus.h>
14+
#include <merkleblock.h>
1415
#include <net.h>
1516
#include <netaddress.h>
1617
#include <netbase.h>
@@ -24,6 +25,7 @@
2425
#include <test/util/setup_common.h>
2526
#include <txmempool.h>
2627
#include <uint256.h>
28+
#include <util/time.h>
2729
#include <version.h>
2830

2931
#include <algorithm>
@@ -39,6 +41,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr
3941
return {s.begin(), s.end()};
4042
}
4143

44+
NODISCARD inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
45+
{
46+
return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
47+
}
48+
4249
NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
4350
{
4451
return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
@@ -89,6 +96,13 @@ NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider)
8996
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
9097
}
9198

99+
NODISCARD inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
100+
{
101+
static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:00Z");
102+
static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
103+
return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
104+
}
105+
92106
NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
93107
{
94108
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);

0 commit comments

Comments
 (0)