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