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 [ + - ]: 173 : #include <cstdint> 18 [ + - ]: 173 : #include <limits> 19 : : #include <string> 20 : : #include <vector> 21 : : 22 : : namespace { 23 : 14577 : 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 [ + - ]: 14577 : return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max()); 28 : : } 29 : : } // namespace 30 : : 31 : 1 : void initialize_banman() 32 : : { 33 [ + - - + : 1 : static const auto testing_setup = MakeNoLogFileContext<>(); + - ] 34 : 1 : } 35 : : 36 : 8524 : static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs) 37 : : { 38 [ + - ]: 17048 : return lhs.nVersion == rhs.nVersion && 39 [ - + ]: 8524 : lhs.nCreateTime == rhs.nCreateTime && 40 : 8524 : lhs.nBanUntil == rhs.nBanUntil; 41 : : } 42 : : 43 [ + - - + ]: 1028 : FUZZ_TARGET(banman, .init = initialize_banman) 44 : : { 45 : 682 : FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; 46 : 682 : SetMockTime(ConsumeTime(fuzzed_data_provider)); 47 [ + - ]: 682 : fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist"; 48 : : 49 [ + - ]: 682 : const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()}; 50 : 682 : bool force_read_and_write_to_err{false}; 51 [ + + ]: 682 : if (start_with_corrupted_banlist) { 52 [ + - + - : 476 : assert(WriteBinaryFile(banlist_file + ".json", + - + - - + ] 53 : : fuzzed_data_provider.ConsumeRandomLengthString())); 54 : 476 : } else { 55 [ + - ]: 206 : force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool(); 56 [ + + ]: 206 : if (force_read_and_write_to_err) { 57 [ + - + - : 34 : banlist_file = fs::path{"path"} / "to" / "inaccessible" / "fuzzed_banlist"; + - - + ] 58 : 34 : } 59 : : } 60 : : 61 : : { 62 [ + - + - ]: 682 : 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 [ + - + + : 28529 : LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300) + + ] 67 : : { 68 [ + - ]: 27847 : CallOneOf( 69 : : fuzzed_data_provider, 70 : 32682 : [&] { 71 [ + - ]: 4835 : ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider), 72 [ + - ]: 4835 : ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool()); 73 : 4835 : }, 74 : 37080 : [&] { 75 [ + - ]: 9060 : ban_man.Ban(ConsumeSubNet(fuzzed_data_provider), 76 [ + - ]: 9060 : ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool()); 77 : 9060 : }, 78 : 28834 : [&] { 79 : 987 : ban_man.ClearBanned(); 80 : 987 : }, 81 : 29945 : [&] { 82 [ + - ]: 2098 : ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider)); 83 [ + - ]: 2271 : }, 84 : 28710 : [&] { 85 [ + - ]: 863 : ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider)); 86 : 863 : }, 87 : 32086 : [&] { 88 [ + - ]: 4239 : ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider)); 89 : 4239 : }, 90 : 28229 : [&] { 91 [ + - ]: 382 : ban_man.Unban(ConsumeSubNet(fuzzed_data_provider)); 92 : 382 : }, 93 : 32371 : [&] { 94 : 4524 : banmap_t banmap; 95 [ + - ]: 4524 : ban_man.GetBanned(banmap); 96 : 4524 : }, 97 : 27905 : [&] { 98 : 58 : ban_man.DumpBanlist(); 99 : 58 : }, 100 : 28648 : [&] { 101 [ + - ]: 801 : ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider)); 102 : 801 : }); 103 : 27847 : } 104 [ + + ]: 682 : if (!force_read_and_write_to_err) { 105 [ + - ]: 648 : ban_man.DumpBanlist(); 106 [ + - ]: 648 : SetMockTime(ConsumeTime(fuzzed_data_provider)); 107 : 648 : banmap_t banmap; 108 [ + - ]: 648 : ban_man.GetBanned(banmap); 109 [ + - + - ]: 648 : BanMan ban_man_read{banlist_file, /*client_interface=*/nullptr, /*default_ban_time=*/0}; 110 : 648 : banmap_t banmap_read; 111 [ + - ]: 648 : ban_man_read.GetBanned(banmap_read); 112 [ + - + - ]: 648 : assert(banmap == banmap_read); 113 : 648 : } 114 : 682 : } 115 [ + - + - : 682 : fs::remove(fs::PathToString(banlist_file + ".json")); + - + - + - ] 116 : 682 : }