Table of Contents
syzkaller with Ubuntu host and FreeBSD guest
syzkaller is a fuzzer that test system calls. Therefore, it starts one or more VMs in order to test system calls on the OS (target) inside the VM.
syzkaller consists of three main components. syz-manager runs on the host. It starts the VMs and connects to them via SSH. syz-fuzzer runs inside a VM. It maintains one or more syz-executor, syz-executor actually executes the system call on the target.
To be able to start a VM, syzkaller uses a virtualization software. syzkaller best supports qemu.
The first task is to create VM with target OS. The second one is to build syzkaller (requires go) and the third and last one is to create a config in order to run syzkaller.
My environment:
- Host: Ubuntu 18.04.1 LTS (amd64)
- Target: FreeBSD-13.0-CURRENT-amd64-20190110
- QEMU emulator version 2.11.1
Create FreeBSD VM
Create VM and install FreeBSD
create directory and qemu hard disk image
mkdir -p ~/qemu/freebsd cd ~/qemu/freebsd sudo qemu-img create freebsd.img 16G
start vm and install FreeBSD (download iso from freebsd.org). Make sure FreeBSD source files are copied to /usr/src during installation.
sudo qemu-system-x86_64 -enable-kvm -hda freebsd.img -m 2G -net user,hostfwd=tcp::10021-:22 -net nic -curses -cdrom FreeBSD.iso -boot d
after installation let vm print to console → add in /boot/loader.conf
console="comconsole"
start vm without graphic and with network
sudo qemu-system-x86_64 -hda freebsd.img -enable-kvm -m 2G -net user,hostfwd=tcp::10021-:22 -net nic -nographic
- -net user let the vm uses a user mode network stack. Since hostfwd=tcp::10021-:22 is added, a connection to localhost:10021 (on host) is forwarded to the vm.
guest (10.0.2.15) <------> Firewall/DHCP server <-----> Internet
| (10.0.2.2)
|
----> DNS server (10.0.2.3)
|
----> SMB server (10.0.2.4)
- -nographic prints the console output of the vm directly into the console on the host
Enable KCOV support for FreeBSD
By now, KCOV support is not enabled by default. Create a own kernel config file in the VM (/usr/src should contain the FreeBSD source files).
cd /usr/src/sys/amd64/conf cp GENERIC KCOV
In file KCOV, uncomment the lines
options COVERAGE options KCOV
Build and install FreeBSD kernel as root, and restart
cd /usr/src make -j4 kernel KERNCONF=KCOV shutdown -r now
Allow SSH root access to FreeBSD
syzkaller needs root access to the OS in the VM via SSH.
create ssh keys on the host
ssh-keygen -f freebsd_id_rsa
add public key of the host (freebsd_id_rsa.pub) into /root/.ssh/authorized_keys in the vm
allow ssh as root in vm. In /etc/ssh/sshd_config set
#PermitRootLogin no
to
PermitRootLogin yes
after that, restart sshd
sudo service sshd restart
Test ssh from host to vm
ssh -i ~/qemu/freebsd/freebsd_id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
This must work without entering a password.
Build syzkaller
syzkaller uses Go → Install Go
wget https://storage.googleapis.com/golang/go1.10.4.linux-amd64.tar.gz tar -xf go1.10.4.linux-amd64.tar.gz mv go goroot export GOROOT=`pwd`/goroot export PATH=$GOROOT/bin:$PATH mkdir gopath export GOPATH=`pwd`/gopath
get syzkaller
go get -u -d github.com/google/syzkaller/...
build syz-manager, syz-fuzzer on host
cd gopath/src/github.com/google/syzkaller/ mkdir workdir make manager fuzzer execprog TARGETOS=freebsd
note the used GitRevision, for me it was
GitRevision=5b11ac2c91d99eababa8f04c7e2f9484c0763b53
build syz-executor on target (inside the VM)
- create folder in VM
mkdir -p ~/syzkaller/executor
- use scp on host to copy source files from host to VM
scp -P 10021 ~/gopath/github.com/google/syzkaller/executor/* localhost:~/src/syzkaller/executor/
- build syz-executor in vm using the GitRevision as noted before.
cd ~/syzkaller c++ -o syz-executor executor/executor.cc -pthread -Wall -Wframe-larger-than=8192 -Wparentheses -Werror -O2 -m64 -static -DGOOS_freebsd=1 -DGOARCH_amd64=1 -DGIT_REVISION=\"5b11ac2c91d99eababa8f04c7e2f9484c0763b53\"
- use scp to copy built executable from VM to host.
scp -P 10021 localhost:~/syzkaller/syz-executor ~/gopath/src/github.com/google/syzkaller/bin/freebsd_amd64/
Run syzkaller
To present code coverage, syzkaller needs FreeBSD source and object files. Start the VM with qemu and use scp on host to copy source and object files from target to host.
mkdir -p ~/freebsd/usr scp -r -o "StrictHostKeyChecking no" -P 10021 localhost:/usr/src ~/freebsd/usr/ scp -r -o "StrictHostKeyChecking no" -P 10021 localhost:/usr/obj ~/freebsd/usr/
create syz-manager config file (on host) ~/gopath/src/github.com/google/syzkaller/freebsd.cfg
{
"target": "freebsd/amd64",
"http": "127.0.0.1:56741",
"workdir": "/home/msvoelker/gopath/src/github.com/google/syzkaller/workdir",
"image": "/home/msvoelker/qemu/freebsd/freebsd.img",
"sshkey": "/home/msvoelker/qemu/freebsd/freebsd_id_rsa",
"syzkaller": "/home/msvoelker/gopath/src/github.com/google/syzkaller",
"kernel_obj": "/home/msvoelker/freebsd/usr/obj/usr/src/amd64.amd64/sys/KCOV",
"kernel_src": "/home/msvoelker/freebsd",
"enable_syscalls": [
"socket$inet_sctp",
"bind$inet",
"listen",
"connect$inet",
"accept$inet",
"read",
"write",
"close"
],
"procs": 1,
"type": "qemu",
"cover": true,
"vm": {
"count": 16,
"cpu": 1,
"mem": 1024
}
}
start syz-manager on host
cd ~/gopath/src/github.com/google/syzkaller sudo bin/syz-manager -config freebsd.cfg
For a status page, open http://localhost:56741 in a browser.
Links
github repository for syzkaller (contains documentation): https://github.com/google/syzkaller
