Skip to content

Commit 498fe4b

Browse files
committed
Merge bitcoin/bitcoin#23575: fuzz: Rework FillNode
fa19bab fuzz: Rework FillNode (MarcoFalke) fae6e31 refactor: Set fSuccessfullyConnected in FillNode (MarcoFalke) fa3583f fuzz: Avoid negative NodeId in ConsumeNode (MarcoFalke) Pull request description: Currently `FillNode` is a bit clumsy because it directly modifies memory of `CNode`. This gets in the way of moving that memory to `Peer`. Also, it isn't particularly consistent. See for example bitcoin/bitcoin#21160 (comment) . Fix all issues by sending a `version`/`verack` in `FillNode` and let net_processing figure out the internal details. ACKs for top commit: jnewbery: Strong concept ACK and light code review ACK fa19bab Tree-SHA512: 33261d857c3fa6d5d39d742624009a29178ad5a15eb3fd062da741affa5a4854fd45ed20d59a6bba2fb068cf7b39cad6f95b2910be7cb6afdc27cd7917955b67
2 parents aaaceb7 + fa19bab commit 498fe4b

File tree

4 files changed

+50
-16
lines changed

4 files changed

+50
-16
lines changed

src/test/fuzz/process_message.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,9 @@ void fuzz_target(FuzzBufferType buffer, const std::string& LIMIT_TO_MESSAGE_TYPE
7979
}
8080
CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release();
8181

82-
const bool successfully_connected{fuzzed_data_provider.ConsumeBool()};
83-
p2p_node.fSuccessfullyConnected = successfully_connected;
8482
connman.AddTestNode(p2p_node);
8583
g_setup->m_node.peerman->InitializeNode(&p2p_node);
86-
FillNode(fuzzed_data_provider, p2p_node, /*init_version=*/successfully_connected);
84+
FillNode(fuzzed_data_provider, connman, *g_setup->m_node.peerman, p2p_node);
8785

8886
const auto mock_time = ConsumeTime(fuzzed_data_provider);
8987
SetMockTime(mock_time);

src/test/fuzz/process_messages.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,8 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages)
4646
peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release());
4747
CNode& p2p_node = *peers.back();
4848

49-
const bool successfully_connected{fuzzed_data_provider.ConsumeBool()};
50-
p2p_node.fSuccessfullyConnected = successfully_connected;
51-
p2p_node.fPauseSend = false;
5249
g_setup->m_node.peerman->InitializeNode(&p2p_node);
53-
FillNode(fuzzed_data_provider, p2p_node, /*init_version=*/successfully_connected);
50+
FillNode(fuzzed_data_provider, connman, *g_setup->m_node.peerman, p2p_node);
5451

5552
connman.AddTestNode(p2p_node);
5653
}

src/test/fuzz/util.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <consensus/amount.h>
6+
#include <net_processing.h>
7+
#include <netmessagemaker.h>
68
#include <pubkey.h>
79
#include <test/fuzz/util.h>
810
#include <test/util/script.h>
@@ -200,22 +202,57 @@ bool FuzzedSock::IsConnected(std::string& errmsg) const
200202
return false;
201203
}
202204

203-
void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept
205+
void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, PeerManager& peerman, CNode& node) noexcept
204206
{
207+
const bool successfully_connected{fuzzed_data_provider.ConsumeBool()};
205208
const ServiceFlags remote_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
206209
const NetPermissionFlags permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
207210
const int32_t version = fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max());
208211
const bool filter_txs = fuzzed_data_provider.ConsumeBool();
209212

210-
node.nServices = remote_services;
211-
node.m_permissionFlags = permission_flags;
212-
if (init_version) {
213-
node.nVersion = version;
214-
node.SetCommonVersion(std::min(version, PROTOCOL_VERSION));
213+
const CNetMsgMaker mm{0};
214+
215+
CSerializedNetMsg msg_version{
216+
mm.Make(NetMsgType::VERSION,
217+
version, //
218+
Using<CustomUintFormatter<8>>(remote_services), //
219+
int64_t{}, // dummy time
220+
int64_t{}, // ignored service bits
221+
CService{}, // dummy
222+
int64_t{}, // ignored service bits
223+
CService{}, // ignored
224+
uint64_t{1}, // dummy nonce
225+
std::string{}, // dummy subver
226+
int32_t{}, // dummy starting_height
227+
filter_txs),
228+
};
229+
230+
(void)connman.ReceiveMsgFrom(node, msg_version);
231+
node.fPauseSend = false;
232+
connman.ProcessMessagesOnce(node);
233+
{
234+
LOCK(node.cs_sendProcessing);
235+
peerman.SendMessages(&node);
215236
}
237+
if (node.fDisconnect) return;
238+
assert(node.nVersion == version);
239+
assert(node.GetCommonVersion() == std::min(version, PROTOCOL_VERSION));
240+
assert(node.nServices == remote_services);
216241
if (node.m_tx_relay != nullptr) {
217242
LOCK(node.m_tx_relay->cs_filter);
218-
node.m_tx_relay->fRelayTxes = filter_txs;
243+
assert(node.m_tx_relay->fRelayTxes == filter_txs);
244+
}
245+
node.m_permissionFlags = permission_flags;
246+
if (successfully_connected) {
247+
CSerializedNetMsg msg_verack{mm.Make(NetMsgType::VERACK)};
248+
(void)connman.ReceiveMsgFrom(node, msg_verack);
249+
node.fPauseSend = false;
250+
connman.ProcessMessagesOnce(node);
251+
{
252+
LOCK(node.cs_sendProcessing);
253+
peerman.SendMessages(&node);
254+
}
255+
assert(node.fSuccessfullyConnected == true);
219256
}
220257
}
221258

src/test/fuzz/util.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include <string>
3737
#include <vector>
3838

39+
class PeerManager;
40+
3941
template <typename... Callables>
4042
size_t CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
4143
{
@@ -257,7 +259,7 @@ inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcep
257259
template <bool ReturnUniquePtr = false>
258260
auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<NodeId>& node_id_in = std::nullopt) noexcept
259261
{
260-
const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegral<NodeId>());
262+
const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegralInRange<NodeId>(0, std::numeric_limits<NodeId>::max()));
261263
const ServiceFlags local_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
262264
const SOCKET socket = INVALID_SOCKET;
263265
const CAddress address = ConsumeAddress(fuzzed_data_provider);
@@ -275,7 +277,7 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<N
275277
}
276278
inline std::unique_ptr<CNode> ConsumeNodeAsUniquePtr(FuzzedDataProvider& fdp, const std::optional<NodeId>& node_id_in = std::nullopt) { return ConsumeNode<true>(fdp, node_id_in); }
277279

278-
void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept;
280+
void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, PeerManager& peerman, CNode& node) noexcept;
279281

280282
class FuzzedFileProvider
281283
{

0 commit comments

Comments
 (0)