OSSFuzz integration (#214)

This commit is contained in:
Bailey Capuano 2023-11-19 07:40:31 -05:00 committed by GitHub
parent f1a38d23b7
commit b19649478c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 2 deletions

39
.github/workflows/cifuzz.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: CIFuzz
on:
push:
branches:
- master
pull_request:
permissions: {}
jobs:
Fuzzing:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'tomlplusplus'
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'tomlplusplus'
language: c++
fuzz-seconds: 800
output-sarif: true
- name: Upload Crash
uses: actions/upload-artifact@v3
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
- name: Upload Sarif
if: always() && steps.build.outcome == 'success'
uses: github/codeql-action/upload-sarif@v2
with:
# Path to SARIF file relative to the root of the repository
sarif_file: cifuzz-sarif/results.sarif
checkout_path: cifuzz-sarif

View File

@ -30,11 +30,15 @@ target_include_directories(
target_compile_features(tomlplusplus_tomlplusplus INTERFACE cxx_std_17)
# ---- Install rules and examples ----
# ---- Install rules, examples, and fuzzing ----
if(PROJECT_IS_TOP_LEVEL)
include(cmake/install-rules.cmake)
option(BUILD_EXAMPLES "Build examples tree." OFF)
option(BUILD_FUZZER "Build fuzzer." OFF)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
if(BUILD_FUZZER AND DEFINED ENV{LIB_FUZZING_ENGINE})
add_subdirectory(fuzzing)
endif()
endif()

View File

@ -302,7 +302,7 @@ UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's '[
- **[@whiterabbit963](https://github.com/whiterabbit963)** - Fixed a bug with value_or conversions
- **[@ximion](https://github.com/ximion)** - Added support for installation with meson
- **[@a-is](https://github.com/a-is)** - Fixed a bug
-**[@capuanob](https://github.com/capuanob)** - Integrated this project into OSSFuzz
<br>
## Contact

31
fuzzing/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
# Utilized by OSSFuzz to build the harness(es) for continuous fuzz-testing
# OSSFuzz defines the following environment variables, that this target relies upon:
# CXX, CFLAGS, LIB_FUZZING_ENGINE, OUT
cmake_minimum_required(VERSION 3.14)
project(Fuzzer LANGUAGES CXX)
include(../cmake/project-is-top-level.cmake)
add_definitions(-DNDEBUG) # Do not want assertions
if (DEFINED ENV{CFLAGS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{CFLAGS}")
endif ()
if (DEFINED ENV{CXXFLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{CXXFLAGS}")
endif ()
if(PROJECT_IS_TOP_LEVEL)
find_package(tomlplusplus REQUIRED)
endif()
add_executable(toml_fuzzer toml_fuzzer.cpp)
target_link_libraries(toml_fuzzer PRIVATE tomlplusplus::tomlplusplus $ENV{LIB_FUZZING_ENGINE})
target_compile_features(toml_fuzzer PRIVATE cxx_std_17)
if (DEFINED ENV{OUT})
install(TARGETS toml_fuzzer DESTINATION $ENV{OUT})
else ()
message(WARNING "Cannot install if $OUT is not defined!")
endif ()

8
fuzzing/build.sh Executable file
View File

@ -0,0 +1,8 @@
cd $SRC/tomlplusplus
mkdir -p build
cmake -S . -B build -DBUILD_FUZZER=ON && cmake --build build --target install
# Build the corpus using the existing toml files in the source
mkdir -p corpus
find $SRC/tomlplusplus -name "*.toml" -exec cp {} corpus \;
zip -q $OUT/toml_fuzzer_seed_corpus.zip corpus/*

41
fuzzing/toml_fuzzer.cpp Normal file
View File

@ -0,0 +1,41 @@
#include <cstdint>
#include <fuzzer/FuzzedDataProvider.h>
#include <toml++/toml.hpp>
enum class SerializationTest
{
NONE = 0,
JSON,
YAML,
TOML,
kMaxValue = YAML
};
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, const std::size_t size)
{
FuzzedDataProvider fdp{data, size};
try
{
const toml::table tbl = toml::parse(fdp.ConsumeRandomLengthString());
switch (fdp.ConsumeEnum<SerializationTest>())
{
case SerializationTest::JSON:
static_cast<void>(toml::json_formatter{tbl});
break;
case SerializationTest::YAML:
static_cast<void>(toml::yaml_formatter{tbl});
break;
case SerializationTest::TOML:
static_cast<void>(toml::toml_formatter{tbl});
default:
break;
}
}
catch (const toml::parse_error&)
{
return -1;
}
return 0;
}