August 02, 2019 posted by Kamil Rytarowski

Prepared by Siddharth Muralee(@R3x) as a part of Google Summer of Code’19

As a part of Google Summer of Code’19, I am working on improving the support for Syzkaller kernel fuzzer. Syzkaller is an unsupervised coverage-guided kernel fuzzer, that supports a variety of operating systems including NetBSD. This report details the work done during the second coding period.

You can also take a look at the first report to learn more about the initial support that we added.

Network Packet Injection

As a part of improving the fuzzing support for the NetBSD kernel. We decided to add support for fuzzing the Network stack. This feature already exists for operating systems such as Linux and OpenBSD.

Motivation

The aim is to fuzz the Network stack by sending packets with malformed/random data and see if it causes any kernel anomalies. We aim to send packets in such a way that the code paths in the kernel which would usually get triggered normally (during ordinary usage of the networking system) would also get triggered here. This is achieved using the TAP/TUN interface.

TAP/TUN Interface

TAP/TUN interface is a software-only interface - which means there are no hardware links involved. This makes it an ideal option to be used for interacting with the kernel networking code.

Userspace programs can create TAP/TUN interfaces and then write properly formatted data into it which will then be sent to the kernel. Also reading from the TAP/TUN interface would give us the data that the interface is sending out.

Basic Design

We create a virtual interface using TAP/TUN and send packets through it. We add two syscalls - syz_emit_ethernet and syz_extract_tcp_res. The former does the job of sending a packet into the kernel and the latter receives the response.

We need the response from the kernel to be read because we need the TCP acknowledgement number to be used for the next packet that we send. So syz_extract_tcp_res also extracts the acknowledgement number from the reply the kernel sent. This article explains the concept of TCP acknowledgement and sequence numbers very well.

Parallelizing Network fuzzing

In the syzkaller config you can define the number of processes that syzkaller can run in a single VM instance. And since we can have multiple instances of the fuzzer(executor) running at the same time we need to make sure that there is no collision between the interfaces. For solving this we create a seperate interface per fuzzer and assign it with a different IP address (both IPv4 and IPv6) to create an isolated network.

Filesystem Image fuzzing

A very less explored area in fuzzing is Filesystem image fuzzing. Syzkaller supports filesystem fuzzing only for the Linux kernel. We are currently working on porting the existing support that Linux has and then improve it.

Motivation

The aim is to fuzz filesystem specific code by mounting custom images and then perform operations on these images. This would lead to execution of the kernel components of filesystem code and allow us to find out potential bugs.

Existing Design

As I mentioned in the previous report - syzkaller generats inputs based on a pseudo formal grammar. This allows us to also write grammar to generate filesystem images on the fly. This is what the current implementation does - generate random images, write the segments into memory and then mount the resulting image.

Miscellaneous work

I have also been fine tuning the syzkaller fuzzer whenever necessary. This involves adding new features and fixing issues.

Coverage Display

Syzkaller has a utility which uses the coverage from KCoV and marks the corresponding lines on the source code and displays the same. This feature wasn’t working for some of the operating systems.

The issue was that syzkaller was trying to strip off the common prefix on all the file paths retrieved from Kcov and then appending the directory where the source code is present to access the files.

Stripping the common prefix made sense for Linux since its files were distributed across multiple folders in the src/ directory. This created issues for NetBSD since almost all of the kernel files are present in src/sys/ which lead to `sys` also being removed from the resultant path leading to an invalid file name.

I worked on revamping the syz-manager such that it removes prefix computation altogether and take the prefix we need to strip as a part of the config for syz-manager. Then we add the filepath of the kernel sources to get the path to the file.

The coverage for NetBSD can be viewed on the NetBSD dashboard.

TODO

The Filesystem fuzzing code isn’t upstream as of now and will be done shortly.

I have added a basic support for fuzzing both the Filesystem and the Network stack. Now there are a lot of improvements to be done for the same. This mainly involves adding more detailed and improved descriptions.

Relevant Links

Summary

So far, we have found around 70 unique crashes with syzkaller. During the final coding period - I would be working on improving the support for the Filesystem fuzzing.

Last but not least, I want to thank my mentors, @kamil and @cryo for their useful suggestions and guidance. I would also like to thank Dmitry Vyukov, Google for helping with any issues faced with regard to Syzkaller. Finally, thanks to Google to give me a good chance to work with NetBSD community.