LCOV - code coverage report
Current view: top level - src/test/fuzz - pcp.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 95.5 % 44 42
Test Date: 2026-07-21 06:28:42 Functions: 100.0 % 7 7
Branches: 54.2 % 48 26

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

Generated by: LCOV version 2.0-1