Branch data Line data Source code
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 <common/args.h>
7 : : #include <netaddress.h>
8 : : #include <test/fuzz/FuzzedDataProvider.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/fs.h>
14 : : #include <util/readwritefile.h>
15 : :
16 : : #include <cassert>
17 [ + - ]: 2 : #include <cstdint>
18 [ + - ]: 2 : #include <limits>
19 : : #include <string>
20 : : #include <vector>
21 : :
22 : : namespace {
23 : 0 : 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 [ # # ]: 0 : return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());
28 : : }
29 : : } // namespace
30 : :
31 : 0 : void initialize_banman()
32 : : {
33 [ # # ][ # # ]: 0 : static const auto testing_setup = MakeNoLogFileContext<>();
[ # # ]
34 : 0 : }
35 : :
36 : 0 : static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)
37 : : {
38 [ # # ]: 0 : return lhs.nVersion == rhs.nVersion &&
39 [ # # ]: 0 : lhs.nCreateTime == rhs.nCreateTime &&
40 : 0 : lhs.nBanUntil == rhs.nBanUntil;
41 : : }
42 : :
43 [ + - ]: 4 : FUZZ_TARGET(banman, .init = initialize_banman)
44 : : {
45 : 0 : FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
46 : 0 : SetMockTime(ConsumeTime(fuzzed_data_provider));
47 [ # # ]: 0 : fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
48 : :
49 [ # # ]: 0 : const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
50 : 0 : bool force_read_and_write_to_err{false};
51 [ # # ]: 0 : if (start_with_corrupted_banlist) {
52 [ # # ][ # # ]: 0 : assert(WriteBinaryFile(banlist_file + ".json",
[ # # ][ # # ]
[ # # ]
53 : : fuzzed_data_provider.ConsumeRandomLengthString()));
54 : 0 : } else {
55 [ # # ]: 0 : force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool();
56 [ # # ]: 0 : if (force_read_and_write_to_err) {
57 [ # # ][ # # ]: 0 : banlist_file = fs::path{"path"} / "to" / "inaccessible" / "fuzzed_banlist";
[ # # ][ # # ]
58 : 0 : }
59 : : }
60 : :
61 : : {
62 [ # # ][ # # ]: 0 : 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 [ # # ][ # # ]: 0 : LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
[ # # ]
67 : : {
68 [ # # ]: 0 : CallOneOf(
69 : : fuzzed_data_provider,
70 : 0 : [&] {
71 [ # # ]: 0 : ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
72 [ # # ]: 0 : ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
73 : 0 : },
74 : 0 : [&] {
75 [ # # ]: 0 : ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
76 [ # # ]: 0 : ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
77 : 0 : },
78 : 0 : [&] {
79 : 0 : ban_man.ClearBanned();
80 : 0 : },
81 : 0 : [&] {
82 [ # # ]: 0 : ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
83 [ + - ]: 2 : },
84 : 0 : [&] {
85 [ # # ]: 0 : ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
86 : 0 : },
87 : 0 : [&] {
88 [ # # ]: 0 : ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
89 : 0 : },
90 : 0 : [&] {
91 [ # # ]: 0 : ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
92 : 0 : },
93 : 0 : [&] {
94 : 0 : banmap_t banmap;
95 [ # # ]: 0 : ban_man.GetBanned(banmap);
96 : 0 : },
97 : 0 : [&] {
98 : 0 : ban_man.DumpBanlist();
99 : 0 : },
100 : 0 : [&] {
101 [ # # ]: 0 : ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
102 : 0 : });
103 : 0 : }
104 [ # # ]: 0 : if (!force_read_and_write_to_err) {
105 [ # # ]: 0 : ban_man.DumpBanlist();
106 [ # # ]: 0 : SetMockTime(ConsumeTime(fuzzed_data_provider));
107 : 0 : banmap_t banmap;
108 [ # # ]: 0 : ban_man.GetBanned(banmap);
109 [ # # ][ # # ]: 0 : BanMan ban_man_read{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/0};
110 : 0 : banmap_t banmap_read;
111 [ # # ]: 0 : ban_man_read.GetBanned(banmap_read);
112 [ # # ][ # # ]: 0 : assert(banmap == banmap_read);
113 : 0 : }
114 : 0 : }
115 [ # # ][ # # ]: 0 : fs::remove(fs::PathToString(banlist_file + ".json"));
[ # # ][ # # ]
[ # # ]
116 : 0 : }
|