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_POW_SERVER OFF CACHE BOOL "")
|
||||||
set (NANO_WARN_TO_ERR OFF CACHE BOOL "")
|
set (NANO_WARN_TO_ERR OFF CACHE BOOL "")
|
||||||
set (NANO_TIMED_LOCKS 0 CACHE STRING "")
|
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)
|
option (NANO_STACKTRACE_BACKTRACE "Use BOOST_STACKTRACE_USE_BACKTRACE in stacktraces, for POSIX" OFF)
|
||||||
if (NANO_STACKTRACE_BACKTRACE)
|
if (NANO_STACKTRACE_BACKTRACE)
|
||||||
|
|
@ -110,6 +111,11 @@ else ()
|
||||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||||
endif()
|
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 (CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86(_64)?)$")
|
||||||
if (NANO_SIMD_OPTIMIZATIONS OR RAIBLOCKS_SIMD_OPTIMIZATIONS OR ENABLE_AVX2)
|
if (NANO_SIMD_OPTIMIZATIONS OR RAIBLOCKS_SIMD_OPTIMIZATIONS OR ENABLE_AVX2)
|
||||||
add_compile_options(-msse4)
|
add_compile_options(-msse4)
|
||||||
|
|
@ -175,6 +181,9 @@ else ()
|
||||||
set (PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tsan_clang_blacklist")
|
set (PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tsan_clang_blacklist")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
if (NANO_FUZZER_TEST)
|
||||||
|
set (PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize=fuzzer-no-link")
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINK_FLAGS}" )
|
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/rpc)
|
||||||
add_subdirectory(nano/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 (NANO_TEST OR RAIBLOCKS_TEST)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(MSVC_VERSION)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
#ifndef NANO_FUZZER_TEST
|
||||||
assert (false);
|
assert (false);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (uniquer_a != nullptr)
|
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);
|
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 nano::work_value (nano::root const & root_a, uint64_t work_a)
|
||||||
{
|
{
|
||||||
uint64_t result;
|
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));
|
blake2b_final (&hash, reinterpret_cast<uint8_t *> (&result), sizeof (result));
|
||||||
return 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) :
|
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),
|
ticket (0),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue