GitLab CI: Add a minimal fuzzing job.

Add a -t option to tools/fuzz-test.sh which lets you specify a maximum
fuzz time.

Add an initial "fuzz-test" job which fuzzes test/captures/* for 5
minutes. To do: Fuzz longer using our capture menagerie and report
failures.
This commit is contained in:
Gerald Combs 2021-05-04 12:22:32 -07:00 committed by Wireshark GitLab Utility
parent 83dc9a247e
commit d7bdd77a4c
2 changed files with 47 additions and 11 deletions

View File

@ -59,6 +59,11 @@ variables:
.if-daily-schedule:
- if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "daily"'
when: always
# Fuzz jobs. Care should be taken when changing this since the scheduler
# often doesn't report errors.
.if-fuzz-schedule:
- if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "fuzz"'
when: always
.build:
stage: build
@ -570,3 +575,24 @@ sloccount:
- sloccount . | awk "/^Computing results/ { results=1 } { if (results) print }" > $SLOC_OUT
- cat $SLOC_OUT
- if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ] && [ -n "$S3_DESTINATION_ANALYSIS" ] ; then aws s3 cp "$SLOC_OUT" "$S3_DESTINATION_ANALYSIS/" ; fi
fuzz-test:
extends: .build-ubuntu
rules: !reference [.if-fuzz-schedule]
stage: test
resource_group: fuzz-master
variables:
MIN_PLUGINS: 10
MAX_PASSES: 5
script:
- mkdir /tmp/fuzz
# - JOB_START_SECS=$( date -d "$CI_JOB_STARTED_AT" +%s )
- cmake -G Ninja -DBUILD_wireshark=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=ON ..
- ninja
# - MAX_SECONDS=$(( 3600 - ( $( date +%s ) - $JOB_START_SECS ) - 300 ))
- MAX_SECONDS=300
- cd ..
- FUZZ_PASSED=false
- ./tools/fuzz-test.sh -a -2 -P $MIN_PLUGINS -b ./build/run -d /tmp/fuzz -t $MAX_SECONDS $( shuf -e test/captures/* ) 2> fuzz-test.err && FUZZ_PASSED=true
- if $FUZZ_PASSED ; then exit 0 ; fi
- echo Fuzzing failed.

View File

@ -22,8 +22,8 @@ TEST_TYPE="fuzz"
# Sanity check to make sure we can find our plugins. Zero or less disables.
MIN_PLUGINS=0
# Did we catch a signal?
DONE=0
# Did we catch a signal or time out?
DONE=false
# Currently running children
RUNNER_PIDS=
@ -48,8 +48,12 @@ CHANGE_OFFSET=0
# Only has effect when running under valgrind.
MAX_LEAK=$(( 1024 * 100 ))
# Our maximum run time.
START_SECONDS=$SECONDS
MAX_SECONDS=$(( START_SECONDS + 86400 ))
# To do: add options for file names and limits
while getopts "2b:C:d:e:agp:P:o:" OPTCHAR ; do
while getopts "2b:C:d:e:agp:P:o:t:" OPTCHAR ; do
case $OPTCHAR in
a) ASAN=1 ;;
2) TWO_PASS="-2 " ;;
@ -61,6 +65,7 @@ while getopts "2b:C:d:e:agp:P:o:" OPTCHAR ; do
p) MAX_PASSES=$OPTARG ;;
P) MIN_PLUGINS=$OPTARG ;;
o) CHANGE_OFFSET=$OPTARG ;;
t) MAX_SECONDS=$(( START_SECONDS + OPTARG )) ;;
*) printf "Unknown option %s" "$OPTCHAR"
esac
done
@ -145,7 +150,7 @@ echo ""
# Clean up on <ctrl>C, etc
trap_all() {
DONE=1
DONE=true
echo 'Caught signal'
}
@ -161,14 +166,14 @@ trap trap_abrt ABRT
# Iterate over our capture files.
PASS=0
while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne 1 ] ; do
while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && ! $DONE ; do
PASS=$(( PASS+1 ))
echo "Starting pass $PASS:"
RUN=0
for CF in "$@" ; do
if [ $DONE -eq 1 ]; then
break # We caught a signal
if $DONE; then
break # We caught a signal or timed out
fi
RUN=$(( RUN + 1 ))
if [ $(( RUN % 50 )) -eq 0 ] ; then
@ -185,7 +190,7 @@ while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne
echo "Not a valid capture file"
rm -f "$TMP_DIR/$ERR_FILE"
continue
elif [ $RETVAL -ne 0 ] && [ $DONE -ne 1 ] ; then
elif [ $RETVAL -ne 0 ] && ! $DONE ; then
# Some other error
ws_exit_error
fi
@ -208,7 +213,7 @@ while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne
RUNNER_PIDS=
RUNNER_ERR_FILES=
for ARGS in "${RUNNER_ARGS[@]}" ; do
if [ $DONE -eq 1 ]; then
if $DONE; then
break # We caught a signal
fi
echo -n "($ARGS) "
@ -242,6 +247,11 @@ while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne
RUNNER_PID=$!
RUNNER_PIDS="$RUNNER_PIDS $RUNNER_PID"
RUNNER_ERR_FILES="$RUNNER_ERR_FILES $TMP_DIR/$ERR_FILE.$RUNNER_PID"
if [ $SECONDS -ge $MAX_SECONDS ] ; then
printf "\nStopping after %d seconds.\n" $(( SECONDS - START_SECONDS ))
DONE=true
fi
done
for RUNNER_PID in $RUNNER_PIDS ; do
@ -254,7 +264,7 @@ while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne
#grep -i "dissector bug" $TMP_DIR/$ERR_FILE \
# > /dev/null 2>&1 && DISSECTOR_BUG=1
if [ $VALGRIND -eq 1 ] && [ $DONE -ne 1 ]; then
if [ $VALGRIND -eq 1 ] && ! $DONE; then
VG_ERR_CNT=$( grep "ERROR SUMMARY:" "$TMP_DIR/$ERR_FILE" | cut -f4 -d' ' )
VG_DEF_LEAKED=$( grep "definitely lost:" "$TMP_DIR/$ERR_FILE" | cut -f7 -d' ' | tr -d , )
VG_IND_LEAKED=$( grep "indirectly lost:" "$TMP_DIR/$ERR_FILE" | cut -f7 -d' ' | tr -d , )
@ -273,7 +283,7 @@ while { [ $PASS -lt "$MAX_PASSES" ] || [ "$MAX_PASSES" -lt 1 ]; } && [ $DONE -ne
fi
fi
if [ $DONE -ne 1 ] && { [ $RUNNER_RETVAL -ne 0 ] || [ $DISSECTOR_BUG -ne 0 ] || [ $VG_ERR_CNT -ne 0 ]; } ; then
if $DONE && { [ $RUNNER_RETVAL -ne 0 ] || [ $DISSECTOR_BUG -ne 0 ] || [ $VG_ERR_CNT -ne 0 ]; } ; then
# shellcheck disable=SC2086
rm -f $RUNNER_ERR_FILES
ws_exit_error