From db5248ad852e745fd3ff2b6f345a16c686085ad0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 28 Apr 2020 15:28:45 -0700 Subject: [PATCH] Test fuzzers against seed corpus under CI ASan build --- .cirrus.yml | 3 ++- ci/test-fuzzers.sh | 40 ++++++++++++++++++++++++++++++ ci/ubuntu-18.04/Dockerfile | 1 + src/analyzer/protocol/pop3/POP3.cc | 2 +- src/fuzzers/FuzzBuffer.cc | 2 +- src/fuzzers/standalone-driver.cc | 6 ++++- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100755 ci/test-fuzzers.sh diff --git a/.cirrus.yml b/.cirrus.yml index f501f0bc4d..437388adf6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,7 +4,7 @@ btest_retries: &BTEST_RETRIES 2 memory: &MEMORY 6GB config: &CONFIG --build-type=release --enable-cpp-tests -memcheck_config: &MEMCHECK_CONFIG --build-type=debug --enable-cpp-tests --sanitizers=address +memcheck_config: &MEMCHECK_CONFIG --build-type=debug --enable-cpp-tests --sanitizers=address --enable-fuzzers resources_template: &RESOURCES_TEMPLATE cpu: *CPUS @@ -133,5 +133,6 @@ memcheck_task: # AddressSanitizer uses a lot more memory than a typical config. memory: 16GB << : *CI_TEMPLATE + test_fuzzers_script: ./ci/test-fuzzers.sh env: ZEEK_CI_CONFIGURE_FLAGS: *MEMCHECK_CONFIG diff --git a/ci/test-fuzzers.sh b/ci/test-fuzzers.sh new file mode 100755 index 0000000000..c3ae93d469 --- /dev/null +++ b/ci/test-fuzzers.sh @@ -0,0 +1,40 @@ +#! /usr/bin/env bash + +result=0 + +echo "Testing fuzzers against their seed corpus" +echo "-----------------------------------------" + +cd build || result=1 +. ./zeek-path-dev.sh + +fuzzers=$(find ./src/fuzzers -name 'zeek-*-fuzzer') + +for fuzzer_path in ${fuzzers}; do + fuzzer_exe=$(basename ${fuzzer_path}) + fuzzer_name=$(echo ${fuzzer_exe} | sed 's/zeek-\(.*\)-fuzzer/\1/g') + corpus="../src/fuzzers/${fuzzer_name}-corpus.zip" + + if [[ -e ${corpus} ]]; then + echo "Fuzzer: ${fuzzer_exe} ${corpus}" + ( rm -rf corpus && mkdir corpus ) || result=1 + ( cd corpus && unzip ../${corpus} >/dev/null ) || result=1 + ${fuzzer_path} corpus/* >${fuzzer_exe}.out 2>${fuzzer_exe}.err + + if [[ $? -eq 0 ]]; then + tail -n 1 ${fuzzer_exe}.out + else + result=1 + cat ${fuzzer_exe}.out + echo " FAILED" + cat ${fuzzer_exe}.err + fi + else + echo "Skipping Fuzzer (no corpus): ${fuzzer_exe}" + fi + + echo "-----------------------------------------" +done + + +exit ${result} diff --git a/ci/ubuntu-18.04/Dockerfile b/ci/ubuntu-18.04/Dockerfile index 64b84692d2..272929749e 100644 --- a/ci/ubuntu-18.04/Dockerfile +++ b/ci/ubuntu-18.04/Dockerfile @@ -20,6 +20,7 @@ RUN apt-get update && apt-get -y install \ sqlite3 \ curl \ wget \ + unzip \ && rm -rf /var/lib/apt/lists/* # Many distros adhere to PEP 394's recommendation for `python` = `python2` so diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index c6753c01da..af91bc4e9f 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -864,7 +864,7 @@ int POP3_Analyzer::ParseCmd(std::string cmd) if ( cmd.size() == 0 ) return -1; - for ( int code = POP3_CMD_OK; code <= POP3_CMD_END; ++code ) + for ( int code = POP3_CMD_OK; code < POP3_CMD_END; ++code ) { char c = cmd.c_str()[0]; if ( c == '+' || c == '-' ) diff --git a/src/fuzzers/FuzzBuffer.cc b/src/fuzzers/FuzzBuffer.cc index 60ae96ca27..866b63bb20 100644 --- a/src/fuzzers/FuzzBuffer.cc +++ b/src/fuzzers/FuzzBuffer.cc @@ -59,7 +59,7 @@ std::optional zeek::FuzzBuffer::Next() // for each chunk. rval.data = std::make_unique(rval.size); memcpy(rval.data.get(), chunk_begin, rval.size); - return rval; + return {std::move(rval)}; } return {}; diff --git a/src/fuzzers/standalone-driver.cc b/src/fuzzers/standalone-driver.cc index 280a332110..e603d73735 100644 --- a/src/fuzzers/standalone-driver.cc +++ b/src/fuzzers/standalone-driver.cc @@ -20,6 +20,10 @@ int main(int argc, char** argv) { auto input_file_name = argv[i + 1]; printf(" %s:", input_file_name); + // If ASan ends up aborting, the previous stdout output may not + // be flushed, so make sure to that and make it easier to see + // what input caused the crash. + fflush(stdout); auto f = fopen(input_file_name, "r"); assert(f); @@ -44,4 +48,4 @@ int main(int argc, char** argv) auto agg_stop = high_resolution_clock::now(); auto agg_dt = duration(agg_stop - agg_start).count(); printf("Processed %d inputs in %fs\n", num_inputs, agg_dt); -} + }