summaryrefslogtreecommitdiff
path: root/tests/fuzzer/CMakeLists.txt
blob: 5deba0fd9d10c6a1b0ada4db5dc2f82c538810f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
cmake_minimum_required(VERSION 3.9)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

project(FlatBuffersFuzzerTests)

option(BUILD_DEBUGGER "Compile a debugger with main() and without libFuzzer" OFF)

if(NOT DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
  # Force checking of RecursionError in the test
  set(FLATBUFFERS_MAX_PARSING_DEPTH 8)
endif()
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")

# Usage '-fsanitize=address' doesn't allowed with '-fsanitize=memory'.
# MemorySanitizer will not work out-of-the-box, and will instead report false
# positives coming from uninstrumented code. Need to re-build both C++ standard
# library: https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo
option(USE_ASAN "Use fuzzers with ASASN" OFF)
option(USE_MSAN "Use fuzzers with MSASN" OFF)
option(OSS_FUZZ "Set this option to use flags by oss-fuzz" OFF)

# Use Clang linker.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")

# add_link_options(-stdlib=libc++)

add_compile_options(
  # -stdlib=libc++ # Use Clang libc++ instead of GNU.
  -std=c++17
  -Wall
  -pedantic
  -Werror
  -Wextra
  -Wno-unused-parameter
  -fsigned-char
  -fno-omit-frame-pointer
  -g # Generate source-level debug information
  # -flto # enable link-time optimisation
)

# https://llvm.org/docs/Passes.html save IR to see call graph make one bitcode
# file:> llvm-link *.bc -o out.bc print call-graph:> opt out.bc -analyze -print-
# callgraph &> callgraph.txt set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -save-temps
# -flto")

# A special target with fuzzer+sanitizer flags.
add_library(fuzzer_config INTERFACE)

target_compile_options(
  fuzzer_config
  INTERFACE
    $<$<NOT:$<BOOL:${OSS_FUZZ}>>:
      -fsanitize-coverage=edge,trace-cmp
    >
    $<$<BOOL:${USE_ASAN}>:
      -fsanitize=fuzzer,undefined,address
    >
    $<$<BOOL:${USE_MSAN}>:
      -fsanitize=fuzzer,undefined,memory
      -fsanitize-memory-track-origins=2
    >
    $<$<BOOL:${OSS_FUZZ}>:
      ${CXX}
      ${CXXFLAGS}
    >
)

target_link_libraries(
  fuzzer_config
  INTERFACE
    $<$<BOOL:${USE_ASAN}>:
      -fsanitize=fuzzer,undefined,address
    >
    $<$<BOOL:${USE_MSAN}>:
      -fsanitize=fuzzer,undefined,memory
    >
    $<$<BOOL:${OSS_FUZZ}>:
      $ENV{LIB_FUZZING_ENGINE}
    >
)

set(FLATBUFFERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")

set(FlatBuffers_Library_SRCS
    ${FLATBUFFERS_DIR}/include/flatbuffers/base.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/flatbuffers.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/hash.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/idl.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/util.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/reflection.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/reflection_generated.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/stl_emulation.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/flexbuffers.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/registry.h
    ${FLATBUFFERS_DIR}/include/flatbuffers/minireflect.h
    ${FLATBUFFERS_DIR}/src/idl_parser.cpp
    ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
    ${FLATBUFFERS_DIR}/src/reflection.cpp
    ${FLATBUFFERS_DIR}/src/util.cpp
    ${FLATBUFFERS_DIR}/tests/test_assert.cpp
)

include_directories(${FLATBUFFERS_DIR}/include)
include_directories(${FLATBUFFERS_DIR}/tests)

add_library(flatbuffers_fuzzed STATIC ${FlatBuffers_Library_SRCS})
# Use PUBLIC to force 'fuzzer_config' for all dependent targets
target_link_libraries(flatbuffers_fuzzed PUBLIC fuzzer_config)

# FLATBUFFERS_ASSERT should assert in Release as well. Redefine
# FLATBUFFERS_ASSERT macro definition. Declare as PUBLIC to cover asserts in all
# included header files.
target_compile_definitions(
  flatbuffers_fuzzed
  PUBLIC
    FLATBUFFERS_ASSERT=fuzzer_assert_impl
    FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h"
  PRIVATE
    FLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH}
)

# Setup fuzzer tests.

add_executable(scalar_fuzzer flatbuffers_scalar_fuzzer.cc)
target_link_libraries(scalar_fuzzer PRIVATE flatbuffers_fuzzed)

add_executable(parser_fuzzer flatbuffers_parser_fuzzer.cc)
target_link_libraries(parser_fuzzer PRIVATE flatbuffers_fuzzed)

add_executable(verifier_fuzzer flatbuffers_verifier_fuzzer.cc)
target_link_libraries(verifier_fuzzer PRIVATE flatbuffers_fuzzed)

add_executable(monster_fuzzer flatbuffers_monster_fuzzer.cc)
target_link_libraries(monster_fuzzer PRIVATE flatbuffers_fuzzed)

# Build debugger for weird cases found with fuzzer.
if(BUILD_DEBUGGER)
  add_library(flatbuffers_nonfuzz STATIC ${FlatBuffers_Library_SRCS})
  target_compile_definitions(
    flatbuffers_nonfuzz
    PUBLIC
      FLATBUFFERS_ASSERT=fuzzer_assert_impl
      FLATBUFFERS_ASSERT_INCLUDE="${CMAKE_CURRENT_SOURCE_DIR}/fuzzer_assert.h"
    PRIVATE
      FLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH}
  )
  add_executable(scalar_debug flatbuffers_scalar_fuzzer.cc scalar_debug.cpp)
  target_link_libraries(scalar_debug PRIVATE flatbuffers_nonfuzz)
endif(BUILD_DEBUGGER)