5 # Fuzz-testing script for TShark
7 # This script uses Editcap to add random errors ("fuzz") to a set of
8 # capture files specified on the command line. It runs TShark on
9 # each fuzzed file and checks for errors. The files are processed
10 # repeatedly until an error is found.
12 # This needs to point to a 'date' that supports %s.
14 BASE_NAME=fuzz-`$DATE +%Y-%m-%d`-$$
16 # Directory containing binaries. Default current directory.
19 # Temporary file directory and names.
20 # (had problems with this on cygwin, tried TMP_DIR=./ which worked)
22 if [ "$OSTYPE" == "cygwin" ] ; then
23 TMP_DIR=`cygpath --windows "$TMP_DIR"`
25 TMP_FILE=$BASE_NAME.pcap
26 ERR_FILE=$BASE_NAME.err
28 # Loop this many times (< 1 loops forever)
31 # Perform a two pass analysis on the capture file?
34 # Specific config profile ?
37 # These may be set to your liking
38 # Stop the child process if it's running longer than x seconds
40 # Stop the child process if it's using more than y * 1024 bytes
42 # Stop the child process if its stack is larger than than z * 1024 bytes
49 # Insert z times an error into the capture file (0.02 seems to be a good value to find errors)
51 # Trigger an abort if a dissector finds a bug.
53 # Note that if ABORT is enabled there will be no info
54 # output to stderr about the DISSECTOR_BUG.
55 # (There'll just be a core-dump).
56 ###export WIRESHARK_ABORT_ON_DISSECTOR_BUG="True"
59 # To do: add options for file names and limits
60 while getopts ":b:d:e:C:Pp:" OPTCHAR ; do
63 C) CONFIG_PROFILE="-C $OPTARG " ;;
65 e) ERR_PROB=$OPTARG ;;
66 p) MAX_PASSES=$OPTARG ;;
70 shift $(($OPTIND - 1))
72 # Tweak the following to your liking. Editcap must support "-E".
73 TSHARK="$BIN_DIR/tshark"
74 EDITCAP="$BIN_DIR/editcap"
75 CAPINFOS="$BIN_DIR/capinfos"
77 if [ "$BIN_DIR" = "." ]; then
78 export WIRESHARK_RUN_FROM_BUILD_DIRECTORY=1
81 # set some limits to the child processes, e.g. stop it if it's running longer then MAX_CPU_TIME seconds
82 # (ulimit is not supported well on cygwin and probably other platforms, e.g. cygwin shows some warnings)
83 ulimit -S -t $MAX_CPU_TIME -v $MAX_VMEM -s $MAX_STACK
86 ### usually you won't have to change anything below this line ###
88 # TShark arguments (you won't have to change these)
89 # n Disable network object name resolution
90 # V Print a view of the details of the packet rather than a one-line summary of the packet
91 # x Cause TShark to print a hex and ASCII dump of the packet data after printing the summary or details
92 # r Read packet data from the following infile
93 TSHARK_ARGS="${CONFIG_PROFILE}${TWO_PASS}-nVxr"
96 for i in "$TSHARK" "$EDITCAP" "$CAPINFOS" "$DATE" "$TMP_DIR" ; do
98 echo "Couldn't find $i"
102 if [ $NOTFOUND -eq 1 ]; then
106 # Make sure we have a valid test set
109 if [ "$OSTYPE" == "cygwin" ] ; then
110 CF=`cygpath --windows "$CF"`
112 "$CAPINFOS" "$CF" > /dev/null 2>&1 && FOUND=1
113 if [ $FOUND -eq 1 ] ; then break ; fi
116 if [ $FOUND -eq 0 ] ; then
118 Error: No valid capture files found.
120 Usage: `basename $0` [-b bin_dir] [-C config_profile] [-p passes] [-d work_dir] [-P ] [-e error probability] capture file 1 [capture file 2]...
125 DISSECTOR_PLUGINS=`$TSHARK -G plugins | grep dissector | wc -l`
126 # 10 is an arbritary value.
127 if [ $DISSECTOR_PLUGINS -lt 10 ] ; then
128 echo "Error: Found fewer plugins than expected."
133 if [ $MAX_PASSES -gt 0 ]; then
134 HOWMANY="$MAX_PASSES passes"
136 echo "Running $TSHARK with args: $TSHARK_ARGS ($HOWMANY)"
139 # Clean up on <ctrl>C, etc
140 trap "rm -f $TMP_DIR/$TMP_FILE $TMP_DIR/$ERR_FILE; echo ""; exit 0" HUP INT TERM
143 ##############################################################################
144 ### Set up environment variables for fuzz testing ###
145 ##############################################################################
146 # Initialize (ep_ and se_) allocated memory to 0xBADDCAFE and freed memory
148 export WIRESHARK_DEBUG_SCRUB_MEMORY=
149 # Use canaries in se_ allocations (off by default due to the memory usage)
150 export WIRESHARK_DEBUG_SE_USE_CANARY=
151 # Verify that ep_ and se_ allocated memory is not passed to certain routines
152 # which need the memory to be persistent.
153 export WIRESHARK_EP_VERIFY_POINTERS=
154 export WIRESHARK_SE_VERIFY_POINTERS=
156 # Turn on GLib memory debugging (since 2.13)
157 export G_SLICE=debug-blocks
158 # Cause glibc (Linux) to abort() if some memory errors are found
159 export MALLOC_CHECK_=3
160 # Cause FreeBSD (and other BSDs) to abort() on allocator warnings and
161 # initialize allocated memory (to 0xa5) and freed memory (to 0x5a). see:
162 # http://www.freebsd.org/cgi/man.cgi?query=malloc&apropos=0&sektion=0&manpath=FreeBSD+8.2-RELEASE&format=html
163 export MALLOC_OPTIONS=AJ
165 # MacOS options; see http://developer.apple.com/library/mac/releasenotes/DeveloperTools/RN-MallocOptions/_index.html
166 # Initialize allocated memory to 0xAA and freed memory to 0x55
167 export MallocPreScribble=1
168 export MallocScribble=1
169 # Add guard pages before and after large allocations
170 export MallocGuardEdges=1
171 # Call abort() if heap corruption is detected. Heap is checked every 1000
172 # allocations (may need to be tuned!)
173 export MallocCheckHeapStart=1000
174 export MallocCheckHeapEach=1000
175 export MallocCheckHeapAbort=1
176 # Call abort() if an illegal free() call is made
177 export MallocBadFreeAbort=1
180 # Iterate over our capture files.
182 while [ $PASS -lt $MAX_PASSES -o $MAX_PASSES -lt 1 ] ; do
183 PASS=`expr $PASS + 1`
184 echo "Starting pass $PASS:"
189 if [ $(( $RUN % 50 )) -eq 0 ] ; then
192 if [ "$OSTYPE" == "cygwin" ] ; then
193 CF=`cygpath --windows "$CF"`
197 "$CAPINFOS" "$CF" > /dev/null 2> $TMP_DIR/$ERR_FILE
199 if [ $RETVAL -eq 1 ] ; then
200 echo "Not a valid capture file"
201 rm -f $TMP_DIR/$ERR_FILE
203 elif [ $RETVAL -ne 0 ] ; then
207 echo -e "Processing failed. Capture info follows:\n"
208 echo " Input file: $CF"
209 echo -e "stderr follows:\n"
210 cat $TMP_DIR/$ERR_FILE
216 "$EDITCAP" -E $ERR_PROB "$CF" $TMP_DIR/$TMP_FILE > /dev/null 2>&1
217 if [ $? -ne 0 ] ; then
218 "$EDITCAP" -E $ERR_PROB -T ether "$CF" $TMP_DIR/$TMP_FILE \
220 if [ $? -ne 0 ] ; then
221 echo "Invalid format for editcap"
226 "$TSHARK" $TSHARK_ARGS $TMP_DIR/$TMP_FILE \
227 > /dev/null 2>> $TMP_DIR/$ERR_FILE
229 # Uncomment the next two lines to enable dissector bug
231 #grep -i "dissector bug" $TMP_DIR/$ERR_FILE \
232 # > /dev/null 2>&1 && DISSECTOR_BUG=1
233 if [ $RETVAL -ne 0 -o $DISSECTOR_BUG -ne 0 ] ; then
236 echo -e "Processing failed. Capture info follows:\n"
237 echo " Output file: $TMP_DIR/$TMP_FILE"
238 echo -e "stderr follows:\n"
239 cat $TMP_DIR/$ERR_FILE
243 rm -f $TMP_DIR/$TMP_FILE $TMP_DIR/$ERR_FILE