libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

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