Bitcoin Core  24.99.0
P2P Digital Currency
banman.cpp
Go to the documentation of this file.
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 <banman.h>
6 #include <fs.h>
7 #include <netaddress.h>
9 #include <test/fuzz/fuzz.h>
10 #include <test/fuzz/util.h>
11 #include <test/fuzz/util/net.h>
12 #include <test/util/setup_common.h>
13 #include <util/readwritefile.h>
14 #include <util/system.h>
15 
16 #include <cassert>
17 #include <cstdint>
18 #include <limits>
19 #include <string>
20 #include <vector>
21 
22 namespace {
23 int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
24 {
25  // Avoid signed integer overflow by capping to int32_t max:
26  // banman.cpp:137:73: runtime error: signed integer overflow: 1591700817 + 9223372036854775807 cannot be represented in type 'long'
27  return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());
28 }
29 } // namespace
30 
32 {
33  static const auto testing_setup = MakeNoLogFileContext<>();
34 }
35 
36 static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)
37 {
38  return lhs.nVersion == rhs.nVersion &&
39  lhs.nCreateTime == rhs.nCreateTime &&
40  lhs.nBanUntil == rhs.nBanUntil;
41 }
42 
44 {
45  FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
46  SetMockTime(ConsumeTime(fuzzed_data_provider));
47  fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
48 
49  const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
50  bool force_read_and_write_to_err{false};
51  if (start_with_corrupted_banlist) {
52  assert(WriteBinaryFile(banlist_file + ".json",
53  fuzzed_data_provider.ConsumeRandomLengthString()));
54  } else {
55  force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool();
56  if (force_read_and_write_to_err) {
57  banlist_file = fs::path{"path"} / "to" / "inaccessible" / "fuzzed_banlist";
58  }
59  }
60 
61  {
62  BanMan ban_man{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/ConsumeBanTimeOffset(fuzzed_data_provider)};
63  // The complexity is O(N^2), where N is the input size, because each call
64  // might call DumpBanlist (or other methods that are at least linear
65  // complexity of the input size).
66  LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
67  {
68  CallOneOf(
69  fuzzed_data_provider,
70  [&] {
71  ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
72  ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
73  },
74  [&] {
75  ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
76  ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
77  },
78  [&] {
79  ban_man.ClearBanned();
80  },
81  [&] {
82  ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
83  },
84  [&] {
85  ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
86  },
87  [&] {
88  ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
89  },
90  [&] {
91  ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
92  },
93  [&] {
94  banmap_t banmap;
95  ban_man.GetBanned(banmap);
96  },
97  [&] {
98  ban_man.DumpBanlist();
99  },
100  [&] {
101  ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
102  });
103  }
104  if (!force_read_and_write_to_err) {
105  ban_man.DumpBanlist();
106  SetMockTime(ConsumeTime(fuzzed_data_provider));
107  banmap_t banmap;
108  ban_man.GetBanned(banmap);
109  BanMan ban_man_read{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/0};
110  banmap_t banmap_read;
111  ban_man_read.GetBanned(banmap_read);
112  assert(banmap == banmap_read);
113  }
114  }
115  fs::remove(fs::PathToString(banlist_file + ".json"));
116 }
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:295
Definition: banman.h:59
Definition: net_types.h:15
int64_t nCreateTime
Definition: net_types.h:19
int nVersion
Definition: net_types.h:18
int64_t nBanUntil
Definition: net_types.h:20
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Definition: fuzz.h:18
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:150
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:41
bool WriteBinaryFile(const fs::path &filename, const std::string &data)
Write contents of std::string to a file.
void initialize_banman()
Definition: banman.cpp:31
FUZZ_TARGET_INIT(banman, initialize_banman)
Definition: banman.cpp:43
static bool operator==(const CBanEntry &lhs, const CBanEntry &rhs)
Definition: banman.cpp:36
CNetAddr ConsumeNetAddr(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: net.cpp:28
CSubNet ConsumeSubNet(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: net.h:88
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition: util.cpp:22
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
Definition: util.h:36
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:89
ArgsManager gArgs
Definition: system.cpp:73
assert(!tx.IsCoinBase())