From fa121f058fdc5f09dd11678480f551246cb3c5e2 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 28 Dec 2020 21:53:19 +0100 Subject: [PATCH 1/5] fuzz: Use ConsumeNode in process_messages target --- src/test/fuzz/process_messages.cpp | 4 +--- src/test/fuzz/util.h | 12 +++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index 0ff95ea1ae9..fcfa623508d 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -47,9 +47,7 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); for (int i = 0; i < num_peers_to_add; ++i) { - const ServiceFlags service_flags = ServiceFlags(fuzzed_data_provider.ConsumeIntegral()); - const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH}); - peers.push_back(MakeUnique(i, service_flags, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, conn_type).release()); + peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release()); CNode& p2p_node = *peers.back(); p2p_node.fSuccessfullyConnected = true; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index ff79dfe5f3c..8fdb16d2df2 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -286,9 +286,10 @@ inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcep return {ConsumeService(fuzzed_data_provider), static_cast(fuzzed_data_provider.ConsumeIntegral()), fuzzed_data_provider.ConsumeIntegral()}; } -inline CNode ConsumeNode(FuzzedDataProvider& fuzzed_data_provider) noexcept +template +auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional& node_id_in = nullopt) noexcept { - const NodeId node_id = fuzzed_data_provider.ConsumeIntegral(); + const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegral()); const ServiceFlags local_services = static_cast(fuzzed_data_provider.ConsumeIntegral()); const SOCKET socket = INVALID_SOCKET; const CAddress address = ConsumeAddress(fuzzed_data_provider); @@ -298,8 +299,13 @@ inline CNode ConsumeNode(FuzzedDataProvider& fuzzed_data_provider) noexcept const std::string addr_name = fuzzed_data_provider.ConsumeRandomLengthString(64); const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH}); const bool inbound_onion{conn_type == ConnectionType::INBOUND ? fuzzed_data_provider.ConsumeBool() : false}; - return {node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion}; + if constexpr (ReturnUniquePtr) { + return std::make_unique(node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion); + } else { + return CNode{node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion}; + } } +inline std::unique_ptr ConsumeNodeAsUniquePtr(FuzzedDataProvider& fdp, const std::optional& node_id_in = nullopt) { return ConsumeNode(fdp, node_id_in); } inline void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST) { From fa42da2d5424c0aeccfae4b49fde2bea330b63dc Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 28 Dec 2020 21:52:40 +0100 Subject: [PATCH 2/5] fuzz: Use ConsumeNode in process_message target --- src/test/fuzz/process_message.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 97e2b04a7d0..b6865c53478 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -63,13 +64,15 @@ void fuzz_target(const std::vector& buffer, const std::string& LIMIT_TO } const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()}; if (jump_out_of_ibd) chainstate.JumpOutOfIbd(); - CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes(), SER_NETWORK, PROTOCOL_VERSION}; - CNode& p2p_node = *MakeUnique(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND_FULL_RELAY).release(); + CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release(); p2p_node.fSuccessfullyConnected = true; p2p_node.nVersion = PROTOCOL_VERSION; p2p_node.SetCommonVersion(PROTOCOL_VERSION); connman.AddTestNode(p2p_node); g_setup->m_node.peerman->InitializeNode(&p2p_node); + + // fuzzed_data_provider is fully consumed after this call, don't use it + CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes(), SER_NETWORK, PROTOCOL_VERSION}; try { g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, GetTime(), std::atomic{false}); From faaef9434c19e3643322ee442c240c166af5adbd Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 28 Dec 2020 21:31:33 +0100 Subject: [PATCH 3/5] fuzz: [refactor] Extract ALL_CONNECTION_TYPES constant --- src/test/fuzz/util.h | 3 ++- src/test/util/net.h | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 8fdb16d2df2..cd5da8aae83 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -297,7 +298,7 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional(); const CAddress addr_bind = ConsumeAddress(fuzzed_data_provider); const std::string addr_name = fuzzed_data_provider.ConsumeRandomLengthString(64); - const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH}); + const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES); const bool inbound_onion{conn_type == ConnectionType::INBOUND ? fuzzed_data_provider.ConsumeBool() : false}; if constexpr (ReturnUniquePtr) { return std::make_unique(node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion); diff --git a/src/test/util/net.h b/src/test/util/net.h index 1208e927625..5fad570c29f 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -30,4 +30,13 @@ struct ConnmanTestMsg : public CConnman { bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const; }; +constexpr ConnectionType ALL_CONNECTION_TYPES[]{ + ConnectionType::INBOUND, + ConnectionType::OUTBOUND_FULL_RELAY, + ConnectionType::MANUAL, + ConnectionType::FEELER, + ConnectionType::BLOCK_RELAY, + ConnectionType::ADDR_FETCH, +}; + #endif // BITCOIN_TEST_UTIL_NET_H From fa9949b91414ee0da376a322cee32ba4e3989d8c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 28 Dec 2020 21:58:00 +0100 Subject: [PATCH 4/5] fuzz: Add ConsumeWeakEnum helper, Extract ALL_NET_PERMISSION_FLAGS --- src/test/fuzz/net.cpp | 5 ++--- src/test/fuzz/net_permissions.cpp | 13 +------------ src/test/fuzz/util.h | 8 ++++++++ src/test/util/net.h | 13 +++++++++++++ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp index ec02cf94e9b..3ca921b5cf8 100644 --- a/src/test/fuzz/net.cpp +++ b/src/test/fuzz/net.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -122,9 +123,7 @@ FUZZ_TARGET_INIT(net, initialize_net) (void)node.GetCommonVersion(); (void)node.RelayAddrsWithConn(); - const NetPermissionFlags net_permission_flags = fuzzed_data_provider.ConsumeBool() ? - fuzzed_data_provider.PickValueInArray({NetPermissionFlags::PF_NONE, NetPermissionFlags::PF_BLOOMFILTER, NetPermissionFlags::PF_RELAY, NetPermissionFlags::PF_FORCERELAY, NetPermissionFlags::PF_NOBAN, NetPermissionFlags::PF_MEMPOOL, NetPermissionFlags::PF_ISIMPLICIT, NetPermissionFlags::PF_ALL}) : - static_cast(fuzzed_data_provider.ConsumeIntegral()); + const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS); (void)node.HasPermission(net_permission_flags); (void)node.ConnectedThroughNetwork(); } diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp index 3620e16d306..544a33047bb 100644 --- a/src/test/fuzz/net_permissions.cpp +++ b/src/test/fuzz/net_permissions.cpp @@ -17,18 +17,7 @@ FUZZ_TARGET(net_permissions) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(32); - const NetPermissionFlags net_permission_flags = fuzzed_data_provider.ConsumeBool() ? fuzzed_data_provider.PickValueInArray({ - NetPermissionFlags::PF_NONE, - NetPermissionFlags::PF_BLOOMFILTER, - NetPermissionFlags::PF_RELAY, - NetPermissionFlags::PF_FORCERELAY, - NetPermissionFlags::PF_NOBAN, - NetPermissionFlags::PF_MEMPOOL, - NetPermissionFlags::PF_ADDR, - NetPermissionFlags::PF_ISIMPLICIT, - NetPermissionFlags::PF_ALL, - }) : - static_cast(fuzzed_data_provider.ConsumeIntegral()); + const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS); NetWhitebindPermissions net_whitebind_permissions; bilingual_str error_net_whitebind_permissions; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index cd5da8aae83..1aa6463b88f 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -87,6 +87,14 @@ template return obj; } +template +[[nodiscard]] WeakEnumType ConsumeWeakEnum(FuzzedDataProvider& fuzzed_data_provider, const WeakEnumType (&all_types)[size]) noexcept +{ + return fuzzed_data_provider.ConsumeBool() ? + fuzzed_data_provider.PickValueInArray(all_types) : + WeakEnumType(fuzzed_data_provider.ConsumeIntegral::type>()); +} + [[nodiscard]] inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept { return static_cast(fuzzed_data_provider.ConsumeIntegralInRange(0, MAX_OPCODE)); diff --git a/src/test/util/net.h b/src/test/util/net.h index 5fad570c29f..661d21227fd 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -30,6 +30,19 @@ struct ConnmanTestMsg : public CConnman { bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const; }; +constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{ + NetPermissionFlags::PF_NONE, + NetPermissionFlags::PF_BLOOMFILTER, + NetPermissionFlags::PF_RELAY, + NetPermissionFlags::PF_FORCERELAY, + NetPermissionFlags::PF_NOBAN, + NetPermissionFlags::PF_MEMPOOL, + NetPermissionFlags::PF_ADDR, + NetPermissionFlags::PF_DOWNLOAD, + NetPermissionFlags::PF_ISIMPLICIT, + NetPermissionFlags::PF_ALL, +}; + constexpr ConnectionType ALL_CONNECTION_TYPES[]{ ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, From eeee43bc48ea7fbacd3c5e3f076f01f04744adb8 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 2 Jan 2021 10:14:39 +0100 Subject: [PATCH 5/5] fuzz: Use ConsumeWeakEnum for ServiceFlags --- src/test/fuzz/connman.cpp | 2 +- src/test/fuzz/util.h | 4 ++-- src/test/util/net.h | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index 76217510770..fdf51d8558c 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -128,7 +128,7 @@ FUZZ_TARGET_INIT(connman, initialize_connman) connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool()); break; case 26: - connman.SetServices(random_service, static_cast(fuzzed_data_provider.ConsumeIntegral())); + connman.SetServices(random_service, ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)); break; case 27: connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool()); diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 1aa6463b88f..94c691936e7 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -292,14 +292,14 @@ inline CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcep inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept { - return {ConsumeService(fuzzed_data_provider), static_cast(fuzzed_data_provider.ConsumeIntegral()), fuzzed_data_provider.ConsumeIntegral()}; + return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), fuzzed_data_provider.ConsumeIntegral()}; } template auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional& node_id_in = nullopt) noexcept { const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegral()); - const ServiceFlags local_services = static_cast(fuzzed_data_provider.ConsumeIntegral()); + const ServiceFlags local_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS); const SOCKET socket = INVALID_SOCKET; const CAddress address = ConsumeAddress(fuzzed_data_provider); const uint64_t keyed_net_group = fuzzed_data_provider.ConsumeIntegral(); diff --git a/src/test/util/net.h b/src/test/util/net.h index 661d21227fd..e25036be26a 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -30,6 +30,15 @@ struct ConnmanTestMsg : public CConnman { bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const; }; +constexpr ServiceFlags ALL_SERVICE_FLAGS[]{ + NODE_NONE, + NODE_NETWORK, + NODE_BLOOM, + NODE_WITNESS, + NODE_COMPACT_FILTERS, + NODE_NETWORK_LIMITED, +}; + constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{ NetPermissionFlags::PF_NONE, NetPermissionFlags::PF_BLOOMFILTER,