Buffer parser fuzzing (#2496)
* Buffer parser fuzzing * add clang-6 with libfuzzer base Dockerfile Co-authored-by: Russel Waters <vaelstrom@gmail.com>
This commit is contained in:
parent
a752debfc7
commit
d41d4c5633
6 changed files with 132 additions and 0 deletions
|
@ -38,6 +38,7 @@ set (NANO_ROCKSDB OFF CACHE BOOL "")
|
|||
set (NANO_POW_SERVER OFF CACHE BOOL "")
|
||||
set (NANO_WARN_TO_ERR OFF CACHE BOOL "")
|
||||
set (NANO_TIMED_LOCKS 0 CACHE STRING "")
|
||||
set (NANO_FUZZER_TEST OFF CACHE BOOL "")
|
||||
|
||||
option (NANO_STACKTRACE_BACKTRACE "Use BOOST_STACKTRACE_USE_BACKTRACE in stacktraces, for POSIX" OFF)
|
||||
if (NANO_STACKTRACE_BACKTRACE)
|
||||
|
@ -110,6 +111,11 @@ else ()
|
|||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
endif()
|
||||
|
||||
if (NANO_FUZZER_TEST)
|
||||
add_compile_options (-fsanitize=fuzzer-no-link -fno-omit-frame-pointer)
|
||||
add_definitions (-DNANO_FUZZER_TEST)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86(_64)?)$")
|
||||
if (NANO_SIMD_OPTIMIZATIONS OR RAIBLOCKS_SIMD_OPTIMIZATIONS OR ENABLE_AVX2)
|
||||
add_compile_options(-msse4)
|
||||
|
@ -175,6 +181,9 @@ else ()
|
|||
set (PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tsan_clang_blacklist")
|
||||
endif()
|
||||
endif()
|
||||
if (NANO_FUZZER_TEST)
|
||||
set (PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize=fuzzer-no-link")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINK_FLAGS}" )
|
||||
|
@ -352,6 +361,14 @@ add_subdirectory(nano/nano_node)
|
|||
add_subdirectory(nano/rpc)
|
||||
add_subdirectory(nano/nano_rpc)
|
||||
|
||||
if (NANO_FUZZER_TEST)
|
||||
if (NOT WIN32)
|
||||
add_subdirectory (nano/fuzzer_test)
|
||||
else ()
|
||||
message (WARNING "Fuzzing is not supported on Windows")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NANO_TEST OR RAIBLOCKS_TEST)
|
||||
if(WIN32)
|
||||
if(MSVC_VERSION)
|
||||
|
|
22
docker/ci/Dockerfile-clang-6
Normal file
22
docker/ci/Dockerfile-clang-6
Normal file
|
@ -0,0 +1,22 @@
|
|||
FROM nanocurrency/nano-env:base
|
||||
|
||||
RUN apt-get update && apt-get install -yqq software-properties-common && \
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
|
||||
apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main" && \
|
||||
apt-get update -qq && apt-get install -yqq \
|
||||
clang-6.0 lldb-6.0 libfuzzer-6.0-dev git
|
||||
|
||||
ADD util/build_prep/fetch_rocksdb.sh fetch_rocksdb.sh
|
||||
RUN ./fetch_rocksdb.sh
|
||||
|
||||
ENV CXX=/usr/bin/clang++
|
||||
ENV CC=/usr/bin/clang
|
||||
RUN ln -s /usr/bin/clang-6.0 /usr/bin/clang
|
||||
RUN ln -s /usr/bin/clang++-6.0 /usr/bin/clang++
|
||||
RUN update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
ENV BOOST_ROOT=/tmp/boost
|
||||
|
||||
ADD util/build_prep/bootstrap_boost.sh bootstrap_boost.sh
|
||||
|
||||
RUN ./bootstrap_boost.sh -m -c -B 1.70
|
3
nano/fuzzer_test/CMakeLists.txt
Normal file
3
nano/fuzzer_test/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
add_executable(fuzz_buffer fuzz_buffer.cpp)
|
||||
target_compile_options(fuzz_buffer PUBLIC -fsanitize=fuzzer)
|
||||
target_link_libraries(fuzz_buffer PRIVATE -fsanitize=fuzzer node)
|
75
nano/fuzzer_test/fuzz_buffer.cpp
Normal file
75
nano/fuzzer_test/fuzz_buffer.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include <nano/core_test/testutil.hpp>
|
||||
#include <nano/node/common.hpp>
|
||||
#include <nano/node/testing.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
void force_nano_test_network ();
|
||||
}
|
||||
namespace
|
||||
{
|
||||
std::shared_ptr<nano::system> system0;
|
||||
std::shared_ptr<nano::node> node0;
|
||||
|
||||
class fuzz_visitor : public nano::message_visitor
|
||||
{
|
||||
public:
|
||||
virtual void keepalive (nano::keepalive const &) override
|
||||
{
|
||||
}
|
||||
virtual void publish (nano::publish const &) override
|
||||
{
|
||||
}
|
||||
virtual void confirm_req (nano::confirm_req const &) override
|
||||
{
|
||||
}
|
||||
virtual void confirm_ack (nano::confirm_ack const &) override
|
||||
{
|
||||
}
|
||||
virtual void bulk_pull (nano::bulk_pull const &) override
|
||||
{
|
||||
}
|
||||
virtual void bulk_pull_account (nano::bulk_pull_account const &) override
|
||||
{
|
||||
}
|
||||
virtual void bulk_push (nano::bulk_push const &) override
|
||||
{
|
||||
}
|
||||
virtual void frontier_req (nano::frontier_req const &) override
|
||||
{
|
||||
}
|
||||
virtual void node_id_handshake (nano::node_id_handshake const &) override
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** Fuzz live message parsing. This covers parsing and block/vote uniquing. */
|
||||
void fuzz_message_parser (const uint8_t * Data, size_t Size)
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
nano::force_nano_test_network ();
|
||||
initialized = true;
|
||||
system0 = std::make_shared<nano::system> (1);
|
||||
node0 = system0->nodes[0];
|
||||
}
|
||||
|
||||
fuzz_visitor visitor;
|
||||
nano::message_parser parser (node0->block_uniquer, node0->vote_uniquer, visitor, node0->work);
|
||||
parser.deserialize_buffer (Data, Size);
|
||||
}
|
||||
|
||||
/** Fuzzer entry point */
|
||||
extern "C" int LLVMFuzzerTestOneInput (const uint8_t * Data, size_t Size)
|
||||
{
|
||||
fuzz_message_parser (Data, Size);
|
||||
return 0;
|
||||
}
|
|
@ -1313,7 +1313,9 @@ std::shared_ptr<nano::block> nano::deserialize_block (nano::stream & stream_a, n
|
|||
break;
|
||||
}
|
||||
default:
|
||||
#ifndef NANO_FUZZER_TEST
|
||||
assert (false);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (uniquer_a != nullptr)
|
||||
|
|
|
@ -22,6 +22,7 @@ bool nano::work_validate (nano::block const & block_a, uint64_t * difficulty_a)
|
|||
return work_validate (block_a.root (), block_a.block_work (), difficulty_a);
|
||||
}
|
||||
|
||||
#ifndef NANO_FUZZER_TEST
|
||||
uint64_t nano::work_value (nano::root const & root_a, uint64_t work_a)
|
||||
{
|
||||
uint64_t result;
|
||||
|
@ -32,6 +33,18 @@ uint64_t nano::work_value (nano::root const & root_a, uint64_t work_a)
|
|||
blake2b_final (&hash, reinterpret_cast<uint8_t *> (&result), sizeof (result));
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
uint64_t nano::work_value (nano::root const & root_a, uint64_t work_a)
|
||||
{
|
||||
static nano::network_constants network_constants;
|
||||
if (!network_constants.is_test_network ())
|
||||
{
|
||||
assert (false);
|
||||
std::exit (1);
|
||||
}
|
||||
return network_constants.publish_threshold + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
nano::work_pool::work_pool (unsigned max_threads_a, std::chrono::nanoseconds pow_rate_limiter_a, std::function<boost::optional<uint64_t> (nano::root const &, uint64_t, std::atomic<int> &)> opencl_a) :
|
||||
ticket (0),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue