1#!/bin/bash
2#
3# Copyright 2013 Gerald Combs <gerald@wireshark.org>
4#
5# Wireshark - Network traffic analyzer
6# By Gerald Combs <gerald@wireshark.org>
7# Copyright 1998 Gerald Combs
8#
9# SPDX-License-Identifier: GPL-2.0-or-later
10
11# Common variables and functions for fuzz and randpkt tests.
12
13# This needs to point to a 'date' that supports %s.
14if [ -z "$TEST_TYPE" ] ; then
15    echo "TEST_TYPE must be defined by the sourcing script."
16    exit 1
17fi
18
19DATE=/bin/date
20BASE_NAME=$TEST_TYPE-$($DATE +%Y-%m-%d)-$$
21
22# Directory containing binaries.  Default: cmake run directory.
23if [ -z "$WIRESHARK_BIN_DIR" ]; then
24    WIRESHARK_BIN_DIR=run
25fi
26
27# Temporary file directory and names.
28# (had problems with this on cygwin, tried TMP_DIR=./ which worked)
29TMP_DIR=/tmp
30if [ "$OSTYPE" == "cygwin" ] ; then
31        TMP_DIR=$(cygpath --windows "$TMP_DIR")
32fi
33TMP_FILE=$BASE_NAME.pcap
34ERR_FILE=$BASE_NAME.err
35
36# Loop this many times (< 1 loops forever)
37MAX_PASSES=0
38
39# These may be set to your liking
40# Stop the child process if it's running longer than x seconds
41MAX_CPU_TIME=600
42# Stop the child process if it's using more than y * 1024 bytes
43MAX_VMEM=1000000
44# Stop the child process if its stack is larger than than z * 1024 bytes
45# Windows XP:    2033
46# Windows 7:     2034
47# Mac OS X 10.6: 8192
48# Linux 2.6.24:  8192
49# Solaris 10:    8192
50MAX_STACK=2033
51# Insert z times an error into the capture file (0.02 seems to be a good value to find errors)
52ERR_PROB=0.02
53
54# Call *after* any changes to WIRESHARK_BIN_DIR (e.g., via command-line options)
55function ws_bind_exec_paths() {
56# Tweak the following to your liking.  Editcap must support "-E".
57TSHARK="$WIRESHARK_BIN_DIR/tshark"
58EDITCAP="$WIRESHARK_BIN_DIR/editcap"
59CAPINFOS="$WIRESHARK_BIN_DIR/capinfos"
60RANDPKT="$WIRESHARK_BIN_DIR/randpkt"
61
62if [ "$WIRESHARK_BIN_DIR" = "." ]; then
63    export WIRESHARK_RUN_FROM_BUILD_DIRECTORY=1
64fi
65}
66
67function ws_check_exec() {
68NOTFOUND=0
69for i in "$@" ; do
70    if [ ! -x "$i" ]; then
71        echo "Couldn't find \"$i\""
72        NOTFOUND=1
73    fi
74done
75if [ $NOTFOUND -eq 1 ]; then
76    exit 1
77fi
78}
79
80##############################################################################
81### Set up environment variables for fuzz testing			   ###
82##############################################################################
83# Use the Wmem strict allocator which does canaries and scrubbing etc.
84export WIRESHARK_DEBUG_WMEM_OVERRIDE=strict
85# Abort if a dissector adds too many items to the tree
86export WIRESHARK_ABORT_ON_TOO_MANY_ITEMS=
87
88# Turn on GLib memory debugging (since 2.13)
89export G_SLICE=debug-blocks
90# Cause glibc (Linux) to abort() if some memory errors are found
91export MALLOC_CHECK_=3
92# Cause FreeBSD (and other BSDs) to abort() on allocator warnings and
93# initialize allocated memory (to 0xa5) and freed memory (to 0x5a).  see:
94# https://www.freebsd.org/cgi/man.cgi?query=malloc&apropos=0&sektion=0&manpath=FreeBSD+8.2-RELEASE&format=html
95export MALLOC_OPTIONS=AJ
96
97# macOS options; see https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html
98# Initialize allocated memory to 0xAA and freed memory to 0x55
99export MallocPreScribble=1
100export MallocScribble=1
101# Add guard pages before and after large allocations
102export MallocGuardEdges=1
103# Call abort() if heap corruption is detected.  Heap is checked every 1000
104# allocations (may need to be tuned!)
105export MallocCheckHeapStart=1000
106export MallocCheckHeapEach=1000
107export MallocCheckHeapAbort=1
108# Call abort() if an illegal free() call is made
109export MallocBadFreeAbort=1
110
111# Address Sanitizer options
112export ASAN_OPTIONS=detect_leaks=0
113
114# See if we were configured with gcc or clang's AddressSanitizer.
115CONFIGURED_WITH_ASAN=0
116# If tshark is built with ASAN this will generate an error. We could
117# also pass help=1 and look for help text.
118ASAN_OPTIONS=Invalid_Option_Flag $TSHARK -h > /dev/null 2>&1
119if [ $? -ne 0 ] ; then
120    CONFIGURED_WITH_ASAN=1
121fi
122export CONFIGURED_WITH_ASAN
123
124# Create an error report
125function ws_exit_error() {
126    echo -e "\n ERROR"
127    echo -e "Processing failed. Capture info follows:\n"
128    echo "  Input file: $CF"
129    echo "  Output file: $TMP_DIR/$TMP_FILE"
130    echo "  Pass: $PASS"
131    echo
132
133    # Fill in build information
134    {
135        echo -e "Branch: $(git rev-parse --abbrev-ref HEAD)\n"
136        echo -e "Input file: $CF\n"
137        echo -e "Build host information:"
138        uname -srvm
139        lsb_release -a 2> /dev/null
140
141        if [ -n "$CI_COMMIT_BRANCH" ] ; then
142            echo -e "\nBranch: $CI_COMMIT_BRANCH"
143        fi
144
145        if [ -n "$CI_JOB_NAME" ] ; then
146            echo -e "\nCI job name: $CI_JOB_NAME, ID: $CI_JOB_ID"
147        fi
148
149        echo -e "\nReturn value: " $RETVAL
150        echo -e "\nDissector bug: " $DISSECTOR_BUG
151        echo -e "\nValgrind error count: " $VG_ERR_CNT
152
153        if [ -d "${GIT_DIR:-.git}" ] ; then
154                echo -e "\nLatest (but not necessarily the problem) commit:"
155                git log --max-count=1 --oneline
156        fi
157    } > "$TMP_DIR/${ERR_FILE}.header"
158
159    # Trim the stderr output if needed
160    ERR_SIZE=$(du -sk $TMP_DIR/$ERR_FILE | awk '{ print $1 }')
161    if [ $ERR_SIZE -ge 5000 ] ; then
162        mv $TMP_DIR/$ERR_FILE $TMP_DIR/${ERR_FILE}.full
163        head -n 2000 $TMP_DIR/${ERR_FILE}.full > $TMP_DIR/$ERR_FILE
164        echo -e "\n\n[ Output removed ]\n\n" >> $TMP_DIR/$ERR_FILE
165        tail -n 2000 $TMP_DIR/${ERR_FILE}.full >> $TMP_DIR/$ERR_FILE
166        rm -f $TMP_DIR/${ERR_FILE}.full
167    fi
168
169    cat $TMP_DIR/${ERR_FILE} >> $TMP_DIR/${ERR_FILE}.header
170    mv $TMP_DIR/${ERR_FILE}.header $TMP_DIR/${ERR_FILE}
171
172    echo -e "stderr follows:\n"
173    cat $TMP_DIR/$ERR_FILE
174
175    exit 255
176}
177