Skip to content

Commit c73b59d

Browse files
committed
fuzz: implement targets for PCP and NAT-PMP port mapping requests
1 parent 1695c8a commit c73b59d

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

src/test/fuzz/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ add_executable(fuzz
7575
p2p_handshake.cpp
7676
p2p_headers_presync.cpp
7777
p2p_transport_serialization.cpp
78+
pcp.cpp
7879
package_eval.cpp
7980
parse_hd_keypath.cpp
8081
parse_iso8601.cpp

src/test/fuzz/pcp.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) 2024 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 <test/fuzz/FuzzedDataProvider.h>
6+
#include <test/fuzz/fuzz.h>
7+
#include <test/fuzz/util.h>
8+
#include <test/fuzz/util/net.h>
9+
10+
#include <common/pcp.h>
11+
#include <util/check.h>
12+
13+
using namespace std::literals;
14+
15+
//! Fixed nonce to use in PCP port mapping requests.
16+
constexpr PCPMappingNonce PCP_NONCE{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
17+
18+
//! Number of attempts to request a NAT-PMP or PCP port mapping to the gateway.
19+
constexpr int NUM_TRIES{5};
20+
21+
//! Timeout for each attempt to request a port mapping.
22+
constexpr std::chrono::duration TIMEOUT{100ms};
23+
24+
void port_map_target_init()
25+
{
26+
LogInstance().DisableLogging();
27+
}
28+
29+
FUZZ_TARGET(pcp_request_port_map, .init = port_map_target_init)
30+
{
31+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
32+
33+
// Create a mocked socket between random (and potentially invalid) client and gateway addresses.
34+
CreateSock = [&](int domain, int type, int protocol) {
35+
if ((domain == AF_INET || domain == AF_INET6) && type == SOCK_DGRAM && protocol == IPPROTO_UDP) {
36+
return std::make_unique<FuzzedSock>(fuzzed_data_provider);
37+
}
38+
return std::unique_ptr<FuzzedSock>();
39+
};
40+
41+
// Perform the port mapping request. The mocked socket will return fuzzer-provided data.
42+
const auto gateway_addr{ConsumeNetAddr(fuzzed_data_provider)};
43+
const auto local_addr{ConsumeNetAddr(fuzzed_data_provider)};
44+
const auto port{fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
45+
const auto lifetime{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
46+
const auto res{PCPRequestPortMap(PCP_NONCE, gateway_addr, local_addr, port, lifetime, NUM_TRIES, TIMEOUT)};
47+
48+
// In case of success the mapping must be consistent with the request.
49+
if (const MappingResult* mapping = std::get_if<MappingResult>(&res)) {
50+
Assert(mapping);
51+
Assert(mapping->internal.GetPort() == port);
52+
mapping->ToString();
53+
}
54+
}
55+
56+
FUZZ_TARGET(natpmp_request_port_map, .init = port_map_target_init)
57+
{
58+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
59+
60+
// Create a mocked socket between random (and potentially invalid) client and gateway addresses.
61+
CreateSock = [&](int domain, int type, int protocol) {
62+
if (domain == AF_INET && type == SOCK_DGRAM && protocol == IPPROTO_UDP) {
63+
return std::make_unique<FuzzedSock>(fuzzed_data_provider);
64+
}
65+
return std::unique_ptr<FuzzedSock>();
66+
};
67+
68+
// Perform the port mapping request. The mocked socket will return fuzzer-provided data.
69+
const auto gateway_addr{ConsumeNetAddr(fuzzed_data_provider)};
70+
const auto port{fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
71+
const auto lifetime{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
72+
const auto res{NATPMPRequestPortMap(gateway_addr, port, lifetime, NUM_TRIES, TIMEOUT)};
73+
74+
// In case of success the mapping must be consistent with the request.
75+
if (const MappingResult* mapping = std::get_if<MappingResult>(&res)) {
76+
Assert(mapping);
77+
Assert(mapping->internal.GetPort() == port);
78+
mapping->ToString();
79+
}
80+
}

0 commit comments

Comments
 (0)