fuzz/README.md
The targets are meant to be run by google oss-fuzz however you can test it locally by configuring all the required flags.
In order to build all the targets you need to do the following:
--enable-fuzztargets or --enable--fuzztargets-localFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTIONfuzz_all./autogen.sh
CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" ./configure --enable-fuzztargets-local
fuzz_all targetmake -j$(nproc) fuzz_all
These are all the flags that can be passed to the C/C++ compiler:
main function that calls
LLVMFuzzerTestOneInput. Note that it is not needed when fuzzing on ClusterFuzz.These are all the env variables that can be passed to the configuration script:
Additionally there are some options that can be passed to ./configure
main(int, char **) making it incompatible with libfuzzer.
This is useful in conjuction with -DIS_AFL for fuzzing with AFL++ or to build in
debug mode with no fuzzzing engine.Additional sanitizers can be enabled by passing the specific flags in CFLAGS and CXXFLAGS
Some of the fuzzing targets require a particular directory structure to run correctly. In order to satisfy all the targets it is strongly suggested to create the following directories in the same path where the targets are launched:
installdata-dirdocsscriptsscripts/callbacksYou can build the fuzzing targets with different combinations of fuzzing engines (libfuzzer, AFL++, honggfuzz, ...) and sanitizers (address, undefined, memory). Here you can find some examples on how to build and run some of them.
Remember to run all the commands from the project root directory
IMPORTANT: If the project has been compiled before, it might be useful to first execute make clean
./autogen.sh
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=fuzzer-no-link" \
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=fuzzer-no-link" \
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
NDPI_HOME=/path/to/nDPI \
./configure --enable-fuzztargets
make -j$(nproc) fuzz_all
./autogen.sh
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
NDPI_HOME=/path/to/nDPI \
./configure --enable-fuzztargets
make -j$(nproc) fuzz_all
./autogen.sh
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
NDPI_HOME=/path/to/nDPI \
./configure --enable-fuzztargets --with-fuzz-protobuf
make -j$(nproc) fuzz_all
./autogen.sh
CC=afl-clang-fast CXX=afl-clang-fast++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -DIS_AFL" \
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only" \
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -stdlib=libc++" \
NDPI_HOME=/path/to/nDPI \
./configure --enable-fuzztargets-local
make -j$(nproc) fuzz_all
This is useful to debug a single test case. Note that the code is not instrumented for fuzzing.
./autogen.sh
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
CFLAGS="-O0 -fno-omit-frame-pointer -g" \
CXXFLAGS="-O0 -fno-omit-frame-pointer -g -stdlib=libc++" \
NDPI_HOME=/path/to/nDPI \
./configure --enable-fuzztargets-local
make -j$(nproc) fuzz_all
Once you have built the fuzzing targets you have to properly set up an environment. Some specific commands might vary depending on the fuzzing engine used in the building process.
First we create a directory in which we place the fuzzing targets, the dictionaries and the corpus. Then we set up the required directory structure
mkdir fuzzcampaign
# Copy fuzzers
find fuzz/ -regex 'fuzz/fuzz_[a-z_]*' -exec cp {} fuzzcampaign/ \;
# Copy dictionaries
cp fuzz/*.dict fuzzcampaign/
# Copy corpus
cp fuzz/*.zip fuzzcampaign/
# Create the directory structure needed for fuzzing
mkdir -p fuzzcampaign/install fuzzcampaign/data-dir fuzzcampaign/docs fuzzcampaign/scripts/callbacks
Then we can start to fuzz
cd fuzzcampaign
# Extract the corpus specific for the fuzzing target
mkdir input
unzip fuzz_dissect_packet_seed_corpus.zip -d input/
# Run the fuzzer
./fuzz_dissect_packet -timeout=25 input/ -dict=fuzz_dissect_packet.dict
cd fuzzcampaign
# Extract the corpus specific for the fuzzing target
mkdir input
unzip fuzz_dissect_packet_seed_corpus.zip -d input/
# Run the fuzzer
afl-fuzz -t 2000 -i input -o afl-out -- ./fuzz_dissect_packet