Skip to content

Commit 7489776

Browse files
committed
Add asmap_direct fuzzer that tests Interpreter directly
1 parent 7cf97fd commit 7489776

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ FUZZ_TARGETS = \
99
test/fuzz/address_deserialize \
1010
test/fuzz/addrman_deserialize \
1111
test/fuzz/asmap \
12+
test/fuzz/asmap_direct \
1213
test/fuzz/banentry_deserialize \
1314
test/fuzz/base_encode_decode \
1415
test/fuzz/bech32 \
@@ -322,6 +323,12 @@ test_fuzz_asmap_LDADD = $(FUZZ_SUITE_LD_COMMON)
322323
test_fuzz_asmap_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
323324
test_fuzz_asmap_SOURCES = test/fuzz/asmap.cpp
324325

326+
test_fuzz_asmap_direct_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
327+
test_fuzz_asmap_direct_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
328+
test_fuzz_asmap_direct_LDADD = $(FUZZ_SUITE_LD_COMMON)
329+
test_fuzz_asmap_direct_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
330+
test_fuzz_asmap_direct_SOURCES = test/fuzz/asmap_direct.cpp
331+
325332
test_fuzz_banentry_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBANENTRY_DESERIALIZE=1
326333
test_fuzz_banentry_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
327334
test_fuzz_banentry_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/asmap_direct.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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 <util/asmap.h>
6+
#include <test/fuzz/fuzz.h>
7+
8+
#include <cstdint>
9+
#include <vector>
10+
11+
#include <assert.h>
12+
13+
void test_one_input(const std::vector<uint8_t>& buffer)
14+
{
15+
// Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
16+
bool have_sep = false;
17+
size_t sep_pos;
18+
for (size_t pos = 0; pos < buffer.size(); ++pos) {
19+
uint8_t x = buffer[pos];
20+
if ((x & 0xFE) == 0) continue;
21+
if (x == 0xFF) {
22+
if (have_sep) return;
23+
have_sep = true;
24+
sep_pos = pos;
25+
} else {
26+
return;
27+
}
28+
}
29+
if (!have_sep) return; // Needs exactly 1 separator
30+
if (buffer.size() - sep_pos - 1 > 128) return; // At most 128 bits in IP address
31+
32+
// Checks on asmap
33+
std::vector<bool> asmap(buffer.begin(), buffer.begin() + sep_pos);
34+
if (SanityCheckASMap(asmap, buffer.size() - 1 - sep_pos)) {
35+
// Verify that for valid asmaps, no prefix (except up to 7 zero padding bits) is valid.
36+
std::vector<bool> asmap_prefix = asmap;
37+
while (!asmap_prefix.empty() && asmap_prefix.size() + 7 > asmap.size() && asmap_prefix.back() == false) asmap_prefix.pop_back();
38+
while (!asmap_prefix.empty()) {
39+
asmap_prefix.pop_back();
40+
assert(!SanityCheckASMap(asmap_prefix, buffer.size() - 1 - sep_pos));
41+
}
42+
// No address input should trigger assertions in interpreter
43+
std::vector<bool> addr(buffer.begin() + sep_pos + 1, buffer.end());
44+
(void)Interpret(asmap, addr);
45+
}
46+
}

0 commit comments

Comments
 (0)