aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-07-11 11:41:06 +0200
committerMarcoFalke <falke.marco@gmail.com>2020-07-11 11:41:12 +0200
commita42631775afadf7e8cf07e917f733bd54dc3080e (patch)
treec60ffe0d41aced5ad997c572da1bf2f0339487a7 /src/test/fuzz
parentca055885c631de8ac0ffe24be6b02835dbcc039d (diff)
parent97846d7f5b47ef77469b9f961db77f770e8bcc0f (diff)
Merge #19222: tests: Add fuzzing harness for BanMan
97846d7f5b47ef77469b9f961db77f770e8bcc0f tests: Add fuzzing harness for BanMan (practicalswift) deba199f1c88c2e5f754b0a4ec43b9ef28de8352 tests: Add ConsumeSubNet(...). Move and increase coverage in ConsumeNetAddr(...). (practicalswift) Pull request description: Add fuzzing harness for `BanMan`. See [`doc/fuzzing.md`](https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md) for information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the [Bitcoin Core fuzzing corpus repo](https://github.com/bitcoin-core/qa-assets). Happy fuzzing :) Top commit has no ACKs. Tree-SHA512: f4126c15bbb77638833367d73f58193c8f05d16bed0b1d6c33b39387d5b610ff34af78cd721adb51778062ce3ac5e79756d1c3895ef54c6c80c61dcf056e94ff
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/banman.cpp88
-rw-r--r--src/test/fuzz/netaddress.cpp30
-rw-r--r--src/test/fuzz/util.h36
3 files changed, 125 insertions, 29 deletions
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
new file mode 100644
index 0000000000..fc4a1d9261
--- /dev/null
+++ b/src/test/fuzz/banman.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) 2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <banman.h>
+#include <fs.h>
+#include <netaddress.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/system.h>
+
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <vector>
+
+namespace {
+int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ // Avoid signed integer overflow by capping to int32_t max:
+ // banman.cpp:137:73: runtime error: signed integer overflow: 1591700817 + 9223372036854775807 cannot be represented in type 'long'
+ return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());
+}
+} // namespace
+
+void initialize()
+{
+ InitializeFuzzingContext();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat";
+ fs::remove(banlist_file);
+ {
+ BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)};
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
+ case 0: {
+ ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 1: {
+ ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 2: {
+ ban_man.ClearBanned();
+ break;
+ }
+ case 4: {
+ ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ case 5: {
+ ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
+ break;
+ }
+ case 6: {
+ ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ case 7: {
+ ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
+ break;
+ }
+ case 8: {
+ banmap_t banmap;
+ ban_man.GetBanned(banmap);
+ break;
+ }
+ case 9: {
+ ban_man.DumpBanlist();
+ break;
+ }
+ case 11: {
+ ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ }
+ }
+ }
+ fs::remove(banlist_file);
+}
diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp
index d8d53566c7..2901c704f6 100644
--- a/src/test/fuzz/netaddress.cpp
+++ b/src/test/fuzz/netaddress.cpp
@@ -5,41 +5,13 @@
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <cassert>
#include <cstdint>
#include <netinet/in.h>
#include <vector>
-namespace {
-CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
- if (network == Network::NET_IPV4) {
- const in_addr v4_addr = {
- .s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
- return CNetAddr{v4_addr};
- } else if (network == Network::NET_IPV6) {
- if (fuzzed_data_provider.remaining_bytes() < 16) {
- return CNetAddr{};
- }
- in6_addr v6_addr = {};
- memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
- return CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
- } else if (network == Network::NET_INTERNAL) {
- CNetAddr net_addr;
- net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
- return net_addr;
- } else if (network == Network::NET_ONION) {
- CNetAddr net_addr;
- net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
- return net_addr;
- } else {
- assert(false);
- }
-}
-}; // namespace
-
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 1c1b2cd254..8cf91ef940 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -8,8 +8,11 @@
#include <amount.h>
#include <arith_uint256.h>
#include <attributes.h>
+#include <chainparamsbase.h>
#include <coins.h>
#include <consensus/consensus.h>
+#include <netaddress.h>
+#include <netbase.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/standard.h>
@@ -17,6 +20,7 @@
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/util/setup_common.h>
#include <txmempool.h>
#include <uint256.h>
#include <version.h>
@@ -228,4 +232,36 @@ NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataPro
return result;
}
+CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
+ CNetAddr net_addr;
+ if (network == Network::NET_IPV4) {
+ const in_addr v4_addr = {
+ .s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+ net_addr = CNetAddr{v4_addr};
+ } else if (network == Network::NET_IPV6) {
+ if (fuzzed_data_provider.remaining_bytes() >= 16) {
+ in6_addr v6_addr = {};
+ memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
+ net_addr = CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+ }
+ } else if (network == Network::NET_INTERNAL) {
+ net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
+ } else if (network == Network::NET_ONION) {
+ net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
+ }
+ return net_addr;
+}
+
+CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>()};
+}
+
+void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST)
+{
+ static const BasicTestingSetup basic_testing_setup{chain_name, {"-nodebuglogfile"}};
+}
+
#endif // BITCOIN_TEST_FUZZ_UTIL_H