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 : 2 : [&] { 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 : }