From 74e734ae951fe9e7cc27c6c6c7a9202b600ebba6 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 22 Dec 2024 16:23:16 -0700 Subject: [PATCH 1/4] Initial commit - two fuzzing harnesses and build script --- CMakeLists.txt | 11 +++++++++++ fuzz/CMakeLists.txt | 24 ++++++++++++++++++++++++ fuzz/build.sh | 8 ++++++++ fuzz/corpus/seed.zip | Bin 0 -> 282 bytes fuzz/create_zip_fuzzer.c | 19 +++++++++++++++++++ fuzz/read_entry_fuzzer.c | 38 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+) create mode 100644 fuzz/CMakeLists.txt create mode 100644 fuzz/build.sh create mode 100644 fuzz/corpus/seed.zip create mode 100644 fuzz/create_zip_fuzzer.c create mode 100644 fuzz/read_entry_fuzzer.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 804df5e2..1df1fc8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ endif () option(CMAKE_ENABLE_SANITIZERS "Enable zip sanitizers" OFF) option(ZIP_STATIC_PIC "Build static zip with PIC" ON) option(ZIP_BUILD_DOCS "Generate API documentation with Doxygen" OFF) +option(ZIP_BUILD_FUZZ "Build fuzz targets" OFF) if(ZIP_ENABLE_SHARABLE_FILE_OPEN) add_definitions(-DZIP_ENABLE_SHARABLE_FILE_OPEN) @@ -73,6 +74,16 @@ elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR endif (MSVC) #### + +# fuzz +if (ZIP_BUILD_FUZZ) + if (NOT DEFINED ENV{LIB_FUZZING_ENGINE}) + message(FATAL_ERROR "LIB_FUZZING_ENGINE is not defined") + endif() + add_subdirectory(fuzz) +endif() +### + set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}") set(INCLUDE_INSTALL_DIR "include") diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt new file mode 100644 index 00000000..869029f1 --- /dev/null +++ b/fuzz/CMakeLists.txt @@ -0,0 +1,24 @@ +# 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 + +set(CMAKE_C_STANDARD 23) + +add_definitions(-DNDEBUG) # Do not want assertions + +if (DEFINED ENV{CFLAGS}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{CFLAGS}") +endif () + +add_executable(read_entry_fuzzer read_entry_fuzzer.c) +target_link_libraries(read_entry_fuzzer PRIVATE ${PROJECT_NAME} $ENV{LIB_FUZZING_ENGINE}) + +add_executable(create_zip_fuzzer create_zip_fuzzer.c) +target_link_libraries(create_zip_fuzzer PRIVATE ${PROJECT_NAME} $ENV{LIB_FUZZING_ENGINE}) + +if (DEFINED ENV{OUT}) + install(TARGETS read_entry_fuzzer DESTINATION $ENV{OUT}) + install(TARGETS create_zip_fuzzer DESTINATION $ENV{OUT}) +else () + message(WARNING "Cannot install if $OUT is not defined!") +endif () \ No newline at end of file diff --git a/fuzz/build.sh b/fuzz/build.sh new file mode 100644 index 00000000..e2623608 --- /dev/null +++ b/fuzz/build.sh @@ -0,0 +1,8 @@ +cd $SRC/zip + +mkdir -p build +cmake -S . -B build -DCMAKE_C_COMPILER_WORKS=1 -DZIP_BUILD_FUZZ=ON && cmake --build build --target install + +# Prepare corpora +zip -q $OUT/read_entry_fuzzer_seed_corpus.zip corpus/* +zip -q $OUT/create_zip_fuzzer_seed_corpus.zip corpus/* diff --git a/fuzz/corpus/seed.zip b/fuzz/corpus/seed.zip new file mode 100644 index 0000000000000000000000000000000000000000..56b77bdf0e61f5b3acfe2b538612d85846d3aa3c GIT binary patch literal 282 zcmWIWW@h1H0D<1A{gGe>lwf3#VMq)O;bdU`)f%4;!lf1542&!C$rL;zfC9~P}i zV6DG_+CUgXD +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, const size_t size) +{ + char *outbuf = NULL; + size_t outbufsize = 0; + + struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); + + zip_entry_open(zip, "test"); + zip_entry_write(zip, data, size); + zip_entry_close(zip); + zip_stream_copy(zip, (void **) &outbuf, &outbufsize); + zip_stream_close(zip); + free(outbuf); + return 0; +} diff --git a/fuzz/read_entry_fuzzer.c b/fuzz/read_entry_fuzzer.c new file mode 100644 index 00000000..b9da3071 --- /dev/null +++ b/fuzz/read_entry_fuzzer.c @@ -0,0 +1,38 @@ +#include "zip.h" +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, const size_t size) +{ + void *buf = NULL; + size_t bufsize = 0; + + struct zip_t *zip = zip_stream_open((const char *)data, size, 0, 'r'); + if (NULL == zip) + { + goto end; + } + + const ssize_t zip_entries_count = zip_entries_total(zip); + + if (zip_entries_count <= 0) + { + goto end; + } + + if (0 != zip_entry_openbyindex(zip, 0)) + { + goto end; + } + + zip_entry_read(zip, &buf, &bufsize); + +end: + zip_entry_close(zip); + if (NULL != zip) + { + zip_close(zip); + } + free(buf); + return 0; +} From dfdf51375059294f6e127c93d3b8af30f72bd5d7 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 22 Dec 2024 16:32:14 -0700 Subject: [PATCH 2/4] Avoid double-zip, just copy the zip --- fuzz/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/build.sh b/fuzz/build.sh index e2623608..05cbaef3 100644 --- a/fuzz/build.sh +++ b/fuzz/build.sh @@ -5,4 +5,4 @@ cmake -S . -B build -DCMAKE_C_COMPILER_WORKS=1 -DZIP_BUILD_FUZZ=ON && cmake --bu # Prepare corpora zip -q $OUT/read_entry_fuzzer_seed_corpus.zip corpus/* -zip -q $OUT/create_zip_fuzzer_seed_corpus.zip corpus/* +cp $OUT/read_entry_fuzzer_seed_corpus.zip $OUT/create_zip_fuzzer_seed_corpus.zip From 8898eb880fe742ea7324298e2933a0cf2e99fe24 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 22 Dec 2024 16:35:28 -0700 Subject: [PATCH 3/4] Fixed zip path --- fuzz/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/build.sh b/fuzz/build.sh index 05cbaef3..aecd5f92 100644 --- a/fuzz/build.sh +++ b/fuzz/build.sh @@ -4,5 +4,5 @@ mkdir -p build cmake -S . -B build -DCMAKE_C_COMPILER_WORKS=1 -DZIP_BUILD_FUZZ=ON && cmake --build build --target install # Prepare corpora -zip -q $OUT/read_entry_fuzzer_seed_corpus.zip corpus/* +zip -q $OUT/read_entry_fuzzer_seed_corpus.zip fuzz/corpus/* cp $OUT/read_entry_fuzzer_seed_corpus.zip $OUT/create_zip_fuzzer_seed_corpus.zip From 1b477acbf4e31162889b828d4d3a28532f6f42ea Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 22 Dec 2024 16:56:46 -0700 Subject: [PATCH 4/4] Add OSSFuzz build pipeline --- .github/workflows/cifuzz.yml | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 00000000..0aff957b --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -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: 'zip' + language: c + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'zip' + 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