105 lines
4.3 KiB
CMake
105 lines
4.3 KiB
CMake
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()
|