From 9bd361ca323637b047ecfdf5de3c8cfbf64698d6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petr=20=C5=A0tetiar?= Date: Sat, 3 Oct 2020 01:53:53 +0200 Subject: [PATCH] tests: add libFuzzer based fuzzing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine. LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka "target function"); the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage. So lets use libFuzzer to fuzz uci_import for the start. Ref: https://llvm.org/docs/LibFuzzer.html Signed-off-by: Petr Å tetiar --- tests/CMakeLists.txt | 4 + tests/fuzz/CMakeLists.txt | 18 ++ .../231ee80a172b8e1749b9d91867989d88e4faf7bb | Bin 0 -> 15 bytes .../26a6253fc1eb695b61a2fc7640ee4c03c19e438e | Bin 0 -> 9 bytes .../29a6e206439d792afba5e8e9c1fdf55e65a1145d | Bin 0 -> 4 bytes .../51045ac5401085f5727c6d3c1cac5f8cc32a2927 | 1 + .../845dcf3f15f3c28235e6be148a690e7f03b07f65 | Bin 0 -> 22 bytes .../bb589d0621e5472f470fa3425a234c74b1e202e8 | 1 + .../ea387894a296772f96706df8b999a52d9334c746 | Bin 0 -> 5 bytes ...d:000000,sig:11,src:000001,op:flip1,pos:24 | Bin 0 -> 44 bytes ...sig:11,src:000022,op:arith8,pos:42,val:+26 | Bin 0 -> 43 bytes tests/fuzz/dict/uci.dict | 18 ++ tests/fuzz/inputs/dhcp | 49 +++++ tests/fuzz/inputs/firewall | 208 ++++++++++++++++++ tests/fuzz/test-fuzz.c | 60 +++++ 15 files changed, 359 insertions(+) create mode 100644 tests/fuzz/CMakeLists.txt create mode 100644 tests/fuzz/corpus/231ee80a172b8e1749b9d91867989d88e4faf7bb create mode 100644 tests/fuzz/corpus/26a6253fc1eb695b61a2fc7640ee4c03c19e438e create mode 100644 tests/fuzz/corpus/29a6e206439d792afba5e8e9c1fdf55e65a1145d create mode 100644 tests/fuzz/corpus/51045ac5401085f5727c6d3c1cac5f8cc32a2927 create mode 100644 tests/fuzz/corpus/845dcf3f15f3c28235e6be148a690e7f03b07f65 create mode 100644 tests/fuzz/corpus/bb589d0621e5472f470fa3425a234c74b1e202e8 create mode 100644 tests/fuzz/corpus/ea387894a296772f96706df8b999a52d9334c746 create mode 100644 tests/fuzz/corpus/id:000000,sig:11,src:000001,op:flip1,pos:24 create mode 100644 tests/fuzz/corpus/id:000008,sig:11,src:000022,op:arith8,pos:42,val:+26 create mode 100644 tests/fuzz/dict/uci.dict create mode 100644 tests/fuzz/inputs/dhcp create mode 100644 tests/fuzz/inputs/firewall create mode 100644 tests/fuzz/test-fuzz.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 872ed6d..6f31b93 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,2 +1,6 @@ ADD_SUBDIRECTORY(cram) ADD_SUBDIRECTORY(shunit2) + +IF(CMAKE_C_COMPILER_ID STREQUAL "Clang") + ADD_SUBDIRECTORY(fuzz) +ENDIF() diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt new file mode 100644 index 0000000..1533c46 --- /dev/null +++ b/tests/fuzz/CMakeLists.txt @@ -0,0 +1,18 @@ +FILE(GLOB test_cases "test-*.c") + +MACRO(ADD_FUZZER_TEST name) + ADD_EXECUTABLE(${name} ${name}.c) + TARGET_COMPILE_OPTIONS(${name} PRIVATE -g -O1 -fno-omit-frame-pointer -fsanitize=fuzzer,address,leak,undefined) + TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR}) + TARGET_LINK_OPTIONS(${name} PRIVATE -stdlib=libc++ -fsanitize=fuzzer,address,leak,undefined) + TARGET_LINK_LIBRARIES(${name} uci) + ADD_TEST( + NAME ${name} + COMMAND ${name} -max_len=256 -timeout=10 -max_total_time=300 -dict=${CMAKE_CURRENT_SOURCE_DIR}/dict/uci.dict ${CMAKE_CURRENT_SOURCE_DIR}/corpus + ) +ENDMACRO(ADD_FUZZER_TEST) + +FOREACH(test_case ${test_cases}) + GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE) + ADD_FUZZER_TEST(${test_case}) +ENDFOREACH(test_case) diff --git a/tests/fuzz/corpus/231ee80a172b8e1749b9d91867989d88e4faf7bb b/tests/fuzz/corpus/231ee80a172b8e1749b9d91867989d88e4faf7bb new file mode 100644 index 0000000000000000000000000000000000000000..9c17457fb85abbcc5b28d861981937b3b2dc0fb2 GIT binary patch literal 15 Wcmd;N;9}t7WN<9t?BU literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpus/51045ac5401085f5727c6d3c1cac5f8cc32a2927 b/tests/fuzz/corpus/51045ac5401085f5727c6d3c1cac5f8cc32a2927 new file mode 100644 index 0000000..f47ebca --- /dev/null +++ b/tests/fuzz/corpus/51045ac5401085f5727c6d3c1cac5f8cc32a2927 @@ -0,0 +1 @@ + # \ No newline at end of file diff --git a/tests/fuzz/corpus/845dcf3f15f3c28235e6be148a690e7f03b07f65 b/tests/fuzz/corpus/845dcf3f15f3c28235e6be148a690e7f03b07f65 new file mode 100644 index 0000000000000000000000000000000000000000..cf5c1b00e262ac0b3fcf9c8c7ae43099d4f8488e GIT binary patch literal 22 Tcmd;N;NnC=1)K)FF +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "uci.h" + +static void fuzz_uci_import(const uint8_t *input, size_t size) +{ + int r; + int fd; + FILE *fs = NULL; + struct uci_context *ctx = NULL; + struct uci_package *package = NULL; + + fd = open("/dev/shm", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + perror("unable to create temp file"); + exit(-1); + } + + r = write(fd, input, size); + if (r < 0) { + perror("unable to write()"); + exit(-1); + } + + fs = fdopen(fd, "r"); + if (fs == NULL) { + perror("unable to fdopen()"); + exit(-1); + } + + fseek(fs, 0L, SEEK_SET); + + ctx = uci_alloc_context(); + if (ctx == NULL) { + perror("unable to uci_alloc_context()"); + exit(-1); + } + + uci_import(ctx, fs, NULL, &package, false); + uci_free_context(ctx); + close(fd); + fclose(fs); +} + +int LLVMFuzzerTestOneInput(const uint8_t *input, size_t size) +{ + fuzz_uci_import(input, size); + return 0; +} -- 2.30.2