zzuf_socat_test_runner.sh (6194B)
1 #!/bin/sh 2 # 3 # Run one fuzzing test with zzuf fuzzing a socat relay that sits between 4 # the test clients and MHD. This mode is mandatory when MHD is built with 5 # sanitizers (zzuf and the sanitizers cannot both intercept the standard 6 # library calls) or when MHD uses accept4(). 7 # 8 # Recognised environment variables: 9 # ZZUF the zzuf command (set by configure) 10 # ZZUF_SEED the single seed to use (default "0") 11 # ZZUF_SEED_START the first seed of a seed range (overrides ZZUF_SEED) 12 # ZZUF_SEED_STOP the last seed of a seed range 13 # ZZUF_FLAGS additional flags for zzuf 14 # SOCAT the socat command (set by configure) 15 # SOCAT_FLAGS additional flags for socat 16 # 17 # This script is POSIX shell only, do not use any bashism. 18 19 if set -m ; then : ; else 20 echo "The shell $SHELL does not support background jobs, the test cannot run." 1>&2 21 exit 77 22 fi 23 24 socat_listen_ip='127.0.0.121' 25 socat_listen_port='10121' 26 mhd_listen_port='4010' 27 max_runtime_sec='1800' 28 29 if test "x${ZZUF}" = "xno" ; then 30 echo "zzuf command missing" 1>&2 31 exit 77 32 fi 33 34 if command -v "${ZZUF}" > /dev/null 2>&1 ; then : ; else 35 echo "zzuf command missing" 1>&2 36 exit 77 37 fi 38 39 if test "x${SOCAT}" = "xno" ; then 40 echo "socat command missing" 1>&2 41 exit 77 42 fi 43 44 if command -v "${SOCAT}" > /dev/null 2>&1 ; then : ; else 45 echo "socat command missing" 1>&2 46 exit 77 47 fi 48 49 # Build the "--seed" parameter for zzuf. 50 zzuf_seed_param='' 51 if test -n "${ZZUF_SEED_START}" ; then 52 if test -n "${ZZUF_SEED_STOP}" ; then 53 zzuf_seed_param="--seed=${ZZUF_SEED_START}:${ZZUF_SEED_STOP}" 54 seed_descr="range ${ZZUF_SEED_START}:${ZZUF_SEED_STOP}" 55 else 56 zzuf_seed_param="--seed=${ZZUF_SEED_START}" 57 seed_descr="${ZZUF_SEED_START}" 58 fi 59 elif test -n "${ZZUF_SEED}" ; then 60 zzuf_seed_param="--seed=${ZZUF_SEED}" 61 seed_descr="${ZZUF_SEED}" 62 else 63 seed_descr="(zzuf default)" 64 fi 65 66 test_descr="$*" 67 test_name=`echo "$1" | sed 's|^.*/||'` 68 69 # Print a loud, easy to grep report about a failing run. 70 # In this mode zzuf fuzzes socat, while the test program (and MHD) runs 71 # outside of zzuf, so the exit code below is the exit code (or the signal) 72 # of the *server side* and the seed is the one this run was started with. 73 # $1: the exit code of the test program 74 report_failure () 75 { 76 echo '' 1>&2 77 echo '###############################################################' 1>&2 78 echo '## FUZZING TEST FAILED (server side)' 1>&2 79 echo "## test : ${test_descr}" 1>&2 80 echo "## exit code : $1" 1>&2 81 if test "$1" -gt 128 2> /dev/null ; then 82 echo "## (killed by signal `expr $1 - 128`)" 1>&2 83 fi 84 echo "## FAILING SEED: ${seed_descr}" 1>&2 85 echo '## Replay with:' 1>&2 86 if test -n "${ZZUF_SEED_START}" ; then 87 echo "## make ZZUF_SEED_START=${ZZUF_SEED_START} \ 88 ZZUF_SEED_STOP=${ZZUF_SEED_STOP} TESTS=${test_name} check" 1>&2 89 else 90 echo "## make ZZUF_SEED=${ZZUF_SEED} TESTS=${test_name} check" 1>&2 91 fi 92 echo '###############################################################' 1>&2 93 echo '' 1>&2 94 } 95 96 socat_test_params="-ls -lu \ 97 -T0.1 -4 \ 98 TCP-LISTEN:${socat_listen_port},bind=${socat_listen_ip},reuseaddr,linger=2,linger2=1,accept-timeout=0.1 \ 99 TCP:127.0.0.1:${mhd_listen_port},reuseaddr" 100 101 echo "## Trying to run socat to test ports availability..." 102 if "${SOCAT}" ${socat_test_params} ; then 103 echo "Success." 104 else 105 echo "socat test run failed" 1>&2 106 exit 77 107 fi 108 109 # fuzz the input only for IP ${socat_listen_ip}. libcurl and the raw client 110 # use another IP in these tests, therefore the input of the clients is not 111 # fuzzed. 112 zzuf_all_params="--ratio=0.001:0.4 --autoinc --verbose --signal \ 113 --max-usertime=${max_runtime_sec} --check-exit --network --allow=${socat_listen_ip} --exclude=." 114 115 if test -n "${zzuf_seed_param}" ; then 116 zzuf_all_params="${zzuf_all_params} ${zzuf_seed_param}" 117 fi 118 119 if test -n "${ZZUF_FLAGS}" ; then 120 zzuf_all_params="${zzuf_all_params} ${ZZUF_FLAGS}" 121 fi 122 123 # Uncomment the next line to see more zzuf data in logs 124 #zzuf_all_params="${zzuf_all_params} -dd" 125 126 socat_options="-ls -lu \ 127 -T3 -4" 128 socat_addr1="TCP-LISTEN:${socat_listen_port},bind=${socat_listen_ip},reuseaddr,nodelay,linger=2,linger2=1,accept-timeout=${max_runtime_sec},fork" 129 socat_addr2="TCP:127.0.0.1:${mhd_listen_port},reuseaddr,connect-timeout=3,nodelay,linger=2,linger2=1" 130 131 if test -n "${SOCAT_FLAGS}" ; then 132 socat_options="${socat_options} ${SOCAT_FLAGS}" 133 fi 134 135 # Uncomment the next line to see more socat data in logs 136 #socat_options="${socat_options} -dd -D" 137 138 # Uncomment the next line to see all traffic in logs 139 #socat_options="${socat_options} -v" 140 141 stop_zzuf_socat () 142 { 143 trap - EXIT 144 if test -n "$zzuf_pid" ; then 145 echo "The test has been interrupted." 1>&2 146 test "x$zzuf_pid" = "xstarting" && zzuf_pid=$! 147 # Finish zzuf + socat 148 kill -TERM ${zzuf_pid} -${zzuf_pid} 149 # Finish the test 150 kill -INT %2 2> /dev/null || kill -INT %1 2> /dev/null 151 exit 99 152 fi 153 } 154 155 echo "## Starting zzuf with socat to reflect fuzzed traffic (seed: ${seed_descr})..." 156 trap 'stop_zzuf_socat' EXIT 157 zzuf_pid="starting" 158 "${ZZUF}" ${zzuf_all_params} "${SOCAT}" ${socat_options} ${socat_addr1} ${socat_addr2} & 159 if test $? -eq 0 ; then 160 zzuf_pid=$! 161 echo "zzuf with socat has been started." 162 else 163 zzuf_pid='' 164 echo "Failed to start zzuf with socat" 1>&2 165 exit 99 166 fi 167 168 echo "## Starting real test of $* with traffic fuzzed by zzuf with socat..." 169 "$@" --with-socat 170 test_result=$? 171 trap - EXIT 172 echo "$* has exited with the return code $test_result" 173 if kill -s 0 -- $$ 2> /dev/null ; then 174 if kill -s 0 -- ${zzuf_pid} -${zzuf_pid} 2> /dev/null ; then : ; else 175 echo "No running zzuf with socat is detected after the test." 1>&2 176 echo "Looks like zzuf ended prematurely, at least part of the testing has not been performed." 1>&2 177 if test "x${test_result}" = "x0" ; then 178 test_result=99 179 else 180 echo "The test itself has already failed with the code ${test_result}," 1>&2 181 echo "this code is kept as the result of this run." 1>&2 182 fi 183 fi 184 fi 185 kill -TERM ${zzuf_pid} -${zzuf_pid} 2> /dev/null 186 zzuf_pid='' 187 if test "x${test_result}" != "x0" && test "x${test_result}" != "x77" ; then 188 report_failure "${test_result}" 189 fi 190 exit $test_result