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>
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
21namespace {
22int64_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
35static 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 + ".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 {
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(fs::PathToString(banlist_file + ".json"));
115}
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:288
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 prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:34
#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 byte string.
Definition: fs.h:120
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:30
FUZZ_TARGET_INIT(banman, initialize_banman)
Definition: banman.cpp:42
static bool operator==(const CBanEntry &lhs, const CBanEntry &rhs)
Definition: banman.cpp:35
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition: util.cpp:227
CNetAddr ConsumeNetAddr(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.cpp:374
CSubNet ConsumeSubNet(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:242
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
Definition: util.h:40
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:101
ArgsManager gArgs
Definition: system.cpp:85
assert(!tx.IsCoinBase())