test: Add llvm fuzz testing

Moved the afl fuzz test and added llvm fuzz tests including inflate
and round trip compress and inflate.  Currently only works with clang,
std makefile and libFuzzer installed.  Need to add checking and
support later when libfuzzer is more tightly integrated into the
compiler.

Change-Id: I2db9ad2335d6c5ed846886703b58225f67bcc935
Signed-off-by: Greg Tucker <greg.b.tucker@intel.com>
This commit is contained in:
Greg Tucker 2017-10-06 18:48:38 -07:00
parent f7b6e73146
commit 4f59eeda90
13 changed files with 502 additions and 102 deletions

View File

@ -31,6 +31,7 @@ include erasure_code/Makefile.am
include raid/Makefile.am include raid/Makefile.am
include crc/Makefile.am include crc/Makefile.am
include igzip/Makefile.am include igzip/Makefile.am
include tests/fuzz/Makefile.am
# LIB version info not necessarily the same as package version # LIB version info not necessarily the same as package version
LIBISAL_CURRENT=2 LIBISAL_CURRENT=2

View File

@ -33,9 +33,13 @@ default: lib
include $(foreach unit,$(units), $(unit)/Makefile.am) include $(foreach unit,$(units), $(unit)/Makefile.am)
ifneq (,$(findstring igzip,$(units)))
include tests/fuzz/Makefile.am
endif
# Override individual lib names to make one inclusive library. # Override individual lib names to make one inclusive library.
lib_name := bin/isa-l.a lib_name := bin/isa-l.a
include make.inc include make.inc
VPATH = . $(units) include VPATH = . $(units) include tests/fuzz

View File

@ -114,7 +114,6 @@ lsrc += igzip/huff_codes.c
# Include tools and tests using the reference inflate # Include tools and tests using the reference inflate
other_tests += igzip/igzip_inflate_perf other_tests += igzip/igzip_inflate_perf
other_tests += igzip/igzip_inflate_test other_tests += igzip/igzip_inflate_test
other_tests += igzip/igzip_fuzz_inflate
lsrc += igzip/igzip_inflate.c lsrc += igzip/igzip_inflate.c
other_src += igzip/checksum_test_ref.h other_src += igzip/checksum_test_ref.h
@ -125,6 +124,3 @@ igzip_inflate_test: LDLIBS += -lz
igzip_igzip_inflate_test_LDADD = libisal.la igzip_igzip_inflate_test_LDADD = libisal.la
igzip_igzip_inflate_test_LDFLAGS = -lz igzip_igzip_inflate_test_LDFLAGS = -lz
igzip_igzip_hist_perf_LDADD = libisal.la igzip_igzip_hist_perf_LDADD = libisal.la
igzip_fuzz_inflate: LDLIBS += -lz
igzip_igzip_fuzz_inflate_LDADD = libisal.la
igzip_igzip_fuzz_inflate_LDFLAGS = -lz

View File

