The current oss-fuzz integration with Wireshark uses a special binary
(see tools/oss-fuzz/
in the Wireshark source tree) to generate a binary file
reflecting the data that is passed to a dissector. This data could for example
be passed to the DNS dissector or TCP dissector (with some port number).
The limitation of that approach is that some of the reported issues can not be reproduced with normal tshark since the file is not a packet capture file. Therefore another tool is needed to add the packet capture header. This project contains some tools to assist in automating oss-fuzz triaging.
The oss-fuzz-report.py
script creates a pcap and runs tshark
against it in
order to reproduce it. If issues are found, it will show a report (and report
issues automatically as needed). The grab-monorail.py
script relies on this
script to automate triaging even further, taking care of downloading the
reproducer file too.
Usual packet capture files have an encapsulation method like
LINKTYPE_ETHERNET
. The oss-fuzz-report.py
script creates a pcap file with a
single packet using the "Exported PDU" dissector method (link type 252). This
approach is used rather than using LINKTYPE_ETHERNET
to closer reflect how the
fuzzer is invoked: it bypasses the IP dissector and directly calls into TCP.
To test out-of-memory, timeout (possible infinite loop) reports and report
better call traces for g_error
, build additional tools with:
cc -shared -fPIC -o libmemlimit.so memlimit.c
cc -shared -fPIC -o libtimeout.so timeout.c
cc -shared -fPIC -o libtrapabort.so trapabort.c
The script has some protocols headers built-in, but for some others it needs the
samples_to_pcap
binary from the tools directory in
https://bitbucket.org/jwzawadzki/wireshark-fuzzdb (I plan to remove this
requirement later and incorporate all supported protocols in the script). Build
and move the binary in your $PATH
:
cc tools/samples_to_pcap.c -o ~/bin/samples_to_pcap
Optionally install symlinks for oss-fuzz-report.py and grab-monorail.py in your
$PATH
to make reproduction easier.
Wireshark must be built with ASAN/UBSAN (Address Sanitizer and Undefined Behavior Sanitizer). Debug mode is recommended to get meaningful stacktraces. Using CMake, this is what I would use:
mkdir /tmp/build && cd /tmp/build
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=1 -DENABLE_UBSAN=1 \
/path/to/sources/for/wireshark
The ENABLE_UBSAN
option was added in Wireshark 2.4 while ENABLE_ASAN
was
added in Wireshark 2.0. In older (and newer) versions you can replace those
options with:
-DCMAKE_C_FLAGS=-fsanitize=address,undefined \
-DCMAKE_CXX_FLAGS=-fsanitize=address,undefined
Note that in this way, you must disable memleak detection via an environment variable or the build fails with Lemon:
ASAN_OPTIONS=detect_leaks=0 ninja
Once an issue has been reproduced, it is possible to automatically file a bug. This is totally optional, you could also manually fill in the bugs form if you prefer.
To get started, generate a new token at
https://bugs.wireshark.org/bugzilla/userprefs.cgi?tab=apikey and save the
Bugzilla API key to ~/.cache/wireshark-bugzilla-apikey.txt
. Then install the
python-bugzilla library in this project:
git clone https://github.com/python-bugzilla/python-bugzilla
The version I currently tested with is v2.1.0 (commit 44045cbbb70b6777d3c8803459abac90c8799449 from 2017-03-30).
Requirements:
- Setup this project and build Wireshark as above
- Ensure that PATH contains tshark (e.g.
PATH=/tmp/wsbuild/run:$PATH
).
Assuming a mail like:
Subject: Issue 3535 in oss-fuzz: wireshark: Global-buffer-overflow in dissect_gtpv2_ie_common
...
wireshark: Global-buffer-overflow in dissect_gtpv2_ie_common
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3535
Detailed report: https://oss-fuzz.com/testcase?key=5241250057814016
Project: wireshark
Fuzzer: afl_wireshark_fuzzshark_ip_proto-udp
Fuzz target binary: fuzzshark_ip_proto-udp
Job Type: afl_asan_wireshark
Platform Id: linux
...
Reproducer Testcase:
https://oss-fuzz.com/download?testcase_id=5241250057814016
The key part is ip_proto-udp
which says that this issue was found by calling
the UDP dissector within an IP packet. The next important value is the issue ID
(3535 in this case), this is used to credit oss-fuzz and provide a reference for
more information.
The next step is to download the Reproducer Testcase and run it:
oss-fuzz-report.py --proto ip_proto-udp clusterfuzz-testcase-minimized-5241250057814016 3535
If it reports an error, add the --report
option so it will automatically file
a Bugzilla entry (of course do not do this if there is an existing report). This
requires a valid Bugzilla API key.
Since downloading the packet, configuring the protocol and providing the oss-fuzz issue ID is repetitive and error-prone work, I have further automated this.
First login to https://oss-fuzz.com/ and
https://bugs.chromium.org/p/oss-fuzz/issues, then copy the SACSID
cookies
using Cookie Manager extension by Rob W (for Firefox and Chrome).
Select the two SACSID cookies, use the "Export cookies" option from the menu in
the bottom, select output format "Netscape" and press the Export button. Save it
to a temporary file, e.g. /tmp/mc
. The file looks like:
#HttpOnly_bugs.chromium.org TRUE / TRUE 1552926226 SACSID ~...
#HttpOnly_oss-fuzz.com TRUE / TRUE 1564357360 session ...
These session cookies expire quite fast, so if you get unexpected errors and have specified a correct Issue ID, try to refresh the cookies manually.
Grab a file with:
grab-monorail.py -c /tmp/mc 3535
Use grab-monorail.py --help
for more options. In particular, --report
automatically reports a bug to Bugzilla, similarly to oss-fuzz-report.py
.
After confirming the bug above (and reporting it via the --report
option), you
could inform the oss-fuzz project. To help automating this, install
userscripts/oss-fuzz_monorail_helpers_for_Wireshark.user.js
(tested with
GreaseMonkey in Firefox). It will automatically populate the comment form with a
comment linking to the Wireshark bug and include its status.
There is also userscripts/Wireshark_oss-fuzz_bugzilla.user.js
which is used to
convert the Link columns in Bugzilla search queries into the Issue ID. Two named
queried shared by me (unfortunately this requires a Bugzilla account with
canconfirm permissions):
List of bugs:
- open "oss-fuzz" bugs in Wireshark Bugzilla
- all "oss-fuzz" bugs in Wireshark Bugzilla
- all proj-Wireshark issues on oss-fuzz issue tracker
Where to find oss-fuzz stuff related to Wireshark:
Alternative way to actually reproduce the exact issue reported by oss-fuzz:
- oss-fuzz docs: Reproducing OSS-Fuzz issues explains how to use the oss-fuzz tooling (requires Docker).
If you have further questions, feel free to contact me (https://lekensteyn.nl/) or the wireshark-dev mailing list.