1#!/bin/bash -eu
2
3# Load script configuration
4source $(dirname $0)/config.sh
5
6# Set fuzzing environment
7# Fallback to local
8FUZZ_ENV=${FUZZ_ENV-$DEFAULT_ENV}
9
10# Set working paths from the environment
11# Fallback to values used for local testing
12SRC=${SRC-$DEFAULT_SRC}
13OUT=${OUT-$DEFAULT_OUT}
14WORK=${WORK-$DEFAULT_WORK}
15JANUSGW=${JANUSGW-$DEFAULT_JANUSGW}
16
17# Set compiler from the environment
18# Fallback to clang
19FUZZ_CC=${CC-$DEFAULT_CC}
20
21# Set linker from the environment (CXX is used as linker in oss-fuzz)
22# Fallback to clang
23FUZZ_CCLD=${CXX-${CC-$DEFAULT_CCLD}}
24
25# Set CFLAGS from the environment
26# Fallback to using address and undefined behaviour sanitizers
27FUZZ_CFLAGS=${CFLAGS-$DEFAULT_CFLAGS}
28# Allow users to optionally append extra CFLAGS
29ECFLAGS=${ECFLAGS-""}
30FUZZ_CFLAGS="${FUZZ_CFLAGS} ${ECFLAGS}"
31
32# Set LDFLAGS from the environment (CXXFLAGS var is used for linker flags in oss-fuzz)
33# Fallback to using address and undefined behaviour sanitizers
34FUZZ_LDFLAGS=${CXXFLAGS-${LDFLAGS-$DEFAULT_LDFLAGS}}
35# Allow users to optionally append extra LDFLAGS
36ELDFLAGS=${ELDFLAGS-""}
37FUZZ_LDFLAGS="${FUZZ_LDFLAGS} ${ELDFLAGS}"
38
39# Set fuzzing engine from the environment (optional)
40FUZZ_ENGINE=${LIB_FUZZING_ENGINE-""}
41
42# Use shared libraries in local execution
43FUZZ_DEPS="$DEPS_LIB"
44if [[ $FUZZ_ENV == "local" ]]; then
45	FUZZ_DEPS="$DEPS_LIB_SHARED"
46fi
47# Mess with the flags only in local execution
48if [[ $FUZZ_ENV == "local" &&  $FUZZ_CC == clang* ]]; then
49	# For coverage testing with clang uncomment
50	# 	FUZZ_CFLAGS="$COVERAGE_CFLAGS"
51	# 	FUZZ_LDFLAGS="$COVERAGE_LDFLAGS"
52
53	# Add fuzzer CFLAG only if not present
54	if [[ ! $FUZZ_CFLAGS =~ .*-fsanitize=([^\s].*)*fuzzer(-.*)* ]]; then
55		FUZZ_CFLAGS="$FUZZ_CFLAGS -fsanitize=fuzzer-no-link"
56	fi
57	# Add fuzzer LDFLAG only if not present
58	if [[ ! $FUZZ_LDFLAGS =~ .*-fsanitize=([^\s].*)*fuzzer(-.*)* ]]; then
59		# Link against libFuzzer only if FUZZ_ENGINE has not been set
60		if [[ ! -z $FUZZ_ENGINE ]]; then
61			FUZZ_LDFLAGS="$FUZZ_LDFLAGS -fsanitize=fuzzer-no-link"
62		else
63			FUZZ_LDFLAGS="$FUZZ_LDFLAGS -fsanitize=fuzzer"
64		fi
65	fi
66fi
67
68rm -f $WORK/*.a $WORK/*.o
69
70# Build and archive necessary Janus objects
71JANUS_LIB="$WORK/janus-lib.a"
72cd $SRC/$JANUSGW
73# Use this variable to skip Janus objects building
74SKIP_JANUS_BUILD=${SKIP_JANUS_BUILD-"0"}
75if [ "$SKIP_JANUS_BUILD" -eq "0" ]; then
76	echo "Building Janus objects"
77	./autogen.sh
78	./configure CC="$FUZZ_CC" CFLAGS="$FUZZ_CFLAGS" $JANUS_CONF_FLAGS
79	make clean
80	make -j$(nproc) $JANUS_OBJECTS
81fi
82ar rcs $JANUS_LIB $JANUS_OBJECTS
83cd -
84
85# Build standalone fuzzing engines
86engines=$(find $SRC/$JANUSGW/fuzzers/engines/ -name "*.c")
87for sourceFile in $engines; do
88  name=$(basename $sourceFile .c)
89  echo "Building engine: $name"
90  $FUZZ_CC -c $FUZZ_CFLAGS $sourceFile -o $WORK/$name.o
91done
92
93# Build Fuzzers
94mkdir -p $OUT
95fuzzers=$(find $SRC/$JANUSGW/fuzzers/ -name "*.c" | grep -v "engines/")
96for sourceFile in $fuzzers; do
97  name=$(basename $sourceFile .c)
98  echo "Building fuzzer: $name"
99
100  $FUZZ_CC -c $FUZZ_CFLAGS $DEPS_CFLAGS -I. -I$SRC/$JANUSGW $sourceFile -o $WORK/$name.o
101  $FUZZ_CCLD $FUZZ_LDFLAGS $WORK/${name}.o -o $OUT/${name} $FUZZ_ENGINE $JANUS_LIB $FUZZ_DEPS
102
103  if [ -d "$SRC/$JANUSGW/fuzzers/corpora/${name}" ]; then
104	echo "Exporting corpus: $name "
105	zip -jqr --exclude=*LICENSE* $OUT/${name}_seed_corpus.zip $SRC/$JANUSGW/fuzzers/corpora/${name}
106  fi
107done
108