Merge bitcoin/bitcoin#26497: fuzz: Make ConsumeNetAddr always produce valid onion addresses

0eeb9b0442 [fuzz] Move ConsumeNetAddr to fuzz/util/net.h (dergoegge)
291c8697d4 [fuzz] Make ConsumeNetAddr produce valid onion addresses (dergoegge)
c9ba3f836e [netaddress] Make OnionToString public (dergoegge)

Pull request description:

  The chance that the fuzzer is able to guess a valid onion address is probably slim, as they are Base32 encoded and include a checksum.  Right now, any target using `ConsumeNetAddr` would have a hard time uncovering bugs that require valid onion addresses as input.

  This PR makes `ConsumeNetAddr` produce valid onion addresses by using the 32 bytes given by the fuzzer as the pubkey for the onion address and forming a valid address according to the torv3 spec.

ACKs for top commit:
  vasild:
    ACK 0eeb9b0442
  brunoerg:
    ACK 0eeb9b0442

Tree-SHA512: 7c687a4d12f9659559be8f0c3cd4265167d1261d419cfd3d503fd7c7f207cc0db745220f02fb1737e4a5700ea7429311cfc0b42e6c15968ce6a85f8813c7e1d8
This commit is contained in:
MacroFake 2022-11-21 14:35:13 +01:00
commit 0968c51401
No known key found for this signature in database
GPG Key ID: CE2B75697E69A548
12 changed files with 63 additions and 28 deletions

View File

@ -11,7 +11,8 @@ TEST_FUZZ_H = \
test/fuzz/fuzz.h \
test/fuzz/FuzzedDataProvider.h \
test/fuzz/util.h \
test/fuzz/util/mempool.h
test/fuzz/util/mempool.h \
test/fuzz/util/net.h
libtest_fuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS)
libtest_fuzz_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@ -19,4 +20,5 @@ libtest_fuzz_a_SOURCES = \
test/fuzz/fuzz.cpp \
test/fuzz/util.cpp \
test/fuzz/util/mempool.cpp \
test/fuzz/util/net.cpp \
$(TEST_FUZZ_H)

View File

@ -588,7 +588,7 @@ static std::string IPv6ToString(Span<const uint8_t> a, uint32_t scope_id)
return r;
}
static std::string OnionToString(Span<const uint8_t> addr)
std::string OnionToString(Span<const uint8_t> addr)
{
uint8_t checksum[torv3::CHECKSUM_LEN];
torv3::Checksum(addr, checksum);

View File

@ -111,6 +111,8 @@ static constexpr size_t ADDR_INTERNAL_SIZE = 10;
/// SAM 3.1 and earlier do not support specifying ports and force the port to 0.
static constexpr uint16_t I2P_SAM31_PORT{0};
std::string OnionToString(Span<const uint8_t> addr);
/**
* Network address.
*/

View File

@ -11,6 +11,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <time.h>
#include <util/asmap.h>

View File

@ -8,6 +8,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <util/readwritefile.h>
#include <util/system.h>

View File

@ -11,6 +11,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
#include <util/system.h>
#include <util/translation.h>

View File

@ -5,7 +5,7 @@
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <cassert>
#include <cstdint>

View File

@ -6,7 +6,7 @@
#include <netbase.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <cstdint>
#include <string>

View File

@ -4,6 +4,7 @@
#include <consensus/amount.h>
#include <net_processing.h>
#include <netaddress.h>
#include <netmessagemaker.h>
#include <pubkey.h>
#include <test/fuzz/util.h>
@ -507,28 +508,6 @@ bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) n
return false;
}
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) {
in_addr v4_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;
}
CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};

View File

@ -22,6 +22,7 @@
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util/net.h>
#include <test/util/net.h>
#include <uint256.h>
#include <version.h>
@ -283,8 +284,6 @@ inline void SetFuzzedErrNo(FuzzedDataProvider& fuzzed_data_provider) noexcept
return result;
}
CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept;
inline CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint8_t>()};

View File

@ -0,0 +1,36 @@
// Copyright (c) 2009-2021 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 <compat/compat.h>
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <util/strencodings.h>
#include <cstdint>
#include <vector>
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) {
in_addr v4_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) {
auto pub_key{fuzzed_data_provider.ConsumeBytes<uint8_t>(ADDR_TORV3_SIZE)};
pub_key.resize(ADDR_TORV3_SIZE);
const bool ok{net_addr.SetSpecial(OnionToString(pub_key))};
assert(ok);
}
return net_addr;
}

14
src/test/fuzz/util/net.h Normal file
View File

@ -0,0 +1,14 @@
// Copyright (c) 2009-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TEST_FUZZ_UTIL_NET_H
#define BITCOIN_TEST_FUZZ_UTIL_NET_H
#include <netaddress.h>
class FuzzedDataProvider;
CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept;
#endif // BITCOIN_TEST_FUZZ_UTIL_NET_H