Debug a Finding
CI Fuzz provides an intuitive way to debug a Finding.
This workflow applies to C/C++ projects with CMake as a build system.
As an example, we want to fuzz the following (simple) Fuzz Test:
FUZZ_TEST(const uint8_t *data, size_t size) {
if(std::string((char*)data, size) != "crashing input") {
throw "Crash triggered";
}
}
This Fuzz Test generates a Finding called exciting_eagle
.
To debug this Finding, the user can add the macro DEBUG_FINDING(...)
to the source file containing the Fuzz Test.
This macro receives the name of the Finding as an argument:
DEBUG_FINDING(exciting_eagle)
FUZZ_TEST(const uint8_t *data, size_t size) {
if(std::string((char*)data, size) != "ci-daemon") {
throw "Crash triggered";
}
}
Furthermore, the user needs to add the test framework of their choice to the Fuzz Test definition in the CMakeLists.txt
file:
Currently only Google Test is supported.
add_fuzz_test(fuzz_test fuzz_test.cpp TEST_FRAMEWORK GTEST)
In case the user didn't follow the default installation instructions of Google Test, it's possible to pass the target names of the Google Test libraries:
add_fuzz_test(fuzz_test fuzz_test.cpp TEST_FRAMEWORK GTEST TEST_FRAMEWORK_LIBS ${GTEST_BOTH_LIBRARIES})
In order to be able to reproduce Findings reliably, the Fuzz Test has to be instrumented with address sanitizer and undefined behaviour sanitizer.
The user needs to add the following lines to the top of their CMakeLists.txt
before any commands related to the Fuzz Test:
add_compile_options(-fsanitize=address,undefined)
add_link_options(-fsanitize=address,undefined)
The IDE picks up the macro as a unit test, which in turn calls the Fuzz Test with the crashing input of the Finding:
The user can directly place a breakpoint in the Fuzz Test and start debugging the Finding: