Skip to content

Commit c3b4715

Browse files
author
MarcoFalke
committed
Merge #18206: tests: Add fuzzing harness for bloom filter classes (CBloomFilter + CRollingBloomFilter)
eabbbe4 tests: Add fuzzing harness for rolling bloom filter class CRollingBloomFilter (practicalswift) 2a6a6ea tests: Add fuzzing harness for bloom filter class CBloomFilter (practicalswift) Pull request description: Add fuzzing harness for bloom filter classes (`CBloomFilter` + `CRollingBloomFilter`). Test this PR using: ``` $ make distclean $ ./autogen.sh $ CC=clang CXX=clang++ ./configure --enable-fuzz \ --with-sanitizers=address,fuzzer,undefined $ make $ src/test/fuzz/bloom_filter … $ src/test/fuzz/rolling_bloom_filter … ``` ACKs for top commit: MarcoFalke: ACK eabbbe4 🤞 Tree-SHA512: 765d30bc52e3eb04dbd4d2b8f517387aa61312416e8fea3767250ef5c074e08641699019ee4600d42303de32f98379c20bfc0c0e60cb5154d0338088c1d29cb6
2 parents 31c0006 + eabbbe4 commit c3b4715

File tree

5 files changed

+187
-1
lines changed

5 files changed

+187
-1
lines changed

src/Makefile.test.include

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ FUZZ_TARGETS = \
2222
test/fuzz/blocktransactions_deserialize \
2323
test/fuzz/blocktransactionsrequest_deserialize \
2424
test/fuzz/blockundo_deserialize \
25+
test/fuzz/bloom_filter \
2526
test/fuzz/bloomfilter_deserialize \
2627
test/fuzz/coins_deserialize \
2728
test/fuzz/decode_tx \
@@ -50,6 +51,7 @@ FUZZ_TARGETS = \
5051
test/fuzz/psbt_input_deserialize \
5152
test/fuzz/psbt_output_deserialize \
5253
test/fuzz/pub_key_deserialize \
54+
test/fuzz/rolling_bloom_filter \
5355
test/fuzz/script \
5456
test/fuzz/script_deserialize \
5557
test/fuzz/script_flags \
@@ -96,7 +98,8 @@ BITCOIN_TEST_SUITE = \
9698
FUZZ_SUITE = \
9799
test/fuzz/fuzz.cpp \
98100
test/fuzz/fuzz.h \
99-
test/fuzz/FuzzedDataProvider.h
101+
test/fuzz/FuzzedDataProvider.h \
102+
test/fuzz/util.h
100103

101104
FUZZ_SUITE_LD_COMMON = \
102105
$(LIBBITCOIN_SERVER) \
@@ -347,6 +350,12 @@ test_fuzz_blockundo_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
347350
test_fuzz_blockundo_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
348351
test_fuzz_blockundo_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
349352

353+
test_fuzz_bloom_filter_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
354+
test_fuzz_bloom_filter_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
355+
test_fuzz_bloom_filter_LDADD = $(FUZZ_SUITE_LD_COMMON)
356+
test_fuzz_bloom_filter_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
357+
test_fuzz_bloom_filter_SOURCES = $(FUZZ_SUITE) test/fuzz/bloom_filter.cpp
358+
350359
test_fuzz_bloomfilter_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBLOOMFILTER_DESERIALIZE=1
351360
test_fuzz_bloomfilter_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
352361
test_fuzz_bloomfilter_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
@@ -515,6 +524,12 @@ test_fuzz_pub_key_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
515524
test_fuzz_pub_key_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
516525
test_fuzz_pub_key_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
517526

