a6dc4f1d3a
The setup instructions now reflect the steps needed to fuzz a recent FreeBSD-CURRENT system. The previous instructions were written for 11.0-era FreeBSD and can be simplified. Steps required only on older versions (e.g., 11.2 or 12.0) can be re-added if there is demand, but it is expect that most syzkaller users are FreeBSD developers running -CURRENT. - Remove completed TODOs. - Document how to build and install a KCOV-enabled kernel. - Update set-up steps for a FreeBSD host. The newly added llvm metaport makes it unnecessary to compile clang-format. The stock QEMU package works fine on FreeBSD-CURRENT and it is not necessary to compile QEMU binaries anymore. - Document steps for preparing an image to be fuzzed under GCE as well as QEMU. (The required steps are identical aside from syz-manager configuration.) |
||
---|---|---|
.. | ||
found_bugs.md | ||
README.md |
FreeBSD
This page contains instructions to set up syzkaller to run on a FreeBSD or Linux host and fuzz an amd64 FreeBSD kernel running in a virtual machine.
Currently, syzkaller can fuzz FreeBSD running under QEMU or GCE (Google Compute Engine). Regardless of the mode of operation, some common steps must be followed.
Setting up a host
syz-manager
is the component of syzkaller that manages target VMs. It runs on a host system and automatically creates, runs and destroys VMs which share a user-specified image file.
Setting up a FreeBSD host
To build syzkaller out of the box, a recent version of FreeBSD 13.0-CURRENT must be used for the host. Older versions of FreeBSD can be used but will require manual tweaking.
The required dependencies can be installed by running:
$ sudo pkg install bash gcc git gmake go llvm
To checkout the syzkaller sources, run:
$ go get -u -d github.com/google/syzkaller/...
and the binaries can be built by running:
$ cd go/src/github.com/google/syzkaller/
$ gmake
Once this completes, a syz-manager
executable should be available under bin/
.
Setting up a Linux host
To build Go binaries do:
make manager fuzzer execprog TARGETOS=freebsd
To build C syz-executor
binary, copy executor/*
files to a FreeBSD machine and build there with:
c++ executor/executor_freebsd.cc -o syz-executor -O1 -lpthread -DGOOS=\"freebsd\" -DGIT_REVISION=\"CURRENT_GIT_REVISION\"
Then, copy out the binary back to host into bin/freebsd_amd64
dir.
Setting up the FreeBSD VM
It is easiest to start with a snapshot image of FreeBSD. Fetch a QCOW2 disk image for QEMU or a raw image for GCE.
To enable KCOV on FreeBSD, a custom kernel must be compiled. It is easiest to do this in the VM itself. Use QEMU to start a VM using the downloaded image:
$ qemu-system-x86_64 -hda $IMAGEFILE -nographic -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -net nic,model=e1000
When the boot loader menu is printed, escape to the loader prompt and enter the commands set console="comconsole"
and boot
. Once you reach a login prompt, log in as root and add a couple of configuration parameters to /boot/loader.conf
:
# cat <<__EOF__ >>/boot/loader.conf
autoboot_delay="-1"
console="comconsole"
__EOF__
Fetch a copy of the FreeBSD kernel sources and place them in /usr/src
. For instance, to get a copy of the current development sources, run:
# pkg install git
# git clone --depth=1 --branch=master https://github.com/freebsd/freebsd /usr/src
To create a custom kernel configuration file for syzkaller and build a new kernel, run:
# cd /usr/src/sys/amd64/conf
# cat <<__EOF__ > SYZKALLER
include "./GENERIC"
ident SYZKALLER
options COVERAGE
options KCOV
__EOF__
# cd /usr/src
# make -j $(sysctl -n hw.ncpu) KERNCONF=SYZKALLER buildkernel
# make KERNCONF=SYZKALLER installkernel
# shutdown -r now
When the VM is restarted, verify that uname -i
prints SYZKALLER
to confirm that your newly built kernel is running.
Then, to permit remote access to the VM, you must configure DHCP and enable sshd
:
# sysrc sshd_enable=YES
# sysrc ifconfig_DEFAULT=DHCP
If you plan to run the syscall executor as root, ensure that root SSH logins are permitted by adding PermitRootLogin without-password
to /etc/ssh/sshd_config
. Otherwise, create a new user with adduser
. Install an ssh key for the user and verify that you can SSH into the VM from the host.
If all of the above worked, create a freebsd.cfg
configuration file with the following contents (alter paths as necessary):
{
"name": "freebsd",
"target": "freebsd/amd64",
"http": ":10000",
"workdir": "/workdir",
"syzkaller": "/gopath/src/github.com/google/syzkaller",
"image": "/FreeBSD-13.0-CURRENT-amd64.qcow2",
"sshkey": "/freebsd_id_rsa",
"sandbox": "none",
"procs": 8,
}
If running the fuzzer under QEMU, add:
"type": "qemu",
"vm": {
"count": 10,
"cpu": 4,
"mem": 2048
}
For GCE, add the following instead (alter the storage bucket path as necessary):
"type": "gce",
"vm": {
"count": 10,
"instance_type": "n1-standard-4",
"gcs_path": "syzkaller"
}
Then, start syz-manager
with:
$ bin/syz-manager -config freebsd.cfg
It should start printing output along the lines of:
booting test machines...
wait for the connection from test machine...
machine check: 253 calls enabled, kcov=true, kleakcheck=false, faultinjection=false, comps=false
executed 3622, cover 1219, crashes 0, repro 0
executed 7921, cover 1239, crashes 0, repro 0
executed 32807, cover 1244, crashes 0, repro 0
executed 35803, cover 1248, crashes 0, repro 0
If something does not work, try adding the -debug
flag to syz-manager
.
Missing things
- System call descriptions.
sys/freebsd/*.txt
is a dirty copy fromsys/linux/*.txt
with everything that does not compile dropped. We need to go through syscalls and verify/fix/extend them, including devices/ioctls/etc. - Currently only the
amd64
arch is supported. It would be useful to support a 32-bit executor in order to cover 32-bit compatibility syscalls. - We should support fuzzing the Linux compatibility subsystem.
pkg/csource
needs to be taught how to generate/build C reproducers.pkg/host
needs to be taught how to detect supported syscalls/devices.pkg/report
/pkg/symbolizer
need to be taught how to extract/symbolize kernel crash reports.- KASAN for FreeBSD would be useful.
- On Linux we have emission of exernal networking/USB traffic into kernel using tun/gadgetfs. Implementing these for FreeBSD could uncover a number of high-profile bugs.