aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-11-13 07:40:23 +0100
committerMarcoFalke <falke.marco@gmail.com>2020-11-13 07:40:35 +0100
commit28cb61646b29178dbdc0687670b685c30367347f (patch)
tree4288364acdf7a1c8b6bdc7b30113e450fae3f1d3
parent99fcc2b4778fa5e534f4cc5d6487bcaf3e840ac2 (diff)
parentd04a17a7907c57f7b570e1b9743fd63489bdad68 (diff)
Merge #19065: tests: Add fuzzing harness for CAddrMan
d04a17a7907c57f7b570e1b9743fd63489bdad68 fuzz: Use ConsumeRandomLengthBitVector(...) in src/test/fuzz/connman and src/test/fuzz/net (practicalswift) e6bb9fde851422808f5d9870782c394f74a1f400 tests: Add fuzzing harness for CAddrMan (practicalswift) Pull request description: Add fuzzing harness for `CAddrMan`. ~~Fill some fuzzing coverage gaps for functions in `addrdb.h`, `merkleblock.h` and `outputtype.h`.~~ 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 :) ACKs for top commit: MarcoFalke: review ACK d04a17a7907c57f7b570e1b9743fd63489bdad68 Tree-SHA512: a6b627e3a0cb51e3a8cb02ad0f19088fc0e965ca34ab110b68d5822d0ea7f473207ae312b49fb217cb6cf2f9f211d00bb69c83bac9f50d79c9ed1e157e85775d
-rw-r--r--src/Makefile.test.include7
-rw-r--r--src/test/fuzz/addrman.cpp119
-rw-r--r--src/test/fuzz/connman.cpp2
-rw-r--r--src/test/fuzz/net.cpp2
-rw-r--r--src/test/fuzz/util.h14
5 files changed, 142 insertions, 2 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 157b62cef5..9cc383c240 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -7,6 +7,7 @@ FUZZ_TARGETS = \
test/fuzz/addr_info_deserialize \
test/fuzz/addrdb \
test/fuzz/address_deserialize \
+ test/fuzz/addrman \
test/fuzz/addrman_deserialize \
test/fuzz/asmap \
test/fuzz/asmap_direct \
@@ -353,6 +354,12 @@ test_fuzz_address_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_address_deserialize_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
test_fuzz_address_deserialize_SOURCES = test/fuzz/deserialize.cpp
+test_fuzz_addrman_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
+test_fuzz_addrman_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_addrman_LDADD = $(FUZZ_SUITE_LD_COMMON)
+test_fuzz_addrman_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
+test_fuzz_addrman_SOURCES = test/fuzz/addrman.cpp
+
test_fuzz_addrman_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DADDRMAN_DESERIALIZE=1
test_fuzz_addrman_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_addrman_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
new file mode 100644
index 0000000000..0ceeea2d36
--- /dev/null
+++ b/src/test/fuzz/addrman.cpp
@@ -0,0 +1,119 @@
+// 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 <addrdb.h>
+#include <addrman.h>
+#include <chainparams.h>
+#include <merkleblock.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <time.h>
+#include <util/asmap.h>
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ SelectParams(CBaseChainParams::REGTEST);
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
+ CAddrMan addr_man;
+ if (fuzzed_data_provider.ConsumeBool()) {
+ addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (!SanityCheckASMap(addr_man.m_asmap)) {
+ addr_man.m_asmap.clear();
+ }
+ }
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
+ case 0: {
+ addr_man.Clear();
+ break;
+ }
+ case 1: {
+ addr_man.ResolveCollisions();
+ break;
+ }
+ case 2: {
+ (void)addr_man.SelectTriedCollision();
+ break;
+ }
+ case 3: {
+ (void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 4: {
+ (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ break;
+ }
+ case 5: {
+ const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_address && opt_net_addr) {
+ addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
+ }
+ break;
+ }
+ case 6: {
+ std::vector<CAddress> addresses;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ if (!opt_address) {
+ break;
+ }
+ addresses.push_back(*opt_address);
+ }
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_net_addr) {
+ addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
+ }
+ break;
+ }
+ case 7: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 8: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 9: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 10: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
+ }
+ break;
+ }
+ case 11: {
+ (void)addr_man.Check();
+ break;
+ }
+ }
+ }
+ (void)addr_man.size();
+ CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
+ data_stream << addr_man;
+}
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
index bb9d28a4ab..6521c3f3b2 100644
--- a/src/test/fuzz/connman.cpp
+++ b/src/test/fuzz/connman.cpp
@@ -117,7 +117,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
connman.RemoveAddedNode(random_string);
break;
case 24: {
- const std::vector<bool> asmap = ConsumeRandomLengthIntegralVector<bool>(fuzzed_data_provider, 512);
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (SanityCheckASMap(asmap)) {
connman.SetAsmap(asmap);
}
diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp
index 3818838765..c61d406291 100644
--- a/src/test/fuzz/net.cpp
+++ b/src/test/fuzz/net.cpp
@@ -63,7 +63,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
break;
}
case 3: {
- const std::vector<bool> asmap = ConsumeRandomLengthIntegralVector<bool>(fuzzed_data_provider, 128);
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (!SanityCheckASMap(asmap)) {
break;
}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index fec6e13e86..e99ed8d72d 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -11,6 +11,7 @@
#include <chainparamsbase.h>
#include <coins.h>
#include <consensus/consensus.h>
+#include <merkleblock.h>
#include <net.h>
#include <netaddress.h>
#include <netbase.h>
@@ -24,6 +25,7 @@
#include <test/util/setup_common.h>
#include <txmempool.h>
#include <uint256.h>
+#include <util/time.h>
#include <version.h>
#include <algorithm>
@@ -39,6 +41,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr
return {s.begin(), s.end()};
}
+NODISCARD inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+{
+ return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
+}
+
NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
@@ -89,6 +96,13 @@ NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider)
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
}
+NODISCARD inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:00Z");
+ static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
+ return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
+}
+
NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);