onnxruntime/cmake/onnxruntime_fuzz_test.cmake
0xdr3dd 5c361106e6
[Fuzzer] Add two new ORT libfuzzer (Linux clang support for now) (#22055)
### Description
This PR adds two new libfuzzer in fuzzer project.
1. Binary libfuzzer 
2. libprotobuf-fuzzer

To compile run below cmd on linux:
```
LLVM_PROFILE_FILE="%p.profraw" CFLAGS="-g -fsanitize=address,fuzzer-no-link -shared-libasan -fprofile-instr-generate -fcoverage-mapping" CXXFLAGS="-g -shared-libasan -fsanitize=address,fuzzer-no-link -fprofile-instr-generate -fcoverage-mapping" CC=clang CXX=clang++ ./build.sh --update --build --config Debug --compile_no_warning_as_error --build_shared_lib --skip_submodule_sync --use_full_protobuf  --parallel --fuzz_testing --build_dir build/
```
Run fuzzer:
```
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) build/Debug/onnxruntime_libfuzzer_fuzz  testinput -rss_limit_mb=8196 -max_total_time=472800 -fork=2 -jobs=4 -workers=4 -ignore_crashes=1 -max_len=2097152 2>&1 | grep -v "\[libprotobuf ERROR"
```


### Motivation and Context
The existing custom fuzzer is not coverage guided and it's slow and it
will work on one model mutation at a time. The new fuzzers are coverage
guided, and we can use more models' files as a corpus to increase the
coverage.
2024-09-12 11:50:34 -07:00

140 lines
7 KiB
CMake

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# Check that the options are properly set for
# the fuzzing project
if (onnxruntime_FUZZ_ENABLED)
message(STATUS "Building dependency protobuf-mutator and libfuzzer")
# set the options used to control the protobuf-mutator build
set(PROTOBUF_LIBRARIES ${PROTOBUF_LIB})
set(LIB_PROTO_MUTATOR_TESTING OFF)
# include the protobuf-mutator CMakeLists.txt rather than the projects CMakeLists.txt to avoid target clashes
# with google test
add_subdirectory("external/libprotobuf-mutator/src")
# add the appropriate include directory and compilation flags
# needed by the protobuf-mutator target and the libfuzzer
set(PROTOBUF_MUT_INCLUDE_DIRS "external/libprotobuf-mutator")
onnxruntime_add_include_to_target(protobuf-mutator ${PROTOBUF_LIB})
onnxruntime_add_include_to_target(protobuf-mutator-libfuzzer ${PROTOBUF_LIB})
target_include_directories(protobuf-mutator PRIVATE ${INCLUDE_DIRECTORIES} ${PROTOBUF_MUT_INCLUDE_DIRS})
target_include_directories(protobuf-mutator-libfuzzer PRIVATE ${INCLUDE_DIRECTORIES} ${PROTOBUF_MUT_INCLUDE_DIRS})
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# MSVC-specific compiler options
target_compile_options(protobuf-mutator PRIVATE "/wd4244" "/wd4245" "/wd4267" "/wd4100" "/wd4456")
target_compile_options(protobuf-mutator-libfuzzer PRIVATE "/wd4146" "/wd4267")
else()
# Linux-specific compiler options
target_compile_options(protobuf-mutator PRIVATE
-Wno-shorten-64-to-32
-Wno-conversion
-Wno-sign-compare
-Wno-unused-parameter
-Wno-shadow
-Wno-unused
-fexceptions
)
target_compile_options(protobuf-mutator-libfuzzer PRIVATE
-Wno-shorten-64-to-32
-Wno-conversion
-Wno-unused
-fexceptions
)
endif()
# add Fuzzing Engine Build Configuration
message(STATUS "Building Fuzzing engine")
# set Fuzz root directory
set(SEC_FUZZ_ROOT ${TEST_SRC_DIR}/fuzzing)
# Security fuzzing engine src file reference
set(SEC_FUZ_SRC "${SEC_FUZZ_ROOT}/src/BetaDistribution.cpp"
"${SEC_FUZZ_ROOT}/src/OnnxPrediction.cpp"
"${SEC_FUZZ_ROOT}/src/testlog.cpp"
"${SEC_FUZZ_ROOT}/src/test.cpp")
# compile the executables
onnxruntime_add_executable(onnxruntime_security_fuzz ${SEC_FUZ_SRC})
# compile with c++17
target_compile_features(onnxruntime_security_fuzz PUBLIC cxx_std_17)
# Security fuzzing engine header file reference
onnxruntime_add_include_to_target(onnxruntime_security_fuzz onnx onnxruntime)
# Assign all include to one variable
set(SEC_FUZ_INC "${SEC_FUZZ_ROOT}/include")
set(INCLUDE_FILES ${SEC_FUZ_INC} "$<TARGET_PROPERTY:protobuf-mutator,INCLUDE_DIRECTORIES>")
# add all these include directory to the Fuzzing engine
target_include_directories(onnxruntime_security_fuzz PRIVATE ${INCLUDE_FILES})
# add link libraries to the project
target_link_libraries(onnxruntime_security_fuzz onnx_proto onnxruntime protobuf-mutator ${PROTOBUF_LIB})
# add the dependencies
add_dependencies(onnxruntime_security_fuzz onnx_proto onnxruntime protobuf-mutator ${PROTOBUF_LIB})
# copy the shared libraries (DLLs on Windows, SOs on Linux) to the execution directory
add_custom_command(TARGET onnxruntime_security_fuzz POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime> $<TARGET_FILE_DIR:onnxruntime_security_fuzz>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${PROTOBUF_LIB}> $<TARGET_FILE_DIR:onnxruntime_security_fuzz>)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Add a second fuzzer that uses libFuzzer in fuzzer/libfuzzer
message(STATUS "Building libProtoBufFuzzer-based fuzzer")
# Set source files for the libFuzzer
set(LIBFUZZER_SRC "${SEC_FUZZ_ROOT}/src/OnnxPrediction.cpp"
"${SEC_FUZZ_ROOT}/src/testlog.cpp"
"${SEC_FUZZ_ROOT}/ort_libfuzzer/OrtProtoLibfuzzer.cpp")
# Compile the libFuzzer-based fuzzer
onnxruntime_add_executable(onnxruntime_proto_libfuzzer ${LIBFUZZER_SRC})
# Security fuzzing engine header file reference
onnxruntime_add_include_to_target(onnxruntime_proto_libfuzzer onnx onnxruntime)
# Set include directories for libFuzzer
target_include_directories(onnxruntime_proto_libfuzzer PRIVATE ${INCLUDE_FILES})
# Add link libraries for libFuzzer
target_link_libraries(onnxruntime_proto_libfuzzer onnx_proto onnxruntime protobuf-mutator protobuf-mutator-libfuzzer -fsanitize=fuzzer,address ${PROTOBUF_LIB})
# Add the dependencies for libFuzzer
add_dependencies(onnxruntime_proto_libfuzzer onnx_proto onnxruntime protobuf-mutator protobuf-mutator-libfuzzer ${PROTOBUF_LIB})
# Copy shared libraries for libFuzzer
add_custom_command(TARGET onnxruntime_proto_libfuzzer POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime> $<TARGET_FILE_DIR:onnxruntime_proto_libfuzzer>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${PROTOBUF_LIB}> $<TARGET_FILE_DIR:onnxruntime_proto_libfuzzer>)
# Add a second fuzzer that uses libFuzzer in fuzzer/libfuzzer
message(STATUS "Building libBufFuzzer-based fuzzer")
# Set source files for the libFuzzer
set(LIBFUZZER_SRC "${SEC_FUZZ_ROOT}/src/OnnxPrediction.cpp"
"${SEC_FUZZ_ROOT}/src/testlog.cpp"
"${SEC_FUZZ_ROOT}/ort_libfuzzer/OrtLibfuzzer.cpp")
# Compile the libFuzzer-based fuzzer
onnxruntime_add_executable(onnxruntime_libfuzzer_fuzz ${LIBFUZZER_SRC})
# Security fuzzing engine header file reference
onnxruntime_add_include_to_target(onnxruntime_libfuzzer_fuzz onnx onnxruntime)
# Set include directories for libFuzzer
target_compile_definitions(onnxruntime_libfuzzer_fuzz PRIVATE GOOGLE_PROTOBUF_NO_LOGGING=1)
target_include_directories(onnxruntime_libfuzzer_fuzz PRIVATE ${INCLUDE_FILES})
# Add link libraries for libFuzzer
target_link_libraries(onnxruntime_libfuzzer_fuzz onnx_proto onnxruntime protobuf-mutator protobuf-mutator-libfuzzer -fsanitize=fuzzer,address ${PROTOBUF_LIB})
# Add the dependencies for libFuzzer
add_dependencies(onnxruntime_libfuzzer_fuzz onnx_proto onnxruntime protobuf-mutator protobuf-mutator-libfuzzer ${PROTOBUF_LIB})
# Copy shared libraries for libFuzzer
add_custom_command(TARGET onnxruntime_libfuzzer_fuzz POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime> $<TARGET_FILE_DIR:onnxruntime_libfuzzer_fuzz>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${PROTOBUF_LIB}> $<TARGET_FILE_DIR:onnxruntime_libfuzzer_fuzz>)
endif()
endif()