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.