Skip to content

Commit 8682414

Browse files
author
MarcoFalke
committed
Merge #19247: tests: Add fuzzing harness for {Read,Write}{LE,BE}{16,32,64} (crypto/common.h)
cf5b8f6 tests: Add fuzzing harness for {Read,Write}{LE,BE}{16,32,64} (crypto/common.h) (practicalswift) 4a8181b tests: Add std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) (practicalswift) Pull request description: Add fuzzing harness for `{Read,Write}{LE,BE}{16,32,64}` (`crypto/common.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: ACK cf5b8f6 Tree-SHA512: 26412daa6987add1c721ad0348a5a894d68a646e724f328f2db6d9c9358a533481d8888b89d4b0743e9d1c11aa4e0e5341eb4c0d05a4da77b15ab75489327749
2 parents 85f7db2 + cf5b8f6 commit 8682414

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ FUZZ_TARGETS = \
3232
test/fuzz/checkqueue \
3333
test/fuzz/coins_deserialize \
3434
test/fuzz/coins_view \
35+
test/fuzz/crypto_common \
3536
test/fuzz/cuckoocache \
3637
test/fuzz/decode_tx \
3738
test/fuzz/descriptor_parse \
@@ -478,6 +479,12 @@ test_fuzz_coins_view_LDADD = $(FUZZ_SUITE_LD_COMMON)
478479
test_fuzz_coins_view_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
479480
test_fuzz_coins_view_SOURCES = test/fuzz/coins_view.cpp
480481

482+
test_fuzz_crypto_common_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
483+
test_fuzz_crypto_common_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
484+
test_fuzz_crypto_common_LDADD = $(FUZZ_SUITE_LD_COMMON)
485+
test_fuzz_crypto_common_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
486+
test_fuzz_crypto_common_SOURCES = test/fuzz/crypto_common.cpp
487+
481488
test_fuzz_cuckoocache_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
482489
test_fuzz_cuckoocache_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
483490
test_fuzz_cuckoocache_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/crypto_common.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 <crypto/common.h>
6+
#include <test/fuzz/FuzzedDataProvider.h>
7+
#include <test/fuzz/fuzz.h>
8+
#include <test/fuzz/util.h>
9+
10+
#include <array>
11+
#include <cassert>
12+
#include <cstdint>
13+
#include <cstring>
14+
#include <vector>
15+
16+
void test_one_input(const std::vector<uint8_t>& buffer)
17+
{
18+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
19+
const uint16_t random_u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
20+
const uint32_t random_u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
21+
const uint64_t random_u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
22+
const std::vector<uint8_t> random_bytes_2 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 2);
23+
const std::vector<uint8_t> random_bytes_4 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 4);
24+
const std::vector<uint8_t> random_bytes_8 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 8);
25+
26+
std::array<uint8_t, 2> writele16_arr;
27+
WriteLE16(writele16_arr.data(), random_u16);
28+
assert(ReadLE16(writele16_arr.data()) == random_u16);
29+
30+
std::array<uint8_t, 4> writele32_arr;
31+
WriteLE32(writele32_arr.data(), random_u32);
32+
assert(ReadLE32(writele32_arr.data()) == random_u32);
33+
34+
std::array<uint8_t, 8> writele64_arr;
35+
WriteLE64(writele64_arr.data(), random_u64);
36+
assert(ReadLE64(writele64_arr.data()) == random_u64);
37+
38+
std::array<uint8_t, 4> writebe32_arr;
39+
WriteBE32(writebe32_arr.data(), random_u32);
40+
assert(ReadBE32(writebe32_arr.data()) == random_u32);
41+
42+
std::array<uint8_t, 8> writebe64_arr;
43+
WriteBE64(writebe64_arr.data(), random_u64);
44+
assert(ReadBE64(writebe64_arr.data()) == random_u64);
45+
46+
const uint16_t readle16_result = ReadLE16(random_bytes_2.data());
47+
std::array<uint8_t, 2> readle16_arr;
48+
WriteLE16(readle16_arr.data(), readle16_result);
49+
assert(std::memcmp(random_bytes_2.data(), readle16_arr.data(), 2) == 0);
50+
51+
const uint32_t readle32_result = ReadLE32(random_bytes_4.data());
52+
std::array<uint8_t, 4> readle32_arr;
53+
WriteLE32(readle32_arr.data(), readle32_result);
54+
assert(std::memcmp(random_bytes_4.data(), readle32_arr.data(), 4) == 0);
55+
56+
const uint64_t readle64_result = ReadLE64(random_bytes_8.data());
57+
std::array<uint8_t, 8> readle64_arr;
58+
WriteLE64(readle64_arr.data(), readle64_result);
59+
assert(std::memcmp(random_bytes_8.data(), readle64_arr.data(), 8) == 0);
60+
61+
const uint32_t readbe32_result = ReadBE32(random_bytes_4.data());
62+
std::array<uint8_t, 4> readbe32_arr;
63+
WriteBE32(readbe32_arr.data(), readbe32_result);
64+
assert(std::memcmp(random_bytes_4.data(), readbe32_arr.data(), 4) == 0);
65+
66+
const uint64_t readbe64_result = ReadBE64(random_bytes_8.data());
67+
std::array<uint8_t, 8> readbe64_arr;
68+
WriteBE64(readbe64_arr.data(), readbe64_result);
69+
assert(std::memcmp(random_bytes_8.data(), readbe64_arr.data(), 8) == 0);
70+
}

src/test/fuzz/util.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,18 @@ NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsVie
214214
return false;
215215
}
216216

217+
/**
218+
* Returns a byte vector of specified size regardless of the number of remaining bytes available
219+
* from the fuzzer. Pads with zero value bytes if needed to achieve the specified size.
220+
*/
221+
NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
222+
{
223+
std::vector<uint8_t> result(length);
224+
const std::vector<uint8_t> random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(length);
225+
if (!random_bytes.empty()) {
226+
std::memcpy(result.data(), random_bytes.data(), random_bytes.size());
227+
}
228+
return result;
229+
}
230+
217231
#endif // BITCOIN_TEST_FUZZ_UTIL_H

0 commit comments

Comments
 (0)