@ -1,96 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <assert.h>
#include <zlib.h>
#include "huff_codes.h"
#include "igzip_lib.h"
#include "test.h"
#define OUT_BUFFER_SIZE 64*1024
int main(int argc, char *argv[])
{
FILE *in = NULL;
unsigned char *in_buf = NULL, *isal_out_buf = NULL, *zlib_out_buf = NULL;
uint64_t in_file_size;
int out_buf_size, zret, iret;
struct inflate_state *state = NULL;
z_stream zstate;
char z_msg_invalid_code_set[] = "invalid code lengths set";
char z_msg_invalid_dist_set[] = "invalid distances set";
char z_msg_invalid_lit_len_set[] = "invalid literal/lengths set";
if (argc != 2) {
fprintf(stderr, "Usage: isal_inflate_file_perf infile\n"
"\t - Runs multiple iterations of igzip on a file to "
"get more accurate time results.\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(1);
}
/* Allocate space for entire input file and output
* (assuming some possible expansion on output size)
*/
in_file_size = get_filesize(in);
out_buf_size = OUT_BUFFER_SIZE;
state = malloc(sizeof(struct inflate_state));
in_buf = malloc(in_file_size);
isal_out_buf = malloc(OUT_BUFFER_SIZE);
zlib_out_buf = malloc(OUT_BUFFER_SIZE);
if (state == NULL || in_buf == NULL || isal_out_buf == NULL || zlib_out_buf == NULL) {
fprintf(stderr, "Failed to malloc input and outputs buffers\n");
exit(1);
}
fread(in_buf, 1, in_file_size, in);
/* Inflate data with isal_inflate */
memset(state, 0xff, sizeof(struct inflate_state));
isal_inflate_init(state);
state->next_in = in_buf;
state->avail_in = in_file_size;
state->next_out = isal_out_buf;
state->avail_out = out_buf_size;
iret = isal_inflate_stateless(state);
/* Inflate data with zlib */
zstate.zalloc = Z_NULL;
zstate.zfree = Z_NULL;
zstate.opaque = Z_NULL;
zstate.avail_in = in_file_size;
zstate.next_in = in_buf;
zstate.avail_out = out_buf_size;
zstate.next_out = zlib_out_buf;
inflateInit2(&zstate, -15);
zret = inflate(&zstate, Z_FINISH);
if (zret == Z_STREAM_END) {
/* If zlib finished, assert isal finished with the same answer */
assert(state->block_state == ISAL_BLOCK_FINISH);
assert(zstate.total_out == state->total_out);
assert(memcmp(isal_out_buf, zlib_out_buf, state->total_out) == 0);
} else if (zret < 0) {
if (zret != Z_BUF_ERROR)
/* If zlib errors, assert isal errors, excluding a few
* cases where zlib is overzealous */
assert(iret < 0 || strcmp(zstate.msg, z_msg_invalid_code_set) == 0
|| strcmp(zstate.msg, z_msg_invalid_dist_set) == 0
|| strcmp(zstate.msg, z_msg_invalid_lit_len_set) == 0);
} else
/* If zlib did not finish or error, assert isal did not finish
* or that isal found an invalid header since isal notices the
* error faster than zlib */
assert(iret > 0 || iret == ISAL_INVALID_BLOCK);
return 0;
}

View File

@ -126,18 +126,27 @@ all_tests = $(notdir $(sort $(perf_tests) $(check_tests) $(unit_tests) $(example
all_unit_tests = $(notdir $(sort $(check_tests) $(unit_tests))) all_unit_tests = $(notdir $(sort $(check_tests) $(unit_tests)))
all_perf_tests = $(notdir $(sort $(perf_tests))) all_perf_tests = $(notdir $(sort $(perf_tests)))
all_check_tests = $(notdir $(sort $(check_tests))) all_check_tests = $(notdir $(sort $(check_tests)))
all_llvm_fuzz_tests = $(notdir $(sort $(llvm_fuzz_tests)))
$(all_unit_tests): % : %.c $(lib_name) $(all_unit_tests): % : %.c $(lib_name)
$(all_perf_tests): % : %.c $(lib_name) $(all_perf_tests): % : %.c $(lib_name)
$(sort $(notdir $(examples))): % : %.c $(lib_name) $(sort $(notdir $(examples))): % : %.c $(lib_name)
$(sort $(notdir $(other_tests))): % : %.c $(lib_name) $(sort $(notdir $(other_tests))): % : %.c $(lib_name)
$(all_llvm_fuzz_tests): LDLIBS += -lFuzzer
$(all_llvm_fuzz_tests): CFLAGS += -fsanitize-coverage=trace-pc-guard -fsanitize=address
$(all_llvm_fuzz_tests): CXXFLAGS += -fsanitize-coverage=trace-pc-guard -fsanitize=address
$(all_llvm_fuzz_tests): % : %.o $(lib_name)
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
sim test trace: $(addsuffix .run,$(all_unit_tests)) sim test trace: $(addsuffix .run,$(all_unit_tests))
perf: $(addsuffix .run,$(all_perf_tests)) perf: $(addsuffix .run,$(all_perf_tests))
check: $(addsuffix .run,$(all_check_tests)) check: $(addsuffix .run,$(all_check_tests))
ex: $(notdir $(examples)) ex: $(notdir $(examples))
all: lib $(all_tests) all: lib $(all_tests)
other: $(notdir $(other_tests)) other: $(notdir $(other_tests))
llvm_fuzz_tests: $(all_llvm_fuzz_tests)
tests: $(all_unit_tests) tests: $(all_unit_tests)
perfs: $(all_perf_tests) perfs: $(all_perf_tests)
checks: $(all_check_tests) checks: $(all_check_tests)
@ -273,7 +282,7 @@ perf_report:
clean: clean:
@echo Cleaning up @echo Cleaning up
@$(RM) -r $(O) *.o *.a $(all_tests) $(lib_name) $(so_lib_name) @$(RM) -r $(O) *.o *.a $(all_tests) $(lib_name) $(so_lib_name) $(all_llvm_fuzz_tests)
doc: isa-l.h doc: isa-l.h

52
tests/fuzz/Makefile.am Normal file
View File

@ -0,0 +1,52 @@
########################################################################
# Copyright(c) 2011-2017 Intel Corporation All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
########################################################################
src_include += -I $(srcdir)/tests/fuzz
# AFL fuzz tests
other_tests += tests/fuzz/igzip_fuzz_inflate
igzip_fuzz_inflate: igzip_checked_inflate_fuzz_test.o
igzip_fuzz_inflate: LDLIBS += -lz
tests_fuzz_igzip_fuzz_inflate_LDADD = tests/fuzz/igzip_checked_inflate_fuzz_test.lo libisal.la
tests_fuzz_igzip_fuzz_inflate_LDFLAGS = -lz
other_tests += tests/fuzz/igzip_dump_inflate_corpus
tests_fuzz_igzip_dump_inflate_corpus_LDADD = libisal.la
# LLVM fuzz tests
llvm_fuzz_tests = tests/fuzz/igzip_simple_inflate_fuzz_test
other_src += tests/fuzz/igzip_simple_inflate_fuzz_test.c
llvm_fuzz_tests += tests/fuzz/igzip_checked_inflate_fuzz_test
other_src += tests/fuzz/igzip_checked_inflate_fuzz_test.c
llvm_fuzz_tests += tests/fuzz/igzip_simple_round_trip_fuzz_test
other_src += tests/fuzz/igzip_simple_round_trip_fuzz_test.c
igzip_checked_inflate_fuzz_test: LDLIBS += -lz

12
tests/fuzz/Makefile.unx Normal file
View File

@ -0,0 +1,12 @@
default: llvm_fuzz_tests
include ../../igzip/Makefile.am
include Makefile.am
include ../../make.inc
CC = clang
CXX = clang++
CXXFLAGS += $(DEFINES)
VPATH = . ../../igzip ../../include

View File

@ -0,0 +1,69 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <zlib.h>
#include <assert.h>
#include "igzip_lib.h"
int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
{
struct inflate_state state;
z_stream zstate;
size_t out_buf_size = 2 * size;
int zret, iret;
char z_msg_invalid_code_set[] = "invalid code lengths set";
char z_msg_invalid_dist_set[] = "invalid distances set";
char z_msg_invalid_lit_len_set[] = "invalid literal/lengths set";
uint8_t *isal_out_buf = (uint8_t *) malloc(size * 2);
uint8_t *zlib_out_buf = (uint8_t *) malloc(size * 2);
assert(NULL != isal_out_buf && NULL != zlib_out_buf);
/* Inflate data with isal_inflate */
memset(&state, 0xff, sizeof(struct inflate_state));
isal_inflate_init(&state);
state.next_in = (uint8_t *) data;
state.avail_in = size;
state.next_out = isal_out_buf;
state.avail_out = out_buf_size;
iret = isal_inflate_stateless(&state);
/* Inflate data with zlib */
zstate.zalloc = Z_NULL;
zstate.zfree = Z_NULL;
zstate.opaque = Z_NULL;
zstate.avail_in = size;
zstate.next_in = (Bytef *) data;
zstate.avail_out = out_buf_size;
zstate.next_out = zlib_out_buf;
inflateInit2(&zstate, -15);
zret = inflate(&zstate, Z_FINISH);
if (zret == Z_STREAM_END) {
/* If zlib finished, assert isal finished with the same answer */
assert(state.block_state == ISAL_BLOCK_FINISH);
assert(zstate.total_out == state.total_out);
assert(memcmp(isal_out_buf, zlib_out_buf, state.total_out) == 0);
} else if (zret < 0) {
if (zret != Z_BUF_ERROR)
/* If zlib errors, assert isal errors, excluding a few
* cases where zlib is overzealous */
assert(iret < 0 || strcmp(zstate.msg, z_msg_invalid_code_set) == 0
|| strcmp(zstate.msg, z_msg_invalid_dist_set) == 0
|| strcmp(zstate.msg, z_msg_invalid_lit_len_set) == 0);
} else
/* If zlib did not finish or error, assert isal did not finish
* or that isal found an invalid header since isal notices the
* error faster than zlib */
assert(iret > 0 || iret == ISAL_INVALID_BLOCK);
inflateEnd(&zstate);
free(isal_out_buf);
free(zlib_out_buf);
return 0;
}

View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "inflate_std_vects.h"
#define FNAME_MAX 180
int main(int argc, char *argv[])
{
uint8_t *buf;
int i, len, err;
FILE *fout = NULL;
char fname[FNAME_MAX];
char dname[FNAME_MAX];
if (argc != 2) {
fprintf(stderr, "Usage: %s <outdir>\n", argv[0]);
exit(1);
}
strncpy(dname, argv[1], FNAME_MAX);
for (i = 0; i < sizeof(std_vect_array) / sizeof(struct vect_result); i++) {
buf = std_vect_array[i].vector;
len = std_vect_array[i].vector_length;
err = std_vect_array[i].expected_error;
snprintf(fname, FNAME_MAX, "%s/inflate_corp_n%03d_e%d", dname, i, err);
printf(" writing %s\n", fname);
fout = fopen(fname, "w+");
if (!fout) {
fprintf(stderr, "Can't open %s for writing\n", fname);
exit(1);
}
fwrite(buf, len, 1, fout);
fclose(fout);
}
}

View File

@ -0,0 +1,37 @@
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <assert.h>
#include <zlib.h>
#include "huff_codes.h"
#include "igzip_lib.h"
#include "test.h"
extern int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size);
int main(int argc, char *argv[])
{
FILE *in = NULL;
unsigned char *in_buf = NULL;
uint64_t in_file_size;
if (argc != 2) {
fprintf(stderr, "Usage: isal_fuzz_inflate <infile>\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(1);
}
in_file_size = get_filesize(in);
in_buf = malloc(in_file_size);
if (in_buf == NULL) {
fprintf(stderr, "Failed to malloc input and outputs buffers\n");
exit(1);
}
fread(in_buf, 1, in_file_size, in);
return LLVMFuzzerTestOneInput(in_buf, in_file_size);
}

View File

@ -0,0 +1,22 @@
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include "igzip_lib.h"
int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
{
struct inflate_state state;
uint8_t *isal_out_buf = (uint8_t *) (malloc(size * 2));
size_t out_buf_size = 2 * size;
isal_inflate_init(&state);
state.next_in = (uint8_t *) data;
state.avail_in = size;
state.next_out = isal_out_buf;
state.avail_out = out_buf_size;
isal_inflate_stateless(&state);
free(isal_out_buf);
return 0;
}

View File

@ -0,0 +1,113 @@
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <byteswap.h>
#include "igzip_lib.h"
#define LEVEL_BITS 2
#define HEADER_BITS 3
#define LVL_BUF_BITS 3
#define LEVEL_BIT_MASK ((1<<LEVEL_BITS) - 1)
#define HEADER_BIT_MASK ((1<<HEADER_BITS) - 1)
#define TYPE0_HDR_SIZE 5
#define TYPE0_MAX_SIZE 65535
#define MIN(x,y) (((x) > (y)) ? y : x )
const int header_size[] = {
0, //IGZIP_DEFLATE
10, //IGZIP_GZIP
0, //IGZIP_GZIP_NO_HDR
2, //IGZIP_ZLIB
0, //IGZIP_ZLIB_NO_HDR
};
const int trailer_size[] = {
0, //IGZIP_DEFLATE
8, //IGZIP_GZIP
8, //IGZIP_GZIP_NO_HDR
4, //IGZIP_ZLIB
4, //IGZIP_ZLIB_NO_HDR
};
int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
{
struct inflate_state istate;
struct isal_zstream cstate;
uint8_t *in_data = (uint8_t *) data;
int ret = 1;
// Parameter default
int level = 1;
int lev_buf_size = ISAL_DEF_LVL1_DEFAULT;
int wrapper_type = 0;
size_t cmp_buf_size = size + ISAL_DEF_MAX_HDR_SIZE;
// Parameters are set by one byte of data input
if (size > 1) {
uint8_t in_param = in_data[--size];
level = MIN(in_param & LEVEL_BIT_MASK, ISAL_DEF_MAX_LEVEL);
in_param >>= LEVEL_BITS;
wrapper_type = (in_param & HEADER_BIT_MASK) % (IGZIP_ZLIB_NO_HDR + 1);
in_param >>= HEADER_BITS;
lev_buf_size = (0 == level) ?
ISAL_DEF_LVL0_MIN + (in_param) * (ISAL_DEF_LVL0_EXTRA_LARGE /
LEVEL_BIT_MASK) :
ISAL_DEF_LVL1_MIN + (in_param) * (ISAL_DEF_LVL1_EXTRA_LARGE /
LEVEL_BIT_MASK);
if (0 == level)
cmp_buf_size = 2 * size + ISAL_DEF_MAX_HDR_SIZE;
else
cmp_buf_size = size + 8 + (TYPE0_HDR_SIZE * (size / TYPE0_MAX_SIZE));
cmp_buf_size += header_size[wrapper_type] + trailer_size[wrapper_type];
}
uint8_t *isal_cmp_buf = (uint8_t *) malloc(cmp_buf_size);
uint8_t *isal_out_buf = (uint8_t *) malloc(size);
uint8_t *isal_lev_buf = (uint8_t *) malloc(lev_buf_size);
assert(NULL != isal_cmp_buf || NULL != isal_out_buf || NULL != isal_lev_buf);
isal_deflate_init(&cstate);
cstate.end_of_stream = 1;
cstate.flush = NO_FLUSH;
cstate.next_in = in_data;
cstate.avail_in = size;
cstate.next_out = isal_cmp_buf;
cstate.avail_out = cmp_buf_size;
cstate.level = level;
cstate.level_buf = isal_lev_buf;
cstate.level_buf_size = lev_buf_size;
cstate.gzip_flag = wrapper_type;
ret = isal_deflate_stateless(&cstate);
isal_inflate_init(&istate);
istate.next_in = isal_cmp_buf + header_size[wrapper_type];
istate.avail_in = cstate.total_out - header_size[wrapper_type];;
istate.next_out = isal_out_buf;
istate.avail_out = size;
istate.crc_flag = wrapper_type;
ret |= isal_inflate_stateless(&istate);
ret |= memcmp(isal_out_buf, in_data, size);
// Check trailer
uint32_t crc = 0;
int trailer_idx = cstate.total_out - trailer_size[wrapper_type];
if (wrapper_type == IGZIP_GZIP || wrapper_type == IGZIP_GZIP_NO_HDR)
crc = *(uint32_t *) & isal_cmp_buf[trailer_idx];
else if (wrapper_type == IGZIP_ZLIB || wrapper_type == IGZIP_ZLIB_NO_HDR)
crc = bswap_32(*(uint32_t *) & isal_cmp_buf[trailer_idx]);
assert(istate.crc == crc);
free(isal_cmp_buf);
free(isal_out_buf);
free(isal_lev_buf);
return ret;
}

144
tools/test_fuzz.sh Executable file
View File

@ -0,0 +1,144 @@
#!/usr/bin/env bash
usage ()
{
cat << EOF
usage: $0 options
options:
-h Help
-l, --llvm <n> Use llvm fuzz tests and run n times 0=just build, -1=skip (default $use_llvm).
-a, --afl <n> Use AFL fuzz tests and run n times 0=just build, -1=skip (default $use_afl).
-t, --time <n> Run each group of max time <n>[s,h,m,d] - n seconds, hours, minutes or days.
-e <exec|rand|all> Run a specific llvm test or [test, rand, all].
-f <file> Use this file as initial raw input. Can be repeated.
-d <0,1> Use dump of internal inflate test corpus (default $use_internal_corp).
-i <dir> Fuzz input dir (default $fuzzin_dir).
-o <dir> Fuzz output dir (default $fuzzout_dir).
EOF
exit 0
}
# Defaults
use_afl=-1
use_llvm=1
samp_files=
use_internal_corp=1
fuzzin_dir=fuzzin
fuzzout_dir=fuzzout
llvm_opts=" -print_final_stats=1"
afl_timeout_cmd=""
run_secs=0
llvm_tests=("igzip_simple_inflate_fuzz_test")
llvm_all_tests=("igzip_simple_inflate_fuzz_test" "igzip_checked_inflate_fuzz_test" "igzip_simple_round_trip_fuzz_test")
# Options
while [ "$1" != "${1##-}" ]; do
case $1 in
-h | --help)
usage
;;
-t | --time)
run_secs=$(echo $2 | sed -e 's/d$/*24h/' -e 's/h$/*60m/' -e 's/m$/*60/' -e 's/s$//'| bc)
llvm_opts+=" -max_total_time=$run_secs"
afl_timeout_cmd="timeout --preserve-status $run_secs"
echo Run each for $run_secs seconds
shift 2
;;
-a | --afl)
use_afl=$2
shift 2
;;
-l | --llvm)
use_llvm=$2
shift 2
;;
-f)
samp_files+="$2 "
use_internal_corp=0
shift 2
;;
-d)
use_internal_corp=$2
shift 2
;;
-e)
case $2 in
all)
llvm_tests=${llvm_all_tests[@]}
;;
rand)
llvm_tests=${llvm_all_tests[$RANDOM % ${#llvm_all_tests[@]} ]}
;;
*)
llvm_tests[0]="$2"
;;
esac
shift 2
;;
-i)
fuzzin_dir=$2
shift 2
;;
-o)
fuzzout_dir=$2
shift 2
;;
esac
done
set -xe #exit on fail
mkdir -p $fuzzout_dir $fuzzin_dir
# Optionally build afl fuzz tests
if [ $use_afl -ge 0 ]; then
echo Build afl fuzz tests
if ! command -V afl-gcc > /dev/null; then
echo $0 option --afl requires package afl installed
exit 0
fi
make -f Makefile.unx clean
make -f Makefile.unx units=igzip CC=afl-gcc other
fi
# Optionally build llvm fuzz tests
if [ $use_llvm -ge 0 ]; then
echo Build llvm fuzz tests
if ! command -V clang++ > /dev/null &&
echo int LLVMFuzzerTestOneInput\(\)\{return 0\;\} | clang++ -x c - -lFuzzer -lpthread -o /dev/null; then
echo $0 option --llvm requires clang++ and libFuzzer
exit 0
fi
rm -rf bin
make -f Makefile.unx units=igzip llvm_fuzz_tests igzip_dump_inflate_corpus CC=clang CXX=clang++
fi
# Optionally fill fuzz input with internal tests corpus
[ $use_internal_corp -gt 0 ] && ./igzip_dump_inflate_corpus $fuzzin_dir
# Optionally compress input samples as input into fuzz dir
for f in $samp_files; do
echo Using sample file $f
f_base=`basename $f`
./igzip_stateless_file_perf $f -o $fuzzin_dir/samp_${f_base}_cmp
done
# Optionally run tests alternately one after the other
while [ $use_llvm -gt 0 -o $use_afl -gt 0 ]; do
if [ $use_afl -gt 0 ]; then
echo afl run $use_afl
let use_afl--
$afl_timeout_cmd afl-fuzz -T "Run inflate $run_secs s" -i $fuzzin_dir -o $fuzzout_dir -M fuzzer1 -- ./igzip_fuzz_inflate @@
afl-whatsup $fuzzout_dir
fi
if [ $use_llvm -gt 0 ]; then
echo llvm run $use_llvm
let use_llvm--
for test in $llvm_tests; do
echo "Run llvm test $test"
./$test $fuzzin_dir $llvm_opts
done
fi
done
make -f Makefile.unx clean