From 2ca632e5b44a8385989c8539cc4e30e60fdee16c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 25 Jan 2019 18:35:36 -0500 Subject: test: Build fuzz targets into seperate executables --- src/test/fuzz/fuzz.cpp | 77 +++++++++++++++ src/test/fuzz/fuzz.h | 17 ++++ src/test/test_bitcoin_fuzzy.cpp | 210 +++++----------------------------------- 3 files changed, 116 insertions(+), 188 deletions(-) create mode 100644 src/test/fuzz/fuzz.cpp create mode 100644 src/test/fuzz/fuzz.h (limited to 'src/test') diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp new file mode 100644 index 0000000000..0709da5563 --- /dev/null +++ b/src/test/fuzz/fuzz.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2009-2019 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 + +#include + +#include +#include + + +static bool read_stdin(std::vector& data) +{ + uint8_t buffer[1024]; + ssize_t length = 0; + while ((length = read(STDIN_FILENO, buffer, 1024)) > 0) { + data.insert(data.end(), buffer, buffer + length); + + if (data.size() > (1 << 20)) return false; + } + return length == 0; +} + +static void initialize() +{ + const static auto verify_handle = MakeUnique(); +} + +// This function is used by libFuzzer +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + test_one_input(std::vector(data, data + size)); + return 0; +} + +// This function is used by libFuzzer +extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) +{ + initialize(); + return 0; +} + +// Disabled under WIN32 due to clash with Cygwin's WinMain. +#ifndef WIN32 +// Declare main(...) "weak" to allow for libFuzzer linking. libFuzzer provides +// the main(...) function. +__attribute__((weak)) +#endif +int main(int argc, char **argv) +{ + initialize(); +#ifdef __AFL_INIT + // Enable AFL deferred forkserver mode. Requires compilation using + // afl-clang-fast++. See fuzzing.md for details. + __AFL_INIT(); +#endif + +#ifdef __AFL_LOOP + // Enable AFL persistent mode. Requires compilation using afl-clang-fast++. + // See fuzzing.md for details. + while (__AFL_LOOP(1000)) { + std::vector buffer; + if (!read_stdin(buffer)) { + continue; + } + test_one_input(buffer); + } +#else + std::vector buffer; + if (!read_stdin(buffer)) { + return 0; + } + test_one_input(buffer); +#endif + return 0; +} diff --git a/src/test/fuzz/fuzz.h b/src/test/fuzz/fuzz.h new file mode 100644 index 0000000000..ad62a5faf0 --- /dev/null +++ b/src/test/fuzz/fuzz.h @@ -0,0 +1,17 @@ +// Copyright (c) 2009-2019 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_FUZZ_H +#define BITCOIN_TEST_FUZZ_FUZZ_H + +#include +#include +#include + + +const std::function G_TRANSLATION_FUN = nullptr; + +void test_one_input(std::vector buffer); + +#endif // BITCOIN_TEST_FUZZ_FUZZ_H diff --git a/src/test/test_bitcoin_fuzzy.cpp b/src/test/test_bitcoin_fuzzy.cpp index 6588ac38ec..859fba0bdc 100644 --- a/src/test/test_bitcoin_fuzzy.cpp +++ b/src/test/test_bitcoin_fuzzy.cpp @@ -2,10 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#if defined(HAVE_CONFIG_H) -#include -#endif - #include #include #include @@ -28,54 +24,10 @@ #include #include -const std::function G_TRANSLATION_FUN = nullptr; - -enum TEST_ID { - CBLOCK_DESERIALIZE=0, - CTRANSACTION_DESERIALIZE, - CBLOCKLOCATOR_DESERIALIZE, - CBLOCKMERKLEROOT, - CADDRMAN_DESERIALIZE, - CBLOCKHEADER_DESERIALIZE, - CBANENTRY_DESERIALIZE, - CTXUNDO_DESERIALIZE, - CBLOCKUNDO_DESERIALIZE, - CCOINS_DESERIALIZE, - CNETADDR_DESERIALIZE, - CSERVICE_DESERIALIZE, - CMESSAGEHEADER_DESERIALIZE, - CADDRESS_DESERIALIZE, - CINV_DESERIALIZE, - CBLOOMFILTER_DESERIALIZE, - CDISKBLOCKINDEX_DESERIALIZE, - CTXOUTCOMPRESSOR_DESERIALIZE, - BLOCKTRANSACTIONS_DESERIALIZE, - BLOCKTRANSACTIONSREQUEST_DESERIALIZE, - TEST_ID_END -}; - -static bool read_stdin(std::vector& data) -{ - uint8_t buffer[1024]; - ssize_t length = 0; - while ((length = read(STDIN_FILENO, buffer, 1024)) > 0) { - data.insert(data.end(), buffer, buffer + length); - - if (data.size() > (1 << 20)) return false; - } - return length == 0; -} +#include void test_one_input(std::vector buffer) { - if (buffer.size() < sizeof(uint32_t)) return; - - uint32_t test_id = 0xffffffff; - memcpy(&test_id, buffer.data(), sizeof(uint32_t)); - buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t)); - - if (test_id >= TEST_ID_END) return; - CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); try { int nVersion; @@ -85,35 +37,24 @@ void test_one_input(std::vector buffer) return; } - switch(test_id) { - case CBLOCK_DESERIALIZE: - { +#if BLOCK_DESERIALIZE try { CBlock block; ds >> block; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CTRANSACTION_DESERIALIZE: - { +#elif TRANSACTION_DESERIALIZE try { CTransaction tx(deserialize, ds); } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBLOCKLOCATOR_DESERIALIZE: - { +#elif BLOCKLOCATOR_DESERIALIZE try { CBlockLocator bl; ds >> bl; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBLOCKMERKLEROOT: - { +#elif BLOCKMERKLEROOT try { CBlock block; @@ -121,82 +62,55 @@ void test_one_input(std::vector buffer) bool mutated; BlockMerkleRoot(block, &mutated); } catch (const std::ios_base::failure& e) {return;} - break; - } - case CADDRMAN_DESERIALIZE: - { +#elif ADDRMAN_DESERIALIZE try { CAddrMan am; ds >> am; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBLOCKHEADER_DESERIALIZE: - { +#elif BLOCKHEADER_DESERIALIZE try { CBlockHeader bh; ds >> bh; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBANENTRY_DESERIALIZE: - { +#elif BANENTRY_DESERIALIZE try { CBanEntry be; ds >> be; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CTXUNDO_DESERIALIZE: - { +#elif TXUNDO_DESERIALIZE try { CTxUndo tu; ds >> tu; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBLOCKUNDO_DESERIALIZE: - { +#elif BLOCKUNDO_DESERIALIZE try { CBlockUndo bu; ds >> bu; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CCOINS_DESERIALIZE: - { +#elif COINS_DESERIALIZE try { Coin coin; ds >> coin; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CNETADDR_DESERIALIZE: - { +#elif NETADDR_DESERIALIZE try { CNetAddr na; ds >> na; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CSERVICE_DESERIALIZE: - { +#elif SERVICE_DESERIALIZE try { CService s; ds >> s; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CMESSAGEHEADER_DESERIALIZE: - { +#elif MESSAGEHEADER_DESERIALIZE CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00}; try { @@ -204,130 +118,50 @@ void test_one_input(std::vector buffer) ds >> mh; if (!mh.IsValid(pchMessageStart)) {return;} } catch (const std::ios_base::failure& e) {return;} - break; - } - case CADDRESS_DESERIALIZE: - { +#elif ADDRESS_DESERIALIZE try { CAddress a; ds >> a; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CINV_DESERIALIZE: - { +#elif INV_DESERIALIZE try { CInv i; ds >> i; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CBLOOMFILTER_DESERIALIZE: - { +#elif BLOOMFILTER_DESERIALIZE try { CBloomFilter bf; ds >> bf; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CDISKBLOCKINDEX_DESERIALIZE: - { +#elif DISKBLOCKINDEX_DESERIALIZE try { CDiskBlockIndex dbi; ds >> dbi; } catch (const std::ios_base::failure& e) {return;} - break; - } - case CTXOUTCOMPRESSOR_DESERIALIZE: - { +#elif TXOUTCOMPRESSOR_DESERIALIZE CTxOut to; CTxOutCompressor toc(to); try { ds >> toc; } catch (const std::ios_base::failure& e) {return;} - - break; - } - case BLOCKTRANSACTIONS_DESERIALIZE: - { +#elif BLOCKTRANSACTIONS_DESERIALIZE try { BlockTransactions bt; ds >> bt; } catch (const std::ios_base::failure& e) {return;} - - break; - } - case BLOCKTRANSACTIONSREQUEST_DESERIALIZE: - { +#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE try { BlockTransactionsRequest btr; ds >> btr; } catch (const std::ios_base::failure& e) {return;} - - break; - } - default: - return; - } - return; -} - -void initialize() -{ - const static auto verify_handle = MakeUnique(); -} - -// This function is used by libFuzzer -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - test_one_input(std::vector(data, data + size)); - return 0; -} - -// This function is used by libFuzzer -extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) -{ - initialize(); - return 0; -} - -// Disabled under WIN32 due to clash with Cygwin's WinMain. -#ifndef WIN32 -// Declare main(...) "weak" to allow for libFuzzer linking. libFuzzer provides -// the main(...) function. -__attribute__((weak)) -#endif -int main(int argc, char **argv) -{ - initialize(); -#ifdef __AFL_INIT - // Enable AFL deferred forkserver mode. Requires compilation using - // afl-clang-fast++. See fuzzing.md for details. - __AFL_INIT(); -#endif - -#ifdef __AFL_LOOP - // Enable AFL persistent mode. Requires compilation using afl-clang-fast++. - // See fuzzing.md for details. - while (__AFL_LOOP(1000)) { - std::vector buffer; - if (!read_stdin(buffer)) { - continue; - } - test_one_input(buffer); - } #else - std::vector buffer; - if (!read_stdin(buffer)) { - return 0; - } - test_one_input(buffer); +#error Need at least one fuzz target to compile #endif } -- cgit v1.2.3