527+
test_fuzz_rolling_bloom_filter_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
528+
test_fuzz_rolling_bloom_filter_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
529+
test_fuzz_rolling_bloom_filter_LDADD = $(FUZZ_SUITE_LD_COMMON)
530+
test_fuzz_rolling_bloom_filter_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
531+
test_fuzz_rolling_bloom_filter_SOURCES = $(FUZZ_SUITE) test/fuzz/rolling_bloom_filter.cpp
532+
518533
test_fuzz_script_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
519534
test_fuzz_script_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
520535
test_fuzz_script_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/bloom_filter.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) 2020 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 <bloom.h>
6+
#include <optional.h>
7+
#include <primitives/transaction.h>
8+
#include <test/fuzz/FuzzedDataProvider.h>
9+
#include <test/fuzz/fuzz.h>
10+
#include <test/fuzz/util.h>
11+
#include <uint256.h>
12+
13+
#include <cassert>
14+
#include <cstdint>
15+
#include <string>
16+
#include <vector>
17+
18+
void test_one_input(const std::vector<uint8_t>& buffer)
19+
{
20+
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
21+
22+
CBloomFilter bloom_filter{
23+
fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, 10000000),
24+
1.0 / fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, std::numeric_limits<unsigned int>::max()),
25+
fuzzed_data_provider.ConsumeIntegral<unsigned int>(),
26+
static_cast<unsigned char>(fuzzed_data_provider.PickValueInArray({BLOOM_UPDATE_NONE, BLOOM_UPDATE_ALL, BLOOM_UPDATE_P2PUBKEY_ONLY, BLOOM_UPDATE_MASK}))};
27+
while (fuzzed_data_provider.remaining_bytes() > 0) {
28+
switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 6)) {
29+
case 0: {
30+
const std::vector<unsigned char>& b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
31+
(void)bloom_filter.contains(b);
32+
bloom_filter.insert(b);
33+
const bool present = bloom_filter.contains(b);
34+
assert(present);
35+
break;
36+
}
37+
case 1: {
38+
const Optional<COutPoint> out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
39+
if (!out_point) {
40+
break;
41+
}
42+
(void)bloom_filter.contains(*out_point);
43+
bloom_filter.insert(*out_point);
44+
const bool present = bloom_filter.contains(*out_point);
45+
assert(present);
46+
break;
47+
}
48+
case 2: {
49+
const Optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
50+
if (!u256) {
51+
break;
52+
}
53+
(void)bloom_filter.contains(*u256);
54+
bloom_filter.insert(*u256);
55+
const bool present = bloom_filter.contains(*u256);
56+
assert(present);
57+
break;
58+
}
59+
case 3:
60+
bloom_filter.clear();
61+
break;
62+
case 4:
63+
bloom_filter.reset(fuzzed_data_provider.ConsumeIntegral<unsigned int>());
64+
break;
65+
case 5: {
66+
const Optional<CMutableTransaction> mut_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
67+
if (!mut_tx) {
68+
break;
69+
}
70+
const CTransaction tx{*mut_tx};
71+
(void)bloom_filter.IsRelevantAndUpdate(tx);
72+
break;
73+
}
74+
case 6:
75+
bloom_filter.UpdateEmptyFull();
76+
break;
77+
}
78+
(void)bloom_filter.IsWithinSizeConstraints();
79+
}
80+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2020 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 <bloom.h>
6+
#include <optional.h>
7+
#include <test/fuzz/FuzzedDataProvider.h>
8+
#include <test/fuzz/fuzz.h>
9+
#include <test/fuzz/util.h>
10+
#include <uint256.h>
11+
12+
#include <cassert>
13+
#include <cstdint>
14+
#include <string>
15+
#include <vector>
16+
17+
void test_one_input(const std::vector<uint8_t>& buffer)
18+
{
19+
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
20+
21+
CRollingBloomFilter rolling_bloom_filter{
22+
fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, 1000),
23+
0.999 / fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, std::numeric_limits<unsigned int>::max())};
24+
while (fuzzed_data_provider.remaining_bytes() > 0) {
25+
switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 2)) {
26+
case 0: {
27+
const std::vector<unsigned char>& b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
28+
(void)rolling_bloom_filter.contains(b);
29+
rolling_bloom_filter.insert(b);
30+
const bool present = rolling_bloom_filter.contains(b);
31+
assert(present);
32+
break;
33+
}
34+
case 1: {
35+
const Optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
36+
if (!u256) {
37+
break;
38+
}
39+
(void)rolling_bloom_filter.contains(*u256);
40+
rolling_bloom_filter.insert(*u256);
41+
const bool present = rolling_bloom_filter.contains(*u256);
42+
assert(present);
43+
break;
44+
}
45+
case 2:
46+
rolling_bloom_filter.reset();
47+
break;
48+
}
49+
}
50+
}

src/test/fuzz/util.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2009-2019 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+
#ifndef BITCOIN_TEST_FUZZ_UTIL_H
6+
#define BITCOIN_TEST_FUZZ_UTIL_H
7+
8+
#include <attributes.h>
9+
#include <optional.h>
10+
#include <serialize.h>
11+
#include <streams.h>
12+
#include <test/fuzz/FuzzedDataProvider.h>
13+
#include <version.h>
14+
15+
#include <cstdint>
16+
#include <string>
17+
#include <vector>
18+
19+
NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, size_t max_length = 4096) noexcept
20+
{
21+
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length);
22+
return {s.begin(), s.end()};
23+
}
24+
25+
template <typename T>
26+
NODISCARD inline Optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, size_t max_length = 4096) noexcept
27+
{
28+
const std::vector<uint8_t>& buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
29+
CDataStream ds{buffer, SER_NETWORK, INIT_PROTO_VERSION};
30+
T obj;
31+
try {
32+
ds >> obj;
33+
} catch (const std::ios_base::failure&) {
34+
return nullopt;
35+
}
36+
return obj;
37+
}
38+
39+
#endif // BITCOIN_TEST_FUZZ_UTIL_H

test/fuzz/test_runner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"block_file_info_deserialize",
2222
"block_filter_deserialize",
2323
"block_header_and_short_txids_deserialize",
24+
"bloom_filter",
2425
"decode_tx",
2526
"fee_rate_deserialize",
2627
"flat_file_pos_deserialize",
@@ -39,6 +40,7 @@
3940
"psbt_input_deserialize",
4041
"psbt_output_deserialize",
4142
"pub_key_deserialize",
43+
"rolling_bloom_filter",
4244
"script_deserialize",
4345
"strprintf",
4446
"sub_net_deserialize",

0 commit comments

Comments
 (0)