Branch data Line data Source code
1 : : // Copyright (c) 2020-2022 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 <addrman.h>
6 : : #include <chainparams.h>
7 : : #include <common/args.h>
8 : : #include <net.h>
9 : : #include <net_processing.h>
10 : : #include <netaddress.h>
11 : : #include <protocol.h>
12 : : #include <test/fuzz/FuzzedDataProvider.h>
13 : : #include <test/fuzz/fuzz.h>
14 : : #include <test/fuzz/util.h>
15 : : #include <test/fuzz/util/net.h>
16 : : #include <test/fuzz/util/threadinterrupt.h>
17 : : #include <test/util/setup_common.h>
18 : : #include <util/translation.h>
19 : :
20 : : #include <cstdint>
21 : : #include <vector>
22 : :
23 : : namespace {
24 : : const TestingSetup* g_setup;
25 : :
26 : 2422 : int32_t GetCheckRatio()
27 : : {
28 [ + - + - ]: 4844 : return std::clamp<int32_t>(g_setup->m_node.args->GetIntArg("-checkaddrman", 0), 0, 1000000);
29 : : }
30 : :
31 : : } // namespace
32 : :
33 : 1 : void initialize_connman()
34 : : {
35 [ + - + - : 1 : static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
+ - ]
36 : 1 : g_setup = testing_setup.get();
37 : 1 : }
38 : :
39 [ + - ]: 2169 : FUZZ_TARGET(connman, .init = initialize_connman)
40 : : {
41 : 1713 : SeedRandomStateForTest(SeedRand::ZEROS);
42 : 1713 : FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
43 : 1713 : SetMockTime(ConsumeTime(fuzzed_data_provider));
44 : 1713 : auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
45 [ + - + - ]: 1713 : auto addr_man_ptr{std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio())};
46 [ + + ]: 1713 : if (fuzzed_data_provider.ConsumeBool()) {
47 : 1145 : const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
48 [ - + + - ]: 1145 : DataStream ds{serialized_data};
49 : 1145 : try {
50 [ + + ]: 2290 : ds >> *addr_man_ptr;
51 [ - + ]: 709 : } catch (const std::ios_base::failure&) {
52 [ + - + - ]: 1418 : addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider, GetCheckRatio());
53 : 709 : }
54 : 1145 : }
55 [ + - ]: 1713 : AddrManDeterministic& addr_man{*addr_man_ptr};
56 [ + - ]: 1713 : auto net_events{ConsumeNetEvents(fuzzed_data_provider)};
57 : :
58 : : // Mock CreateSock() to create FuzzedSock.
59 [ + - ]: 1713 : auto CreateSockOrig = CreateSock;
60 : 2926 : CreateSock = [&fuzzed_data_provider](int, int, int) {
61 : 1213 : return std::make_unique<FuzzedSock>(fuzzed_data_provider);
62 : 1713 : };
63 : :
64 : : // Mock g_dns_lookup() to return a fuzzed address.
65 [ + - ]: 1713 : auto g_dns_lookup_orig = g_dns_lookup;
66 : 1725 : g_dns_lookup = [&fuzzed_data_provider](const std::string&, bool) {
67 [ + - + + : 36 : return std::vector<CNetAddr>{ConsumeNetAddr(fuzzed_data_provider)};
- - ]
68 : 1725 : };
69 : :
70 : 1713 : ConnmanTestMsg connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
71 : : fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
72 : : addr_man,
73 : : netgroupman,
74 : : Params(),
75 : 1713 : fuzzed_data_provider.ConsumeBool(),
76 [ + - + - : 3426 : ConsumeThreadInterrupt(fuzzed_data_provider)};
+ - ]
77 : :
78 : 1713 : const uint64_t max_outbound_limit{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
79 : 1713 : CConnman::Options options;
80 : 1713 : options.m_msgproc = &net_events;
81 : 1713 : options.nMaxOutboundLimit = max_outbound_limit;
82 [ + - ]: 1713 : connman.Init(options);
83 : :
84 [ + - ]: 1713 : CNetAddr random_netaddr;
85 [ + - ]: 1713 : CAddress random_address;
86 : 1713 : CNode random_node = ConsumeNode(fuzzed_data_provider);
87 [ + - ]: 1713 : CSubNet random_subnet;
88 : 1713 : std::string random_string;
89 : :
90 [ + + + + ]: 13750 : LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) {
91 : 12037 : CNode& p2p_node{*ConsumeNodeAsUniquePtr(fuzzed_data_provider).release()};
92 [ + - ]: 12037 : connman.AddTestNode(p2p_node);
93 : : }
94 : :
95 [ + + - + ]: 47088 : LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
96 [ + - ]: 45375 : CallOneOf(
97 : : fuzzed_data_provider,
98 : 634 : [&] {
99 : 634 : random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
100 : 634 : },
101 : 2458 : [&] {
102 : 2458 : random_address = ConsumeAddress(fuzzed_data_provider);
103 : 2458 : },
104 : 2698 : [&] {
105 : 2698 : random_subnet = ConsumeSubNet(fuzzed_data_provider);
106 : 2698 : },
107 : 2070 : [&] {
108 : 2070 : random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
109 : 2070 : },
110 : 66 : [&] {
111 : 264 : connman.AddNode({random_string, fuzzed_data_provider.ConsumeBool()});
112 [ - + + - ]: 198 : },
113 : 422 : [&] {
114 : 422 : connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
115 : 422 : },
116 : 1704 : [&] {
117 : 1704 : connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
118 : 1704 : },
119 : 160 : [&] {
120 : 160 : connman.DisconnectNode(random_netaddr);
121 : 160 : },
122 : 11 : [&] {
123 : 11 : connman.DisconnectNode(random_string);
124 : 11 : },
125 : 28 : [&] {
126 : 28 : connman.DisconnectNode(random_subnet);
127 : 28 : },
128 : 323 : [&] {
129 [ + - ]: 323 : connman.ForEachNode([](auto) {});
130 : 323 : },
131 : 16 : [&] {
132 [ + - ]: 16 : (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
133 : 16 : },
134 : 2629 : [&] {
135 : 2629 : auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
136 : 2629 : auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
137 : 2629 : auto filtered = fuzzed_data_provider.ConsumeBool();
138 : 2629 : (void)connman.GetAddressesUnsafe(max_addresses, max_pct, /*network=*/std::nullopt, filtered);
139 : 2629 : },
140 : 82 : [&] {
141 : 82 : auto max_addresses = fuzzed_data_provider.ConsumeIntegral<size_t>();
142 : 82 : auto max_pct = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 100);
143 : 82 : (void)connman.GetAddresses(/*requestor=*/random_node, max_addresses, max_pct);
144 : 82 : },
145 : 19 : [&] {
146 : 19 : (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
147 : 19 : },
148 : 1380 : [&] {
149 : 1380 : (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({ConnectionDirection::None, ConnectionDirection::In, ConnectionDirection::Out, ConnectionDirection::Both}));
150 : 1380 : },
151 : 27375 : [&] {
152 : 27375 : (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
153 : 27375 : },
154 : 71 : [&] {
155 [ + - ]: 71 : CSerializedNetMsg serialized_net_msg;
156 [ + - ]: 71 : serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::MESSAGE_TYPE_SIZE);
157 : 71 : serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
158 [ + - ]: 71 : connman.PushMessage(&random_node, std::move(serialized_net_msg));
159 : 71 : },
160 : 207 : [&] {
161 : 207 : connman.RemoveAddedNode(random_string);
162 : 207 : },
163 : 759 : [&] {
164 : 759 : connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
165 : 759 : },
166 : 24 : [&] {
167 : 24 : connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
168 : 24 : },
169 : 847 : [&] {
170 : 847 : ConnectionType conn_type{
171 : 847 : fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES)};
172 [ + + ]: 847 : if (conn_type == ConnectionType::INBOUND) { // INBOUND is not allowed
173 : 5 : conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
174 : : }
175 : :
176 [ - + ]: 1694 : connman.OpenNetworkConnection(
177 : : /*addrConnect=*/random_address,
178 [ + - ]: 847 : /*fCountFailure=*/fuzzed_data_provider.ConsumeBool(),
179 : : /*grant_outbound=*/{},
180 [ + + ]: 847 : /*pszDest=*/fuzzed_data_provider.ConsumeBool() ? nullptr : random_string.c_str(),
181 : : /*conn_type=*/conn_type,
182 : 847 : /*use_v2transport=*/fuzzed_data_provider.ConsumeBool());
183 : 847 : },
184 : 1185 : [&] {
185 : 1185 : connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
186 : 1185 : const auto peer = ConsumeAddress(fuzzed_data_provider);
187 : 1185 : connman.CreateNodeFromAcceptedSocketPublic(
188 [ + - ]: 2370 : /*sock=*/CreateSock(AF_INET, SOCK_STREAM, IPPROTO_TCP),
189 : : /*permissions=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS),
190 : 2370 : /*addr_bind=*/ConsumeAddress(fuzzed_data_provider),
191 : : /*addr_peer=*/peer);
192 : 1185 : },
193 : 14 : [&] {
194 : 14 : CConnman::Options options;
195 : :
196 : 14 : options.vBinds = ConsumeServiceVector(fuzzed_data_provider);
197 : :
198 : 14 : options.vWhiteBinds = std::vector<NetWhitebindPermissions>{
199 [ + - ]: 28 : fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 5)};
200 [ + + ]: 38 : for (auto& wb : options.vWhiteBinds) {
201 : 24 : wb.m_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
202 : 24 : wb.m_service = ConsumeService(fuzzed_data_provider);
203 : : }
204 : :
205 : 14 : options.onion_binds = ConsumeServiceVector(fuzzed_data_provider);
206 : :
207 [ + + + + ]: 14 : options.bind_on_any = options.vBinds.empty() && options.vWhiteBinds.empty() &&
208 [ - + ]: 1 : options.onion_binds.empty();
209 : :
210 [ + - ]: 14 : connman.InitBindsPublic(options);
211 : 14 : },
212 : 193 : [&] {
213 : 193 : connman.SocketHandlerPublic();
214 : 193 : });
215 : : }
216 [ + - ]: 1713 : (void)connman.GetAddedNodeInfo(fuzzed_data_provider.ConsumeBool());
217 [ + - ]: 1713 : (void)connman.GetExtraFullOutboundCount();
218 [ + - ]: 1713 : (void)connman.GetLocalServices();
219 [ + - - + ]: 1713 : assert(connman.GetMaxOutboundTarget() == max_outbound_limit);
220 [ + - ]: 1713 : (void)connman.GetMaxOutboundTimeframe();
221 [ + - ]: 1713 : (void)connman.GetMaxOutboundTimeLeftInCycle();
222 [ + - ]: 1713 : (void)connman.GetNetworkActive();
223 : 1713 : std::vector<CNodeStats> stats;
224 [ + - ]: 1713 : connman.GetNodeStats(stats);
225 [ + - ]: 1713 : (void)connman.GetOutboundTargetBytesLeft();
226 [ + - ]: 1713 : (void)connman.GetTotalBytesRecv();
227 [ + - ]: 1713 : (void)connman.GetTotalBytesSent();
228 [ + - ]: 1713 : (void)connman.GetTryNewOutboundPeer();
229 : 1713 : (void)connman.GetUseAddrmanOutgoing();
230 [ + - ]: 1713 : (void)connman.ASMapHealthCheck();
231 : :
232 [ + - ]: 1713 : connman.ClearTestNodes();
233 [ + - ]: 1713 : g_dns_lookup = g_dns_lookup_orig;
234 [ + - ]: 1713 : CreateSock = CreateSockOrig;
235 : 1713 : }
|