1cmake_minimum_required(VERSION 3.9) 2 3set(CMAKE_VERBOSE_MAKEFILE ON) 4set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 5set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 7project(FlatBuffersFuzzerTests) 8 9option(BUILD_DEBUGGER "Compile a debugger with main() and without libFuzzer" OFF) 10 11if(NOT DEFINED FLATBUFFERS_MAX_PARSING_DEPTH) 12 # Force checking of RecursionError in the test 13 set(FLATBUFFERS_MAX_PARSING_DEPTH 24) 14endif() 15message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}") 16 17# Usage '-fsanitize=address' doesn't allowed with '-fsanitize=memory'. 18# MemorySanitizer will not work out-of-the-box, and will instead report false 19# positives coming from uninstrumented code. Need to re-build both C++ standard 20# library: https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo 21option(USE_ASAN "Use fuzzers with ASASN" OFF) 22option(USE_MSAN "Use fuzzers with MSASN" OFF) 23option(OSS_FUZZ "Set this option to use flags by oss-fuzz" OFF) 24 25# Use Clang linker. 26set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld") 27 28# add_link_options(-stdlib=libc++) 29 30add_compile_options( 31 # -stdlib=libc++ # Use Clang libc++ instead of GNU. 32 -std=c++17 33 -Wall 34 -pedantic 35 -Werror 36 -Wextra 37 -Wno-unused-parameter 38 -fsigned-char 39 -fno-omit-frame-pointer 40 -g # Generate source-level debug information 41 # -flto # enable link-time optimisation 42) 43 44# https://llvm.org/docs/Passes.html save IR to see call graph make one bitcode 45# file:> llvm-link *.bc -o out.bc print call-graph:> opt out.bc -analyze -print- 46# callgraph &> callgraph.txt set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -save-temps 47# -flto") 48 49# A special target with fuzzer+sanitizer flags. 50add_library(fuzzer_config INTERFACE) 51 52target_compile_options( 53 fuzzer_config 54 INTERFACE 55 $<$<NOT:$<BOOL:${OSS_FUZZ}>>: 56 -fsanitize-coverage=edge,trace-cmp 57 > 58 $<$<BOOL:${USE_ASAN}>: 59 -fsanitize=fuzzer,undefined,address 60 > 61 $<$<BOOL:${USE_MSAN}>: 62 -fsanitize=fuzzer,undefined,memory 63 -fsanitize-memory-track-origins=2 64 > 65 $<$<BOOL:${OSS_FUZZ}>: 66 ${CXX} 67 ${CXXFLAGS} 68 > 69) 70 71target_link_libraries( 72 fuzzer_config 73 INTERFACE 74 $<$<BOOL:${USE_ASAN}>: 75 -fsanitize=fuzzer,undefined,address 76 > 77 $<$<BOOL:${USE_MSAN}>: 78 -fsanitize=fuzzer,undefined,memory 79 > 80 $<$<BOOL:${OSS_FUZZ}>: 81 $ENV{LIB_FUZZING_ENGINE} 82 > 83) 84 85set(FLATBUFFERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../") 86 87set(FlatBuffers_Library_SRCS 88 ${FLATBUFFERS_DIR}/include/flatbuffers/base.h 89 ${FLATBUFFERS_DIR}/include/flatbuffers/flatbuffers.h 90 ${FLATBUFFERS_DIR}/include/flatbuffers/hash.h 91 ${FLATBUFFERS_DIR}/include/flatbuffers/idl.h 92 ${FLATBUFFERS_DIR}/include/flatbuffers/util.h 93 ${FLATBUFFERS_DIR}/include/flatbuffers/reflection.h 94 ${FLATBUFFERS_DIR}/include/flatbuffers/reflection_generated.h 95 ${FLATBUFFERS_DIR}/include/flatbuffers/stl_emulation.h 96 ${FLATBUFFERS_DIR}/include/flatbuffers/flexbuffers.h 97 ${FLATBUFFERS_DIR}/include/flatbuffers/registry.h 98 ${FLATBUFFERS_DIR}/include/flatbuffers/minireflect.h 99 ${FLATBUFFERS_DIR}/src/idl_parser.cpp 100 ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp 101 ${FLATBUFFERS_DIR}/src/reflection.cpp 102 ${FLATBUFFERS_DIR}/src/util.cpp 103 ${FLATBUFFERS_DIR}/tests/test_assert.cpp 104) 105 106include_directories(${FLATBUFFERS_DIR}/include) 107include_directories(${FLATBUFFERS_DIR}/tests) 108 109add_library(flatbuffers_fuzzed STATIC ${FlatBuffers_Library_SRCS}) 110# Use PUBLIC to force 'fuzzer_config' for all dependent targets 111target_link_libraries(flatbuffers_fuzzed PUBLIC fuzzer_config) 112 113# FLATBUFFERS_ASSERT should assert in Release as well. Redefine 114# FLATBUFFERS_ASSERT macro definition. Declare as PUBLIC to cover asserts in all 115# included header files. 116target_compile_definitions( 117 flatbuffers_fuzzed 118 PUBLIC 119 FLATBUFFERS_ASSERT=fuzzer_assert_impl 120 FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h" 121 PRIVATE 122 FLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH} 123) 124 125# Setup fuzzer tests. 126 127add_executable(scalar_fuzzer flatbuffers_scalar_fuzzer.cc) 128target_link_libraries(scalar_fuzzer PRIVATE flatbuffers_fuzzed) 129 130add_executable(parser_fuzzer flatbuffers_parser_fuzzer.cc) 131target_link_libraries(parser_fuzzer PRIVATE flatbuffers_fuzzed) 132 133add_executable(verifier_fuzzer flatbuffers_verifier_fuzzer.cc) 134target_link_libraries(verifier_fuzzer PRIVATE flatbuffers_fuzzed) 135 136add_executable(monster_fuzzer flatbuffers_monster_fuzzer.cc) 137target_link_libraries(monster_fuzzer PRIVATE flatbuffers_fuzzed) 138add_custom_command( 139 TARGET monster_fuzzer PRE_BUILD 140 COMMAND ${CMAKE_COMMAND} -E copy 141 ${CMAKE_SOURCE_DIR}/../monster_test.bfbs 142 ${CMAKE_CURRENT_BINARY_DIR}/monster_test.bfbs) 143 144 145# Build debugger for weird cases found with fuzzer. 146if(BUILD_DEBUGGER) 147 add_library(flatbuffers_nonfuzz STATIC ${FlatBuffers_Library_SRCS}) 148 target_compile_options( 149 flatbuffers_nonfuzz 150 PUBLIC 151 $<$<BOOL:${USE_ASAN}>: 152 -fsanitize=undefined,address 153 > 154 -fno-limit-debug-info 155 ) 156 157 target_link_libraries( 158 flatbuffers_nonfuzz 159 PUBLIC 160 $<$<BOOL:${USE_ASAN}>: 161 -fsanitize=undefined,address 162 > 163 ) 164 165 target_compile_definitions( 166 flatbuffers_nonfuzz 167 PUBLIC 168 FLATBUFFERS_ASSERT=fuzzer_assert_impl 169 FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h" 170 PRIVATE 171 FLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH} 172 ) 173 add_executable(scalar_debug 174 flatbuffers_scalar_fuzzer.cc 175 scalar_debug.cpp 176 ) 177 target_link_libraries(scalar_debug PRIVATE flatbuffers_nonfuzz) 178 179 add_executable(monster_debug 180 flatbuffers_monster_fuzzer.cc 181 monster_debug.cpp 182 ) 183 target_link_libraries(monster_debug PRIVATE flatbuffers_nonfuzz) 184 add_custom_command( 185 TARGET monster_debug PRE_BUILD 186 COMMAND ${CMAKE_COMMAND} -E copy 187 ${CMAKE_SOURCE_DIR}/../monster_test.bfbs 188 ${CMAKE_CURRENT_BINARY_DIR}/monster_test.bfbs) 189 190endif(BUILD_DEBUGGER) 191