github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/docs/freebsd/README.md (about) 1 # FreeBSD 2 3 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. 4 5 Currently, syzkaller can fuzz FreeBSD running under bhyve, QEMU or GCE (Google Compute Engine). Regardless of the mode of operation, some common steps must be followed. 6 7 ## Setting up a host 8 9 `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. 10 11 ### Setting up a FreeBSD host 12 13 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. 14 15 The required dependencies can be installed by running: 16 ```console 17 # pkg install bash gcc git gmake go golangci-lint llvm 18 ``` 19 When using bhyve as the VM backend, a DHCP server must also be installed: 20 ```console 21 # pkg install dnsmasq 22 ``` 23 To checkout the syzkaller sources, run: 24 ```console 25 $ git clone https://github.com/google/syzkaller 26 ``` 27 and the binaries can be built by running: 28 ```console 29 $ cd syzkaller 30 $ gmake 31 ``` 32 33 Once this completes, a `syz-manager` executable should be available under `bin/`. 34 35 ### Setting up a Linux host 36 37 To build Go binaries do: 38 ``` 39 make manager fuzzer execprog TARGETOS=freebsd 40 ``` 41 To build C `syz-executor` binary, copy `executor/*` files to a FreeBSD machine and build there with: 42 ``` 43 c++ executor/executor.cc -o syz-executor -O1 -lpthread -DGOOS_freebsd=1 -DGOARCH_amd64=1 -DGIT_REVISION=\"CURRENT_GIT_REVISION\" 44 ``` 45 Then, copy out the binary back to host into `bin/freebsd_amd64` dir. 46 47 ## Setting up the FreeBSD VM 48 49 It is easiest to start with a [snapshot image](https://ftp.freebsd.org/pub/FreeBSD/snapshots/VM-IMAGES/14.0-CURRENT/amd64/Latest/) of FreeBSD. Fetch a QCOW2 disk image for QEMU or a raw image for GCE or bhyve. 50 Fetch a copy of the FreeBSD kernel sources and place them in `/usr/src`. You will likely need to expand the disk of the VM. Before booting the VM, run: 51 ```console 52 # truncate -s 15G $IMAGEFILE 53 ``` 54 To enable KCOV on FreeBSD, a custom kernel must be compiled. It is easiest to do this on the host.<br> 55 Before booting the VM, compile a custom kernel on the host and install it on the VM. On the host: 56 ```console 57 # mdconfig -a -f $IMAGEFILE 58 # mount /dev/md0p4 /mnt 59 ``` 60 This will create a memory device for the VM file and allow host to install the custom kernel source on the VM. <br> 61 To get a copy of the current development sources: 62 ```console 63 # pkg install git 64 # git clone --depth=1 --branch=main https://github.com/freebsd/freebsd-src /usr/src 65 ``` 66 To create a custom kernel configuration file for syzkaller and build a new kernel, run: 67 68 ```console 69 # cd /usr/src/sys/amd64/conf 70 # cat <<__EOF__ > SYZKALLER 71 include "./GENERIC" 72 73 ident SYZKALLER 74 75 options COVERAGE 76 options KCOV 77 __EOF__ 78 # cd /usr/src 79 # make -j $(sysctl -n hw.ncpu) KERNCONF=SYZKALLER buildkernel 80 # make KERNCONF=SYZKALLER installkernel DESTDIR=/mnt 81 ``` 82 Before booting the VM, make sure to run: 83 ```console 84 # umount /mnt 85 ``` 86 The md device will linger and you can use it again later if you want. Otherwise destroy it: 87 ```console 88 # mdconfig -d -u 0 89 ``` 90 Use QEMU to start a VM using the downloaded image: 91 92 ```console 93 $ qemu-system-x86_64 -hda $IMAGEFILE -nographic -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -net nic,model=e1000 94 ``` 95 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`: 96 97 ```console 98 # cat <<__EOF__ >>/boot/loader.conf 99 autoboot_delay="-1" 100 console="comconsole" 101 __EOF__ 102 ``` 103 After VM is booted, /etc/rc.d/growfs should haven grown its file system automatically. Otherwise run: 104 ```console 105 # /etc/rc.d/growfs onestart 106 ``` 107 Verify that `uname -i` prints `SYZKALLER` to confirm that your newly built kernel is running. 108 109 Then, to permit remote access to the VM, you must configure DHCP and enable `sshd`: 110 111 ```console 112 # sysrc sshd_enable=YES 113 # sysrc ifconfig_DEFAULT=DHCP 114 ``` 115 116 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. Note that bhyve requires the use of the root user for the time being. 117 118 ### Running Under bhyve 119 120 Some additional steps are required on the host in order to use bhyve. First, ensure that the host system is at r346550 or later. Second, since bhyve currently does not support disk image snapshots, ZFS must be used to provide equivalent functionality. Create a ZFS data set and copy the VM image there. The data set can also be used to store the syzkaller workdir. For example, with a zpool named `data` mounted at `/data`, write: 121 ```console 122 # zfs create data/syzkaller 123 # cp FreeBSD-13.0-CURRENT-amd64.raw /data/syzkaller 124 ``` 125 Third, configure networking and DHCP for the VM instances: 126 127 ```console 128 # ifconfig bridge create 129 bridge0 130 # ifconfig bridge0 inet 169.254.0.1 131 # echo 'dhcp-range=169.254.0.2,169.254.0.254,255.255.255.0' > /usr/local/etc/dnsmasq.conf 132 # echo 'interface=bridge0' >> /usr/local/etc/dnsmasq.conf 133 # sysrc dnsmasq_enable=YES 134 # service dnsmasq start 135 # echo 'net.link.tap.up_on_open=1' >> /etc/sysctl.conf 136 # sysctl net.link.tap.up_on_open=1 137 ``` 138 To enable automatic configuration of bridged network every time the system boots, add the following to /etc/rc.conf: 139 ```console 140 # cloned_interfaces="bridge0 tap0" 141 # ifconfig_bridge0="inet 169.254.0.1 addm tap0 up" 142 # ifconfig_tap0="up" 143 ``` 144 Finally, ensure that the bhyve kernel module is loaded: 145 ```console 146 # kldload vmm 147 ``` 148 149 ### Putting It All Together 150 151 If all of the above worked, create a `freebsd.cfg` configuration file with the following contents (alter paths as necessary): 152 153 ``` 154 { 155 "name": "freebsd", 156 "target": "freebsd/amd64", 157 "http": ":10000", 158 "workdir": "/workdir", 159 "syzkaller": "/gopath/src/github.com/google/syzkaller", 160 "sshkey": "/freebsd_id_rsa", 161 "sandbox": "none", 162 "procs": 8, 163 } 164 ``` 165 If running the fuzzer under QEMU, add: 166 167 ``` 168 "image": "/FreeBSD-13.0-CURRENT-amd64.qcow2", 169 "type": "qemu", 170 "vm": { 171 "count": 10, 172 "cpu": 4, 173 "mem": 2048 174 } 175 ``` 176 For GCE, add the following instead (alter the storage bucket path as necessary): 177 178 ``` 179 "image": "/FreeBSD-13.0-CURRENT-amd64.raw", 180 "type": "gce", 181 "vm": { 182 "count": 10, 183 "instance_type": "n1-standard-4", 184 "gcs_path": "syzkaller" 185 } 186 ``` 187 For bhyve, we need to specify the VM image snapshot name and networking info (alter the dataset name and paths as necessary): 188 ``` 189 "image": "/data/syzkaller/FreeBSD-13.0-CURRENT-amd64.raw", 190 "type": "bhyve", 191 "vm": { 192 "count": 10, 193 "bridge": "bridge0", 194 "hostip": "169.254.0.1", 195 "dataset": "data/syzkaller" 196 } 197 ``` 198 199 Then, start `syz-manager` with: 200 ```console 201 $ bin/syz-manager -config freebsd.cfg 202 ``` 203 It should start printing output along the lines of: 204 ``` 205 booting test machines... 206 wait for the connection from test machine... 207 machine check: 253 calls enabled, kcov=true, kleakcheck=false, faultinjection=false, comps=false 208 executed 3622, cover 1219, crashes 0, repro 0 209 executed 7921, cover 1239, crashes 0, repro 0 210 executed 32807, cover 1244, crashes 0, repro 0 211 executed 35803, cover 1248, crashes 0, repro 0 212 ``` 213 If something does not work, try adding the `-debug` flag to `syz-manager`. 214 215 ## Missing things 216 217 - System call descriptions. The initial list of FreeBSD system calls was a copy-and-paste of Linux's, and while they have been cleaned up over time they should be audited more carefully. We are also still missing many system call descriptions. 218 - We should support fuzzing the Linux compatibility subsystem. 219 - We should provide instructions for fuzzing a FreeBSD system on ZFS 220 - `pkg/host` needs to be taught how to detect supported syscalls/devices. 221 - KASAN and KCSAN for FreeBSD would be useful. 222 - 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.