Add the CMake integration for the fuzzing tool
This commit is contained in:
parent
3162a30858
commit
5fb19f9856
@ -48,6 +48,8 @@ option(JSON_Install "Install CMake targets during install
|
||||
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." ON)
|
||||
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
||||
|
||||
option(JSON_BuildFuzzers "Build fuzz testing binaries. Requires JSON_BuildTests=ON." OFF)
|
||||
|
||||
if (JSON_CI)
|
||||
include(ci)
|
||||
endif ()
|
||||
@ -145,7 +147,7 @@ CONFIGURE_FILE(
|
||||
|
||||
##
|
||||
## TESTS
|
||||
## create and configure the unit test target
|
||||
## create and configure the unit test target; build fuzzers, if enabled
|
||||
##
|
||||
if (JSON_BuildTests)
|
||||
include(CTest)
|
||||
|
||||
@ -172,3 +172,11 @@ add_subdirectory(cmake_add_subdirectory)
|
||||
add_subdirectory(cmake_fetch_content)
|
||||
add_subdirectory(cmake_fetch_content2)
|
||||
add_subdirectory(cmake_target_include_directories)
|
||||
|
||||
#############################################################################
|
||||
# fuzz testing
|
||||
#############################################################################
|
||||
|
||||
if(JSON_BuildFuzzers)
|
||||
add_subdirectory(fuzz)
|
||||
endif()
|
||||
|
||||
104
tests/fuzz/CMakeLists.txt
Normal file
104
tests/fuzz/CMakeLists.txt
Normal file
@ -0,0 +1,104 @@
|
||||
set(JSON_FUZZ_ENGINE "afl++" CACHE STRING "The engine to use for fuzz testing.")
|
||||
set(JSON_FUZZ_TARGETS "json;bjdata;bson;cbor;msgpack;ubjson" CACHE STRING "List of targets/formats to fuzz test.")
|
||||
set(JSON_FUZZ_SANITIZERS "asan+cfisan+lsan+ubsan;msan" CACHE STRING "List of sanitizers/combinations of sanitizers to build fuzzers for.")
|
||||
set(JSON_FUZZ_CORPUS_MAX_SIZE "5k" CACHE STRING "Maximum file size for corpus data.")
|
||||
option(JSON_FUZZ_MINIMIZE_CORPUS "Minimize the corpa generated from test data." ON)
|
||||
set(JSON_FUZZ_TEMP_DIR "" CACHE PATH "Path to temporary directory. Should be on a tmpfs or equivalent (AFL++).")
|
||||
set(JSON_FUZZ_NUM_JOBS 8 CACHE STRING "Number of parallel fuzzing jobs.")
|
||||
set(JSON_FUZZ_AFL_DIR "" CACHE PATH "Path to AFL++.")
|
||||
set(JSON_FUZZ_AFL_INSTRUMENTATIONS "laf-intel;complog" CACHE STRING "List of AFL++ instrumentations to build fuzzers for.")
|
||||
|
||||
option(JSON_FUZZ_AFL_EXIT_WHEN_DONE "Exit fuzzer when no new paths have been discovered for a while." ON)
|
||||
|
||||
set(JSON_FUZZ_MAX_TIME "" ON)
|
||||
|
||||
include(fuzz)
|
||||
|
||||
# find_program() requires permission to execute but not to read
|
||||
cmake_policy(SET CMP0109 NEW)
|
||||
|
||||
#############################################################################
|
||||
# validate settings
|
||||
#############################################################################
|
||||
|
||||
# check fuzz engine
|
||||
string(TOLOWER "${JSON_FUZZ_ENGINE}" fuzz_engine)
|
||||
if(NOT "${fuzz_engine}" STREQUAL "afl++")
|
||||
message(FATAL_ERROR "Unsupoorted fuzz engine: ${fuzz_engine}")
|
||||
endif()
|
||||
set(JSON_FUZZ_ENGINE "${fuzz_engine}" CACHE STRING "" FORCE)
|
||||
|
||||
if(${JSON_FUZZ_ENGINE} STREQUAL afl++)
|
||||
# find compiler
|
||||
find_program (JSON_FUZZ_CXX_COMPILER
|
||||
NAMES afl-clang-lto++ afl-clang-fast++
|
||||
DOC "AFL++ C++ compiler" REQUIRED)
|
||||
find_program (JSON_FUZZ_AFL_FUZZ
|
||||
NAMES afl-fuzz
|
||||
DOC "AFL++ fuzzer runner" REQUIRED)
|
||||
if(JSON_FUZZ_MINIMIZE_CORPUS)
|
||||
find_program (JSON_FUZZ_AFL_CMIN
|
||||
NAMES afl-cmin
|
||||
DOC "AFL++ corpus minimizer" REQUIRED)
|
||||
endif()
|
||||
elseif(${JSON_FUZZ_ENGINE} STREQUAL libfuzzer)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
set(JSON_FUZZ_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
|
||||
endif()
|
||||
find_program (JSON_FUZZ_CXX_COMPILER
|
||||
NAMES clang++
|
||||
DOC "Clang C++ compiler" REQUIRED)
|
||||
endif()
|
||||
|
||||
# TODO does libFuzzer hammer the disk as much as AFL++?
|
||||
if(${JSON_FUZZ_ENGINE} STREQUAL afl++)
|
||||
if(NOT JSON_FUZZ_TEMP_DIR)
|
||||
# try to default AFL++ temp. directory to XDG_RUNTIME_DIR on Linux
|
||||
if(UNIX AND NOT APPLE AND DEFINED ENV{XDG_RUNTIME_DIR})
|
||||
find_program(mount_program mount)
|
||||
if(mount_program)
|
||||
execute_process(COMMAND ${mount_program}
|
||||
OUTPUT_VARIABLE mount_output
|
||||
ERROR_QUIET)
|
||||
string(REGEX MATCH "[^ ]+ on $ENV{XDG_RUNTIME_DIR}(/[^ ]*)? type tmpfs" mount_match "${mount_output}")
|
||||
if(mount_match)
|
||||
string(RANDOM suffix)
|
||||
set(temp_dir "$ENV{XDG_RUNTIME_DIR}/json_fuzz_tmp.${suffix}")
|
||||
set(JSON_FUZZ_TEMP_DIR "${temp_dir}" CACHE PATH "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT JSON_FUZZ_TEMP_DIR)
|
||||
message(WARNING "JSON_FUZZ_TEMP_DIR should point to a directory on an in-memory file system.")
|
||||
string(RANDOM suffix)
|
||||
set(temp_dir "$ENV{CMAKE_CURRENT_BINARY_DIR}/json_fuzz_tmp.${suffix}")
|
||||
set(JSON_FUZZ_TEMP_DIR "${temp_dir}" CACHE PATH "" FORCE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Temporary directory for fuzzing: ${JSON_FUZZ_TEMP_DIR}")
|
||||
endif()
|
||||
|
||||
#############################################################################
|
||||
# set up fuzzing
|
||||
#############################################################################
|
||||
|
||||
foreach(target ${JSON_FUZZ_TARGETS})
|
||||
json_fuzz_add_fuzzers(${target}
|
||||
SOURCES src/fuzzer-parse_${target}.cpp
|
||||
ENGINE ${JSON_FUZZ_ENGINE}
|
||||
SANITIZERS ${JSON_FUZZ_SANITIZERS}
|
||||
INSTRUMENTATIONS ${JSON_FUZZ_AFL_INSTRUMENTATIONS})
|
||||
|
||||
json_fuzz_add_corpus(${target} GLOB "**/*.${target}"
|
||||
MAX_SIZE ${JSON_FUZZ_CORPUS_MAX_SIZE})
|
||||
|
||||
if(JSON_FUZZ_MINIMIZE_CORPUS)
|
||||
json_fuzz_minimize_corpus(${target}
|
||||
ENGINE ${JSON_FUZZ_ENGINE})
|
||||
endif()
|
||||
|
||||
json_fuzz_add_fuzz_run_target(${target}
|
||||
TEMP_DIR "${JSON_FUZZ_TEMP_DIR}")
|
||||
endforeach()
|
||||
Loading…
Reference in New Issue
Block a user