# Technical Documentation: google/syzkaller

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/google/syzkaller)

### Overview (`README.md`)

# syzkaller - kernel fuzzer

[](https://github.com/google/syzkaller/actions?query=workflow/ci)
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=label:Proj-syzkaller)
[](https://goreportcard.com/report/github.com/google/syzkaller)
[](https://codecov.io/gh/google/syzkaller)
[](https://godoc.org/github.com/google/syzkaller)
[](LICENSE)

`syzkaller` (`[siːzˈkɔːlə]`) is an unsupervised coverage-guided kernel fuzzer.\
Supported OSes: `FreeBSD`, `Fuchsia`, `gVisor`, `Linux`, `NetBSD`, `OpenBSD`, `Windows`.

Mailing list: [syzkaller@googlegroups.com](https://groups.google.com/forum/#!forum/syzkaller) (join on [web](https://groups.google.com/forum/#!forum/syzkaller) or by [email](mailto:syzkaller+subscribe@googlegroups.com)).

Found bugs: [Darwin/XNU](docs/darwin/README.md), [FreeBSD](docs/freebsd/found_bugs.md), [Linux](docs/linux/found_bugs.md), [NetBSD](docs/netbsd/found_bugs.md), [OpenBSD](docs/openbsd/found_bugs.md), [Windows](docs/windows/README.md).

## Documentation

Initially, syzkaller was developed with Linux kernel fuzzing in mind, but now
it's being extended to support other OS kernels as well.
Most of the documentation at this moment is related to the [Linux](docs/linux/setup.md) kernel.
For other OS kernels check:
[Darwin/XNU](docs/darwin/README.md),
[FreeBSD](docs/freebsd/README.md),
[Fuchsia](docs/fuchsia/README.md),
[NetBSD](docs/netbsd/README.md),
[OpenBSD](docs/openbsd/setup.md),
[Starnix](docs/starnix/README.md),
[Windows](docs/windows/README.md),
[gVisor](docs/gvisor/README.md),
[Akaros](docs/akaros/README.md).

- [How to install syzkaller](docs/setup.md)
- [How to use syzkaller](docs/usage.md)
- [How syzkaller works](docs/internals.md)
- [How to install syzbot](docs/setup_syzbot.md)
- [How to contribute to syzkaller](docs/contributing.md)
- [How to report Linux kernel bugs](docs/linux/reporting_kernel_bugs.md)
- [Tech talks and articles](docs/talks.md)
- [Research work based on syzkaller](docs/research.md)

## Disclaimer

This is not an official Google product.

---

### Overview (`syz-agent/README.md`)

# syz-agent

`syz-agent` is an AI agent running as part of the continuous fuzzing
infrastructure. It continuously polls the syzbot web dashboard for tasks and
executes agentic workflows.

## Running Locally with Docker

You can easily run `syz-agent` locally without Kubernetes. This is the best
approach for testing and development.

1. Build the Docker image from the root of the syzkaller repository:
   ```bash
   make -C syz-agent container
   ```
   *Note: The default image name is `local/syz-agent:latest`. You can override it by passing `IMAGE_NAME=your-image-name IMAGE_TAG=your-tag`.*

2. Prepare a configuration file (e.g. `config.json`):
   ```json
   {
       "http": ":8080",
       "dashboard_client": "my-local-agent",
       "dashboard_addr": "https://syzkaller.appspot.com",
       "dashboard_key": "YOUR_KEY",
       "targets": {
         "linux/amd64": {
           "image": "/disk-images/buildroot_amd64",
           "kernel_config": "/kernel-configs/upstream-apparmor-kasan.config",
           "type": "qemu",
           "vm": {
             "cpu": 2,
             "mem": 2048,
             "cmdline": "root=/dev/sda1"
           }
         }
       },
       "cache_size": 107374182400
   }
   ```

3. Run the container, mounting your configuration file:
   ```bash
   docker run -it --rm \
       -p 8080:8080 \
       --privileged \
       -e GOOGLE_API_KEY=$GOOGLE_API_KEY \
       -v $(pwd)/config.json:/etc/syz-agent/config.json:ro \
       local/syz-agent:latest \
       -name=$MY_UNIQUE_AGENT_NAME \
       -config=/etc/syz-agent/config.json
   ```
  *Note: `pkg/updater` is bypassed inside Docker because the
  `-syzkaller=/syzkaller` flag is passed via `run.sh` which serves as the Dockerfile's
  ENTRYPOINT. `syz-agent` will use the pre-built binaries inside the container.*

## Running on Kubernetes

`syz-agent` can be deployed as a `StatefulSet` on Kubernetes (Minikube or GKE) for persistent identity.

### Local Development (Minikube)

To deploy to a standard minikube cluster:

```bash
# 1. Build and load image into Minikube
make container
minikube image load local/syz-agent:latest

# 2. Deploy (automatically binds host's GOOGLE_API_KEY and DASHBOARD_KEY)
GOOGLE_API_KEY=xxx DASHBOARD_KEY=yyy make k8s-minikube | kubectl apply -f -
```

---

### Overview (`syz-cluster/README.md`)

`syz-cluster` is a distributed patch series fuzzing that is relying on syzkaller.
It's deployed at https://ci.syzbot.org.

## Overview

The system is to be deployed on a K8S cluster. The main services are:
* `dashboard`: the web interface, read-only.
* `controller`: manages the state of the system, provides
  [API](./pkg/api/client.go) for other components, schedules fuzzing sessions.
* `series-tracker`: polls LKML git archives for the new series.
* `reporter-server`: generates new reports, provides API for actual reporter
  implementations.
* `email-reporter`: sends reports over email, handles incoming email commands.

The actual patch processing is orchestrated by Argo Workflows: see [the
template](./pkg/workflow/template.yaml). It relies on the following processing
steps:
* `workflow/triage`
* `workflow/build`
* `workflow/boot`
* `workflow/fuzz`

Triage and build steps need the actual kernel checkouts. The base kernel repo is
hosted on a shared network disk and is regularly updated by the scripts in
`kernel-disk`.

The system can be deployed in multiple environments, which is achieved with the
help of Kustomize. Depending on the actual deployment target, different pieces of
configuration are applied:
* `overlays/local/minikube`: the local dev environment.
* `overlays/gke/staging`: the staging prod environment.
* `overlays/gke/prod`: https://ci.syzbot.org.

`global-config.yaml` is the main configuration file of the system - it
determines the mailing lists to poll, configures resource usage and the actual
reporting.

## Local installation steps

1. Install and start minikube: https://minikube.sigs.k8s.io/docs/start/
```
$ minikube start --cni=cilium --container-runtime=docker --memory=128g
```

`--cni=cilium` enables the use of a more advanced Network plugin that supports
the emulation of network policies.

`--container-runtime=docker` is needed for `minikube docker-env` (the default
is containerd since minikube v1.39).

`--memory=128g` limits the memory of the whole cluster. Fuzzing may use a lot
of it, and on OOM random pods get killed (e.g. the Spanner emulator).

2. Build all docker containers (might take a while):
```
$ eval $(minikube docker-env)
$ make all-containers
```
3. Deploy local infrastructure (Argo, Spanner, Service Accounts):
```
$ kubectl create namespace argo
$ make k8s-config-local-infra
$ make migrate-local
```

4. Deploy the rest of the cluster:
```
$ make k8s-config-dev | kubectl apply -f -
```
5. Pre-fetch the kernel git repository:
```
$ make fetch-kernels-once.yaml | kubectl create -f -
```

Note that actual series processing won't start until the job created in (5)
finishes.

## Developmental tips

1. Install Argo Workflows client: https://github.com/argoproj/argo-workflows/releases

Then you can use the `argo` tool like this:

```
$ argo list
```

2. Forward the dashboard port:

```
$ kubectl port-forward service/web-dashboard-service --address 0.0.0.0 50123:80
```

---

### Overview (`dashboard/app/README.md`)

# Dashboard

`dashboard` is an [App Engine](https://cloud.google.com/appengine) app that powers [syzbot](/docs/syzbot.md).
The main deployment is at [syzkaller.appspot.com](https://syzkaller.appspot.com).

It is so-called [Standard environment](https://cloud.google.com/appengine/docs/standard) Go app.\
To deploy and manage the app you need to install [Google Cloud SDK](https://cloud.google.com/sdk/install).\
For more details about App Engine refer to the [docs](https://cloud.google.com/appengine/docs/standard/go/).

**Note**: The app is not stable and is not officially supported. It's here only to power the main deployment.

Here is "big" picture of a possible setup:


**Note**: the vector source is [here](https://docs.google.com/drawings/d/16EdqYrWD4PWD2nV_PoDPvC5VPry2H40Sm8Min-RtDdA);
to update: make a copy of the source, edit, download a png, update the png and include a link to your vector copy into the PR.

To deploy the app you need to add a `.go` file with production config. The config specifies kernel namespaces,
bug reporting details, API keys, etc. Tests contain a [config example](app_test.go), but it's not ready for
production use.

The app also needs one or more [syz-ci](/syz-ci/syz-ci.go) instances running elsewhere. The `syz-ci` instances
do the actual fuzzing, bisection, patch testing, etc.

The app can be deployed by `gcloud app deploy ./dashboard/app/app.yaml`.

The following optional flags are available:

1. "--no-promote" to test the app firs and migrate the traffic to it later.
2. "--verbosity=info" to see what files are going to be deployed.

The app tests can be run with:
```
go test github.com/google/syzkaller/dashboard/app
```
During development it's handy to use `-short` flag to not run the longest tests.

If any of the tests fail, use `-v` flag to see log of what happens and `-run` flag
to run a single test, e.g.:
```
go test -short -v -run=TestEmailReport github.com/google/syzkaller/dashboard/app
```

## Local Test Deployment

It's possible to run the dashboard locally for testing purposes.
However, note that it won't have any data, so you would need to connect `syz-ci`
instances so that they populate database with some bugs.

First, you need to install Google Cloud SDK (`gcloud` command, and required components,
this is one time step).

Then, create emulator config (this is one time step):

```
gcloud config configurations create emulator
gcloud config set auth/disable_credentials true
gcloud config set project syzkaller
gcloud config set api_endpoint_overrides/spanner http://localhost:9020/
```

Then, start local spanner emulator in one console:

```
gcloud emulators spanner start
gcloud spanner instances create syzbot --config=emulator --nodes=1
gcloud spanner databases create ai --instance=syzbot
```

Then, initialize the schema from another console:

```
for SQL in dashboard/app//aidb/migrations/*.up.sql; do \
	gcloud spanner databases ddl update ai \
	--instance=syzbot --ddl-file ${SQL}; done
```

Finally, start the web server:

```
SPANNER_EMULATOR_HOST="localhost:9010" \
	GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS=false \
	google-cloud-sdk/bin/dev_appserver.py --application=syzkaller \
	--host=0.0.0.0 --enable_host_checking=false dashboard/app/
```

---

### Overview (`docs/akaros/README.md`)

# Akaros support

[Akaros](http://akaros.cs.berkeley.edu/) support was **removed**.
You can find it in git history, if needed.
Found bugs are [here](https://groups.google.com/forum/#!searchin/akaros/syzbot),
[here](https://syzkaller.appspot.com/akaros)
and [here](https://github.com/brho/akaros/issues?q=is%3Aissue+syzkaller).

---

### Overview (`docs/darwin/README.md`)

# Darwin/XNU

It turned out to be unreasonably hard to bootstrap a VM image usable for fuzzing from the XNU source drops without using any of the proprietary kernel extensions shipped with macOS. This guide is therefore based on a normal macOS installation. Unfortunately Apples macOS EULA makes this unsuitable for fuzzing XNU on Google Cloud Platform.

## Prepare a macOS installation disk image

Nowadays Apple mainly distributes macOS updates via the Mac App Store. This will however only give us the latest builds. Luckily the Munki people are kind enough to maintain a script, allowing us to fetch a macOS build of our choice from the shell.

We'll need a macOS build that has a kernel version close to the one we will be building. You can [see Apples most recent source drops on this page](https://opensource.apple.com/). At the time of writing the most recent version is macOS 11.5 containing kernel xnu-7195.141.2. The Munki download script can only tell the macOS version and build number, but not the XNU version. Unfortunately you might occasionally download a matching macOS release, but the kernel you build won't boot anyway. Among many other reasons this can be caused by this mismatch in kernel and bootloader versions. Some trial and error can be involved in getting the correct build. Sometimes the correct build might no longer be available. At the time of writing 11.5 build 20G71 was available and worked with the 11.5 xnu source drop.

In the instructions below I will assume you have VMware Fusion installed on your host macOS for creating the VM disk image. This is for convenience sake as Fusion allows us to simply drag and drop in the macOS installer App we downloaded. If you want to use another tool like Qemu for this, [take note of Apples own process for creating a bootable install media](https://support.apple.com/en-us/HT201372). I had trouble generating bootable ISOs from certain macOS builds using Apples method, hence I just always let Fusion create the installation medium for me.

Additionally the below instructions ask you to disable System Integrity Protection and Authenticated Root inside the VM. We need to do this in order to run the DIY kernel we will build in a bit. Executive Summary on these features:
- In OS X 10.11 Apple introduced System Integrity Protection, a feature that (among other things) limits even root from writing to certain critical system directories during normal operations. We need to disable it to write our kernel to disk
- In macOS 11 Apple introduced Authenticated Root. Starting with this version only a cryptographically signed read only snapshot of the root filesystem is mounted during boot. We need to disable it in order to remount a writable version and take a new snapshot to boot from later

**Tl;Dr: To create the VM image:**
- [Clone Munkis macadmin-script repo](https://github.com/munki/macadmin-scripts)
- Run `installinstallmacos.py` and choose a version matching the last kernel source drop
- Mount and open the downloaded `Install_macOS_<version>-<build>.dmg`
- Open VMware Fusion and create a new VM via the File menu
- Drag and Drop the `Install macOS <name>` App from the mounted disk image into the `Select the Installation Method` Fusion dialog
- I suggest cranking up the VMs CPU and Memory at this point
- After picking your language in the macOS installer open `Utilities -> Terminal`
- Enter `csrutil disable` to disable System Integrity Protection
- Enter `csrutil authenticated-root disable` to disable Authenticated Root
- Quit the Terminal app via Cmd+Q
- Follow through with the macOS installation, creating a user called `user`. If you don’t have any disk available to install to, you might need to use the Disk Utility to format the virtual disk first
- Go to `System Preferences -> Software Update -> Advanced…` and uncheck `Check for updates`
- Go to `System Preferences -> Energy Saver` and check `Prevent computer from sleeping automatically when the display is off`
- Go to `System Preferences -> Sharing` and check `Remote Login` to enable sshd
- Add your ssh pubkey to both your users and roots authorized_keys files
- Optionally disable WindowServer and other non-essential services via launchd. Note that you will obviously loose the GUI: `sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.WindowServer.plist`


Check that everything looks alright:



## Prepare a Kernel optimized for fuzzing

You might be wondering why we aren’t using one of the precompiled kernels available in Apples Kernel Development Kits. However those don’t include any kernel built with the KSANCOV feature flag. KSANCOV is Apples take on an API that allows userspace to request the kernel to start tracing which kernel code a given thread touched and exposing that information to userspace. This information is required by Syzkaller to be really effective at fuzzing.

Luckily [afrojer@](https://twitter.com/afrojer) is releasing semi-regularly updated instructions on building XNU from source and installing it on macOS on his blog. At the time of writing he is lagging three minor source drop versions behind. The [most recent instructions are for macOS 11.2](https://web.archive.org/web/20210524205524/https://kernelshaman.blogspot.com/2021/02/building-xnu-for-macos-112-intel-apple.html). We’ll cover some additional required changes in this text.

Building and testing a XNU useful for fuzzing:
- Download a somewhat recent Xcode from [Apples Xcode versions archive (Apple ID login required)](https://developer.apple.com/download/all/?q=xcode) to your VM. I’m using Xcode 12.5. I had issues with 12.5.1 and 13 beta 4
- Open the `Xcode_<version>.xip` to extract. Make a coffee ⏳
- Drag and Drop the extracted Xcode app into your VMs Applications folder
- Start Xcode, agree to the license and quit it after it finishes installation
- Create and join a directory named `kernel` in the users home dir and cd into it
- Downloading afrojer@s Makefile: `curl https://jeremya.com/sw/Makefile.xnudeps > Makefile.xnudeps` Note this file is not versioned, but always updated in place. [Here is an archive link to the version at the time of writing.](https://web.archive.org/web/20210210224511/https://jeremya.com/sw/Makefile.xnudeps)
- `make -f Makefile.xnudeps macos_version=11.5 xnudeps` This will get the dependencies for building the 11.5 XNU. [Check out the original blog post for details on how to fetch dependencies for a specific version](https://kernelshaman.blogspot.com/2021/02/building-xnu-for-macos-112-intel-apple.html)
- cd into `~/kernel/xnu-<version>/`
- Apply [required XNU patches](0001-fuzzing.patch) manually or via `git am`. Applying via git requires you to init the repo and commit all files first. That's probably a good idea anyway to track further changes you might make
    - The patches for `MakeInc.def` and `kasan.c` are required for the KASAN kernel to build. KASAN is short for KernelAddressSANitizer - a feature to detect a bunch of memory safety issues inside the kernel during runtime
    - The `ksancov.h` patch is required for building syzkallers executor. Executor is C++ and hence doesn't like the void pointer casting
    - Finally the `cpuid.c` and `cpu_threads.c` patches are required for our kernel to boot on Qemu

- Run `mount` and look for the roots mount device. On my VM it looks like this `/dev/disk2s5s1 on / (apfs, sealed, local, read-only, journaled)`. Now remember the devices name, ignoring the last sN part. So I note down `/dev/disk2s5`
- Cd into `~/kernel/xnu-<version>/` and run the following, replacing `<your_disk>` to build and install your kernel

```
mkdir -p BUILD/mnt
sudo mount -o nobrowse -t apfs /dev/<your_disk> $PWD/BUILD/mnt

make SDKROOT=macosx TARGET_CONFIGS="KASAN X86_64 NONE" KSANCOV=1

kmutil create -a x86_64 -Z -n boot sys \
-B BUILD/BootKernelExtensions.kc.kasan \
-S BUILD/SystemKernelExtensions.kc.kasan \
-k BUILD/obj/kernel.kasan \
--elide-identifier com.apple.driver.AppleIntelTGLGraphicsFramebuffer

sudo ditto BUILD/BootKernelExtensions.kc.kasan "$PWD/BUILD/mnt/System/Library/KernelCollections/"
sudo ditto BUILD/SystemKernelExtensions.kc.kasan "$PWD/BUILD/mnt/System/Library/KernelCollections/"
sudo ditto BUILD/obj/kernel.kasan "$PWD/BUILD/mnt/System/Library/Kernels/"

sudo bless --folder $PWD/BUILD/mnt/System/Library/CoreServices --bootefi --create-snapshot
sudo nvram boot-args="-v kcsuffix=kasan wlan.skywalk.enable=0"
```

After rebooting you should see your shiny new kernel when running `uname -a`: `Darwin users-Mac.local 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug  9 16:12:43 PDT 2021; user:xnu-7195.141.2/BUILD/obj/KASAN_X86_64 x86_64`


For effective fuzzing we'll need the kernels binary, symbols and source on the host. Copy them like this:

```
mkdir -p ~/115/src/Users/user/kernel/ ~/115/obj
rsync -r mac:/Users/user/kernel/xnu-7195.141.2 ~/115/src/Users/user/kernel/
mv ~/115/src/Users/user/kernel/xnu-7195.141.2/BUILD/obj/KASAN_X86_64/kernel.kasan ~/115/obj/
mv ~/115/src/Users/user/kernel/xnu-7195.141.2/BUILD/obj/KASAN_X86_64/kernel.kasan.dSYM/ ~/115/obj/
```

## Preparing VM for Qemu

Even though Macs are AMD64 machines with EFIs (at least the once we care about here), they aren't exactly IBM PC compatible. So far VMWare Fusion did all the trickery necessary to virtualize macOS for us, but qemu-system-x86_64 does not.

To make macOS boot we'll first start Qemu with OVMF (tianocore based UEFI for qemu). Next we boot OpenCore, which will do some trickery making it possible to chainload Apples stock AMD64 EFI bootloader. It also does some binary kernel patching, making it possible to load the RELEASE kernel shipped with macOS, should we want that.

OpenCore is rather configurable, but we don't care about real hardware. [I'm using this version prebuild and configured to work inside Qemu](https://github.com/thenickdude/KVM-Opencore/releases). We can simply overwrite the EFI partition on our VMs disk with the EFI partition from one of the images from this repo.

Let's first find out which partition we will overwrite in a minute. From the following output from within the macOS VM (still booted via Fusion for now) we can see that in my case the EFI partition is at `/dev/disk0s1`:

```
user@users-Mac ~ % diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *69.8 GB    disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                 Apple_APFS Container disk1         69.6 GB    disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +69.6 GB    disk1
                                 Physical Store disk0s2
   1:                APFS Volume macos - Data            43.2 GB    disk1s1
   2:                APFS Volume Preboot                 385.6 MB   disk1s2
   3:                APFS Volume Recovery                623.2 MB   disk1s3
   4:                APFS Volume VM                      1.1 MB     disk1s4
   5:                APFS Volume macos                   16.0 GB    disk1s5
   6:              APFS Snapshot com.apple.bless.4099... 16.0 GB    disk1s5s1
```

Now download [OpenCore-v13.iso.gz](https://github.com/thenickdude/KVM-Opencore/releases/download/v13/OpenCore-v13.iso.gz) and extract the image via `gzip -d OpenCore-v13.iso.gz`. Display the partition map to find out the images blocksize and the EFI partitions offset and size.


```
user@users-Mac ~ % hdiutil pmap ./OpenCore-v13.iso

MEDIA: ""; Size 150 MB [307200 x 512]; Max Transfer Blocks 2048
SCHEME: 1 GPT, "GPT Partition Scheme" [16]
SECTION: 1 Type:'MAP'; Size 150 MB [307200 x 512]; Offset 34 Blocks (307133 + 67) x 512
ID Type                 Offset       Size         Name                      (1)
-- -------------------- ------------ ------------ -------------------- --------
 1 EFI                            40       307120 disk image
```

Now put all those values together in a dd command like so: `sudo dd if=./OpenCore-v13.iso of=/dev/disk0s1 bs=512 iseek=40 count=307120`

Now let's mount the EFI disk via `sudo mount -t msdos /dev/disk0s1 ~/mnt/`. We have to edit OpenCores config file a tiny bit. We disable the boot device selector, as that will prevent us from starting the VMs during fuzzing completely automatically. Additionally note how we set boot-args here. In VMware Fusion we were able to use the normal macOS tools like nvram and csrutil. In OpenCore we need to set these settings in the config.plist instead.

Edit `~/mnt/EFI/OC/config.plist` like so:

```diff
index 8537ca8..a46de97 100755
--- a/Users/user/mnt/EFI/OC/config.plist
+++ b/Users/user/mnt/EFI/OC/config.plist
@@ -799,7 +799,7 @@
 			<key>PollAppleHotKeys</key>
 			<true/>
 			<key>ShowPicker</key>
-			<true/>
+			<false/>
 			<key>TakeoffDelay</key>
 			<integer>0</integer>
 			<key>Timeout</key>
@@ -944,7 +944,7 @@
 				<key>SystemAudioVolume</key>
 				<data>Rg==</data>
 				<key>boot-args</key>
-				<string>keepsyms=1</string>
+				<string>-v kcsuffix=kasan wlan.skywalk.enable=0 keepsyms=1 debug=0x100008 kasan.checks=4294967295</string>
 				<key>csr-active-config</key>
 				<data>Jg8=</data>
 				<key>prev-lang:kbd</key>

```

At this point you should still be able to (re)boot the VM in Fusion. It will just ignore OpenCore however. That's fine.

## Prepare isa-applesmc

On boot macOS checks whether it is booted on a proper Mac by reading a value from its System Management Controller and comparing it with the value it expects. We'll retrieve this value now and pass it to qemu later. To retrieve the value:
- [Download the smc_read.c source from this site.](https://web.archive.org/web/20200603015401/http://www.osxbook.com/book/bonus/chapter7/tpmdrmmyth/)
- `gcc -Wall -o smc_read smc_read.c -framework IOKit`
`./smc_read`

That will produce a single line of text which you will later have to substitute in for a place marked `<YOUR_APPLE_SMC_HERE>`.


## Booting macOS via Qemu

- Setup [Homebrew](https://brew.sh/) on your host macOS
- Install `qemu` via homebrew
- Your VMs disk should be somewhere like this on your host `~/Virtual\ Machines.localized/macOS-11.5-20G71.vmwarevm/Virtual\ Disk.vmdk`. Convert it to qcow2 via something like this `qemu-img convert -U ./Virtual\ Disk.vmdk -O qcow2 ~/115/mac_hdd.qcow`
- Unfortunately OVMF is currently not packaged in Homebrew. Download the [`ovmf` package from ubuntu](https://packages.ubuntu.com/hirsute/ovmf). Extract it via `ar -xv ./ovmf_2020.11-4_all.deb` and `tar -xvf ./data.tar.xz`. Finally `mv ./usr/share/OVMF /usr/local/share/OVMF`

That's pretty much all you should need in order to boot the VM image we build. Start Qemu like so. Remember to substitute `<YOUR_APPLE_SMC_HERE>` and the username in the disk image path:
```
qemu-system-x86_64 \
  -device isa-applesmc,osk="<YOUR_APPLE_SMC_HERE>" \
  -accel hvf -machine q35 -smp "2",cores="2",sockets="1" -m "4096" \
  -cpu Penryn,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,"+pcid,+ssse3,+sse4.2,+popcnt,+avx,+aes,+xsave,+xsaveopt,check" \
  -drive if=pflash,format=raw,readonly=on,file="/usr/local/share/OVMF/OVMF_CODE.fd" \
  -drive if=pflash,format=raw,readonly=on,file="/usr/local/share/OVMF/OVMF_VARS.fd" \
  -device ich9-intel-hda -device hda-duplex -device ich9-ahci,id=sata \
  -device ide-hd,bus=sata.4,drive=MacHDD \
  -drive id=MacHDD,if=none,file="/Users/user/115/macos_11_5.qcow",format=qcow2 \
  -netdev user,id=net0,hostfwd=tcp::1042-:22, -device e1000-82545em,netdev=net0,id=net0 \
  -device usb-ehci,id=ehci -usb -device usb-kbd -device usb-tablet \
  -monitor stdio -vga vmware
```

You should both see the macOS UI and be able to `ssh user@localhost -p 1042`. Confirm we are booted into your KASAN kernel:

```
user@users-Mac ~ % uname -a
Darwin users-Mac.local 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug  9 16:12:43 PDT 2021; user:xnu-7195.141.2/BUILD/obj/KASAN_X86_64 x86_64
```

Shut down your VM now. We'll let syzkaller boot it back up soon.

## Building Syzkaller

- Install `go` via homebrew
- Add something like this to your .zshrc:
```
export GOPATH=/Users/user/go
export PATH=$GOPATH/bin:$PATH
```
- Relogin and build syzkaller like this:
```
git clone https://github.com/google/syzkaller
cd syzkaller
make HOSTOS=darwin HOSTARCH=amd64 TARGETOS=darwin TARGETARCH=amd64 SOURCEDIR=/Users/user/115/src/Users/user/kernel/xnu-7195.141.2
```

## Fuzzing with Syzkaller

- We need g++ to make C reproducers work. Install `gcc@11` via homebrew
- We need addr2line from binutils to make the `/cover` endpoint work. Install `binutils` via homebrew
- Add something like this to your .zshrc `export PATH="/usr/local/opt/binutils/bin:$PATH"`. Restart your shell
- Save the following to `~/115/syzkaller.cfg`. Remember to substitute `<YOUR_APPLE_SMC_HERE>`:
```
{
    "target": "darwin/amd64",
    "http": "127.0.0.1:56741",
    "sshkey": "/Users/user/.ssh/id_macos115",
    "workdir": "/Users/user/sk_darwin/",
    "kernel_obj": "/Users/user/115/obj/",
    "kernel_src": "/Users/user/115/src/",
    "syzkaller": "/Users/user/go/src/github.com/google/syzkaller",
    "procs": 2,
    "type": "qemu",
    "cover": true,
    "image": "/Users/user/115/macos_11_5.qcow",
    "vm": {
        "count": 2,
        "cpu": 2,
        "mem": 4096,
        "efi_code_device": "/usr/local/share/OVMF/OVMF_CODE.fd",
        "efi_vars_device": "/usr/local/share/OVMF/OVMF_VARS.fd",
        "apple_smc_osk": "<YOUR_APPLE_SMC_HERE>"
    }
}
```

Start syzkaller via `~/115/bin/syz-manager -config=/root/115/syzkaller.cfg` and open http://localhost:56741 in your browser.

---

### Overview (`docs/freebsd/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 bhyve, 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:
```console
# pkg install bash gcc git gmake go golangci-lint llvm
```
When using bhyve as the VM backend, a DHCP server must also be installed:
```console
# pkg install dnsmasq
```
To checkout the syzkaller sources, run:
```console
$ git clone https://github.com/google/syzkaller
```
and the binaries can be built by running:
```console
$ cd 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.cc -o syz-executor -O1 -lpthread -DGOOS_freebsd=1 -DGOARCH_amd64=1 -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](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.
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:
```console
# truncate -s 15G $IMAGEFILE
```
To enable KCOV on FreeBSD, a custom kernel must be compiled. It is easiest to do this on the host.<br>
Before booting the VM, compile a custom kernel on the host and install it on the VM. On the host:
```console
# mdconfig -a -f $IMAGEFILE
# mount /dev/md0p4 /mnt
```
This will create a memory device for the VM file and allow host to install the custom kernel source on the VM. <br>
To get a copy of the current development sources:
```console
# pkg install git
# git clone --depth=1 --branch=main https://github.com/freebsd/freebsd-src /usr/src
```
To create a custom kernel configuration file for syzkaller and build a new kernel, run:

```console
# 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 DESTDIR=/mnt
```
Before booting the VM, make sure to run:
```console
# umount /mnt
```
The md device will linger and you can use it again later if you want. Otherwise destroy it:
```console
# mdconfig -d -u 0
```
Use QEMU to start a VM using the downloaded image:

```console
$ 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`:

```console
# cat <<__EOF__ >>/boot/loader.conf
autoboot_delay="-1"
console="comconsole"
__EOF__
```
After VM is booted, /etc/rc.d/growfs should haven grown its file system automatically. Otherwise run:
```console
# /etc/rc.d/growfs onestart
```
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`:

```console
# 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.  Note that bhyve requires the use of the root user for the time being.

### Running Under bhyve

Some additional steps are required on the host in order to use bhyve.  First, 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:
```console
# zfs create data/syzkaller
# cp FreeBSD-13.3-CURRENT-amd64.raw /data/syzkaller
```
Third, configure bridged networking and DHCP for the VM instances.  This is no longer required on FreeBSD 14.1 and 15.0-CURRENT, as bhyve now supports libslirp-based user networking similar to the QEMU backend.

```console
# ifconfig bridge create
bridge0
# ifconfig bridge0 inet 169.254.0.1
# echo 'dhcp-range=169.254.0.2,169.254.0.254,255.255.255.0' > /usr/local/etc/dnsmasq.conf
# echo 'interface=bridge0' >> /usr/local/etc/dnsmasq.conf
# sysrc dnsmasq_enable=YES
# service dnsmasq start
# echo 'net.link.tap.up_on_open=1' >> /etc/sysctl.conf
# sysctl net.link.tap.up_on_open=1
```
To enable automatic configuration of bridged network every time the system boots, add the following to /etc/rc.conf:
```console
# cloned_interfaces="bridge0 tap0"
# ifconfig_bridge0="inet 169.254.0.1 addm tap0 up"
# ifconfig_tap0="up"
```
Finally, ensure that the bhyve kernel module is loaded:
```console
# kldload vmm
```

### Putting It All Together

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",
	"sshkey": "/freebsd_id_rsa",
	"sandbox": "none",
	"procs": 8,
}
```
If running the fuzzer under QEMU, add:

```
	"image": "/FreeBSD-13.0-CURRENT-amd64.qcow2",
	"type": "qemu",
	"vm": {
		"count": 10,
		"cpu": 4,
		"mem": 2048
	}
```
For GCE, add the following instead (alter the storage bucket path as necessary):

```
	"image": "/FreeBSD-13.0-CURRENT-amd64.raw",
	"type": "gce",
	"vm": {
		"count": 10,
		"instance_type": "n1-standard-4",
		"gcs_path": "syzkaller"
	}
```
For bhyve, we need to specify the VM image snapshot name and networking info (alter the dataset name and paths as necessary):
```
	"image": "/data/syzkaller/FreeBSD-13.0-CURRENT-amd64.raw",
	"type": "bhyve",
	"vm": {
		"count": 10,
		"hostip": "169.254.0.1",
		"dataset": "data/syzkaller"
	}
```
If using bridged networking, the name of the bridge interface needs to be included in the "vm" block:
```
	"vm": {
		"count": 10,
		"hostip": "169.254.0.1",
		"dataset": "data/syzkaller",
        "bridge": "bridge0"
	}
```

Then, start `syz-manager` with:
```console
$ 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.  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.
- We should support fuzzing the Linux compatibility subsystem.
- We should provide instructions for fuzzing a FreeBSD system on ZFS
- `pkg/host` needs to be taught how to detect supported syscalls/devices.
- KASAN and KCSAN for FreeBSD would be useful.
- On Linux we have emission of external networking/USB traffic into kernel using tun/gadgetfs. Implementing these for FreeBSD could uncover a number of high-profile bugs.

---

### Overview (`docs/fuchsia/README.md`)

# Fuchsia support

For information about checking out and building Fuchsia see [Get started with
Fuchsia](https://fuchsia.dev/fuchsia-src/get-started) and [Download the Fuchsia
source code](https://fuchsia.dev/fuchsia-src/get-started/get_fuchsia_source).

## Caveat

Please note that Fuchsia support is currently incomplete, and may break at any
time due to changes in Fuchsia and/or Syzkaller.

Some known issues include:

* System call definitions require manual updates.
* Crash parsing does not work reliably.
* Coverage feedback is not supported.

## Prerequisites

To run Syzkaller with a Fuchsia target, you will need a checkout of the Fuchsia
source repository.

The rest of this document will use the environment variable `SOURCEDIR` to
identify the path to your Fuchsia checkout (e.g. `/home/you/fuchsia`). The
commands below assume you have set `SOURCEDIR`, like so:

```bash
export SOURCEDIR=/home/you/fuchsia
```

## Quick and easy version

The shell script [setup.sh](setup.sh) automates the building and running
`syz-manager` steps described below. Give it a try, and see if it works for you.
For usage help, invoke it with no arguments.

## Building Fuchsia

To build Fuchsia for x64, run:

```bash
fx --dir "out/x64" set core.x64 \
  --with-base "//bundles/tools" \
  --with-base "//src/testing/fuzzing/syzkaller" \
  --args=syzkaller_dir='"/full/path/to/syzkaller"' \
  --variant=kasan
fx build
```

Alternatively, for arm64, run:

```bash
fx --dir "out/arm64" set core.arm64 \
  --with-base "//bundles/tools" \
  --with-base "//src/testing/fuzzing/syzkaller" \
  --args=syzkaller_dir='"/full/path/to/syzkaller"' \
  --variant=kasan
fx clean-build
```

## Building binaries for Fuchsia

To build all the binaries required for running Syzkaller in Fuchsia, run this
from inside your Syzkaller checkout (assuming you built Fuchsia for x64):

```bash
make TARGETOS=fuchsia TARGETARCH=amd64 SOURCEDIR=${SOURCEDIR}
```

## Running syz-manager

Running syz-manager requires you to have built Fuchsia previously, and added the
ssh keys to the fuchsia.zbi image:

The output of the Fuchsia build is a _product bundle_. Look up the image files needed
via `ffx product get-image-path`:

```bash
  product_bundle_path="$(ffx config get product.path | tr -d '"')"
  fxfs_path="$(ffx product get-image-path "$product_bundle_path" --slot a --image-type fxfs)"
  zbi_path="$(ffx product get-image-path "$product_bundle_path" --slot a --image-type zbi)"
  multiboot_path="$(ffx product get-image-path "$product_bundle_path" --slot a --image-type qemu-kernel)"
```

Make sure the ssh keys exist and are properly configured:

```bash
  # Make sure there are ssh keys available
  ffx config check-ssh-keys
  auth_keys_path="$(ffx config get ssh.pub | tr -d '"')"
  priv_key_path="$(ffx config get ssh.priv | tr -d '"')"
```

Add the authorized keys to the zbi.
```bash
fx host-tool zbi -o "${SOURCEDIR}/out/x64/fuchsia-ssh.zbi" \
  "${zbi_path}" \
  --entry "data/ssh/authorized_keys=${auth_keys_path}"
```

Note: This needs to be repeated after each `fx build`.

Create a `syz-manager` configuration file, using this as a starting point:

```json
{
  "name": "fuchsia",
  "target": "fuchsia/amd64",
  "http": ":12345",
  "workdir": "/workdir.fuchsia",
  "kernel_obj": "/fuchsia/out/syz/kernel_x64-kasan/obj/zircon/kernel",
  "syzkaller": "/syzkaller",
  "image": "$fxfs_path",
  "sshkey": "$priv_key_path",
  "reproduce": false,
  "cover": false,
  "procs": 8,
  "type": "qemu",
  "vm": {
    "count": 10,
    "cpu": 4,
    "mem": 2048,
    "kernel": "${multiboot_path}",
    "initrd": " ${SOURCEDIR}/out/x64/fuchsia-ssh.zbi"
  }
}
```

Run `syz-manager` with that config:

```bash
bin/syz-manager -config manager.cfg
```

Note: You may need to modify your `PATH` so that qemu can be found, e.g.

```bash
export `PATH="$SOURCEDIR/prebuilt/third_party/qemu/linux-x64/bin:$PATH"`
```

## Update syscall and FIDL definitions

Syscall descriptions live in the `sys/fuchsia` folder. To update a syscall, you
need to modify the `.txt` file that contains it, make sure your new definition
matches the one in Zircon's
[syscalls.abigen](https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/public/zircon/syscalls.abigen)
file. **If the syscall was used in `executor/common_fuchsia.h`, you need to
update the usages there as well.** FIDL definitions do not need manual updating
because they are extracted automatically when you run `make extract`, but they
require Fuchsia to be rebuilt for each architecture (see [Building
Fuchsia](#building-fuchsia) above).

Once you updated the syscall definitions, everything can be regenerated by
running (in your Syzkaller checkout):

```bash
make extract TARGETOS=fuchsia SOURCEDIR=${SOURCEDIR}
make generate
```

**Caveat:** This command does not currently work.

## How to generate syscall definitions from FIDL

TODO: This section is out of date.

Syscall descriptions for FIDL are automatically generated as part of `make
extract` as described above.

However, if you wish to manually generate syscall descriptions for a given
`.fidl` file, do the following.

FIDL files should first be compiled into FIDL intermediate representation (JSON)
files using `fidlc`:

```bash
${SOURCEDIR}/out/x64/host_x64/fidlc --json /tmp/io.json --files ${SOURCEDIR}/zircon/system/fidl/fuchsia-io/io.fidl
```

Then run the FIDL compiler backend `fidlgen` with the syzkaller generator, which
compiles a FIDL IR file into a syscall description file:

```bash
${SOURCEDIR}/out/x64/host_x64/fidlgen -generators syzkaller -json /tmp/io.json -output-base fidl_io -include-base fidl_io
```

## Running syz-ci locally

To run `syz-ci` locally for Fuchsia, you need:

- bootstrapped Fuchsia checkout (in `/bootstrap/fuchsia` dir in the example below)
- bootstrap `syz-ci` binary (in the current dir, build with `make ci`)
- `syz-ci` config similar to the one below (in `ci.cfg` file in the current dir)

```json
{
	"name": "testci",
	"http": ":50000",
	"manager_port_start": 50001,
	"syzkaller_repo": "https://github.com/google/syzkaller.git",
	"managers": [
		{
			"name": "fuchsia",
			"repo": "https://fuchsia.googlesource.com",
			"manager_config": {
				"target": "fuchsia/amd64",
				"type": "qemu",
				"cover": false,
				"procs": 8,
				"vm": {
					"count": 4,
					"cpu": 4,
					"mem": 1024
				}
			}
		}
	]
}
```

Run `syz-ci` as:

```bash
SOURCEDIR=/bootstrap/fuchsia ./syz-ci -config ci.cfg
```

## Troubleshooting

While running the `make extract` step, it's possible that the FIDL definitions
are not up to date. It could happen that they have been removed or renamed.

If this is the case, you would see an error mentioning that the fidl.json file
could not be found:

```bash
go generate ./sys/fuchsia
cannot find /path-to-fuchsia/out/x64/fidling/gen/zircon/public/fidl/zircon-ethernet/zircon-ethernet.fidl.json
exit status 1
```

You can search for the string in [the Fuchsia code search
interface](https://cs.opensource.google/fuchsia/fuchsia/+/main:) or in [the
Gerrit code-review tool](https://fuchsia-review.googlesource.com/) to see what
happened to it. If the FIDL interface was renamed or removed, you should update
`sys/fuchsia/fidlgen/main.go` to reflect this change, and remove the stale
autogenerated files.

---

### Overview (`docs/gvisor/README.md`)

# gVisor

[gVisor](https://github.com/google/gvisor) is a user-space kernel, written in
Go, that implements a substantial portion of the Linux system surface.

`gVisor` uses `linux` OS, but the special `gvisor` VM type. There is nothing
special regarding `gVisor` besides that. The `image` is a gVisor release
tarball (`gvisor.tar.bz2`, see
[installation instructions](https://gvisor.dev/docs/user_guide/install/)),
which syzkaller extracts into the `workdir`. There is no kernel object, so
`kernel_obj` is not needed; for coverage, point `kernel_src` to the gVisor
source tree. Here is an example manager config:

```
{
	"name": "gvisor",
	"target": "linux/amd64",
	"http": ":12345",
	"workdir": "/workdir",
	"image": "/path/to/gvisor.tar.bz2",
	"syzkaller": "/gopath/src/github.com/google/syzkaller",
	"cover": false,
	"procs": 8,
	"type": "gvisor",
	"vm": {
		"count": 5,
		"runsc_args": "-platform=kvm"
	}
}
```

## Reproducing crashes

`syz-execprog` can be used inside gVisor to (hopefully) reproduce crashes.

To run a single program inside a minimal gVisor sandbox, do the following.

1. Build all of the syzkaller tools:

```bash
$ cd $SYZKALLER_DIR
$ make
```

2. Build the gVisor release tarball and extract it:

```bash
$ cd $GVISOR_DIR
$ make release-tarball DESTINATION=bin/
$ tar -C bin/ -xf bin/gvisor.tar.bz2
```

3. Create a `bundle/` directory with a config like the one below. Be sure to
   update the paths to the `linux_amd64` directory and input log/program file.

```bash
$ mkdir bundle
$ $EDITOR bundle/config.json
```

4. Run gVisor:

```bash
$ sudo bin/runsc \
    -platform=ptrace \
    -file-access=shared \
    -network=host \
    run \
    -bundle /PATH/TO/bundle/ \
    syzkaller
```

5. Remove container:

```bash
$ sudo bin/runsc delete -force syzkaller
```

Note that you'll want to adjust the `runsc` args to match the config in which
the crash was discovered. You may also want to add `-debug -strace` for more
debugging information.

You can also adjust the args to `syz-execprog` in `config.json`. e.g., add
`-repeat` to repeat the program.

### config.json

```
/* Detailed source-code truncated for AI context efficiency. */
```
## syzkaller way gVisor use

To build a specific gVisor version:

```
git clone https://github.com/google/gvisor
git checkout be6ffa78e4df78df13d004a17f2a8833305285c4
```

syzkaller uses gVisor release tarballs as images. `pkg/build` builds them from
the gVisor sources with `make copy` (see `pkg/build/gvisor.go`), e.g. for the
coverage-instrumented build that syzbot uses:

```
make copy TARGETS=//debian:gvisor-release-coverage-tar-bz2 DESTINATION=gvisor-coverage.tar.bz2
```

`-race` and `-race-coverage` variants of the tarball are available as well.
The kernel config of a gVisor manager consists of the `-cover` and `-race`
flags that select the variant.

To get coverage symbols, extract the tarball and run `runsc symbolize`:

```
tar -xf gvisor-coverage.tar.bz2
./runsc symbolize -all > symbolize_all_gvisor_be6ffa78e4df78df13d004a17f2a8833305285c4.txt
```

---

### Overview (`docs/hafnium/README.md`)

# Hafnium

[Hafnium](https://hafnium.googlesource.com/hafnium) is a hypervisor.

This is work-in-progress, see #996.

For details on how to build/run Hafnium see [GettingStarted](https://hafnium.googlesource.com/hafnium/+/HEAD/docs/GettingStarted.md), [HafniumRamDisk](https://hafnium.googlesource.com/hafnium/+/HEAD/docs/HafniumRamDisk.md) and [PreparingLinux](https://hafnium.googlesource.com/hafnium/+/HEAD/docs/PreparingLinux.md).

For now we only have descriptions for [AF_HF protocol](/sys/linux/hafnium.txt) provided by Hafnium linux driver.

---

### Overview (`docs/netbsd/README.md`)

# NetBSD

Instructions to set up syzkaller for a Linux host and a NetBSD guest.

## Preparing the NetBSD sources

1. Get the NetBSD kernel source (preferably HEAD).
	```sh
	host$ mdkir $HOME/netbsd
	host$ cd $HOME/netbsd
	host$ git clone https://github.com/NetBSD/src.git
	```

2. Build the tools. You will have the toolchain in `$HOME/netbsd/tools`.
	```sh
	host$ cd src
	host$ ./build.sh -j4 -m amd64 -U -T ../tools tools
	```

3. Build the distribution. This might take a while.
	```sh
	host$ ./build.sh -j4 -m amd64 -U -T ../tools -D ../dest distribution
	```

At this point you should have a NetBSD distribution in `$HOME/netbsd/dest`.

## Installing and building syzkaller on the Linux host

1. Install all the dependencies for syzkaller.

2. Clone the syzkaller repository.
	```sh
	host$ git clone https://github.com/google/syzkaller
	host$ cd syzkaller
	```

3. Compile syzkaller for NetBSD.
	```sh
	host$ make TARGETOS=netbsd SOURCEDIR=$HOME/netbsd
	```

The above steps should have built the syzkaller binaries for NetBSD.

You can see the compiled binaries in `bin/netbsd_amd64`.

## Setting up a NetBSD VM with qemu

You can use the script given [here](https://github.com/R3x/netbsd-fuzzing-aids/blob/master/install_netbsd.sh) to create a disk image with NetBSD installed.
The script would also automatically give you a ssh key to ssh into the VM.

Alternatively, you can follow the tutorial given [here](https://wiki.qemu.org/Hosts/BSD#NetBSD) to
set up a basic NetBSD VM with qemu.

After installing and running the NetBSD VM on qemu, please follow the steps below to
configure ssh.

1. Create a ssh-keypair on the host and save it as `netbsdkey`.
	```sh
	host$ ssh-keygen -f netbsdkey -t rsa -N ""
	```

2. Make sure you have a NAT enabled in your Qemu command line. Typically to
   forward the host port `10022` to the guest port `22`:
	```sh
	host$ qemu-system-x86_64 ... -netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:10022-:22 -device e1000,netdev=mynet0
	```

3. Append the following lines to `/etc/rc.conf` on the guest. You can use the `vi` editor to do that.
	```
	sshd=YES
	dhcpcd=YES
	ifconfig_wm0="inet 10.0.2.15 netmask 255.255.255.0"
	```

4. Append this to `/etc/ssh/sshd_config` on the guest.
	```
	Port 22
	ListenAddress 10.0.2.15
	PermitRootLogin yes
	PermitRootLogin without-password
	```

5. Now you should be able to ssh into the NetBSD VM.
	```sh
	host$ ssh -p 10022 root@127.0.0.1
	```

6. Copy and paste your public key to `/root/.ssh/authorized_keys` on the guest
   and `reboot` the VM.

7. After reboot make sure that ssh is working properly. Replace the port with what
   you have configured.
	```sh
	host$ ssh -i path/to/netbsdkey -p 10022 root@127.0.0.1
	```

If the last command returns a proper shell it means the VM has been configured.

## Compiling a NetBSD kernel (Optional)

You can compile a kernel with KASAN to increase the chances of finding bugs.

1. Make a copy of the config file.
	```sh
	host$ cd $HOME/netbsd/src
	host$ cp sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/SYZKALLER
	```

2. Uncomment the following lines in `sys/arch/amd64/conf/SYZKALLER` to enable KASAN.
	```
	#makeoptions 	KASAN=1		# Kernel Address Sanitizer
	#options 	KASAN
	#no options	SVS
	```

3. Compile the kernel with KASAN (assuming you have followed the initial steps to
   build tools).
	```sh
	host$ cd $HOME/netbsd/src
	host$ ./build.sh -m amd64 -U -T ../tools -j4 kernel=SYZKALLER
	```

4. At this point you should have the new compiled kernel image which can be found in
   `$HOME/netbsd/src/sys/arch/amd64/compile/SYZKALLER` and should have the name
   `netbsd`. You need to copy it to the installed VM and reboot the VM.

## Running syzkaller

1. If all of the above worked, `poweroff` the VM and create the `netbsd.cfg` config
   file on the host with the following contents (alter paths as necessary):
	```
	{
		"name": "netbsd",
		"target": "netbsd/amd64",
		"http": ":10000",
		"workdir": "work",
		"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
		"image": "path/to/netbsd.img",
		"sshkey": "/path/to/netbsdkey",
		"sandbox": "none",
		"procs": 2,
		"cover": false,
		"type": "qemu",
		"vm": {
			"qemu": "qemu-system-x86_64",
			"count": 2,
			"cpu": 2,
			"mem": 2048
		}
	}
	```
   The above directories have to be specified to the exact locations and the ssh keys
   must be in a separate directory with chmod 700 permissions set to that directory
   and chmod 600 permissions to the files in both the guest and the host.

2. Then, inside the syzkaller folder where the `netbsd.cfg` file also exists, start `syz-manager` with:
	```sh
	host$ bin/syz-manager -config netbsd.cfg
	```
   You can add a `-debug` flag to the above command to view the log if any issues arise.

3. Once syzkaller has started executing, 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
	```

## syzbot

[syzbot](/docs/syzbot.md) tests NetBSD and reports bugs to
[syzkaller-netbsd-bugs](https://groups.google.com/forum/#!forum/syzkaller-netbsd-bugs) mailing list
(also can be seen on [dashboard](https://syzkaller.appspot.com/netbsd)).

The image `syzbot` uses can be downloaded [here](https://storage.googleapis.com/syzkaller/netbsd-image.tar.gz) (266MB, includes root ssh key). The image was built using this [script](https://github.com/R3x/netbsd-fuzzing-aids/blob/master/install_netbsd.sh).

The image can be used with qemu as follows:
```
qemu-system-x86_64 -m 1024 -smp 2 -nographic -enable-kvm \
	-netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:10022-:22 \
	-device e1000,netdev=mynet0 -hda netbsd-image.raw
```

And then you can ssh/scp into the VM using:
```
ssh -i netbsd-image.key -p 10022 -o IdentitiesOnly=yes root@localhost
scp -i netbsd-image.key -P 10022 -o IdentitiesOnly=yes FILE root@localhost:/root/
```

Note: the image contains a stock kernel, so if you are reproducing a bug
most likely you want to update kernel as the first step:
```
scp -i netbsd-image.key -P 10022 -o IdentitiesOnly=yes \
	src/sys/arch/amd64/compile/obj/GENERIC_SYZKALLER/netbsd root@localhost:/netbsd
ssh -i netbsd-image.key -p 10022 -o IdentitiesOnly=yes root@localhost /sbin/reboot
```

## Missing things

- Automating the configuration changes (like appending to config files), generating the json config file on the fly (with customizable values to the keys using command line parameters) and calling syz-manager with `anita` using just a single command.
- System call descriptions. `sys/netbsd/*.txt` is a dirty copy from `sys/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 `amd64` arch is supported. Supporting `386` would be useful, because it should cover compat paths. Also, we could do testing of the linux-compatibility subsystem.
- `pkg/host` needs to be taught how to detect supported syscalls/devices.
- On Linux we have emission of external networking/USB traffic into kernel using tun/gadgetfs. Implementing these for NetBSD could uncover a number of high-profile bugs.

---

### Overview (`docs/starnix/README.md`)

# starnix support

## Prerequisites

To run syzkaller for fuzzing starnix, you will need a checkout of the Fuchsia
source repository.

The rest of this document will use the environment variable `SOURCEDIR` to
identify the path to your Fuchsia checkout (e.g. `/home/you/fuchsia`). The
commands below assume you have set `SOURCEDIR`, like so:

```bash
export SOURCEDIR=/home/you/fuchsia
```

To build Fuchsia for qemu-x64, run:
```
fx --dir "out/qemu-x64" set workstation_eng.qemu-x64 \
  --with "//bundles/tools" \
  --with "//src/proc/bin/starnix"
fx build
```

You will also need to follow the instructions in the sections `GCC` and `Kernel`
of the [setup\_ubuntu-host\_qemu-vm\_x86-64-kernel.md](../linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md) file.


## syzkaller

### Building binaries for starnix
First, you need to build all the binaries required for running syzkaller in starnix.
For that, you only need to run this from inside your syzkaller checkout (assuming you built Fuchsia for x64):

```bash
SYZ_STARNIX_HACK=1 make TARGETOS=linux TARGETARCH=amd64
```

### Configuration file
Create a manager config like the following, replacing the environment variables `$SYZKALLER`, `$KERNEL` and `$IMAGE` with their actual values.

> **_NOTE:_**  `ffx` is still under development, for that reason VM count of 1 is recommended until fxbug.dev/118926 is solved.

```bash
{
    "target": "linux/amd64",
    "http": "127.0.0.1:56741",
    "workdir": "$SYZKALLER/workdir",
    "kernel_obj": "$KERNEL",
    "kernel_src": "$SOURCEDIR",
    "syzkaller": "$SYZKALLER",
    "procs": 8,
    "type": "starnix",
    "vm": {
        "count": 1
    },
    "cover": false
}
```

### Running

Lastly, just run the command below to start fuzzing.

```bash
SYZ_STARNIX_HACK=1 bin/syz-manager -config=./starnix.cfg
```

---

### Overview (`docs/trusty/README.md`)

# Trusty support

[Trusty](https://source.android.com/security/trusty) is a set of software
components supporting a Trusted Execution Environment (TEE) on mobile devices.

This is work-in-progress, see #933. For now we only support testing `Trusty` via actual application ports.

# Building kernel with Trusty IPC support

```
git remote add android https://android.googlesource.com/kernel/common
git fetch android
git checkout android/android-trusty-4.9
make distclean
# TODO: consider using trusty_qemu_defconfig instead.
make ARCH=arm64 ranchu64_defconfig
# Required to enable qemu networking:
make ARCH=arm64 defconfig
make ARCH=arm64 kvmconfig
# Some custom configs:
ARCH=arm64 ./scripts/kconfig/merge_config.sh .config trusty.config
# We don't install modules:
sed -i 's#^\(.*\)=m$#\# \1 is not set#g' .config
make ARCH=arm64 olddefconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j64
```

```
# trusty.config
CONFIG_TRUSTY=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_INFO=y
CONFIG_KCOV=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_VM=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=140
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_WQ_WATCHDOG=y
```

# Building Trusty

```
mkdir trusty; cd trusty
repo init -u https://android.googlesource.com/trusty/manifest -b master
repo sync -j32
source trusty/vendor/google/aosp/scripts/envsetup.sh
make -j32 generic-arm64
# Build Trusty and qemu images:
trusty/vendor/google/aosp/scripts/build.py qemu-generic-arm64-test-debug
# Create qemu-comb.dtb:
KERNEL_DIR=$KERNEL build-root/build-qemu-generic-arm64-test-debug/run-qemu
```

# Building arm64 image

```
git clone git://git.buildroot.net/buildroot
cd buildroot
make qemu_aarch64_virt_defconfig
support/kconfig/merge_config.sh .config syzkaller.config
make -j64
```

```
# syzkaller.config
BR2_cortex_a57=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_ARM_AARCH64=y
BR2_TARGET_GENERIC_HOSTNAME="syzkaller"
BR2_TARGET_GENERIC_ISSUE="syzkaller"
BR2_PACKAGE_DHCPCD=y
BR2_PACKAGE_OPENSSH=y
BR2_TARGET_ROOTFS_EXT2_SIZE="1G"
BR2_ROOTFS_POST_FAKEROOT_SCRIPT="./syzkaller.sh"
# BR2_LINUX_KERNEL is not set
```

```
# syzkaller.sh
set -eux
# Mount debugfs for KCOV.
echo "debugfs /sys/kernel/debug debugfs defaults 0 0" >> $1/etc/fstab
# Generate and install ssh key.
rm -f key key.pub
ssh-keygen -f key -t rsa -N ""
mkdir -p $1/root/.ssh
cp key.pub $1/root/.ssh/authorized_keys
```

# Testing build

TODO: where does the firmware come from?

Boot in qemu:
```
cd $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug
$TRUSTY/build-root/build-qemu-generic-arm64-test-debug/qemu-build/aarch64-softmmu/qemu-system-aarch64 -m 1024 -smp 1 -net nic -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -display none -serial stdio -no-reboot -machine virt,secure=on,virtualization=on -cpu cortex-a57 -bios $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug/bl1.bin -d unimp -semihosting-config enable,target=native -no-acpi -dtb $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug/qemu-comb.dtb -hda $BUILDROOT/output/images/rootfs.ext4 -snapshot -kernel $KERNEL/arch/arm64/boot/Image -append "androidboot.hardware=qemu_trusty earlyprintk=serial console=ttyAMA0,38400 root=/dev/vda"
```

SSH into the VM:
```
ssh -i $BUILDROOT/key -p 10022 -o IdentitiesOnly=yes root@localhost
```

# Running syzkaller

Build and run `syzkaller` as:
```
cd $SYZKALLER
make TARGETARCH=arm64
cd $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug
$SYZKALLER/bin/syz-manager -config trusty.cfg
```

using config along the lines of (substitute actual values for `$KERNEL`, `$SYZKALLER`, `$BUILDROOT` and `$TRUSTY`):
```
{
	"name": "trusty",
	"target": "linux/arm64",
	"http": ":10000",
	"workdir": "/workdir",
	"kernel_obj": "$KERNEL",
	"syzkaller": "$SYZKALLER",
	"image": "$BUILDROOT/output/images/rootfs.ext4",
	"sshkey": "$BUILDROOT/key",
	"cover": false,
	"procs": 4,
	"type": "qemu",
	"vm": {
		"count": 4,
		"cpu": 1,
		"mem": 1024,
		"qemu": "$TRUSTY/build-root/build-qemu-generic-arm64-test-debug/qemu-build/aarch64-softmmu/qemu-system-aarch64",
		"qemu_args": "-machine virt,secure=on,virtualization=on -cpu cortex-a57 -bios $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug/bl1.bin -d unimp -semihosting-config enable,target=native -no-acpi -dtb $TRUSTY/build-root/build-qemu-generic-arm64-test-debug/atf/qemu/debug/qemu-comb.dtb",
		"cmdline": "androidboot.hardware=qemu_trusty console=ttyAMA0,38400 root=/dev/vda",
		"kernel": "$KERNEL/arch/arm64/boot/Image"
	},
	"enable_syscalls": [
		"openat$trusty*",
		"write$trusty*",
		"read",
		"ioctl$TIPC_IOC_CONNECT*",
		"ppoll",
		"dup3",
		"tkill",
		"gettid",
		"close"
	]
}
```

---

### Overview (`docs/windows/README.md`)

# Windows

`Windows` support is very raw and preliminary (read, non-working).

There is a [closed-source port at Microsoft](https://github.com/dwizzzle/Presentations/blob/master/David%20Weston%20-%20Keeping%20Windows%20Secure%20-%20Bluehat%20IL%202019.pdf).

There is a more complete
[closed-source Windows port](https://www.slideshare.net/AnthonyLAOUHINETSUEI/wsl-reloaded)
done by [Fritz](https://twitter.com/anarcheuz) and [zer0mem](https://twitter.com/zer0mem).
The port has found 6 bugs including
[CVE-2018-8441](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8441).

Also, BSoDs in WSL: [1](https://twitter.com/yoavalon/status/1102563655743406082), [2](https://twitter.com/NetanelBenSimon/status/1102563950221316096).
See [BUGS ON THE WINDSHIELD: FUZZING THE WINDOWS KERNEL](https://www.offensivecon.org/speakers/2020/netanel-ben-simon-yoav-alon.html) presentation.

To update descriptions run (assumes `cl` cross-compiler is in PATH):
```
syz-extract -os=windows
syz-sysgen
```

`sys/windows/windows.txt` was auto-extracted from windows headers with `tools/syz-declextract`.

To build binaries:
```
make fuzzer execprog stress TARGETOS=windows
REV=git rev-parse HEAD
cl executor\executor_windows.cc /EHsc -o bin\windows_amd64\syz-executor.exe \
	-DGIT_REVISION=\"$REV\" \
	kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib \
	shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
	winmm.lib rpcrt4.lib Crypt32.lib imm32.lib Urlmon.lib Oleaut32.lib \
	Winscard.lib Opengl32.lib Mpr.lib Ws2_32.lib Bcrypt.lib Ncrypt.lib \
	Synchronization.lib Shell32.lib Rpcns4.lib Mswsock.lib  Mincore.lib \
	Msimg32.lib RpcRT4.lib Rpcrt4.lib lz32.lib
```

To run `syz-execprog`:
```
bin\windows_amd64\syz-execprog.exe -executor c:\full\path\to\bin\windows_amd64\syz-executor.exe -stress
```

Windows is supported by only `gce` VMs at the moment.
To use `gce`, create a Windows GCE VM, inside of the machine:

 - Enable serial console debugging (see [this](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/boot-parameters-to-enable-debugging) for details):
```
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200 /noumex
```

 - Disable automatic restart in `sysdm.cpl -> Advanced -> Startup and Recovery`

 - Setup sshd with key auth, [these](https://winscp.net/eng/docs/guide_windows_openssh_server) instructions worked for me.
   Preferably use non-admin user. Save private ssh key.

Then shutdown the machine, stop the instance and create an image from the disk.
Then start `syz-manager` with config similar to the following one:

```
{
	"name": "windows",
	"target": "windows/amd64",
	"http": ":20000",
	"workdir": "/workdir",
	"syzkaller": "/syzkaller",
	"sshkey": "/id_rsa",
	"ssh_user": "you",
	"cover": false,
	"procs": 8,
	"type": "gce",
	"vm": {
		"count": 10,
		"machine_type": "n1-highcpu-2",
		"gce_image": "your-gce-image"
	}
}
```

---

### Overview (`pkg/coveragedb/README.md`)

# Prepare coverage aggregation pipeline

Assuming you have the coverage `*.jsonl` files in some bucket:
1. Create BigQuery table.
2. Start data transfers from the bucket to BigQuery table.

Coverage merger job is consuming data from BQ table and store aggregations
in the Spanner DB.

The dots in BQ table name are not supported, thus:
1. For the namespace "upstream" the expected BQ table name is "upstream".
2. For the namespace "android-6.12" the expected BQ table name is "android-6-12".


### Create new BigQuery table for coverage data
```bash
bq mk \
  --table \
  --description "android 6.12" \
  --time_partitioning_field timestamp \
  --time_partitioning_type DAY \
  --require_partition_filter=true \
  --clustering_fields file_path,kernel_commit,hit_count \
  syzkaller:syzbot_coverage.android-6-12 \
  ./pkg/coveragedb/bq-schema.json
```

### Add new data transfer
```bash
bq mk \
  --transfer_config \
  --display_name=ci-android-6-12-bucket-to-syzbot_coverage \
  --params='{"destination_table_name_template":"android-6-12",
  "data_path_template": "gs://$COVERAGE_STREAM_BUCKET/ci-android-6.12/*.jsonl",
  "allow_jagged_rows": false,
  "allow_quoted_newlines": false,
  "delete_source_files": true,
  "encoding": "UTF8",
  "field_delimiter": ",",
  "file_format": "JSON",
  "ignore_unknown_values": false,
  "max_bad_records": "0",
  "parquet_enable_list_inference": false,
  "parquet_enum_as_string": false,
  "preserve_ascii_control_characters": false,
  "skip_leading_rows": "0",
  "use_avro_logical_types": false,
  "write_disposition": "APPEND"
  }' \
  --project_id=syzkaller \
  --data_source=google_cloud_storage \
  --target_dataset=syzbot_coverage
```

### List BigQuery data transfers
```bash
bq ls \
  --transfer_config \
  --transfer_location=us-central1 \
  --project_id=syzkaller
```

---

### Overview (`pkg/report/README.md`)

# Bugs scoring

Until triaged we don't really know the bug impact. But we can learn a lot from the bug title.

Syzbot scoring is based on our understanding of what bug class looks historically more impactful. It allows to
prioritize the triaging queue.

## Heuristics

### KASAN > KMSAN > KCSAN
KASAN detected bugs are typically more dangerous than KMSAN detected bugs. And KMSAN detected bugs are typically more
dangerous than KCSAN detected bugs.

### Invalid-free (double-free) >= use-after-free write > use-after-free read.

### KASAN write > KASAN read
KASAN write indicates an out-of-bounds or use-after-free write operation. Any uncontrolled write to kernel memory is
extremely dangerous because it can corrupt data or code pointers, making it a high-value target for exploitation
and leading to system compromise. KASAN read indicates an out-of-bounds or use-after-free read. This is generally
less critical. It can crash the system (DoS) or leak sensitive data, but it doesn't provide a direct path for an
attacker to execute their own code.

### Memory Safety bugs > DoS bugs.
This heuristic establishes a broad priority between two major classes of bugs based on their ultimate impact.

Memory Safety bugs: This category includes all the issues mentioned above—use-after-free, double-free, out-of-bounds
reads/writes, etc. These are considered more severe because they represent a potential system compromise. A successful
exploit can allow an attacker to escalate privileges and gain complete control over the kernel and the entire system.

DoS bugs (Denial of Service): This category includes bugs like kernel hangs, crashes, or resource exhaustion
(e.g., memory leaks). While they are serious because they disrupt system availability, they typically do not allow an
attacker to execute code or steal data. The impact is usually temporary and can be resolved by rebooting the system.
They disrupt the service but don't compromise its integrity.

### Information Leaks > Denial of Service (DoS)
Kmsan infoleak and other bugs that leak kernel memory are generally more severe than a typical DoS. These leaks can be
used to bypass security mitigations like Kernel Address Space Layout Randomization (KASLR), which makes exploiting
other vulnerabilities easier.

### Concurrency Issues > Simple DoS
Bugs like DataRace and LockdepBug can be more critical than a standard DoS. Data races can lead to unpredictable
behavior, including memory corruption, which might be exploitable.

LockdepBug indicates potential deadlocks, which can cause a more severe system Hang than a resource-exhaustion DoS.

### KFENCE reports are high priority
KFENCE is a lighter-weight memory safety detector compared to KASAN. While it may have a lower performance overhead,
the bugs it finds (use-after-free, out-of-bounds) are of the same high-impact nature as those found by KASAN.
Therefore, KFENCE detected bugs should be treated with a similar level of urgency as KASAN reports.

### UBSAN reports require careful evaluation
The Undefined Behavior Sanitizer (UBSAN) can detect a wide range of issues. Their severity can vary greatly:

1. A shift-out-of-bounds or array-index-out-of-bounds issue can be very severe if it leads to memory corruption.
2. An integer-overflow can also be critical if it results in bypassing security checks and leads to a buffer overflow.
3. Other UBSAN issues might be less critical but still indicate latent bugs that could become problematic.

### LockdepSleeping in Atomic Context is a critical flaw
AtomicSleep is a serious bug that can lead to system-wide hangs and instability. This is because holding a spinlock
or being in another atomic context while sleeping can cause deadlocks.

These are generally more severe than a typical DoS.

### Memory Leaks are a form of DoS
MemoryLeak bugs are a type of denial of service where the kernel gradually runs out of memory. While generally less
severe than memory corruption, a fast memory leak that can be triggered by an unprivileged user can be a high-impact
DoS vector.

### NULL pointer dereference in reads/writes
They may be exploitable (see [proof](https://googleprojectzero.blogspot.com/2023/01/exploiting-null-dereferences-in-linux.html ))
but the exploitation probability is not clear. Because of this uncertainty they are put to the bottom of the high
priority bugs.

---

### Overview (`sys/fuchsia/README.md`)

# Fuchsia system call definitions

This directory contains the system call definitions for Fuchsia's kernel,
Zircon. They are currently updated manually, but we hope that will change Real
Soon Now. When/if it does, we'll update this file.

The `.fidl` files in the [vDSO
directory](https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/vdso/)
describe Zircon's system calls in FIDL, and in the comments there are English
and C++ descriptions. For every FIDL file, there should be a corresponding
`.txt` file in this directory that describes the system calls using [Syzkaller's
syzlang
language](https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions_syntax.md).

---

### Overview (`syz-cluster/dashboard/README.md`)

To update and access the web dashboard during local development:

```
$ make install-dev-config
$ make deploy-web-dashboard-dev
$ kubectl port-forward service/web-dashboard-service --address 0.0.0.0 50123:80
```

---

### Overview (`tools/docker/README.md`)

# Docker images

We provide a set of Docker images that provide dev environment suitable for syzkaller development/testing.
These images are used by CI, but can also be used for [local development](/docs/contributing.md#using-syz-env).

- [env](/tools/docker/env/Dockerfile) includes Go/fuchsia/netbsd toolchains, gcloud sdk, C/C++ cross-compilers, make, git and other essential tools.
- [old-env](/tools/docker/old-env/Dockerfile) provides essential tools but based on an older disto (ubuntu:16.04).

These images are available as `gcr.io/syzkaller/{env,old-env}`, respectively.

To download and run locally:
```
docker pull gcr.io/syzkaller/env
docker run -it gcr.io/syzkaller/env
```

## Building Multi-arch Images

The `syzbot` and `env` images support multiple architectures (amd64, arm64). To build and push them, we use [Docker buildx](https://docs.docker.com/build/building/multi-platform/) to build a multi-arch image in a way that allows distributing it under one tag name.

### 1. One-time Setup

Install the QEMU emulators and create a new builder instance:

```bash
# Install QEMU emulators for multi-arch support
docker run --privileged --rm tonistiigi/binfmt --install all

# Create and bootstrap a new builder
docker buildx create --name mybuilder --driver docker-container --bootstrap
docker buildx use mybuilder
```

### 2. Build and Push

Once the builder is configured, you can build and push the images. Ensure you are authenticated with Google Cloud:

```bash
gcloud auth login && gcloud auth configure-docker
```

**Building the `syzbot` image:**

```bash
docker buildx build --platform linux/amd64,linux/arm64 \
  -t gcr.io/syzkaller/syzbot \
  tools/docker/syzbot \
  --push
```

**Building the `env` image:**

```bash
docker buildx build --platform linux/amd64,linux/arm64 \
  -t gcr.io/syzkaller/env \
  tools/docker/env \
  --push
```

## [DEPRECATED] Github Packages

Github packages are not supported (if you can't access gcr.io, please contact us).

```
docker tag gcr.io/syzkaller/env [docker.pkg.github.com/google/syzkaller/env](https://docker.pkg.github.com/google/syzkaller/env)
docker login [https://docker.pkg.github.com](https://docker.pkg.github.com)
docker push [docker.pkg.github.com/google/syzkaller/env](https://docker.pkg.github.com/google/syzkaller/env)
```

---

### Overview (`tools/syz-aflow/README.md`)

# `syz-aflow` - AI Workflow Executor

`syz-aflow` is a CLI tool designed to execute `aflow` workflows locally for debugging and testing purposes.

## Building

To build `syz-aflow`, use the `syz-env` environment from the repository root:
```bash
./tools/syz-env go build ./tools/syz-aflow
```
This will create a `syz-aflow` binary in the repository root.

## Usage

### Basic Execution

To run a workflow, you need to specify the workflow name, an input JSON file, and a working directory:

```bash
./tools/syz-env ./syz-aflow -workflow <workflow_name> -input <input.json> -workdir <workdir>
```

### Batch Execution

If `-input` is a directory, each `*.json` file in it is executed as a separate task:

```bash
./tools/syz-env ./syz-aflow -workflow seed-gen-file-line -input ./tasks -workdir ./workdir -parallel 4
```

Results are saved to `<workdir>/trajectories/<state>/`. Completed tasks are skipped on restart.
Batch execution is currently only supported for the `seed-gen-file-line` workflow and cannot be combined
with `-html` and `-output`.

To spread the load over several Gemini API keys, put them one per line into `GOOGLE_API_KEY`
(e.g. `GOOGLE_API_KEY="$(cat keys.txt)"`). Each task sticks to one key. Keys only help with rate limits
if they belong to different projects.

With `-corpus <path>`, all programs executed during the batch run are also saved into the given `corpus.db`
(without call properties such as fault injection), e.g. to be used as fuzzing seeds.

### Workflow Inputs

`syz-aflow` does not require a standard `syz-manager` configuration file. Instead, it takes a JSON file containing the arguments specific to the workflow you are running.

If the workflow needs to perform actions that interact with VMs (like reproducing a crash or testing a patch), it will expect fields in that input JSON that describe the environment (e.g., `Image`, `VM` type and config, `KernelSrc`, etc.). The workflow code then takes these individual arguments and builds the necessary manager configuration programmatically on the fly.

#### Example Input for `patching` Workflow

```json
{
  "Syzkaller": "/path/to/syzkaller",
  "Image": "/path/to/linux/image",
  "Type": "qemu",
  "VM": {
    "count": 1,
    "cpu": 2,
    "mem": 2048,
    "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
  },
  "ReproSyz": "syz_open$dir(0x0, 0x1) ...",
  "KernelConfig": "@/path/to/linux.config"
}
```

Any string field in the input JSON starting with `@` (e.g. `"@/path/to/file"` or `"@./relative/path"`) will be automatically expanded with the contents of that file. Relative paths are resolved relative to the directory of the `-input` JSON file. Literal leading `@` characters can be escaped with `@@` (e.g. `"@@literal"`).


### Flags

- `-workflow`: The name of the workflow to execute.
- `-input`: Path to a JSON file containing the arguments for the workflow (or a directory of them).
- `-parallel`: Number of tasks to run concurrently in batch execution.
- `-corpus`: Path to a `corpus.db` to save all executed programs into in batch execution.
- `-workdir`: Directory where the workflow can perform checkouts, builds, etc.
- `-html`: Path to an HTML file where the execution trajectory will be rendered in real-time.
- `-model`: Override the default LLM model.
- `-cache-size`: Set the maximum cache size (default "10GB").
- `-download-bug`: Download bug details from the dashboard by ID or ExtID.
- `-auth`: Use gcloud auth token when downloading bugs.

### Live Trajectory Visualization

You can monitor the execution of the workflow in real-time by using the `-html` flag:
```bash
./tools/syz-env ./syz-aflow -workflow patching -input input.json -workdir ./workdir -html trajectory.html
```
Open the specified HTML file in your browser to see the charts and steps as they execute.

---

### Overview (`tools/syz-covermerger/README.md`)

# Covermerger, how it works
## Coverage signal lifetime
Syzkaller relies on KCOV to get information about the actual basic blocks executed
by kernel code.
This tool consumes `line:col` pairs that are coming from `addr2line(pc)` where `pc`
is the actual `pc` where we observed KCOV instrumentation hit.

## What do the dashboard numbers mean
Understanding the coverage percentages displayed on the dashboard can be tricky.
These numbers represent neither pure basic block coverage nor pure line coverage.

Instead, the dashboard shows the percentage of lines with coverage signals where at least one basic block
attributed to that line was executed.

Here's why this matters:

A single line of code can contain multiple basic blocks.

Covermerger reports a "hit" for a line even if only one out of several basic blocks on that line was covered.
For example, if a line has two basic blocks and only one is covered, we report a hit (50% basic block coverage
for that line, but 100% line coverage in our dashboard's context).

Essentially, dashboard coverage will always be greater than or equal to basic block coverage.

## How this tool works
Covermerger's primary function is to merge coverage signals from various kernel versions and configurations.
It provides daily, monthly, and quarterly aggregations.

### Merging Process
Independent File Processing: Each file is processed on its own.

Same Version: If coverage signals come from the exact same version of a file, their hit counts are simply added together.

Different Versions: When merging signals from different file versions (e.g., if a file changed multiple times within
a month), a diff-tool is used to identify equivalent lines across versions.

Projection to Latest Version: All merged signals are projected onto the latest available kernel version within the
aggregation period. For the current month, the target file version may change with each merge run. For past months,
the latest commit available at the end of that month is used as the target version.

Consider a scenario where a file changed three times in a month, and not all lines were included in every build.
Covermerger intelligently combines the signals to provide a comprehensive view despite these variations.

## Update frequency
Merge jobs are automated via [cron.yaml](/dashboard/app/cron.yaml) and follow this schedule:
1. Daily Aggregations: Updated every day. Batch jobs typically refresh "today" and "yesterday" numbers.
2. Monthly Aggregations: Updated weekly, with the current month's data refreshed 4-5 times per month.
3. Quarterly Aggregations: Also updated weekly.

We retain original coverage signals for at least one year, allowing for regeneration of data if needed.

---

### Overview (`tools/syz-db-export/README.md`)

# Syzbot DB export
Every week syzbot runs syz-db-export to export its databases:
1. [Upstream Linux](https://syzkaller.appspot.com/upstream)
db is [here](https://storage.googleapis.com/artifacts.syzkaller.appspot.com/shared-files/repro-export/upstream.tar.gz).
2. Contact us if you want see others.

## Export structure
DB currently includes:
1. Bugs descriptions.
2. First C-Reproducer for every bug.

It doesn't include:
1. Second+ C-Reproducers for every bug.
2. Syz-Reproducers.
3. Any reproducer related metadata (like triggering requirements).

## How to export more data

The best way to see more data exported is to modify the tool and send us PR with your changes.

To reproduce locally what syzbot is doing for upstream Linux:
```golang
go run ./tools/syz-db-export/... -namespace upstream
```
Extending tools/syz-db-export you can teach syzbot to export more.

---

### Overview (`tools/syz-declextract/README.md`)

# syz-declextract

## Linux Kernel (for testing purposes)
```
export KERNEL=$PWD/linux
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $KERNEL
cd $KERNEL
make CC=clang defconfig
./scripts/config -e FTRACE_SYSCALLS
make CC=clang olddefconfig
make CC=clang -j`nproc` vmlinux compile_commands.json # kernel has to be built at least once for the script to work
```

## Running on a single source file
```
./bin/syz-declextract $KERNEL/fs/read_write.c | less # or any other .c file
```

## Coverage Data

Coverage data (coverage.jsonl) can be obtained from syzbot dashboard using:
```
curl --header "accept-encoding: gzip" https://syzkaller.appspot.com/upstream/coverage?jsonl=1 | gunzip > coverage.jsonl
```
Note: the coverage is tied to a particular kernel commit. For consistency that commit
should be used for the rest of the process as well.

## Running on the whole kernel
```
go run ./tools/syz-declextract -config=manager.cfg -coverage coverage.jsonl
syz-env make extract SOURCEDIR=$KERNEL
```

The tool caches results of static kernel analysis in manager.workdir/declextract.cache file,
and results of the dynamic kernel probing in manager.workdir/interfaces.json file.
These can be examined for debugging purposes, and will be reused in future runs if exist
(greatly saves time). If the clang tool/kernel has changed, delete these cache files
so that they are updated.

---

### Overview (`tools/syz-uncovered-batch/README.md`)

# `syz-uncovered-batch` - Uncovered Target Generator

`syz-uncovered-batch` extracts candidate uncovered functions and code locations from Syzkaller dashboard coverage data, and generates batch task input files for `syz-aflow`.

## Building

To build `syz-uncovered-batch`, run:
```bash
./tools/syz-env go build ./tools/syz-uncovered-batch
```

## Usage

See `main.go` (or run `./syz-uncovered-batch -help`) for all available flags.

### 1. Prepare Base Configuration

Create a base template `base.json` defining the VM, kernel source, and image configuration for the target environment:

```json
{
  "AgentName": "syzbot",
  "Syzkaller": "/path/to/syzkaller",
  "Image": "/path/to/image",
  "KernelConfig": "@/path/to/linux.config",
  "TargetOS": "linux",
  "TargetArch": "amd64",
  "Snapshot": true,
  "Type": "qemu",
  "VM": {
    "count": 1,
    "cpu": 2,
    "mem": 2048,
    "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
  }
}
```

### 2. Generate Tasks

Extract uncovered targets for a specific manager and subsystems (e.g. KVM and DRM) and generate 50 task files:

```bash
./tools/syz-env ./syz-uncovered-batch \
    -manager ci-upstream-kasan-gce-root \
    -base base.json \
    -output-dir ./tasks \
    -include-paths virt/kvm,drivers/gpu/drm \
    -limit 50
```

### 3. Run Batch with `syz-aflow`

Execute the generated tasks in parallel using `syz-aflow`:

```bash
./tools/syz-env ./syz-aflow \
    -workflow seed-gen-file-line \
    -input ./tasks \
    -workdir ./workdir \
    -parallel 4 \
    -corpus
```

Results and trajectories will be saved to `./workdir/trajectories/{success,giveup,error}/` and executed programs collected into `./workdir/corpus.db`.

---

### Overview (`dashboard/app/dashboard/README.md`)

This dir exists for the purposes of running the dashboard app locally using dev_appserver.py.
The production app sets CWD to the root of the syzkaller repository, so paths that refer to
static resources in app.yaml look like dashboard/app/static/*. However, dev_appserver.py
sets CWD to dashboard/app, so these paths do not work. This dir contains soft link
dashboard/app/dashboard/app/static that point to dashboard/app/static, so that
dashboard/app/static/* paths work from both locations.

---

### Overview (`dashboard/config/linux/README.md`)

This dir contains Linux kernel configs used by [syzbot](/docs/syzbot.md).

Configs are auto-generated by [syz-kconf](/tools/syz-kconf/kconf.go) utility from declaration file [main.yml](main.yml)
and config [fragments](bits/). [main.yml](main.yml) specifies list of target config files (instances) and their
`features`, as well as order of inclusion of config fragments and their constraints. Config fragment is used for
an instance if all fragment constraints are present in instance features and all negative constraints (`-foo`) are not
present in instance features.

For example, the following declaration file:
```
instances:
 - instance-a:	[x86_64, gcc, upstream]
 - instance-b:	[x86_64, gcc, upstream, foo]
 - instance-c:	[arm64, clang, stable]

includes:
 - always.yml: []
 - only-upstream.yml: [upstream]
 - only-clang-arm64.yml: [clang, arm64]
 - only-upstream-not-foo.yml: [upstream, -foo]
```
specifies 3 target configs (instances) and built from 4 config fragments. Here fragment `always.yml` is included first
and for all instances. Fragment `only-upstream.yml` is included next for instances that have `upstream` feature listed
(`instance-a` and `instance-b`). Fragment `only-clang-arm64.yml` is included next for instances that have both
`clang` and `arm64` listed (`instance-c`). Finally, fragment `only-upstream-not-foo.yml` is included for instances
that have `upstream` features but don't have `foo` feature listed (`instance-a`).

Config fragments can specify several aspects of the target config file. First, they can specify the kernel repository
and revision that will be used for config generation using the following syntax. There must be only one repository
specification for each instance.
```
kernel:
 repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 tag: v5.8-rc7
```

Then, config fragments can specify kernel `make` commands that will be invoked to create the base config.
For example:
```
shell:
 - make x86_64_defconfig
 - make kvm_guest.config
```

Shell commands can have constraints similar to includes, for example:
```
shell:
 - make defconfig: [-nodefconfig]
```

Then, fragments can specify text for verbatim inclusion at the end of the resulting config. `syz-kconf` does not do
anything with these string. For example:
```
verbatim: |
 CONFIG_THIS_CONFIG_DOES_NOT_EXIST_YET=y
```

Finally, fragments can specify individual config options that need to be enabled (or disabled) in the resulting config.
For example:
```
config:
 - CONFIG_WILL_BE_ENABLED
 - CONFIG_WILL_BE_DISABLED: n
 - CONFIG_WITH_INTEGER_VALUE: 10
 - CONFIG_WITH_STRING_VALUE: "foo"
```

Config options can have constraints for more precise control over target instances
(constraints can be combined with values):
```
config:
 - CONFIG_ONLY_FOR_UPSTREAM: [upstream]
 - CONFIG_STABLE_AND_ARM64: [stable, arm64]
 - CONFIG_NOT_CLANG: [-clang]
 - CONFIG_DISABLED_FOR_GCC: [n, gcc]
 - CONFIG_STRING_FOO: ["value", foo]
```

Instance features:
 - `nonoise`: disables auxiliary debug configs (lockdep, stalls, object debug, etc);
   used on instances on which we ignore all crashes except for the main debug tool (KMSAN/KCSAN/LEAK)
   and on instances that are too slow (some qemu emulation).
 - `reduced`: disables some generic (mostly arch-independent) kernel subsystems;
   used on slow qemu emulation instances since these subsystems are well testing on fast native instances.
   `syz-kconf` knows about this feature and gives it special meaning: all configs in fragments enabled
   by this feature are disabled for reduced instances.

Some features/constraints are defined by `syz-kconf` itself or have special meaning:
 - `override` on a config allows to override a previous definition of the same config (otherwise it results in an error)
 - `optional` on a config disables checking that the resulting kernel config file has the specified value for this
   config (otherwise it results in an error)
 - `weak` means both `override` and `optional`
 - `clang`/`gcc` instance feature controls what compiler is used for config generation
 - kernel arch name (`x86_64`, `arm64`, etc) instance feature controls architecture of the kernel config
 - kernel release tag is automatically added to instance features and allows to specify a minimum kernel version
   for a config (e.g. `v5.5` for a config added in that kernel release) or a maximum kernel version (e.g. `-v5.5` for
   a config removed in that kernel release)

`syz-kconf` generates 2 kernel config files for each instance: one `normal` (or full) and one `baseline`.
The `baseline` config has `-base` suffix and has `baseline` and `base-config` features added. The `baseline`
config is meant to not contain majority of subsystem configs enabled (should just boot and have debugging
configs enabled), however, that is fully controlled by config fragments based on the presence of the `baseline`
feature. In order to facilitate even smaller `-base.config` files, the `base-config` feature is automatically
set for them. Such configs are intended to be used by the config minimization procedure.

The only exception to the declarative nature of the process is USB configs. They are added procedurally, see
`addUSBConfigs` function for details.

`syz-kconf` switches between `gcc` and `clang` compilers automatically and is supposed to be used with
[syz-env](/docs/contributing.md#using-syz-env), which provides correct versions of the compilers.

To update kernel configs:
 - update kernel version in [linux-next.yml](bits/linux-next.yml) and [linux-upstream.yml](bits/linux-upstream.yml)
 - change config fragments as necessary (e.g. add additional configs to [subsystems.yml](bits/subsystems.yml))
 - run `./tools/syz-env make configs SOURCEDIR=/path/to/existing/linux/checkout`
   * note: it will be mrproper-ed and a number of remotes will be added
   * see [this](/docs/contributing.md#using-syz-env) on how to setup/use `syz-env`
 - resolve problems. You can iterate faster focusing on the specific instance problem.
   * `./tools/syz-env make configs SOURCEDIR=/path/to/existing/linux/checkout INSTANCE=PROBLEM_INSTANCE_NAME`
 - check in config fragments and changed kernel configs and send a PR
 - changes will be deployed to `syzbot` within a day after merging

---

### Overview (`executor/_include/flatbuffers/README.md`)

This was manually vendored on the version v23.5.26
(which matches the compiler version in the env container)
using the following commands:

```
git clone --branch=v23.5.26 --depth=1 --single-branch https://github.com/google/flatbuffers.git
cp flatbuffers/LICENSE syzkaller/executor/_include/flatbuffers
cp flatbuffers/include/flatbuffers/*.h syzkaller/executor/_include/flatbuffers
```

---

### Overview (`syz-cluster/tools/db-mgmt/README.md`)

How to run DB migrations locally:

```
cd $SYZKALLER/syz-cluster
make build-db-mgmt-dev restart-spanner
./run-local.sh db-mgmt migrate
```

---

### Overview (`syz-cluster/workflow/triage/README.md`)

## Ephemeral disk size usage estimations for Linux

```
$ git fetch origin +refs/tags/torvalds-head:refs/tags/torvalds-head --depth=1
$ du -h .
260M    .
$ git checkout torvalds-head
$ du -h .
2G      .
$ git fetch origin 2dde18cd1d8fac735875f2e4987f11817cc0bc2c --depth=1
$ du -h .
2.1G    .
$ git checkout 2dde18cd1d8fac735875f2e4987f11817cc0bc2c
$ du -h .
2G      .
```

## Without cloning the repository

```
mkdir ~/shallow-repo ~/shallow-repo/.git ~/shallow-repo/workdir ~/overlayfs
mount -t tmpfs -o size=128M tmpfs /root/overlayfs
mkdir ~/overlayfs/upper ~/overlayfs/work
mount -t overlay overlay -o lowerdir=/kernel-repo,upperdir=/root/overlayfs/upper,workdir=/root/overlayfs/work /root/shallow-repo/.git
git --git-dir=/root/shallow-repo/.git --work-tree=/root/shallow-repo/workdir checkout master
```

Needs:

```
        securityContext:
          capabilities:
            add: ["SYS_ADMIN"]
```

---

### Overview (`tools/syz-declextract/testdata/README.md`)

This dir contains sources of a fake kernel that resembles Linux for testing of the `syz-declextract` tool.

For each `*.c` file there 3 golden files:
 - `*.c.json` with the expected output of the clang tool
 - `*.c.txt` with the expected syzlang descriptions
 - `*.c.info` with the expected kernel interface list

Testing is done by `tools/syz-declextract` tests.

`TestClangTool` invokes the clang tool and verifies `*.c.json` contents.
The test requires the clang tool binary specified in the `-bin`, otherwise it skips testing.
You also want to run it with `-count=1` flag since the Go tool does not detect changes in the tool binary,
and will cache and reuse test results:
```
go test -count=1 ./tools/syz-declextract -bin=llvm/build/bin/syz-declextract
```

`TestDeclextract` verifies `*.c.txt` and `*.c.info` using `*.c.json` files as inputs
(it does not involve the clang tool and runs always).

All tests also support `-update` flag, which updates the golden files.
Generally you don't need to update them manually.

Since the test covers multiple packages, it's useful to run coverage as follows:
```
go test -count=1 -coverprofile=/tmp/cover -coverpkg="github.com/google/syzkaller/tools/syz-declextract,github.com/google/syzkaller/pkg/declextract,github.com/google/syzkaller/pkg/clangtool" ./tools/syz-declextract -bin=llvm/build/bin/syz-declextract
go tool cover -html /tmp/cover
```

---

### Overview (`dashboard/config/openbsd/overlays/README.md`)

# File hierarchies to lay on top of default images

`pkg/build/openbsd.go` replaces the files in the image generated by
`create-openbsd-vmm-worker.sh` with the contents of `ci-openbsd-multicore/`.
A minor bit of missing connection between `userspaceDir` and this
location is managed outside this repository by the local filesystem
state on the `ci-openbsd` machine.

---

### Overview (`docs/linux/syzlang/skills/README.md`)

# Syzlang Subsystem Skills (Linux)

This directory contains component and subsystem-specific knowledge and
constraints for LLM agents generating or fixing Linux syzlang programs.

## Format

Each skill must be a Markdown (`.md`) file starting with standard YAML
frontmatter defining `name` and `description`:

```markdown
---
name: kvm
description: KVM Virtualization and Guest Constraints (x86/amd64 Focus)
---

# KVM Virtualization and Guest Constraints (x86/amd64 Focus)

... instructions ...
```

## How Agents Use Skills

In AFlow, available skills are dynamically listed in `SkillsPrompt(osTarget)`.
Agents can inspect any skill using `read-syz-spec` with either a short name
(`kvm.md` or `skills/kvm.md`) or full relative path
(`docs/linux/syzlang/skills/kvm.md`).

---

### Overview (`pkg/ifuzz/arm64/gen/json/README.md`)

arm64.json is taken from the Go Language repository:
https://tip.golang.org/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.json

Please see the LICENSE file (taken from https://tip.golang.org/src/cmd/vendor/golang.org/x/arch/LICENSE)
for the relevant copyright notice and disclaimers.

---

### Adding New Os Support (`docs/adding_new_os_support.md`)

# Adding new OS support

Here are the common parts of syzkaller to edit in order to make syzkaller support a new OS kernel. However, there may be some specific changes that will be required for a given kernel (for example, gathering coverage from a given kernel, or some errors that might pop up and give a hint about what to tweak).

## syz-executor

For each OS, there is this file `executor/executor_GOOS.h` where GOOS is the OS name. This file contains two important functions:

- `os_init` which is responsible for mapping a virtual address space for the calling process,
- `execute_syscall` which is responsible for executing system calls for a particular OS kernel.

These two functions, are called in `executor/executor.cc`, which is mainly responsible for executing the syscalls programs, and managing the threads in which the programs run.

`executor_GOOS.h` also contains functions related to that operating system such as functions that allow it to gather coverage information, detect bitness, etc. (Example: [executor_linux.h](/executor/executor_linux.h) ).

The intended function will be called according to the target kernel as defined by the macros in the `executor/executor.cc` file.

## Build files `pkg/`

- The OS name is added to `pkg/build/build.go` along with the supported architecture
- Creating a file that builds the image for the targeted kernel under `pkg/build/`. This file contains functions for configuring the build of the bootable image, for building it, and for generate SSH keys which will be used by Syzkaller in order to access the VM. There is a file per each of the supported OSes by Syzkaller where the name pattern is `GOOS.go`.

- Adding the given target to the `Makefile`.

## Report files `pkg/report/`

Creating a file that reports build errors  for the targeted kernel under `pkg/report/`. There is a file per each of the supported OSes by Syzkaller where the name pattern is `GOOS.go`.

## Editing `pkg/host/`

- implement `isSupported` function that returns true for a supported syscall, it is located under `pkg/host/GOOS`.

## Creating a file under `sys/GOOS/`

Creating a file `init.go` for the targeted kernel under `sys/GOOS/`that included the function `initTarget` that initializes the target and the different supported architectures.

## Editing `sys/syz-extract`

Adding the new kernel name with already existing supported kernels to the file `sys/syz-extract/extract.go`.

## Editing `sys/targets`

Adding the new kernel name with already existing supported kernels to the file `targets.go` which is located under`sys/targets`.

## Editing `vm/qemu`

Adding the new kernel name with already existing supported kernels to the file `qemu.go` which is located under `vm/qemu`.

## Syzkaller description & pseudo-syscalls

Check [descriptions](/docs/syscall_descriptions.md), and [pseudo-syscalls](/docs/pseudo_syscalls.md).

---

### Bisect (`docs/bisect.md`)

# Syz-bisect

`syz-bisect` program can be used to bisect culprit and fix commits for
crashes found by syzkaller. It can also identify configuration options
that are triggers for the crash.

## Usage

Build `syz-bisect` with `make bisect`.

During bisection different compilers depending on kernel revision are
used. These compilers are available
[here](https://storage.googleapis.com/syzkaller/bisect_bin.tar.gz).

Install ccache to speed up kernel compilations during bisecton.

Create user-space (chroot) using [create-image.sh](../tools/create-image.sh)

Create a config file with following lines adjusted for your environment:

```json
{
	"bin_dir": "/home/syzkaller/bisect_bin",
	"ccache": "/usr/bin/ccache",
	"compiler_type": "gcc",
	"kernel_repo": "git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git",
	"kernel_branch": "master",
	"syzkaller_repo": "https://github.com/google/syzkaller",
	"userspace": "/home/syzkaller/image/chroot",
	"kernel_config": "/home/syzkaller/go/src/github.com/google/syzkaller/dashboard/config/linux/upstream-apparmor-kasan.config",
	"kernel_baseline_config": "/home/syzkaller/go/src/github.com/google/syzkaller/dashboard/config/linux/upstream-apparmor-kasan-base.config",
	"syzctl": "/home/syzkaller/go/src/github.com/google/syzkaller/dashboard/config/linux/upstream.sysctl",
	"cmdline": "/home/syzkaller/go/src/github.com/google/syzkaller/dashboard/config/linux/upstream.cmdline",
	"manager":
	{
		"name" : "bisect",
		"target": "linux/amd64",
		"http": "127.0.0.1:56741",
		"workdir": "/home/syzkaller/workdir",
		"kernel_obj": "/home/syzkaller/linux",
		"image": "/home/syzkaller/workdir/image/image",
		"sshkey": "/home/syzkaller/workdir/image/key",
		"syzkaller": "/home/syzkaller/go/src/github.com/google/syzkaller_bisect",
		"procs": 8,
		"type": "qemu",
		"kernel_src": "/syzkaller/linux",
		"vm": {
		      "count": 4,
		      "kernel": "/home/syzkaller/linux/arch/x86/boot/bzImage",
		      "cpu": 2,
		      "mem": 2048,
		      "cmdline": "root=/dev/sda1 rw console=ttyS0 kaslr crashkernel=512M minnowboard_1:eth0::: security=none"
		}
	}
}
```

And run bisection with `bin/syz-bisect -config vm_bisect.cfg -crash
/syzkaller/workdir/crashes/03ee30ae11dfd0ddd062af26566c34a8c853698d`.

`Syz-bisect` is expecting finding repro.cprog or repro.prog in given
crash directory. It will also utilize repro.opts, but it's not
mandatory.

## Additional Arguments

`-syzkaller_commit` use this if you want to use specific version of syzkaller

`-kernel_commit` kernel commit where crash is known to reproduce. You
want to use this when bisecting fixing commit

`-fix` use this if you want to bisect a fixing commit.

## Output

It takes some time, but after `syz-bisect` completes it dumps out it's
results into console It also stores results into files in given crash
directory:

`cause.commit` commit identified causing the crash or text "the crash
already happened on the oldest tested release"

`fix.commit` commit identified fixing the crash or text "the crash
still happens on HEAD"

`cause.config` config options identified working as one trigger for the crash

`original.config, baseline.config, minimized.config` config files used
in config bisection

---

### Ci (`docs/ci.md`)

# Continuous integration fuzzing

[syz-ci](../syz-ci/) command provides support for continuous fuzzing with syzkaller.
It runs several syz-manager's, polls and rebuilds images for managers and polls
and rebuilds syzkaller binaries.

---

### Configuration (`docs/configuration.md`)

# Configuration

The operation of the syzkaller `syz-manager` process is governed by a
configuration file, passed at invocation time with the `-config` option.
This configuration can be based on the [example](/pkg/mgrconfig/testdata/qemu-example.cfg);
the file is in JSON format and contains the the [following parameters](/pkg/mgrconfig/config.go).

---

### Contributing (`docs/contributing.md`)

# How to contribute to syzkaller

If you want to contribute to the project, feel free to send a pull request following the [guidelines](contributing.md#guidelines) below.

In case this is your first pull request to syzkaller, you will need to [sign Google CLA](https://cla.developers.google.com/)
and add yourself to [AUTHORS](/AUTHORS) _AND_ [CONTRIBUTORS](/CONTRIBUTORS) files in the first commit.

## What to work on

Extending/improving [system call descriptions](syscall_descriptions.md) is always a good idea.

Unassigned issues from the [bug tracker](https://github.com/google/syzkaller/issues) are worth doing, but some of them might be complicated.

To contribute code or syscall descriptions, at the very least you need to be able to build and run syzkaller, see the instructions [here](/docs/setup.md).

## Guidelines

If you want to work on something non-trivial, please briefly describe it on the
[syzkaller@googlegroups.com](https://groups.google.com/forum/#!forum/syzkaller) mailing list first,
so that there is an agreement on the high level approach/design and no duplication of work between contributors.

Split large changes into smaller, logically cohesive commits. Small commits are much easier and faster to review and iterate on.

Everything that can be reasonably tested should be tested.

Provide enough documentation for other users to use the new feature.

Keep the style of the code, tests, comments, docs, log/error messages consistent with the existing style.

Continuous Integration (CI) system runs a number of tests and some [opinionated] style checks. They need to pass.
You can test locally with `make presubmit`, if you don't have some prerequisites installed,
you may use `syz-env` (see below).

### Commits

Commit messages should follow the following template:

```
dir/path: one-line description
<empty line>
Extended multi-line description that includes
the problem you are solving and how it is solved.
```

`dir/path` is a relative path to the main dir this commit changes
(look at examples in the [commit history](https://github.com/google/syzkaller/commits/master)).
If several packages/dirs are significantly affected, then the following format is allowed:
```
dir1/path1, dir2/path2: one-line description
```
Though, dirs should not be included if they have only minor changes.
For pervasive changes the following format is allowed:
```
all: one-line description
```

Please pay attention to punctuation. In particular:

- `one-line description` should *not* start with a Capital letter.
- There is *no dot* at the end of `one-line description`.
- `Extended multi-line description` is full English sentences with Capital letters and dots.

Commit message line length is limited to 120 characters.

Also:

- If your commit fixes an issue, please include `Fixes #NNN` line into commit message
(where `NNN` is the issue number). This will auto-close the issue. If you need to mention
an issue without closing it, add `Update #NNN`.
- For syscall descriptions `*.const` files are checked-in with the `*.txt` changes
in the same commit.

### Pull requests

- Rebase your working branch onto the master branch before sending a pull request to avoid merge conflicts.
- Run `make presubmit` and ensure that it passes before sending a PR.
  This may require some additional packages to be installed (try `sudo make install_prerequisites`).
- Provide a brief high-level description in the pull request title.
  The pull request text is mostly irrelevant, all the details should be in the commit messages.
- If you're asked to add some fixes to your pull request, please squash the fixes into the old commits.

### How to create a pull request on Github

- First, you need your own git fork of syzkaller repository. Navigate to
[github.com/google/syzkaller](https://github.com/google/syzkaller) and press `Fork` button in the top-right corner of
the page. This will create `https://github.com/YOUR_GITHUB_USERNAME/syzkaller` repository.

- Checkout main syzkaller repository if you have not already. The simplest way to do it is to run `git clone https://github.com/google/syzkaller`, this will checkout
the repository in the current working directory.
- Remember to `export PATH=$GOPATH/bin:$PATH` if you have not already.
- Then add your repository as an additional origin:

    ```shell
    cd syzkaller
    git remote add my-origin https://github.com/YOUR_GITHUB_USERNAME/syzkaller.git
    git fetch my-origin
    git checkout -b my-branch my-origin/master
    ```

This adds git origin `my-origin` with your repository and checks out new branch `my-branch` based on `master` branch.

- Change/add files as necessary.
- Commit changes locally. For this you need to run `git add` for all changed files, e.g. `git add sys/linux/sys.txt`. You can run `git status` to see what files were changed/created. When all files are added (`git status` shows no files in `Changes not staged for commit` section and no relevant files in `Untracked files` section), run `git commit` and enter commit description in your editor.
- Run tests locally (`make install_prerequisites` followed by `make presubmit`).
- Push the commit to your fork on github with `git push my-origin my-branch`.
- Navigate to [github.com/google/syzkaller](https://github.com/google/syzkaller) and you should see green `Compare & pull request` button, press it. Then press `Create pull request`. Now your pull request should show up on [pull requests page](https://github.com/google/syzkaller/pulls).
- If you don't see `Create pull request` button for any reason, you can create pull request manually. For that navigate to [pull requests page](https://github.com/google/syzkaller/pulls), press `New pull request`, then `compare across forks` and choose `google/syzkaller`/`master` as base and `YOUR_GITHUB_USERNAME/syzkaller`/`my-branch` as compare and press `Create pull request`.
- If you decided to rebase commits in `my-branch` (e.g. to rebase them onto updated master) after you created a pull-request, you will need to do a force push: `git push -f my-origin my-branch`.

### Using syz-env

Developing syzkaller requires a number of tools installed (Go toolchain, C/C++ cross-compilers, golangci-lint, etc).
Installing all of them may be cumbersome, e.g. due to broken/missing packages.
[syz-env](/tools/syz-env) provides a working hermetic development environment based on a Docker container.
If you don't yet have Docker installed, see [documentation](https://docs.docker.com/engine/install),
in particular regarding enabling [sudo-less](https://docs.docker.com/engine/install/linux-postinstall)
Docker (Googlers see go/docker).

It's recommended to create an alias for `syz-env` script:
```
alias syz-env="$(go env GOPATH)/src/github.com/google/syzkaller/tools/syz-env"
```
Then it can be used to wrap almost any make invocation as:
```
syz-env make format
syz-env make presubmit
syz-env make extract SOURCEDIR=$(readlink -f ~/linux)
```
Or other commands/scripts, e.g.:
```
syz-env go test -short ./pkg/csource
```
Or you may run the shell inside of the container with just `syz-env` and look around.

To update `syz-env` container to the latest version do:

``` bash
docker pull gcr.io/syzkaller/env
```

You can also build the container from the respective `Dockerfile` by setting the `SYZ_ENV_BUILD` environment variable, i.e.:
```
SYZ_ENV_BUILD=1 syz-env
```
This can be useful to test local changes that have not been pushed to the registry yet.

### Using [act](https://github.com/nektos/act)
.github/workflows has more tests compared to `syz-env make presubmit`. To have the same tests as the workflow, we can run these workflow jobs locally.
```
# install act
make act
# list all jobs
bin/act -l
# run all jobs
bin/act
# run job with name build
bin/act -j build
```

---

### Coverage (`docs/coverage.md`)

# Coverage

`syzkaller` uses [sanitizer coverage (tracing mode)](https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs)
and [KCOV](https://www.kernel.org/doc/html/latest/dev-tools/kcov.html) for coverage collection.
Sanitizer coverage is also supported by `gcc` and `KCOV` is supported by some other OSes.
Note: `gVisor` coverage is completely different.

Coverage is based on tracing `coverage points` inserted into the object code by the compiler.
A coverage point generally refers to a [basic block](https://en.wikipedia.org/wiki/Basic_block) of code
or a [CFG edge](https://en.wikipedia.org/wiki/Control-flow_graph)
(this depends on the compiler and instrumentation mode used during build,
e.g. for `Linux` and `clang` the default mode is CFG edges, while for `gcc` the default mode is basic blocks).
Note that coverage points are inserted by the compiler in the middle-end after a significant number
of transformation and optimization passes. As the result coverage may poorly relate to the source code.
For example, you may see a covered line after a non-covered line, or you may not see a coverage point
where you would expect to see it, or vice versa (this may happen if the compiler splits basic blocks,
or turns control flow constructs into conditional moves without control flow, etc).
Assessing coverage is still generally very useful and allows to understand overall fuzzing progress,
but treat it with a grain of salt.

See [this](linux/coverage.md) for Linux kernel specific coverage information.

## Web Interface

When clicking on `cover` link you get view showing each directory located in your kernel build directory. It's showing either percentage number `X% of N` or `---`. `X% of N` means that `X%` of `N` coverage points are covered so far, . `---` indicates there is no coverage in that directory.

Directory can be clicked and you get view on files and possible subdirectories. On each source code file there is again either `---` or coverage percentage.

If you click on any C files you will get source code view. There is certain coloring used in the source code view. Color definitions can be found in [coverTemplate](/pkg/cover/report.go#L504). Coloring is described below.

If you click on percentage number of any listed source file you will get cover percentage for each function in that source file.

### Covered: black (#000000)

All PC values associated to that line are covered. There is number on the left side indicating how many programs have triggered executing the PC values associated to this line. You can click on that number and it will open last executed program. Example below shows how single line which is fully covered is shown.



### Both: orange (#c86400)

There are several PC values associated to the line and not all of these are executed. Again there is number left to the source code line that can clicked to open last program triggering associated PC values. Example below shows single line which has both executed and non-executed PC values associated to it.



### Uncovered: red (#ff0000)

Line is uncovered. Function (symbol) this line is in is executed and one of the PC values associated to this line. Example below shows how single line which is not covered is shown.



### Not executed or non-instrumented code: grey (#505050)

If an entire function was never executed, all its lines are shown in grey. This color is also used for lines that are not instrumented or do not generate code (e.g., comments, macros, or empty lines).

Note that if a function was executed but some lines within it were not covered, those lines are shown in red, not grey.



## syz-cover

There is small utility in syzkaller repository to generate coverage report based on raw coverage data. This is available in [syz-cover](/tools/syz-cover) and can be built by:

``` bash
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/syz-cover github.com/google/syzkaller/tools/syz-cover
```

Raw coverage data can be obtained from running `syz-manager` by:

``` bash
wget http://localhost:<your syz-manager port>/rawcover
```

Now this raw cover data can be fed to `syz-cover` to generate coverage report:

``` bash
./bin/syz-cover --config <location of your syzkaller config> ./rawcover
```

You can also export CSV file containing function coverage by:

``` bash
./bin/syz-cover --config <location of your syzkaller config> --exports funccover ./rawcover
```

You can export a JSON file containing line coverage info by:

```bash
./bin/syz-cover --config <location of your syzkaller config> --exports json ./rawcover
```

---

### Db (`docs/db.md`)

# syz-db

`syz-db` program can be used to manipulate corpus.db databases that are used
by syz-managers.

## Build

Build `syz-db` with `make db` or by changing to `tools/syz-db` and run `go build`.

## Options

`syz-db` currently overs the following generic arguments:

```shell
  -arch string
    	target arch
  -os string
    	target OS
  -version uint
    	database version
  -vv int
    	verbosity
```

That can be used with

```
  syz-db pack dir corpus.db
```

to pack a database

```
  syz-db unpack corpus.db dir
```

to unpack a database. A file containing performed syscalls will be returned.

```
  syz-db merge dst-corpus.db add-corpus.db* add-prog*
```

to merge databases. No additional file will be created: The first file will be replaced by the merged result.

```
  syz-db bench corpus.db
```

to run a deserialization benchmark. For example:

```
syz-db -os=linux -arch=amd64 bench corpus.db
```

could give an output like

```
allocs 123 MB (123 M), next GC 123 MB, sys heap 123 MB, live allocs 123 MB (123 M), time 324s.
```

---

### Headerparser Usage (`docs/headerparser_usage.md`)

## Headerparser

headerparser is a tool that assists in writing device system call descriptions for syzkaller.

In order to make syzkaller smarter when it comes to fuzzing a device node, you can provide it with
information about the ioctl argument struct types it expects.

However, in certain cases the number of argument struct types might be high, increasing the amount of manual
effort that goes into writing the description files for the struct types.

In order to ease the effort of writing ioctl argument type description files, headerlib does a best-effort job at
generating them for you. You will still need to manually select the appropriate syzkaller data type from the list
of types [here](/docs/syscall_descriptions_syntax.md).

## Dependencies
Headerlib uses pycparser. You can install pycparser using pip.

```shell
$ pip install pycparser
```

## Using headerparser
```shell
$ python headerparser.py --filenames=./test_headers/th_b.h
B {
          B1     len|fileoff|flags|intN     #(unsigned long)
          B2     len|fileoff|flags|intN     #(unsigned long)
}
struct_containing_union {
          something          len|fileoff|flags|int32                   #(int)
          a_union.a_char     ptr[in|out, string]|ptr[in, filename]     #(char*)
          a_union.B_ptr      ptr|buffer|array                          #(struct B*)
}
```

You can copy paste the content underneath the `Structure Metadata` over to your syzkaller device description.

## Something breaks
Let us try parsing `test_headers/th_a.h` header file to generate argument structs.

```shell
$ python headerparser.py --filenames=./test_headers/th_a.h
ERROR:root:HeaderFilePreprocessorException: /tmp/tmpW8xzty/source.o:36:2: before: some_type

$ python headerparser.py --filenames=./test_headers/th_a.h --debug
DEBUG:GlobalHierarchy:load_header_files : ['./test_headers/th_a.h']
DEBUG:HeaderFilePreprocessor:HeaderFilePreprocessor._mktempfiles: sourcefile=/tmp/tmpbBQYhR/source.cobjectfile=/tmp/tmpbBQYhR/source.o
DEBUG:HeaderFilePreprocessor:HeaderFilePreprocessor.execute: cp ./test_headers/th_a.h /tmp/tmpbBQYhR
DEBUG:HeaderFilePreprocessor:HeaderFilePreprocessor.execute: gcc -I. -E -P -c /tmp/tmpbBQYhR/source.c > /tmp/tmpbBQYhR/source.o
ERROR:root:HeaderFilePreprocessorException: /tmp/tmpbBQYhR/source.o:36:2: before: some_type
```

From the error message, we can see that the error occurs as pycparser is not aware of the type `some_type`. We can resolve this by making pycparser aware of the unknown type. In order to do this, we supply headerparser with a include file that contains C declarations and includes that can fix the parse error.

```shell
$ cat > include_file
typedef int some_type;
$ python headerparser.py --filenames=./test_headers/th_a.h --include=./include_file
A {
          B_item              ptr|buffer|array                          #(struct B*)
          char_ptr            ptr[in|out, string]|ptr[in, filename]     #(char*)
          an_unsigned_int     len|fileoff|int32                         #(unsigned int)
          a_bool              _Bool                                     #(_Bool)
          another_bool        _Bool                                     #(_Bool)
          var                 some_type                                 #(some_type)
}
```

---

### Hub (`docs/hub.md`)

# Connecting several managers via Hub

`syz-hub` program can be used to connect several `syz-manager`'s together and
allow them to exchange programs.

Build `syz-hub` with `make hub`. Then create a config file along the lines of:

```
{
	"http": ":80",
	"rpc":  ":55555",
	"workdir": "/syzkaller/workdir",
	"clients": [
		{"name": "manager1", "key": "6sCFsJVfyFQVhWVKJpKhHcHxpCH0gAxL"},
		{"name": "manager2", "key": "FZFSjthHHf8nKm2cqqAcAYKM5a3XM4Ao"},
		{"name": "manager3", "key": "fTrIBQCmkEq8NsvQXZiOUyop6uWLBuzf"}
	]
}
```

And start it with `bin/syz-hub -config hub.cfg`. Then add the following
additional parameters to `syz-manager` config files of each manager:

```
	"name": "manager1",
	"hub_client": "manager1",
	"hub_addr": "1.2.3.4:55555",
	"hub_key": "6sCFsJVfyFQVhWVKJpKhHcHxpCH0gAxL",
```

And start managers. Once they triage local corpus, they will connect to the hub
and start exchanging inputs. Both hub and manager web pages will show how many
inputs they send/receive from the hub.

---

### Internals (`docs/internals.md`)

# How syzkaller works

Generic description of how syzkaller works are [below](internals.md#overview).

Linux kernel specific internals can be found [here](linux/internals.md).

## Overview

The process structure for the syzkaller system is shown in the following diagram;
red labels indicate corresponding configuration options.



`syz-manager` is responsible for:

- Starting/restarting/monitoring VM instances.
- The actual fuzzing process (input generation, mutation, minimization, etc.).
- Persistent corpus and crash storage.

It runs on a host with a stable kernel which does not experience white-noise fuzzer load.

`syz-manager` starts `syz-executor` processes (one inside each VM).
`syz-executor`s communicate with `syz-manager` over RPC to receive the programs
that must be executed and to report back the results (error statuses, collected coverage, etc.).

To execute programs, `syz-executor` starts transient subprocesses.

Each transient subprocess executes a single input (a sequence of syscalls).
It is designed to be as simple as possible (to not interfere with fuzzing process),
written in C++, compiled as static binary and uses shared memory for communication.

## Syscall descriptions

The `syz-manager` process generates programs based on syscall descriptions described [here](syscall_descriptions.md).

## Coverage

Syzkaller is a coverage-guided fuzzer. The details about coverage collection can be found [here](coverage.md).

## Crash reports

When `syzkaller` finds a crasher, it saves information about it into `workdir/crashes` directory.
The directory contains one subdirectory per unique crash type.
Each subdirectory contains a `description` file with a unique string identifying the crash (intended for bug identification and deduplication);
and up to 100 `logN` and `reportN` files, one pair per test machine crash:

```
 - crashes/
   - 6e512290efa36515a7a27e53623304d20d1c3e
     - description
     - log0
     - report0
     - log1
     - report1
     ...
   - 77c578906abe311d06227b9dc3bffa4c52676f
     - description
     - log0
     - report0
     ...
```

Descriptions are extracted using a set of [regular expressions](/pkg/report/).
This set may need to be extended if you are using a different kernel architecture, or are just seeing a previously unseen kernel error messages.

`logN` files contain raw `syzkaller` logs and include kernel console output as well as programs executed before the crash.
These logs can be fed to `syz-repro` tool for [crash location and minimization](reproducing_crashes.md),
or to `syz-execprog` tool for [manual localization](reproducing_crashes.md#from-execution-logs).
`reportN` files contain post-processed and symbolized kernel crash reports (e.g. a KASAN report).
Normally you need just 1 pair of these files (i.e. `log0` and `report0`), because they all presumably describe the same kernel bug.
However, `syzkaller` saves up to 100 of them for the case when the crash is poorly reproducible, or if you just want to look at a set of crash reports to infer some similarities or differences.

There are 3 special types of crashes:

- `no output from test machine`: the test machine produces no output whatsoever
- `lost connection to test machine`: the ssh connection to the machine was unexpectedly closed
- `test machine is not executing programs`: the machine looks alive, but no test programs were executed for long period of time

Most likely you won't see `reportN` files for these crashes (e.g. if there is no output from the test machine, there is nothing to put into report).
Sometimes these crashes indicate a bug in `syzkaller` itself (especially if you see a Go panic message in the logs).
However, frequently they mean a kernel lockup or something similarly bad (here are just a few examples of bugs found this way:
[1](https://groups.google.com/d/msg/syzkaller/zfuHHRXL7Zg/Tc5rK8bdCAAJ),
[2](https://groups.google.com/d/msg/syzkaller/kY_ml6TCm9A/wDd5fYFXBQAJ),
[3](https://groups.google.com/d/msg/syzkaller/OM7CXieBCoY/etzvFPX3AQAJ)).

---

### Issue Template (`docs/issue_template.txt`)

Issues are for bugs in syzkaller itself, for everything else please contact syzkaller@googlegroups.com mailing list.

Before filing an issue please check the existing issues and the mailing list (https://groups.google.com/forum/#!forum/syzkaller).

Please provide syzkaller revision, Go version (output of go version), relevant information about host and target systems.

If syz-manager is not working overall, please provide output of syz-manager with -debug flag.

---

### Kernel Config Update Guidelines (`docs/kernel_config_update_guidelines.md`)

# Updating Syzkaller Kernel Configurations Guidelines

These guidelines describe the process for updating the `syzkaller` dashboard configuration files to support new Linux kernel versions.

## Objective

Successfully update configuration fragments (`.yml`) and generate corresponding `.config` files for target kernel versions (e.g., `linux-upstream` and `linux-next`).

## Principles

- **Maximize Coverage**: We want to maximize the coverage of the new code and maintain the coverage of the old code.
- **Enable New Options**: If new options are introduced with the kernel version, we want them to be enabled if they help to shift left the bug detection or directly help to detect bugs. If they help with fuzzing but were not enabled, explain why in the commit message. These changes should be grouped into a commit titled `dashboard/config/linux: enable more configs`.
- **Reasoned Disabling**: If some options are not available anymore, disable them adding a comment in the YAML file referencing the kernel commit that removed, renamed, or moved them. Prefer formats like: `# Removed in <commit_hash> "<commit_title>"`, `# Renamed to <NEW_CONFIG> in <commit_hash> "<commit_title>"`, or `# Migrated to <NEW_LOCATION> in <commit_hash> "<commit_title>"`. If the specific commit cannot be found after a reasonable search, use the format: `# Removed in vX.Y (exact commit not found)`. If the option is not mentioned in any generated config files (i.e., it was not enabled in any instance), you can remove it from the YAML file entirely instead of disabling it. In this case, explain the removal in the commit message.
- **Documenting Constraints**: If you disable an option for a specific architecture (e.g., `-riscv`) or configuration (e.g., `-kmsan`), or if you make some config 'weak', add a comment explaining this decision.
- **Explicit Constraints**: Prefer explicitly enumerating the supported platforms and/or kernel versions instead of using `[optional]` or `[weak]` constraints when possible. If the option was added in `linux-next`, use the tag `[linux-next]`. If the specific kernel version is not known but it is in a released kernel, use `[weak]` and add a comment explaining it. Also use `[weak]` or `[optional]` if the config option has dependencies that might not be met in all configurations (e.g., depends on specific networking features or hardware support). **Do not silently make a failing config `weak` without investigation. Prefer identifying the specific reason (e.g., architecture limitation or kernel version change) and using explicit exclusions if possible.**
- **File-Level Exclusion**: If all options in a configuration fragment are disabled for certain kernel versions or instances, prefer excluding the whole file in `main.yml` using negative tags (e.g., `-upstream`) instead of adding version constraints to every individual option in the fragment. Add an explanatory comment above the inclusion line in `main.yml` to explain why it is disabled.
- **Explanation Headers**: Every new file created in `dashboard/config/linux/bits` requires an explanation header describing the purpose of the file, why we need it, and how it is used.
- **No Manual Edits**: Do NOT manually update the generated `.config` files. They MUST always be generated by running `make configs`.

## Prerequisites

- A local clone of the `linux` kernel repository.
- A local clone of the `syzkaller` repository.
- Docker installed for running `syz-env`.

## Procedure

### 1. Update Kernel Commits

Modify the corresponding YAML files in `dashboard/config/linux/bits/` to point to the desired tags. Use tags instead of commit hashes when updating these files.

- `linux-upstream.yml`
- `linux-next.yml`

### 2. Run Config Generation

Execute the following command from the root of the `syzkaller` repository:

```bash
CI=true ./tools/syz-env make configs SOURCEDIR=/path/to/linux/source
```

*Note: Replace `/path/to/linux/source` with the absolute path to your local Linux kernel directory.*

### 3. Troubleshooting Common Issues

#### A. Kconfig Parser Limitations (`syz-kconf`)

The `syz-kconf` parser in `pkg/kconfig` may not support advanced Kconfig syntax such as `if` in `depends on` statements.

- **Solution:** Implement support for the missing syntax in `pkg/kconfig/parser.go`. Do NOT modify Kconfig files in the kernel source.

#### B. Missing Config Options in Final Config

If an option specified in a YAML fragment is not present in the generated `.config`, `make configs` will fail.

- **Check Dependencies:** Verify if the option depends on another option not enabled, or if it is not supported on the target architecture or kernel version.
- **Version Constraints:** Add version constraints to the option in the YAML file, e.g., `[-v7.1]` to disable it for versions starting from `v7.1`.
- **Weak Constraints:** If the option is optional and may not be present in all versions, make it weak: `[value, weak]`. This prevents failure if the option is missing. **Avoid using `weak` just to bypass errors. Investigate why the option is missing or failing to be set. If it is due to architecture or version specific behavior, use explicit exclusions (e.g. `[-arm]`) instead of `weak`.**

#### C. Git Fetch Failures

If `syz-kconf` fails to checkout a repository or commit (e.g., Android kernels):

- **Diagnosis:** Check the error message to find the auto-generated remote name (often a hash).
- **Workaround:** Manually run `git fetch <remote_name>` in the kernel source directory to pull all objects, then retry `make configs`.

### 4. Finalizing Changes

Once `make configs` completes successfully:

1. Stage and commit the changes to YAML files first.
2. Stage and commit the generated `.config` files as the VERY LAST commit in the PR. The commit message MUST be `dashboard/config/linux: update generated configs`.
3. Push to a separate branch and create a Pull Request.

---

### Kfuzztest (`docs/kfuzztest.md`)

# KFuzzTest Integration With syzkaller

KFuzzTest, introduced initially in [this RFC](https://lore.kernel.org/all/20250813133812.926145-1-ethan.w.s.graham@gmail.com/)
is a framework for exposing internal kernel functions to a userspace fuzzing
engine like syzkaller. As the kernel docs put it:

> The Kernel Fuzz Testing Framework (KFuzzTest) is a framework designed to
> expose internal kernel functions to a userspace fuzzing engine.
>
> It is intended for testing stateless or low-state functions that are difficult
> to reach from the system call interface, such as routines involved in file
> format parsing or complex data transformations. This provides a method for
> in-situ fuzzing of kernel code without requiring that it be built as a
> separate userspace library or that its dependencies be stubbed out.

This document introduces how syzkaller integrates with KFuzzTest.

## Getting Started

Firstly, ensure that the KFuzzTest patch series has been applied to your Linux
tree.

As of the 26th of Semptember 2025, the most up-to-date version can be found in
[this Linux Kernel patch series](https://lore.kernel.org/all/20250919145750.3448393-1-ethan.w.s.graham@gmail.com/).

Once this is done, KFuzzTest targets can be defined on arbitrary kernel
functions using the `FUZZ_TEST` macro as described in the kernel docs in
`Documentation/dev-tools/kfuzztest.rst`.

### Configuration Options

Ensure that the following KConfig options are enabled for your kernel image:

- `CONFIG_DEBUG_FS` (used as a communication interface by KFuzzTest).
- `CONFIG_DEBUG_KERNEL`.
- `CONFIG_KFUZZTEST`.

It is also **highly** recommended to enable the following KConfig options for
more effective fuzzing.

- `CONFIG_KASAN` (catch memory bugs such as out-of-bounds-accesses).
- `CONFIG_KCOV` (to enable coverage guided fuzzing).

## Fuzzing KFuzzTest Targets

Syzkaller implements three ways to fuzz KFuzzTest targets:

1. `syz-manager` integration with static targets
2. `syz-manager` with dynamic targets
3. `syz-kfuzztest`: a standalone tool that runs inside a VM, discovers KFuzzTest
    targets dynamically, and fuzzes them.

### 1. `syz-manager` with static targets

Configuration for this method is identical to `syz-manager`, and is designed to
make it easy to integrate KFuzzTest fuzzing into existing continuous fuzzing
deployments.

One must first write a syzlang description for the KFuzzTest target(s) of
interest, for example in `/sys/linux/my_kfuzztest_target.txt`. Each target
should have the following format:

```
some_buffer {
        buf     ptr[inout, array[int8]]
        buflen  len[buf, int64]
}

kfuzztest_underflow_on_buffer(name ptr[in, string["test_underflow_on_buffer"]], data ptr[in, some_buffer], len bytesize[data], buf ptr[in, array[int8, 65536]]) (kfuzz_test)
```

Where:

- The first argument should be a string pointer to the name of the fuzz target,
  i.e,. the name of its `debugfs` input directory in the kernel.
- The second should be a pointer to a struct of the type that the fuzz
  target accepts as input.
- The third should be the size in bytes of the input argument.
- The call is annotated with attribute `kfuzz_test`.

The final `buf` argument is a buffer of size
`KFUZZTEST_MAX_INPUT_SIZE = 16 * PAGE_SIZE` and is used internally to ensure
that enough space is available in a program for the entire flattened input that
is sent into a KFuzzTest target.

For more information on writing syzkaller descriptions attributes, consult the
[syscall description](syscall_descriptions.md) and [syscall description syntax](syscall_descriptions_syntax.md)
documentation files.

To facilitate the tedious task of writing  `syz_kfuzztest_run` descriptions, a
tool (`tools/kfuzztest-gen`) is provided to automatically generate these from a
`vmlinux` binary. One can run the tool and paste the output into a syzlang file.

```sh
go run ./tools/kfuzztest-gen --vmlinux=path/to/vmlinux
```

After writing these descriptions to a file under the `/sys/linux/` directory
(for example, `/sys/linux/my_fuzz_targets.txt`), they need to be compiled with
`make descriptions`.

Finally, the targets can be enabled in `syz-manager` config file in the
`enable_syscalls` field, e.g.

```json
{
    "enable_syscalls": [ "syz_kfuzztest_run$test_underflow_on_buffer" ]
}
```

### 2. `syz-manager` with dynamic discovery

This feature greatly reduces the amount of setup needed for fuzzing KFuzzTest
targets, by discovering them all dynamically at launch.

This approach is considered less stable than the previous as it involves
generating descriptions for KFuzzTest targets without human input and then
immediately fuzzing them. It does, however, better reflect our intentions for
KFuzzTest: continuously fuzzing the kernel with a dynamically changing set of
targets with little intervention from syzkaller maintainers.

To enable this feature, configure the experimental `enable_kfuzztest` option in
the manager configuration, which enables all discovered KFuzzTest targets by
default.

```json
{
    "enable_kfuzztest": true
}
```

You must also enable pseudo-syscall `syz_kfuzztest_run`, like so:

```json
{
    "enable_syscalls": [
        "syz_kfuzztest_run"
    ],
}
```

**IMPORTANT:** for dynamic discovery to work, it is essential for the kernel
image pointed to by the manager configuration is built with `CONFIG_DWARF4` or
`CONFIG_DWARF5` enabled, as dynamic target discovery depends on these symbols
being emitted.

### 3. `syz-kfuzztest`, an in-VM standalone tool

In contrast with `syz-manager`, `syz-kfuzztest` is designed to perform coverage
guided fuzzing from within a VM directly rather than orchestrating a fleet of
VMs. It is primarily targeted at development-time fuzzing, rather than long-term
continuous fuzzing.

For more information, consult [the `syz-kfuzztest` documentation](syz-kfuzztest.md).

---

### Maintaining (`docs/maintaining.md`)

# Maintainer's Guide

## Linear history

We preserve linear history and have merge commits disabled in repository settings.
Pull requests (PR) have only 2 options:

- **Rebase and merge**\
  This is preferred if all commits in the PR are properly squashed/fixed already,
  as it preserves commits in the PR (takes all commits in the PR as is and adds them
  on top of the master HEAD).
- **Squash and merge**\
  This is preferred if the PR contains fix ups as separate commits and/or other clutter
  in commit organization (squashes all commits in the PR into one commit and adds it
  on top of the master HEAD, also allows to edit commit subject/description).

## PR checks (CI)

`cla/google` check needs to pass before merging.

CI testing generally needs to pass before merging.\
Exceptions may be infrastructure flakes (especially in external services: `codecov`, `ci/fuzzit`);
one-off timeouts/OOMs (but not if this PR itself makes them much more frequent).
All static checking warnings and testing errors are considered hard errors.

## Tests

Adding tests for new code and bug fixes is generally encouraged. Ask contributors to add tests.

However, some code is easier to test, while some is harder. Some examples of cases where
it's easier to add tests (should be added): abstract functionalities without external dependencies
(e.g. parsers, data transformations, calculations); code with established testing infrastructure
(adding new tests is just adding one more of the same). Examples of cases where it's harder
to add tests (may be not added, but still welcome if one wants to go above and beyond):
code with external dependencies that are not easy to fake out (qemu, kernel, image, etc);
code without established testing infrastructure where adding one test would require building
the whole infrastructure first.

## Use your judgement

There are no strict rules for reviews/ownership at the moment. Use your judgement.

If you are maintaining a particular area of the project (e.g. support for one OS),
it is OK to merge your own changes without further review (especially smaller and
if CI gives green light). It's also OK to review and merge changes to other parts
of the project. But loop in other maintainers if you don't feel confident or need
additional feedback/review.

---

### Mcp (`docs/mcp.md`)

# syz-agent in MCP mode

Example use with Gemini CLI:

1. Run `make agent`.

2. Create `mcp.config` file, for example:

```json
{
	"http": "localhost:59999",
	"mcp": true,
	"syzkaller_repo": "git@github.com:syzkaller/syzkaller.git",
	"target": "linux/amd64",
	"image": "/buildroot_amd64-2022.11.clean",
	"kernel_config": "upstream-apparmor-kasan.config",
	"type": "qemu",
	"vm": {
		"count": 10,
		"cpu": 2,
		"mem": 2048,
		"cmdline": "root=/dev/sda1"
	},
	"cache_size": 107374182400
}
```

3. Start `syz-agent`:

```bash
bin/syz-agent -config mcp.config
```

4. Add the following to `~/.gemini/settings.json`:

```json
{
	"mcpServers": {
		"syzkaller": {
			"httpUrl": "http://127.0.0.1:59999",
			"trust": true
		}
	}
}
```

5. Start Gemini CLI:

```bash
gemini
```

6. Test that `gemini` has connected to `syz-agent` by executing `/mcp` or `/mcp schema`.

7. Try the following prompt:

```
/* Detailed source-code truncated for AI context efficiency. */
```

A manual unit test for the MCP server:

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Program Syntax (`docs/program_syntax.md`)

# Program syntax

Syzkaller uses a compact domain-specific language (DSL) for programs
to log executed programs, test its code, and persist programs in the
corpus. This page provides a brief description of the corresponding
syntax. Some useful information can also be found in the
[existing examples](/sys/linux/test) and in the program
[deserialization code](/prog/encoding.go).

Together with execution options, the DSL provides everything that
syz-executor needs to run a program.

For example, consider the program:
```
r0 = syz_open_dev$loop(&(0x7f00000011c0), 0x0, 0x0)
r1 = openat$6lowpan_control(0xffffffffffffff9c, &(0x7f00000000c0), 0x2, 0x0)
ioctl$LOOP_SET_FD(r0, 0x4c00, r1)
```

Each line in this program describes a particular syscall invocation,
with the first two calls saving the result in temporary variables `r0`
and `r1`, which are passed to the third call.

```
line = assignment | call
assignment = variable " = " call
call = syscall-name "(" [arg ["," arg]*] ")"  ["(" [call-prop ["," call-prop*] ")"]
arg = "nil" | "AUTO" | const-arg | resource-arg | result-arg | pointer-arg | string-arg | struct-arg | array-arg | union-arg
const-arg = integer
resource-arg = variable ["/" hex-integer] ["+" hex-integer]
result-arg = "<" variable "=>" arg
pointer-arg = "&" pointer-arg-addr ["=ANY"] "=" arg
pointer-arg-addr = "AUTO" | "(" pointer-addr ["/" region-size] ")"
string-arg = "'" escaped-string "'" | "\"" escaped-string "\"" | "\"$" escaped-string "\""
struct-arg =  "{" [arg ["," arg]*] "}"
array-arg = "[" [arg ["," arg]*] "]"
union-arg = "@" field-name ["=" arg]
call-prop = prop-name ": " prop-value
variable = "r" dec-integer
pointer-addr = integer
region-size = integer
integer = dec-integer | oct-integer | "0x" hex-integer
```

Programs may also contain blank lines and comments.
```
# Obtain a file handle
r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)

# Perform a write operation
write(r0, &AUTO="01010101", 0x4)
```

### Memory management

Memory management is performed by syzkaller itself. It will allocate
virtual memory regions of the necessary size and set the final values
of pointer arguments.

By using the `AUTO` keyword, programs can give syzkaller the full
control over storing the data. This may be convenient e.g. when a
parameter must be passed by reference, but the exact location of its
value is not of particular importance.

```
r1 = syz_genetlink_get_family_id$nl80211(&AUTO='nl80211\x00', 0xffffffffffffffff)
ioctl$sock_SIOCGIFINDEX_80211(r0, 0x8933, &AUTO={'wlan0\x00', <r2=>0x0})
```

Alternatively, some data can be "anchored" to specific addresses. It
may be especially important when a memory region must be shared
between multiple calls.  In this case, pointer addresses must be given
at the 0x7f0000000000 offset. Before the actual execution, syzkaller
will adjust pointers to the start of the actual mmap'ed region.

### Call properties

Call properties specify extra information about how a specific call
must be executed. Each call within a program has its own set of call
properties. If no properties are provided, syzkaller takes the default
ones.

Currently, syzkaller supports the following call properties.

#### Fault injection
Syntax: `fail_nth: N`.

It takes an integer (base 10) argument `N`. If the argument is
non-negative, a fault will be injected into the `N`-th occasion.

```
r0 = openat$6lowpan_control(0xffffffffffffff9c, &(0x7f00000000c0), 0x2, 0x0)
ioctl$LOOP_SET_FD(r0, 0x4c00, r0) (fail_nth: 5)
```

#### Async
Syntax: `async`.

Instructs `syz-executor` not to wait until the call completes and
to proceed immediately to the next call.

```
r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
write(r0, &AUTO="01010101", 0x4) (async)
read(r0, &AUTO=""/4, 0x4)
close(r0)
```

When setting `async` flags be aware of the following considerations:
* Such programs should only be executed in threaded mode (i.e. `-threaded`
flag must be passed to `syz-executor`.
* Each `async` call is executed in a separate thread and there's a
limited number of available threads (`kMaxThreads = 16`).
* If an `async` call produces a resource, keep in mind that some other call
might take it as input and `syz-executor` will just pass 0 if the resource-
producing call has not finished by that time.

---

### Prometheus (`docs/prometheus.md`)

# Prometheus metrics

syz-manager metrics are exposed at the URI `/metrics` on the http endpoint.
Currently exported prometheus metrics from the manager are `syz_exec_total`, `syz_corpus_cover` and `syz_crash_total`.

These metrics can be ingested using following prometheus client configuration:

```yaml
scrape_configs:
- job_name: syzkaller
  scrape_interval: 10s
  static_configs:
  - targets:
    - localhost:56741
```

Values are reset to zero at syz-manager restart and only reflect for current execution of syz-manager.

---

### Pseudo Syscalls (`docs/pseudo_syscalls.md`)

# Pseudo-syscalls

Besides regular system calls, a [syscall
description](syscall_descriptions.md) file can also contain
pseudo-syscalls. These are C functions defined in the
executor. When a test program uses a pseudo-syscall, the executor
will generate the pseudo-syscall function code in the resulting C program.

This allows a test program to have specific code blocks to perform
certain actions, they may also be used as more test-friendly wrappers
for primitive syscalls.

Use of pseudo-syscalls is generally **discouraged** because they ruin all
advantages of the declarative descriptions (declarativeness, conciseness,
fuzzer control over all aspects, possibility of global improvements to
the logic, static checking, fewer bugs, etc), increase maintenance burden,
are non-reusable and make C reproducers longer. However, syzlang is not
expressive enough to cover all possible cases, so use of pseudo-syscalls
needs to be considered on a case-by-cases basis (additional benefit,
amount of code, possibility of extending syzlang to cover this case, etc).

## How to add a pseudo-syscall to the executor

First, think about the scope of the pseudo-syscall and which systems and
subsystems it will be related to. The executor includes a fixed set of C
header files `executor/common*.h` containing the code of the pseudo-syscalls.
Check if the new one can fit in one of the existing files before creating
a new one.

For instance, if our new pseudo-syscall is Linux-specific, then
[common_linux.h](../executor/common_linux.h) would be the place to put it.

The actual pseudo-syscall function may look something like this:

    #if SYZ_EXECUTOR || __NR_syz_mycall
    /* Add all the necessary #include and #define headers */

    static long syz_mycall(volatile long a0, volatile long a1)
    {
            /* Function body */
    }
    #endif

Make sure that all the function requirements are met and that it can
be compiled. Note that the function name must start with "syz_". It may
also take a different number of arguments. Type of arguments must be
`volatile long`, return type - `long`. `long` is required to avoid
potential calling convention issues because it is casted to a function
pointer that accepts `long`'s. The reason for `volatile` is interesting:
lots of libc functions are annotated with various argument constraints
(e.g. this argument should not be `NULL`, or that argument must be a
valid file descriptor); C reproducers may call these functions with
constant arguments and compiler may see that some of these constraints
are violated (e.g. passing `NULL` to a `non-NULL` argument, or passing
`-1` as file descriptor) and produce errors/warnings. `volatile` prevents
that.

Now, to handle the pseudo-syscall properly we have to update the
`linuxSyscallChecks` in
[linux_syscalls.go](../pkg/vminfo/linux_syscalls.go) and add a particular
case for this syscall, enabling it when necessary. If we want to enable
it unconditionally we can simply use `alwaysSupported` for it.

Finally, run `make generate`. Now you can use it in a syscall
description file as if it was a regular system call:

    syz_mycall(arg0 pid, arg1 const[0])

<div id="dependencies"/>

## External Dependencies

The implementation must not use any external libraries nor external headers,
except for the most basic and standard ones (like `<unistd.h>` and
`<sys/mman.h>`). In particular, it must not depend on libraries/headers
installed by additional packages nor on headers for recently added kernel
subsystems. External dependencies have proved to be brittle and easily cause
build breakage because all dependencies will be required for any build/run on
the fuzzer and any C reproducer. For example, packages/headers may be missing
on some distros, named differently, be of a wrong version, broken, or conflict
with other headers. Unfortunately, there is no way to reliably specify such
dependencies and requirements for C programs. Therefore, if the pseudo-syscall
requires definitions of some structures, constants, or helper functions, these
should be described in the executor code itself as minimally as possible (they
will be part of C reproducers).

## Testing

Each new pseudo-syscall should have at least one test in `sys/OS/test`.
See [Linux tests](/sys/linux/test) for an example. A tests is just a program
with checked syscall return values. There should be at least one test
that contains "the main successful scenario" of using the pseudo-syscall.
See [io_uring test](/sys/linux/test/io_uring) as a good example.
Such tests are important because they ensure that the pseudo-syscall code
does not contain "stupid" bugs (e.g. crash on NULL-deref each time),
that it is possible for the fuzzer to come up with the successful scenario
(as a combination of the pseudo-syscall and the surrounding descriptions)
and that it will continue to work in future.
See [Testing of descriptions](syscall_descriptions.md#testing)
for details about the tests.

---

### Pull Request Template (`docs/pull_request_template.txt`)

*******************************************************************************
Before sending a pull request, please review Contribution Guidelines:
https://github.com/google/syzkaller/blob/master/docs/contributing.md
*******************************************************************************

---

### Reproducing Crashes (`docs/reproducing_crashes.md`)

# How to reproduce syzkaller crashes

## Using a C reproducer

If the bug was reported by syzbot, you first need to build the kernel used by
the tool. Syzbot provides the necessary information in its report:

```
Hello,

syzbot found the following issue on:

HEAD commit:    ae58226b89ac Add linux-next specific files for 20241118
git tree:       linux-next
console+strace: https://syzkaller.appspot.com/x/log.txt?x=14a67378580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=45719eec4c74e6ba
dashboard link: https://syzkaller.appspot.com/bug?extid=2159cbb522b02847c053
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=137beac0580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=177beac0580000
```

In this case, you would run:

```shell
$ git checkout ae58226b89ac
$ wget -O '.config' 'https://syzkaller.appspot.com/x/.config?x=45719eec4c74e6ba'
$ make CC=clang LD=ld.lld olddefconfig
$ make CC=clang LD=ld.lld -j$(nproc)
```

You also need a bootable disk image. Syzbot currently uses small Buildroot-based
images that you can either [build locally](/tools/create-buildroot-image.sh) or
[download](https://storage.googleapis.com/syzkaller/images/buildroot_amd64_2024.09.gz).

Download and build the reproducer:

```shell
$ wget -O 'repro.c' 'https://syzkaller.appspot.com/x/repro.c?x=177beac0580000'
$ gcc repro.c -lpthread -static -o repro
```

Run the VM:

```shell
$ export DISK_IMAGE='buildroot_amd64_2024.09'
$ qemu-system-x86_64 -m 2G -smp 2,sockets=2,cores=1 -drive file=$DISK_IMAGE,format=raw -net nic,model=e1000 -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -enable-kvm -nographic -snapshot -machine pc-q35-7.1
```

Run the reproducer:

```shell
$ scp -P 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ./repro root@127.0.0.1:/root/
$ ssh -p 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes root@127.0.0.1 'chmod +x ./repro && ./repro'
```

## Using a Syz reproducer

Syzkaller always generates a "Syz" reproducer first (in [Syzkaller
DSL](/docs/program_syntax.md)). Afterwards, syzkaller attempts to convert the
Syz reproducer into C code. The process does not always succeed due to the
differences between the `syz-executor` environment and the environment emulated
in the C reproducer. Therefore, in some cases, only the Syz version is
available.

To run a Syz reproducer locally, the required actions are mostly similar to
those in the previous section.

Download and [build](/docs/linux/setup.md#go-and-syzkaller) syzkaller. If you
have Docker installed, the instructions are simpler:

```shell
$ git clone https://github.com/google/syzkaller.git
$ cd syzkaller
$ ./tools/syz-env make
```

Build the kernel and boot the VM as described in the section above.

Download the reproducer:

```shell
$ wget -O 'repro.syz' 'https://syzkaller.appspot.com/x/repro.syz?x=137beac0580000'
```

Copy the reproducer and the syzkaller binaries to the test machine:

```shell
$ export SYZKALLER_PATH="~/syzkaller"
$ scp -P 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes $SYZKALLER_PATH/bin/linux_amd64/* ./repro.syz root@127.0.0.1:/root/
```

Now you can use the `syz-execprog` tool to actually execute the program.

```shell
$ ssh -p 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes root@127.0.0.1 './syz-execprog -enable=all -repeat=0 -procs=6 ./repro.syz'
```

Several useful `syz-execprog` flags:

```
  -procs int
    	number of parallel processes to execute programs (default 1)
  -repeat int
    	repeat execution that many times (0 for infinite loop) (default 1)
  -sandbox string
    	sandbox for fuzzing (none/setuid/namespace) (default "setuid")
  -threaded
    	use threaded mode in executor (default true)
```

If you pass `-threaded=0`, all syscalls will be executed in the same thread.
`-threaded=1` forces execution of each syscall in a separate thread, so that
execution can proceed over blocking syscalls.

Before 2021, `syz-execprog` also supported the following flag:

```
  -collide
    	collide syscalls to provoke data races (default true)
```

`-collide=1` forced second round of execution of syscalls when pairs of syscalls
are executed concurrently.

Starting from the revision
[fd8caa54](https://github.com/google/syzkaller/commit/fd8caa5462e64f37cb9eebd75ffca1737dde447d),
the behavior is controlled [directly in syzlang](/docs/program_syntax.md#async).
If you are running older reproducers, you might still need to set the `-collide=1` flag.

If you are replaying a reproducer program that contains a header along the
following lines:

```
# {Threaded:true Repeat:true RepeatTimes:0 Procs:8 Slowdown:1 Sandbox:none Leak:false NetInjection:true NetDevices:true NetReset:true Cgroups:true BinfmtMisc:true CloseFDs:true KCSAN:false DevlinkPCI:false USB:true VhciInjection:true Wifi:true IEEE802154:true Sysctl:true UseTmpDir:true HandleSegv:true Repro:false Trace:false LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
```

then you need to adjust `syz-execprog` flags based on the values in the
header. Namely, `Threaded`/`Procs`/`Sandbox` directly relate to
`-threaded`/`-procs`/`-sandbox` flags. If `Repeat` is set to `true`, add
`-repeat=0` flag to `syz-execprog`.

## Using ktest

[ktest](https://evilpiepirate.org/git/ktest.git/tree/README.md) is a collection
of tests for Linux and an infrastructure that simplifies running them locally.

Ktest includes a special `syzbot-repro.ktest` test that automates building the
kernel, booting the VM, fetching syzbot bug report details and running the
reproducer.

**Installation instructions:**

```shell
$ git clone git://evilpiepirate.org/ktest.git
$ cd ktest
$ export KTEST_PATH=$(pwd)
$ sudo ./root_image init
$ sudo ./root_image create
$ cargo install --path $KTEST_PATH
```

**Instructions to reproduce a syzbot bug:**

```shell
$ cd ~/linux
$ git checkout <kernel-commit>
$ $KTEST_PATH/build-test-kernel run $KTEST_PATH/tests/syzbot-repro.ktest <bug-id>
```

`<bug-id>` can be taken from syzbot bug reports:

```
dashboard link: https://syzkaller.appspot.com/bug?extid=2159cbb522b02847c053
```

In this case, `bug-id` is `2159cbb522b02847c053`.

## Using downloadable assets

In each report, syzbot shares the exact disk image, kernel image and the vmlinux
file that were used to find it.

See [the corresponding documentation](/docs/syzbot_assets.md) on how you can
use those files to reproduce bugs locally.

## From execution logs

The process of creating reproducer programs for syzkaller bugs is automated, but
it's not perfect. In some cases, the tool cannot narrow down the kernel crash to
a single program.

### Obtaining execution logs

* **A local syzkaller instance** \
Crash logs created in manager `workdir/crashes` dir contain programs executed
just before a crash. In parallel execution mode (when `procs` parameter in
manager config is set to value larger than 1), program that caused the crash
does not necessary immediately precedes it; the guilty program can be somewhere
before.

* **Syzbot** shares execution logs in its reports:

```
console output: https://syzkaller.appspot.com/x/log.txt?x=148914c0580000
```

### Crafting reproducers manually

There are two tools that can help you identify and minimize the program that
causes a crash: `syz-execprog` and `syz-prog2c`. You can build them with `make
execprog` and `make prog2c`, respectively.

`syz-execprog` executes a single syzkaller program or a set of programs in
various modes (once or loop indefinitely; in threaded/collide mode (see below),
with or without coverage collection).

You can start by running all programs in the crash log in a loop to check that
at least one of them indeed crashes kernel:

```bash
./syz-execprog -executor=./syz-executor -repeat=0 -procs=8 -cover=0 crash-log-file.txt
```

**Note: `syz-execprog` executes programs locally. So you need to copy
`syz-execprog` and `syz-executor` into a VM with the test kernel and run it
there.** See the [Using a Syz reproducer](#using-a-syz-reproducer) section.

To identify the single program that causes the crash, you can cut out individual
programs from `crash-log-file.txt` and run `syz-execprog` separately.

Once you have a single program that causes the crash, you can try to minimize it by:

* Removing individual syscalls from the program (you can comment out single lines
with `#` at the beginning of line)
* By removing unnecessary data (e.g. replacing `&(0x7f0000001000)="73656c6600"`
syscall argument with `&(0x7f0000001000)=nil`).
* You can also try to coalesce all mmap calls into a single mmap call that maps
whole required area.

Don't forget to test minimization results with the `syz-execprog` tool.

Now that you have a minimized program, check if the crash still reproduces with
`./syz-execprog -threaded=0 -collide=0` flags. If not, then you will need to do
some additional work later.

Now, run the `syz-prog2c` tool on the program. It will give you an executable C
source code. If the crash reproduces with `-threaded/collide=0` flags, then this C
program should cause the crash as well.

If the crash is not reproducible with `-threaded/collide=0` flags, then you need
this last step. You can think of threaded mode as if each syscall is
executed in its own thread. To model such execution mode, move individual
syscalls into separate threads. You can see an example here:
https://groups.google.com/d/msg/syzkaller/fHZ42YrQM-Y/Z4Xf-BbUDgAJ.

This process is automated to some degree in the `syz-repro` utility. You need to
give it your manager config and a crash report file. And you can refer to the
[example config file](/pkg/mgrconfig/testdata/qemu-example.cfg).

```bash
./syz-repro -config my.cfg crash-qemu-1-1455745459265726910
```

It will try to find the offending program and minimize it. But since there are
lots of factors that can affect reproducibility, it does not always work.

---

### Research (`docs/research.md`)

# Research work based on syzkaller

Dear researchers, feel free to contact us at syzkaller@googlegroups.com if you need any assistance.

_newer first_
* [Unlocking Low Frequency Syscalls in Kernel Fuzzing with Dependency-Based RAG](https://dl.acm.org/doi/abs/10.1145/3728913) ([pdf](https://dl.acm.org/doi/pdf/10.1145/3728913), [source code](https://github.com/QGrain/SyzGPT))
* [A Little Goes a Long Way: Tuning Configuration Selection for Continuous Kernel Fuzzing](https://www.computer.org/csdl/proceedings-article/icse/2025/056900a521/215aWUHqo9i)
* [SyzDirect: Directed Greybox Fuzzing for Linux Kernel](https://dl.acm.org/doi/abs/10.1145/3576915.3623146)
* [KIT: Testing OS-Level Virtualization for Functional Interference Bugs](https://doi.org/10.1145/3575693.3575731)
* [SyzDescribe: Principled, Automated, Static Generation of Syscall Descriptions for Kernel Drivers](https://github.com/seclab-ucr/SyzDescribe)
* [GREBE: Unveiling Exploitation Potential for Linux Kernel Bugs](https://zplin.me/papers/GREBE.pdf)
* [Precise Detection of Kernel Data Races with Probabilistic Lockset Analysis](https://www.cs.columbia.edu/~gabe/files/oakland2023_pla.pdf)
* [Linux Kernel Enriched Corpus](https://github.com/cmu-pasta/linux-kernel-enriched-corpus) : [corpus.db](https://github.com/cmu-pasta/linux-kernel-enriched-corpus/raw/main/corpus.db)
* [HotBPF - An On-demand and On-the-fly Memory Protection](https://www.youtube.com/watch?v=1KSLTsgxaSU)
* [KASPER: Scanning for Generalized Transient Execution Gadgets in the Linux Kernel](https://www.vusec.net/projects/kasper/)
* [VaultFuzzer: A state-based approach for Linux kernel](https://hardenedvault.net/blog/2021-09-13-vaultfuzzer/)
* [Demystifying the Dependency Challenge in Kernel Fuzzing](https://conf.researchr.org/details/icse-2022/icse-2022-papers/89/Demystifying-the-Dependency-Challenge-in-Kernel-Fuzzing)
* [SyzVegas: Beating Kernel Fuzzing Odds with Reinforcement Learning](https://www.usenix.org/conference/usenixsecurity21/presentation/wang-daimeng)
* [SyzScope: Revealing High-Risk Security Impacts of Fuzzer-Exposed Bugs in Linux kernel](https://www.usenix.org/conference/usenixsecurity22/presentation/zou)
* [Rtkaller: State-aware Task Generation for RTOS Fuzzing](http://www.wingtecher.com/themes/WingTecherResearch/assets/papers/emsoft21.pdf)
* [BSOD: Binary-only Scalable fuzzing Of device Drivers](https://dmnk.co/raid21-bsod.pdf)
* [Torpedo: A Fuzzing Framework for Discovering Adversarial Container Workloads](https://vtechworks.lib.vt.edu/handle/10919/104159)
* [Healer](https://github.com/SunHao-0/healer) is a kernel fuzzer inspired by syzkaller. ([pdf](http://www.wingtecher.com/themes/WingTecherResearch/assets/papers/healer-sosp21.pdf))
* [SyzGen: Automated Generation of Syscall Specification of Closed-Source macOS Drivers](https://www.cs.ucr.edu/~zhiyunq/pub/ccs21_syzgen.pdf) ([source code](https://github.com/seclab-ucr/SyzGen_setup))
* [Snowboard: Finding Kernel Concurrency Bugs through Systematic Inter-thread Communication Analysis](https://dl.acm.org/doi/10.1145/3477132.3483549)
* [Undo Workarounds for Kernel Bugs](https://www.usenix.org/system/files/sec21fall-talebi.pdf) ([source code](https://trusslab.github.io/hecaton))
* [HFL: Hybrid Fuzzing on the Linux Kernel](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24018-paper.pdf)
* [A Novel Dynamic Analysis Infrastructure to Instrument Untrusted Execution Flow Across User-Kernel Spaces](https://www.computer.org/csdl/proceedings-article/sp/2021/893400a402/1mbmHSlbmvK)
* [Industry Practice of Coverage-Guided Enterprise Linux Kernel Fuzzing](http://wingtecher.com/themes/WingTecherResearch/assets/papers/fse19-linux-kernel.pdf)
* [Agamotto: Accelerating Kernel Driver Fuzzing with Lightweight Virtual Machine Checkpoints](https://www.usenix.org/conference/usenixsecurity20/presentation/song) ([source code](https://github.com/securesystemslab/agamotto))
* [Empirical Notes on the Interaction Between Continuous Kernel Fuzzing and Development](http://users.utu.fi/kakrind/publications/19/vulnfuzz_camera.pdf)
* [FastSyzkaller: Improving Fuzz Efficiency for Linux Kernel Fuzzing](https://iopscience.iop.org/article/10.1088/1742-6596/1176/2/022013)
* [Charm: Facilitating Dynamic Analysis of Device Drivers of Mobile Systems](https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-talebi.pdf)
([video](https://www.usenix.org/conference/usenixsecurity18/presentation/talebi),
[slides](https://www.usenix.org/sites/default/files/conference/protected-files/security18_slides_talebi.pdf),
[source code](https://trusslab.github.io/charm))
* [ALEXKIDD-FUZZER: Kernel Fuzzing Guided by Symbolic Information](https://www.cerias.purdue.edu/assets/symposium/2018-posters/829-D1B.pdf)
* [DIFUZE: Interface Aware Fuzzing for Kernel Drivers](https://acmccs.github.io/papers/p2123-corinaA.pdf)
* [MoonShine: Optimizing OS Fuzzer Seed Selection with Trace Distillation](http://www.cs.columbia.edu/~suman/docs/moonshine.pdf)
* [RAZZER: Finding Kernel Race Bugs through Fuzzing](https://lifeasageek.github.io/papers/jeong:razzer.pdf)
* [SemFuzz: Semantics-based Automatic Generation of Proof-of-Concept Exploits](https://www.informatics.indiana.edu/xw7/papers/p2139-you.pdf)
* [Towards Automating Exploit Generation for Arbitrary Types of Kernel Vulnerabilities](https://i.blackhat.com/us-18/Thu-August-9/us-18-Wu-Towards-Automating-Exploit-Generation-For-Arbitrary-Types-of-Kernel-Vulnerabilities-wp.pdf)
* [KOOBE: Towards Facilitating Exploit Generation of Kernel Out-Of-Bounds Write Vulnerabilities](https://www.usenix.org/system/files/sec20summer_chen-weiteng_prepub.pdf)
* [Synthesis of Linux Kernel Fuzzing Tools Based on Syscall](http://dpi-proceedings.com/index.php/dtcse/article/download/14990/14503)
* [Drill the Apple Core: Up & Down](https://i.blackhat.com/eu-18/Wed-Dec-5/eu-18-Juwei_Lin-Drill-The-Apple-Core.pdf)
* [WSL Reloaded](https://www.slideshare.net/AnthonyLAOUHINETSUEI/wsl-reloaded)

# Other kernel fuzzing work

* [Hydra: Finding Semantic Bugs in File Systems with an Extensible Fuzzing Framework](https://squizz617.github.io/pubs/hydra-sosp19.pdf) ([github](https://github.com/sslab-gatech/hydra))
* [Janus: Fuzzing File Systems via Two-Dimensional Input Space Exploration](https://gts3.org/assets/papers/2019/xu:janus.pdf) ([github](https://github.com/sslab-gatech/janus))
* [CoLaFUZE: Coverage-Guided and Layout-Aware Fuzzing for Android Drivers](https://www.jstage.jst.go.jp/article/transinf/E104.D/11/E104.D_2021NGP0005/_pdf)
* [KRACE: Data Race Fuzzing for Kernel File Systems](https://www.cc.gatech.edu/~mxu80/pubs/xu:krace.pdf)
* [trinity](https://github.com/kernelslacker/trinity)
* [kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels](https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-schumilo.pdf) (bridges AFL and Intel PT)
* [kernel-fuzzing](https://github.com/oracle/kernel-fuzzing) (bridges AFL and KCOV)
* [A gentle introduction to Linux Kernel fuzzing](https://blog.cloudflare.com/a-gentle-introduction-to-linux-kernel-fuzzing/) (bridges AFL and KCOV)
* [IMF: Inferred Model-based Fuzzer](https://acmccs.github.io/papers/p2345-hanA.pdf)

Also see [tech talks page](/docs/talks.md).

---

### Review Guidelines (`docs/review_guidelines.md`)

# Automated Code Review Guidelines (DVYUKOV.md)

This file contains curated recommendations extracted from automated pull request reviews. Ingest this file into your LLM pipeline to ensure compliance with repository style and best practices!

## 1. Go Coding Style & Idioms
- **Naming:**
  - Lowercase package names (no underscores or MixedCaps).
  - Use `NewFoo` or `MakeFoo` for constructors; return pointers if methods are defined on pointers.
  - Avoid repeating type names in method names (e.g., `linux.Foo()` not `linux.FooLinux()`).
  - Avoid "syz" prefixes for internal structs/fields (e.g., `exec_total` not `syz_exec_total`).
  - Use `i` for loop indices; use descriptive names for slice elements.
  - Favor positive boolean naming (`active` vs `not_inactive`).
- **Declarations:**
  - Combine declaration and initialization (`x := foo()`).
  - Rely on zero-value defaults; do not manually initialize to 0, "", or `map[type]type{}`.
  - Unexport symbols (types, fields, constants, functions) not needed externally.
  - Use `iota` for enums and make `Invalid` the first value (0) to catch uninitialized fields.
  - Use `go:embed` for embedding static assets like HTML or text templates.
- **Functions & Control Flow:**
  - Return early on errors (standard `if err != nil` check); avoid deep nesting.
  - Avoid naked or named returns unless they significantly simplify repetitive code.
  - Drop unnecessary `else` after `return`, `break`, or `continue`.
  - Prefer free/normal functions over closures if no context is captured from the outer scope.
  - Use closures to deduplicate scoped logic within a single function.
- **Miscellaneous:**
  - Cap Go lines at 120 columns; use tabs for indentation.
  - Use `%s` for struct string conversion in `fmt` functions (idiomatic `v.String()` call).
  - Avoid unneeded parentheses in expressions and `()` to refer to functions in comments.

## 2. Error Handling & Reliability
- **Return Errors:** Never swallow errors or return `nil` on unexpected conditions.
- **Fail Fast:**
  - Validate invariants early (e.g., during initialization or deserialization).
  - Panic on impossible internal logic corruption or broken engine invariants.
  - For external tools/plugins, use `SYZFAIL:` prefix for internal bugs to distinguish from target crashes.
- **Error Context:**
  - Don't wrap errors without adding specific, helpful context (Syzkaller libs often add basic context).
  - Use `aflow.BadCallError` for invalid tool inputs in agent workflows.
- **Validation:**
  - Always validate inputs at boundaries (datastores, APIs, CLI flags, regexes).
  - Guard against underflows/overflows in length checks and binary formats.

## 3. Testing Best Practices
- **Assertions:** Use `github.com/stretchr/testify/require` (or `assert`) for single-line, readable assertions.
- **Structure:**
  - Use table-driven tests with `t.Run` for isolation and subtest selection.
  - Keep helper functions at the bottom of the test file; use `t.Cleanup` for teardown.
- **Data Handling:**
  - Use backtick raw string literals (`` ` ``) for multi-line test data, regexes, and assembly.
  - Use `AUTO` in syzlang tests for auto-computing lengths and offsets.
  - Use `timeNow` over `time.Now` for deterministic test stubbing.
- **Robustness:**
  - Run tests with `-race` to surface data races.
  - Check for goroutine leaks in tests using background concurrency.
  - Test boundary conditions (e.g., empty slices, index limits, or corrupted inputs).
  - Never just disable failing tests; fix them or document why they are disabled.
  - Include sample reports in `pkg/report/testdata` for new crash parsers.

## 4. Architecture & Design
- **YAGNI (You Ain't Gonna Need It):**
  - Don't add code "just in case"; remove unused types, fields, and dead code immediately.
  - Avoid unnecessary tunables/config flags; pick sensible defaults and scale timeouts.
- **Decoupling:**
  - Keep logic uniform across different execution modes (e.g., fork-server vs no-fork-server).
  - Use standard interfaces (e.g., `io.Closer`) over custom cleanup methods.
  - Prefer specific, descriptive package names over generic ones like `util` or `generic`.
  - Prioritize larger, coherent packages over many micro-packages.
- **State Management:**
  - Favor simple state tracking (single counter/slice) over complex nested maps.
  - Use fields in the `targets.Target` struct (often referred to as Arch struct) instead of logic-driven switches for architecture differences.
  - Pass objects/pointers early instead of passing IDs and doing repeated lookups.

## 5. Performance & Resource Management
- **Efficiency:**
  - Use map lookups (O(1)) instead of double loops (O(N^2)) for filtering.
  - Avoid casting large buffers to strings if only byte processing is needed.
  - Prefer direct slicing over `io.Reader` for byte processing to reduce garbage.
  - Avoid `bufio.Writer` when writing to `bytes.Buffer`.
- **Resource Cleanup:**
  - Always `Wait()` on launched commands; use `defer` to close file descriptors and pipes.
  - Extract loop bodies into functions if they use `defer` to ensure per-iteration cleanup.
- **Concurrency:**
  - Use channels for semaphores or async notifications; use capacity 1 to prevent blocking.
  - Use `nil` channels to disable `select` cases.
  - Ensure condition variables are checked in a loop to prevent race hangs.
  - Avoid infinite goroutine spawning in pools; track wait states.

## 6. Logging & Observability
- **Hygiene:**
  - Use the internal `log` package consistently; avoid mixing multiple logger libraries.
  - Log only actionable information at verbosity 0; use info logs for invalid user requests.
  - Don't suffix log messages with newlines (`\n`).
  - Format string safety: use `Logf(1, "%s", out)` instead of `Logf(1, out)`.
- **Determinism:** Always sort map keys when serializing to persistent formats (configs, logs, coverage).
- **Metrics:** Rename existing metrics rather than adding confusing duplicates when semantics change.
- **Reporting:** Keep email prefixes short; e.g. explain why something was skipped in bisection logs.

## 7. Syzkaller Specifics (Syzlang & Executor)
- **Syzlang (files in `sys/*/*.txt`):**
  - Use exact kernel field names; use descriptive prefixes to avoid collisions.
  - Use `const[0]` for reserved/unused fields to optimize mutation.
  - Use `ignore_return` for syscalls returning random system IDs or times.
- **Executor (C++ files in `executor`):**
  - Keep `executor.cc` free of OS-specific `#ifdefs`; use OS-specific headers.
  - Use `const std::string&` or `std::string_view` for immutable strings.
  - Check for short writes in output loops.
  - Avoid C89 start-of-block declarations; combine declaration and initialization.

## 8. Tooling & Infrastructure
- **CLI Tools:**
  - Standardize on `tool.Init()` and `tool.Failf()` from `pkg/tool`.
  - Declare CLI flags in `main()` to avoid global namespace pollution.
  - Use `runtime.NumCPU()` for default worker counts.
- **OS Operations:**
  - Use `filepath.Join` for OS-agnostic paths; use `osutil.IsExist` for existence checks.
  - Combine multiple shell commands (e.g., `adb shell 'cmd1; cmd2'`) to reduce overhead.
- **HTML/UI:**
  - Use standard `<details>` and `<summary>` for collapsibles.
  - Use tabs for HTML templates.

---

### Setup (`docs/setup.md`)

# How to set up syzkaller

Generic setup instructions for fuzzing Linux kernel are outlined [here](linux/setup.md).

For other kernels see:
[FreeBSD](freebsd/README.md),
[Darwin/XNU](darwin/README.md),
[Fuchsia](fuchsia/README.md),
[NetBSD](netbsd/README.md),
[OpenBSD](openbsd/setup.md),
[Windows](windows/README.md).

After following these instructions you should be able to run `syz-manager`, see it executing programs, and be able to access statistics exposed at `http://127.0.0.1:56741` (or whatever address you've specified in the manager config).
If everything is working properly, a typical execution log would look like:

```
$ ./bin/syz-manager -config=my.cfg
2017/06/14 16:39:05 loading corpus...
2017/06/14 16:39:05 loaded 0 programs (0 total, 0 deleted)
2017/06/14 16:39:05 serving http on http://127.0.0.1:56741
2017/06/14 16:39:05 serving rpc on tcp://127.0.0.1:34918
2017/06/14 16:39:05 booting test machines...
2017/06/14 16:39:05 wait for the connection from test machine...
2017/06/14 16:39:59 received first connection from test machine vm-9
2017/06/14 16:40:05 executed 293, cover 43260, crashes 0, repro 0
2017/06/14 16:40:15 executed 5992, cover 88463, crashes 0, repro 0
2017/06/14 16:40:25 executed 10959, cover 116991, crashes 0, repro 0
2017/06/14 16:40:35 executed 15504, cover 132403, crashes 0, repro 0
```

At this point it's important to ensure that syzkaller is able to collect code coverage of the executed programs
(unless you specified `"cover": false` in the config or coverage is not yet supported for the kernel you're fuzzing).
The `cover` counter on the web page should be non zero.

More information on the configuration file format is available [here](configuration.md).

See [this page](troubleshooting.md) for troubleshooting tips.

---

### Setup Syzbot (`docs/setup_syzbot.md`)

# How to set up syzbot

This doc will be useful to you:

- should you wish to hack on user interface bits like the dashboard / mailing list integration or
- should you wish to continuously run a separate syzbot dashboard for your own kernels

Note: For most development purposes you don't need a full syzbot setup. The meat of syzkaller is really located
in syz-manager and syz-executor. You can run syz-manager directly which is usually what you will want to do during
fuzzer development. [See this documentation for syz-manager setup instructions](setup.md).

This doc assumes that you:

- have a GCP account and billing setup
- created a GCP project for running syzbot in
- are running a reasonably modern linux distro
- locally installed `gcloud`, `ssh`, `go` and `build-essential`
- may need to install `google-cloud-sdk-app-engine-go` for the GAE deployment to work
- ran `gcloud auth login` to run authenticated gcloud commands
- read [go/syzbot-setup](https://goto.google.com/syzbot-setup) if you are a Googler

While most syzkaller bits happily run on various operating systems, the syzbot dashboard does not. The dashboard is a Google App Engine or GAE project. GAE allows developers to develop web applications without needing to worry about the underlying servers. Instead developers just push their code and GAE takes care of web servers, load balancers and more. Hence this document is more Google Cloud focused than the rest of our documentation.

We will also deploy a syz-ci instance. syz-ci keeps track of the syzkaller and kernel repositories and continuously rebuilds the kernel under test, itself and other syzkaller components when new commits land in the upstream repositories. syz-ci also takes care of (re)starting syz-manager instances, which in turn (re)start VMs fuzzing the target kernel. For simplicity we will run everything in this doc on GCP even though syz-ci could run elsewhere.



## Deploying Syz-ci

[local] First prepare an initial syz-ci build locally (later syz-ci rebuilds itself) and a rootfs:

```sh
# Most syzkaller components can be build even outside of the GOPATH, however
# the syzbot app engine deployment only works from the GOPATH right now..
export GOOGLE_GO=$HOME/gopath/src/github.com/google/
mkdir -p $GOOGLE_GO
git clone https://github.com/google/syzkaller.git
mv syzkaller $GOOGLE_GO/
cd $GOOGLE_GO/syzkaller
make ci

cd ~/repos
git clone git://git.buildroot.net/buildroot
cd buildroot
$GOOGLE_GO/syzkaller/tools/create-buildroot-image.sh
```

[local] Enable various services in the project, create a VM, storage bucket, scp assets and login:

```
/* Detailed source-code truncated for AI context efficiency. */
```

[syz-ci] Let's install and configure the syz-ci service on our syz-ci VM:

```
/* Detailed source-code truncated for AI context efficiency. */
```

Check the syc-ci journal logs at this point to see if the service comes up fine. Now syz-ci needs to do a bunch of time consuming stuff like building the kernel under test, so be patient.

If you want to hack on syz-ci you can stop here. Otherwise the next section builds on the syz-ci instructions and extends the setup with a dashboard deployment.

## Deploying Syzbot dashboard

[locally] deploy the dashboard to Google App Engine:

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Integrating Syz-ci with syzbot

[locally] Prepare config and login to syz-ci VM:

```
/* Detailed source-code truncated for AI context efficiency. */
```

[syz-ci] Reconfigure syz-ci to start sending results to the dashboard:

```sh
sudo mv ~/config.ci /syzkaller/
sudo systemctl restart syz-ci
sudo journalctl -fu syz-ci
```

[locally] Open the dashboard in your browser:

```sh
gcloud app browse --project=$PROJECT
```

Once syzkaller finds the first crashes they should show up here. This might take a while.

---

### Strace (`docs/strace.md`)

# Strace

Syzkaller can be instructed to execute programs under
[strace](https://strace.io/) and capture the output.

If the `strace_bin` is set to an `strace` binary, syzkaller will automatically
run each reproducer it managed to find under the `strace` binary.

* If a syz-manager is attached to a `dashboard`, syzkaller will upload the
  resulting output as a normal log file if the generated reproducer still
  managed to produce the same crash.
* Otherwise, the output of strace will be saved to a separate file and will be
  accessible through the syz-manager's web interface.

## How to compile the strace binary

It is safer to compile `strace` as a statically linked binary in order to
prevent problems with mismatching libc versions on the kernel image used for
fuzzing.

```
git clone https://github.com/strace/strace.git
cd strace
./bootstrap
./configure --enable-mpers=no LDFLAGS='-static -pthread'
make -j`nproc`
```

The resulting binary can be found at `src/strace`.

## syz-crush

It's possible to instruct `syz-crush` to run the attached repro under strace. In
order to do so, make sure `strace_bin` is specified in the syz-manager config
file and pass an extra `-strace` argument to the command arguments.

## syz-repro

If `-strace file-name.log` is appended to the `syz-repro`'s arguments, the tool
will run the resulting repro (if it managed to generate one) under strace and
save its output.

---

### Syscall Descriptions (`docs/syscall_descriptions.md`)

# Syscall descriptions

`syzkaller` uses declarative description of syscall interfaces to manipulate
programs (sequences of syscalls). Below you can see (hopefully self-explanatory)
excerpt from the descriptions:

```
open(file filename, flags flags[open_flags], mode flags[open_mode]) fd
read(fd fd, buf buffer[out], count len[buf])
close(fd fd)
open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH
```

The descriptions are contained in `sys/$OS/*.txt` files.
For example see the [sys/linux/dev_snd_midi.txt](/sys/linux/dev_snd_midi.txt) file
for descriptions of the Linux MIDI interfaces.

A more formal description of the description syntax can be found [here](syscall_descriptions_syntax.md).

## Programs

The translated descriptions are then used to generate, mutate, execute, minimize, serialize
and deserialize programs. A program is a sequences of syscalls with concrete values for arguments.
Here is an example (of a textual representation) of a program:

```
r0 = open(&(0x7f0000000000)="./file0", 0x3, 0x9)
read(r0, &(0x7f0000000000), 42)
close(r0)
```

For actual manipulations `syzkaller` uses in-memory AST-like representation consisting of
`Call` and `Arg` values defined in [prog/prog.go](/prog/prog.go). That representation is used to
[analyze](/prog/analysis.go), [generate](/prog/rand.go), [mutate](/prog/mutation.go),
[minimize](/prog/minimization.go), [validate](/prog/validation.go), etc programs.

The in-memory representation can be [transformed](/prog/encoding.go) to/from
textual form to store in on-disk corpus, show to humans, etc.

There is also another [binary representation](/prog/decodeexec.go)
of the programs (called `exec`), that is much simpler, does not contain rich type information (irreversible)
and is used for actual execution (interpretation) of programs by [executor](/executor/executor.cc).

## Describing new system calls

This section describes how to extend syzkaller to allow fuzz testing of more kernel interfaces.
This is particularly useful for kernel developers who are proposing new system calls.

Currently all syscall descriptions are manually-written. There is an
[open issue](https://github.com/google/syzkaller/issues/590) to provide some aid
for this process and some ongoing work, but we are not there yet to have a
fully-automated way to generate descriptions.
There is a helper [headerparser](headerparser_usage.md) utility that can auto-generate
some parts of descriptions from header files. Visual Studio Code has [syz-lang extension](https://marketplace.visualstudio.com/items?itemName=AndreyArtemiev.syzlang-extension&ssr=false#overview) for highlighting syntax.

To enable fuzzing of a new kernel interface:

1. Study the interface, find out which syscalls are required to use it. Sometimes there is nothing besides the source code, but here are some things that may help:

   - Searching the Internet for the interface name and/or some unique constants.
   - Grepping Documentation/ dir in the kernel.
   - Searching tools/testing/ dir in the kernel.
   - Looking for large comment blocks in the source code.
   - Finding commit that added the interface via `git blame` or `git log` and reading the commit description.
   - Reading source code of or tracing libraries or applications that are known to use this interface.

2. Using [syntax documentation](syscall_descriptions_syntax.md) and
   [existing descriptions](/sys/linux/) as an example, add a declarative
   description of this interface to the appropriate file:

    - `sys/linux/<subsystem>.txt` files hold system calls for particular kernel
      subsystems, for example [bpf.txt](/sys/linux/bpf.txt) or [socket.txt](/sys/linux/socket.txt).
    - [sys/linux/sys.txt](/sys/linux/sys.txt) holds descriptions for more general system calls.
    - An entirely new subsystem can be added as a new `sys/linux/<new>.txt` file.
    - If subsystem descriptions are split across multiple files, prefix the name of each file with the name of the subsystem (e.g. use `dev_*.txt` for descriptions of `/dev/` devices, use `socket_*.txt` for sockets, etc).

3. After adding/changing descriptions run:

    ``` bash
    make extract TARGETOS=linux SOURCEDIR=$KSRC
    make generate
    make
    ```

4. Run syzkaller. Make sure that the newly added interface in being reached by
   syzkaller using the [coverage](coverage.md) information page.

In the instructions above `make extract` generates/updates the `*.const` files.
`$KSRC` should point to the _latest_ kernel checkout.\
_Note_: for Linux the _latest_ kernel checkout generally means the
[mainline](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/) tree.\
However, in some cases we add descriptions for interfaces that are not in the mainline tree yet,
so if `make extract` complains about missing header files or constants undefined on all architectures,
try to use the latest [linux-next](https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/)
tree (or if it happens to be broken at the moment, try a slightly older linux-next tree).\
_Note_: `make extract` overwrites `.config` in `$KSRC` and `mrproper`'s it.
_Note_: `*.const` files are checked-in with the `*.txt` changes in the same commit.

Then `make generate` updates generated code and `make` rebuilds binaries.\
Note: `make generate` does not require any kernel sources, native compilers, etc
and is pure text processing.
Note: `make generate` also updates the SYZ_REVISION under `executor/defs.h`, which
is required for machine check while running syz-manager. This should be taken care
of especially if you are trying to rebase with your own change on syscall description.

Note: `make extract` extracts constants for all architectures which requires
installed cross-compilers. If you get errors about missing compilers/libraries,
try `sudo make install_prerequisites` or install equivalent package for your distro.
Note: `sudo make install_prerequisites` will success even with some package failed to
install, `sudo apt-get update && sudo apt-get upgrade` might be required to make this
more efficient.

If you want to fuzz only the new subsystem that you described locally, you may
find the `enable_syscalls` configuration parameter useful to specifically target
the new system calls. All system calls in the `enable_syscalls` list
will be enabled if their requirements are met (ie. if they are supported
in the target machine and any other system calls that need to run in
order to provide inputs for them are also enabled). You can also include
wildcard definitions to enable multiple system calls in a single line,
for example: `"ioctl"` will enable all the described ioctls syscalls
that have their requirements met, ``"ioctl$UDMABUF_CREATE"`` enables
only that particular ioctl call, ``"write$UHID_*"`` enables all write
system calls that start with that description identifier.

When updating existing syzkaller descriptions, note, that unless there's a drastic
change in descriptions for a particular syscall, the programs that are already in
the corpus will be kept there, unless you manually clear them out (for example by
removing the `corpus.db` file).

<div id="tips"/>

## Description tips and FAQ

<div id="names"/>

### Syscall, struct, field, flags names

Stick with existing kernel names for things, don't invent new names if possible.

Following established naming conventions provides the following benefits:
(1) consistency and familiarity of names used across kernel interfaces,
which also enables searching kernel sources for related names; and
(2) enable static checking of descriptions (e.g. missed flags or mistyped fields)
with [syz-check](/tools/syz-check/check.go).

For example, if there is an existing enum `v4l2_buf_type` in the kernel headers,
use this name for flags in descriptions as well. The same for structs, unions,
fields, etc. For syscall and struct variants, append the variant name after the `$` sign.
For example, `fcntl$F_GET_RW_HINT`, `ioctl$FIOCLEX`, `setsockopt$SO_TIMESTAMP`.

<div id="ordering"/>

### Resources for syscall ordering

Resources and resource directions (`in`, `out`, `inout`) impose implicit ordering
constraints on involved syscalls.

If a syscall accepts a resource of a particular type (e.g. has `fd_cdrom` as an input),
then it will be generally placed after a syscall that has this resource as output,
so that the resource value can be passed between syscalls. For example:

```
r0 = openat$cdrom(...)
ioctl$CDROMPAUSE(r0, 0x123)
close(r0)
```

Syscall arguments are always `in`, return values are `out` and pointer indirections
have explicit direction as `ptr` type attribute. Also, it is possible to specify
direction attribute individually for struct fields to account for more complex
producer/consumer scenarios with structs that include both input/output resources.

<div id="values"/>

### Use of unexpected/undeclared values

When specifying integer/string flags or integer fields stick with the official expected values only.

Commonly, bugs are triggered by unexpected inputs. With that in mind, it can be too tempting to introduce
some unexpected values to descriptions (e.g. `-1` or `INT_MAX`). This is not encouraged for several reasons.
First, this is a cross-cutting aspect and these special unexpected values are applicable to just
any flags and integer fields. Manually specifying them thousands of times is not scalable and
is not maintainable. Second, It's hard for the fuzzer to come up with correct complex syscall sequences,
and the descriptions are meant to help with this. Coming up with unexpected integer values is easy
and the fuzzer does not need help here. Overall the idea is to improve the generic fuzzer logic
to handle these cases better, which will help all descriptions, rather than over-specializing each
individual integer separately. Fuzzer already has several tricks to deal with this, e.g. comparison
operand value interception and list of typical magic values.

Note: some values for flags may be undocumented only as an oversight. These values should be added to descriptions.

<div id="flags"/>

### Flags/enums

The `flags` type is used for all of:

 - sets of mutually exclusive values, where only one of them should be chosen (like C enum);
 - sets of bit flags, where multiple values can be combined with bitwise OR (like mmap flags);
 - any combination of the above.

The fuzzer has logic to distinguish enums and bit flags, and generates values
accordingly. So the general guideline is just to enumerate the meaningful values
in `flags` without adding any "special" values to "help" the current fuzzer logic.
When/if the fuzzer logic changes/improves, these manual additions may become
unnecessary, or, worse, interfere with the fuzzer ability to generate good values.

<div id="order"/>

### Declaration order

`syzlang` does not require declaring entities before use (like C/C++ does), entities can refer to entities
declared later (like in Go). It's recommended to declare things in the order of importance so that the reader
sees the most important things first and then proceeds to finer and finer implementation details. For example,
system calls usually should go before flag declarations used in these system calls. Note: this order is usually
the exact opposite of how things are declared in C: the least important things go first.

## Description compilation internals

The process of compiling the textual syscall descriptions into machine-usable
form used by `syzkaller` to actually generate programs consists of 2 steps.

The first step is extraction of values of symbolic constants from kernel sources using
[syz-extract](/sys/syz-extract) utility. `syz-extract` generates a small C program that
includes kernel headers referenced by `include` directives, defines macros as specified
by `define` directives and prints values of symbolic constants.
Results are stored in `.const` files, one per arch.
For example, [sys/linux/dev_ptmx.txt](/sys/linux/dev_ptmx.txt) is translated into
[sys/linux/dev_ptmx.txt.const](/sys/linux/dev_ptmx.txt.const).

The second step is translation of descriptions into Go code using
[syz-sysgen](/sys/syz-sysgen) utility (the actual compiler code lives in
[pkg/ast](/pkg/ast/) and [pkg/compiler](/pkg/compiler/)).
This step uses syscall descriptions and the const files generated during the first step
and produces instantiations of `Syscall` and `Type` types defined in [prog/types.go](/prog/types.go).
You can see an example of the compiler output for Linux/AMD64 in `sys/linux/gen/amd64.go`.
This step also generates some minimal syscall metadata for C++ code in `executor/syscalls.h`.

## Non-mainline subsystems

`make extract` extracts constants for all `*.txt` files and for all supported architectures.
This may not work for subsystems that are not present in mainline kernel or if you have
problems with native kernel compilers, etc. In such cases the `syz-extract` utility
used by `make extract` can be run manually for single file/arch as:

```
make bin/syz-extract
bin/syz-extract -os linux -arch $ARCH -sourcedir $KSRC -builddir $LINUXBLD <new>.txt
make generate
make
```

`$ARCH` is one of `amd64`, `386` `arm64`, `arm`, `ppc64le`, `mips64le`.
If the subsystem is supported on several architectures, then run `syz-extract` for each arch.
`$KSRC` should point to kernel source checkout, which is configured for the
corresponding arch (i.e. you need to run `make ARCH=arch someconfig && make ARCH=arch` there first,
remember to add `CROSS_COMPILE=arm-linux-gnueabi-/aarch64-linux-gnu-/powerpc64le-linux-gnu-` if needed).
If the kernel was built into a separate directory (with `make O=output_dir`, remember to put .config
into output_dir, this will be helpful if you'd like to work on different arch at the same time)
then also set `$LINUXBLD` to the location of the build directory.

<div id="testing"/>

### Testing of descriptions

Descriptions themselves may contain bugs. After running `syz-manager` with the new descriptions
it's always useful to check the kernel code coverage report available in the `syz-manager` web UI.
The report allows to assess if everything one expects to be covered is in fact covered,
and if not, where the fuzzer gets stuck. However, this is a useful but quite indirect assessment
of the descriptions correctness. The fuzzer may get around some bugs in the descriptions by diverging
from what the descriptions say, but it makes it considerably harder for the fuzzer to progress.

Tests stored in `sys/OS/test/*` provide a more direct testing of the descriptions. Each test is just
a program with checked syscall return values. The syntax of the programs is briefly described [here](program_syntax.md).
You can also look at the [existing examples](/sys/linux/test) and at the program [deserialization code](/prog/encoding.go).
`AUTO` keyword can be used as a value for consts and pointers, for pointers it will lead to
some reasonable sequential allocation of memory addresses.

It's always good to add a test at least for "the main successful scenario" for the subsystem.
It will ensure that the descriptions are actually correct and that it's possible for the fuzzer
to come up with the successful scenario. See [io_uring test](/sys/linux/test/io_uring) as a good example.

The tests can be run with the `run-tests` functionality of `syz-manager`:
```
make && bin/syz-manager -config manager.config -mode run-tests
```
It will boot multiple VMs and runs these tests in different execution modes inside of the VMs.

However, the full run takes significant time, so while developing the test, it's more handy to run it
using the `syz-execprog` utility. To run the test, copy `syz-execprog`, `syz-executor` and the test
into a manually booted VM and then run the following command inside of the VM:
```
syz-execprog -debug -threaded=0 mytest
```
It will show results of all executed syscalls. It's also handy for manual debugging of pseudo-syscall code:
if you add some temporal `debug` calls to the pseudo-syscall, `syz-execprog -debug` will show their output.

The test syntax can be checked by running:
```
go test -run=TestParsing ./pkg/runtest
```

---

### Syscall Descriptions Syntax (`docs/syscall_descriptions_syntax.md`)

# Syscall description language

aka `syzlang` (`[siːzˈlæŋg]`)

Pseudo-formal grammar of syscall description:

```
syscallname "(" [arg ["," arg]*] ")" [type] ["(" attribute* ")"]
arg = argname type
argname = identifier
type = typename [ "[" type-options "]" ]
typename = "const" | "intN" | "intptr" | "flags" | "array" | "ptr" |
	   "string" | "filename" | "glob" | "len" |
	   "bytesize" | "bytesizeN" | "bitsize" | "vma" | "proc" |
	   "compressed_image"
type-options = [type-opt ["," type-opt]]
```

common type-options include:

```
"opt" - the argument is optional (like mmap fd argument, or accept peer argument)
```

rest of the type-options are type-specific:

```
/* Detailed source-code truncated for AI context efficiency. */
```

flags/len/flags also have trailing underlying type type-option when used in structs/unions/pointers.

Flags are described as:

```
flagname = const ["," const]*
```

or for string flags as:

```
flagname = "\"" literal "\"" ["," "\"" literal "\""]*
```

Call attributes are:

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Ints

`int8`, `int16`, `int32` and `int64` denote an integer of the corresponding size.
`intptr` denotes a pointer-sized integer, i.e. C `long` type.

By appending `be` suffix (e.g. `int16be`) integers become big-endian.

It's possible to specify a range of values for an integer in the format of `int32[0:100]` or `int32[0:4096, 512]` for a 512-aligned int.

Integers can also take a reference to flags description or a value as its first type-option.
In that case, the alignment parameter is not supported.

To denote a bitfield of size N use `int64:N`.

It's possible to use these various kinds of ints as base types for `const`, `flags`, `len` and `proc`.

```
example_struct {
	f0	int8			# random 1-byte integer
	f1	const[0x42, int16be]	# const 2-byte integer with value 0x4200 (big-endian 0x42)
	f2	int32[0:100]		# random 4-byte integer with values from 0 to 100 inclusive
	f3	int32[1:10, 2]		# random 4-byte integer with values {1, 3, 5, 7, 9}
	f4	int64:20		# random 20-bit bitfield
	f5	int8[10]		# const 1-byte integer with value 10
	f6	int32[flagname]		# random 4-byte integer from the set of values referenced by flagname
}
```

## Structs

Structs are described as:

```
structname "{" "\n"
	(fieldname type ("(" fieldattribute* ")")? (if[expression])? "\n")+
"}" ("[" attribute* "]")?
```

Fields can have attributes specified in parentheses after the field, independent
of their type. `in/out/inout` attribute specify per-field direction, for example:

```
foo {
	field0	const[1, int32]	(in)
	field1	int32		(inout)
	field2	fd		(out)
}
```

You may specify conditions that determine whether a field will be included:

```
foo {
	field0	int32
	field1	int32 (if[value[field0] == 0x1])
}
```

See [the corresponding section](syscall_descriptions_syntax.md#conditional-fields)
for more details.

`out_overlay` attribute allows to have separate input and output layouts for the struct.
Fields before the `out_overlay` field are input, fields starting from `out_overlay` are output.
Input and output fields overlap in memory (both start from the beginning of the struct in memory).
For example:

```
foo {
	in0	const[1, int32]
	in1	flags[bar, int8]
	in2	ptr[in, string]
	out0	fd	(out_overlay)
	out1	int32
}
```

Structs can have attributes specified in square brackets after the struct.
Attributes are:

- `packed`: the struct does not have paddings between fields and has alignment 1; this is similar to GNU C `__attribute__((packed))`; struct alignment can be overridden with `align` attribute
- `align[N]`: the struct has alignment N and padded up to multiple of `N`; contents of the padding are unspecified (though, frequently are zeros); similar to GNU C `__attribute__((aligned(N)))`
- `size[N]`: the struct is padded up to the specified size `N`; contents of the padding are unspecified (though, frequently are zeros)

## Unions

Unions are described as:

```
unionname "[" "\n"
	(fieldname type (if[expression])? "\n")+
"]" ("[" attribute* "]")?
```

During fuzzing, syzkaller randomly picks one of the union options.

You may also specify conditions that determine whether the corresponding
option may or may not be selected, depending on values of other fields. See
[the corresponding section](syscall_descriptions_syntax.md#conditional-fields)
for more details.

Unions can have attributes specified in square brackets after the union.
Attributes are:

- `varlen`: union size is the size of the particular chosen option (not statically known); without this attribute unions are statically sized as maximum of all options (similar to C unions)
- `size[N]`: the union is padded up to the specified size `N`; contents of the padding are unspecified (though, frequently are zeros)

## Resources

Resources represent values that need to be passed from output of one syscall to input of another syscall. For example, `close` syscall requires an input value (fd) previously returned by `open` or `pipe` syscall. To achieve this, `fd` is declared as a resource. This is a way of modelling dependencies between syscalls, as defining a syscall as the producer of a resource and another syscall as the consumer defines a loose sense of ordering between them. Resources are described as:

```
"resource" identifier "[" underlying_type "]" [ ":" const ("," const)* ]
```

`underlying_type` is either one of `int8`, `int16`, `int32`, `int64`, `intptr` or another resource (which models inheritance, for example, a socket is a subtype of fd). The optional set of constants represent resource special values, for example, `0xffffffffffffffff` (-1) for "no fd", or `AT_FDCWD` for "the current dir". Special values are used once in a while as resource values. If no special values specified, special value of `0` is used. Resources can then be used as types, for example:

```
resource fd[int32]: 0xffffffffffffffff, AT_FDCWD, 1000000
resource sock[fd]
resource sock_unix[sock]

socket(...) sock
accept(fd sock, ...) sock
listen(fd sock, backlog int32)
```

Resources don't have to be necessarily returned by a syscall. They can be used as any other data type. For example:

```
resource my_resource[int32]

request_producer(..., arg ptr[out, my_resource])
request_consumer(..., arg ptr[inout, test_struct])

test_struct {
	...
	attr	my_resource
}
```

For more complex producer/consumer scenarios, field attributes can be utilized.
For example:

```
resource my_resource_1[int32]
resource my_resource_2[int32]

request_produce1_consume2(..., arg ptr[inout, test_struct])

test_struct {
	...
	field0	my_resource_1	(out)
	field1	my_resource_2	(in)
}
```

Each resource type must be "produced" (used as an output) by at least one syscall
(outside of unions and optional pointers) and "consumed" (used as an input)
by at least one syscall.

## Type Aliases

Complex types that are often repeated can be given short type aliases using the
following syntax:

```
type identifier underlying_type
```

For example:

```
type signalno int32[0:65]
type net_port proc[20000, 4, int16be]
```

Then, type alias can be used instead of the underlying type in any contexts.
Underlying type needs to be described as if it's a struct field, that is,
with the base type if it's required. However, type alias can be used as syscall
arguments as well. Underlying types are currently restricted to integer types,
`ptr`, `ptr64`, `const`, `flags` and `proc` types.

There are some builtin type aliases:

```
type bool8	int8[0:1]
type bool16	int16[0:1]
type bool32	int32[0:1]
type bool64	int64[0:1]
type boolptr	intptr[0:1]

type fileoff[BASE] BASE

type filename string[filename]

type buffer[DIR] ptr[DIR, array[int8]]
```

## Type Templates

Type templates can be declared as follows:

```
type buffer[DIR] ptr[DIR, array[int8]]
type fileoff[BASE] BASE
type nlattr[TYPE, PAYLOAD] {
	nla_len		len[parent, int16]
	nla_type	const[TYPE, int16]
	payload		PAYLOAD
} [align_4]
```

and later used as follows:

```
syscall(a buffer[in], b fileoff[int64], c ptr[in, nlattr[FOO, int32]])
```

There is builtin type template `optional` defined as:

```
type optional[T] [
	val	T
	void	void
] [varlen]
```

## Length

You can specify length of a particular field in struct or a named argument by
using `len`, `bytesize` and `bitsize` types, for example:

```
write(fd fd, buf ptr[in, array[int8]], count len[buf])

sock_fprog {
	len	len[filter, int16]
	filter	ptr[in, array[sock_filter]]
}
```

If `len`'s argument is a pointer, then the length of the pointee argument is used.

To denote the length of a field in N-byte words use `bytesizeN`, possible values
for N are 1, 2, 4 and 8.

To denote the length of the parent struct, you can use `len[parent, int8]`.
To denote the length of the higher level parent when structs are embedded into
one another, you can specify the type name of the particular parent:

```
s1 {
    f0      len[s2]  # length of s2
}

s2 {
    f0      s1
    f1      array[int32]
    f2      len[parent, int32]
}
```

`len` argument can also be a path expression which allows more complex
addressing. Path expressions are similar to C field references, but also allow
referencing parent and sibling elements. A special reference `syscall` used
in the beginning of the path allows to refer directly to the syscall arguments.
For example:

```
s1 {
	a	ptr[in, s2]
	b	ptr[in, s3]
	c	array[int8]
}

s2 {
	d	array[int8]
}

s3 {
# This refers to the array c in the parent s1.
	e	len[s1:c, int32]
# This refers to the array d in the sibling s2.
	f	len[s1:a:d, int32]
# This refers to the array k in the child s4.
	g	len[i:j, int32]
# This refers to syscall argument l.
	h	len[syscall:l, int32]
	i	ptr[in, s4]
}

s4 {
	j	array[int8]
}

foo(k ptr[in, s1], l ptr[in, array[int8]])
```

## Proc

The `proc` type can be used to denote per process integers.
The idea is to have a separate range of values for each executor, so they don't interfere.

The simplest example is a port number.
The `proc[20000, 4, int16be]` type means that we want to generate an `int16be`
integer starting from `20000` and assign `4` values for each process.
As a result the executor number `n` will get values in the `[20000 + n * 4, 20000 + (n + 1) * 4)` range.

## Integer Constants

Integer constants can be specified as decimal literals, as `0x`-prefixed
hex literals, as `'`-surrounded char literals, or as symbolic constants
extracted from kernel headers or defined by `define` directives. For example:

```
foo(a const[10], b const[-10])
foo(a const[0xabcd])
foo(a int8['a':'z'])
foo(a const[PATH_MAX])
foo(a int32[PATH_MAX])
foo(a ptr[in, array[int8, MY_PATH_MAX]])
define MY_PATH_MAX	PATH_MAX + 2
```

## Conditional fields

### In structures

In syzlang, it's possible to specify a condition for every struct field that
determines whether the field should be included or omitted:

```
header_fields {
  magic       const[0xabcd, int16]
  haveInteger int8
} [packed]

packet {
  header  header_fields
  integer int64  (if[value[header:haveInteger] == 0x1])
  body    array[int8]
} [packed]

some_call(a ptr[in, packet])
```

In this example, the `packet` structure will include the field `integer` only
if `header.haveInteger == 1`. In memory, `packet` will have the following
layout:

| header.magic = 0xabcd | header.haveInteger = 0x1 | integer | body |
| --------------------- | ------------------------ | ------- | ---- |

That corresponds to e.g. the following program:

```
some_call(&AUTO={{AUTO, 0x1}, @value=0xabcd, []})
```

If `header.haveInteger` is not `1`, syzkaller will just pretend that the field
`integer` does not exist.

```
some_call(&AUTO={{AUTO, 0x0}, @void, []})
```

| header.magic = 0xabcd | header.haveInteger = 0x0 | body |
| --------------------- | ------------------------ | ---- |

Every conditional field is assumed to be of variable length and so is the struct
to which this field belongs.

When a variable length field appears in the middle of a structure, the structure
must be marked with `[packed].`

Conditions on bitfields are prohibited:

```
struct {
  f0 int
  f1 int:3 (if[value[f0] == 0x1])  # It will not compile.
}
```

But you may reference bitfields in your conditions:

```
struct {
  f0 int:1
  f1 int:7
  f2 int   (if[value[f0] == value[f1]])
} [packed]
```

### In unions

Let's consider the following example.

```
struct {
  type int
  body alternatives
}

alternatives [
  int     int64 (if[value[struct:type] == 0x1])
  arr     array[int64, 5] (if[value[struct:type] == 0x2])
  default int32
] [varlen]

some_call(a ptr[in, struct])
```

In this case, the union option will be selected depending on the value of the
`type` field. For example, if `type` is `0x1`, then it can be either `int` or
`default`:

```
some_call(&AUTO={0x1, @int=0x123})
some_call(&AUTO={0x1, @default=0x123})
```

If `type` is `0x2`, it can be either `arr` or `default`.

If `type` is neither `0x1` nor `0x2`, syzkaller may only select `default`:

```
some_call(&AUTO={0x0, @default=0xabcd})
```

To ensure that a union can always be constructed, the last union field **must always
have no condition**.

Thus, the following definition would fail to compile:

```
alternatives [
  int int64 (if[value[struct:type] == 0x1])
  arr array[int64, 5] (if[value[struct:type] == 0x1])
] [varlen]
```

During prog mutation and generation syzkaller will select a random union field
whose condition is satisfied.

### Expression syntax

Currently, only `==`, `!=`, `&` and `||` operators are supported. However, the
functionality was designed in such a way that adding more operators is easy.
Feel free to file a GitHub issue or write us an email in case it's needed.

Expressions are evaluated as `int64` values. If the final result of an
expression is not 0, it's assumed to be satisfied.

If you want to reference a field's value, you can do it via
`value[path:to:field]`, which is similar to the `len[]` argument.

```
sub_struct {
  f0 int
  # Reference a field in a parent struct.
  f1 int (if[value[struct:f2]]) # Same as if[value[struct:f2] != 0].
}

struct {
  f2 int
  f3 sub_struct
  f4 int (if[value[f2] == 0x2]) # Reference a sibling field.
  f5 int (if[value[f3:f0] == 0x1]) # Reference a nested field.
  f6 int (if[value[f3:f0] == 0x1 || value[f3:f0] == 0x2]) # Reference a nested field which either equals to 0x1 or 0x2.
} [packed]

call(a ptr[in, struct])
```

The referenced field must be of integer type and there must be no
conditional fields in the path to it. For example, the following
descriptions will not compile.

```
struct {
  f0 int
  f1 int (if[value[f0] == 0x1])
  f2 int (if[value[f1] == 0x1])
}
```

You may also reference constants in expressions:

```
struct {
  f0 int
  f1 int
  f2 int (if[value[f0] & SOME_CONST == OTHER_CONST])
}
```

## Meta

Description files can also contain `meta` directives that specify meta-information for the whole file.

```
meta noextract
```

Tells `make extract` to not extract constants for this file.
Though, `syz-extract` can still be invoked manually on this file.

```
meta arches["arch1", "arch2"]
```

Restricts this file only to the given set of architectures.
`make extract` and `make generate` will not use it on other architectures.

## Misc

Description files also contain `include` directives that refer to Linux kernel header files,
`incdir` directives that refer to custom Linux kernel header directories
and `define` directives that define symbolic constant values.

The syzkaller executor defines some [pseudo system calls](./pseudo_syscalls.md)
that can be used as any other syscall in a description file. These pseudo
system calls expand to literal C code and can perform user-defined
custom actions. You can find some examples in
[executor/common_linux.h](../executor/common_linux.h).

Also see [tips](syscall_descriptions.md#tips) on writing good descriptions.

---

### Syz Dungeon (`docs/syz-dungeon.md`)

# Syzkaller Dungeon

## Overview
The **Syzkaller Dungeon** (/syz-dungeon) ranks contributors (kernel developers) based on their achievements in fixing bugs found by Syzkaller. It uses a retro "terminal hacker" aesthetic with green-on-black text and ASCII art.

Note: Currently, the Dungeon is only available for the `upstream` namespace.

## Core Mechanics

### 1. Character Generation
Each contributor is assigned a "Character" based on their bug fixing history during a specific time period.

**Eras (Time Ranges)**
The Dungeon provides two separate views or "Eras" for statistics:
*   **1 Year (Default)**: A rolling window of exactly the last 365 days from today.
*   **All Time**: A comprehensive view of all bugs fixed since the beginning of tracking.

*   **Era Scoping & Decay**: In the 1-Year Era, the **entire character sheet** (including XP, Level, Class, Badges, and Stats like STR/INT/WIS) is dynamically recalculated based exclusively on the bugs currently within the 365-day rolling window. As fixes age out of the window, these attributes decay. In the All-Time Era, bugs never fall out of the window, providing a permanent, non-decaying global view of the contributor's achievements.
*   **Eligibility**: Bugs must have landed a fix commit within the given period.
    *   **Criteria**: Includes both fully fixed bugs (on the **Fixed** page) and partially fixed bugs (still **Open** but with upstream commits landing in the given period).
    *   **Co-Authored Fixes**: If a bug is resolved by multiple commits, **all unique commit authors** recorded in the bug's history are independently granted 1 bug count and the associated XP/Score. This means a single bug can boost multiple heroes simultaneously, occasionally resulting in leaderboard totals that are higher than naive SQL queries that only map one author per bug.
    *   **Date**: The "date fixed" is determined strictly by `FixTime` (when the fix commit was discovered). `Closed` date is ignored.
*   **Matching**: Identity resolution uses **strict exact matching** on the lowercase **Email** address (`Author` field).
    *   **No Email Grouping**: Contributors using different email addresses (e.g., `@gmail.com` vs a corporate domain) are treated as separate characters.
*   **Hero ID**: Each hero is assigned a stable, 16-character hexadecimal ID. This is generated by calculating the hash of their **lowercased email address** (using SHA-1) and extracting the first 16 characters of the hexadecimal string representation of the hash. This provides a secure, deterministic identifier for individual Hero Profile Pages without exposing raw email addresses in URLs.
*   **Hero Name**: Derived from the `AuthorName` field in the Datastore `CommitInfo` entity, bound to the matched Email.
        *   If a contributor uses multiple names for the same email (e.g. `John Doe` vs `J. Doe`), the system deterministically assigns the **most frequently used name** to the Hero. Ties are broken alphabetically.
    *   **Fallback**: If an email *never* encounters a valid author name across all of its recorded bugs, the hero's name will gracefully fall back to displaying just the raw email address.
*   **Bots**: Bots are implicitly excluded as only humans land fixing commits in the Linux kernel (even bot-generated patches are signed by a human).
*   **Heroic Title**: An adjective is appended to the name based on the first letter, e.g., "Eric Dumazet The Epic".
    *   **Full List**:
        *   `A`: The Arcane
        *   `B`: The Brave
        *   `C`: The Cosmic
        *   `D`: The Devoted
        *   `E`: The Epic
        *   `F`: The Fierce
        *   `G`: The Gallant
        *   `H`: The Heroic
        *   `I`: The Immortal
        *   `J`: The Just
        *   `K`: The Knightly
        *   `L`: The Legendary
        *   `M`: The Mystic
        *   `N`: The Noble
        *   `O`: The Omniscient
        *   `P`: The Prime
        *   `Q`: The Quick
        *   `R`: The Radiant
        *   `S`: The Sacred
        *   `T`: The Titan
        *   `U`: The Undying
        *   `V`: The Valiant
        *   `W`: The Wise
        *   `X`: The Xenial
        *   `Y`: The Youthful
        *   `Z`: The Zealous
    *   *Identity:* Defined by the dynamic **Hero Name** calculated above (which selects the first valid name encountered for the email, or falls back to the raw email).
        *   **No Title for Fallbacks**: If the Hero Name had to fall back to the raw Email because no valid name was found across their commits, **no heroic title modifier is added**. The hero is simply displayed as their address (e.g. `raw.email@domain.com`).
    *   **Logic**: The title is determined by the **first letter of the resolved name**.
    *   **Normalization**: The first letter is **lowercased** before lookup.
    *   **Map**: 26 adjectives corresponding to 'a'-'z'.
    *   **Fallback**: If the name begins with a non-alphabetic character (numbers, symbols, or non-Latin scripts not in the a-z map), the title defaults to **"The Adventurer"**. This fallback applies universally without transliteration (no UTF-8 awareness).
    *   *Note:* There is currently no mechanism for manual identity overrides or merging separate profiles.
*   **Class**: Determined by analyzing the **existing tags** attached to the bug.
    *   **Multi-Class Credit**: A contributor receives exactly **1 point** for **every** subsystem tag present on a fixed bug. For example, a bug tagged with `net` and `mm` increments the contributor's count for both `net` and `mm` by 1.
    *   **Dynamic Class**: The "Main Class" is determined **after** calculating the totals for all valid bugs. The system finds the single subsystem tag that appears most frequently across all of the contributor's fixes, and assigns the Class corresponding to that winning tag.
    *   **Source**: Classes are determined by mapping the winning **tag** (subsystem) to the RPG categories below.
    *   **Weaver** (🕸️): Networking & BPF.
        *   Tags: `net`, `ipv4`, `ipv6`, `tcp`, `udp`, `sctp`, `bpf`, `wireless`, `bluetooth`, `can`, `tipc`, `nfc`, `bridge`, `netlink`.
    *   **Geomancer** (🏔️): Filesystems & Storage.
        *   Tags: `fs`, `ext4`, `btrfs`, `xfs`, `vfs`, `block`, `scsi`, `nvme`, `io-uring`, `fuse`, `overlayfs`.
    *   **Voidwalker** (🔮): Memory Management.
        *   Tags: `mm`, `kasan`, `slab`, `kcsan`, `kmemleak`.
    *   **Paladin** (🛡️): Security & Crypto.
        *   Tags: `security`, `selinux`, `apparmor`, `lsm`, `audit`, `keyrings`, `crypto`.
    *   **Bard** (🎻): Media, Sound, Input, Human Interface.
        *   Tags: `sound`, `usb`, `media`, `video`, `drm`, `gpu`, `input`, `hid`, `drivers` (generic).
    *   **Artificer** (🛠️): Hardware Buses & Infrastructure.
        *   Tags: `pci`, `i2c`, `spi`, `gpio`, `clk`, `pm`, `dmaengine`, `iio`, `rtc`, `watchdog`.
    *   **Warlock** (🌀): Virtualization.
        *   Tags: `kvm`, `xen`, `virt`, `hyperv`.
    *   **Rogue** (🗡️): Architecture Specific.
        *   Tags: `arch`, `arm`, `arm64`, `x86`, `riscv`, `s390`.
    *   **Druid** (🌿): Core Kernel & Sync.
        *   Tags: `kernel`, `sched`, `rcu`, `locking`, `trace`, `cgroups`.
    *   **Warrior** (⚔️): Default class for other subsystems or if **no tags** match any class.
    *   *Tie-Breaking:* If a contributor has multiple tags with the exact same highest frequency count, the **first subsystem tag alphabetically** is chosen as the winner. Warrior is only used if there are no specialized tags.

### 2. Experience (XP) Calculation
Score is calculated for each fixed bug:
*   **Base XP**: 100
*   **Boss Bonus**: 10% of crash count (Capped at 500 XP).
    *   Formula: `ceil(NumCrashes * 0.1)`
    *   *Note:* If the bug data is missing crash counts or has 0 crashes, this bonus is 0.
*   **Ancient Evil Bonus**: 1 XP for every day (measured as a precise 24-hour elapsed duration, i.e., `hours / 24`) the bug was open (Capped at 300 XP).
    *   *Note:* if `FirstTime` is missing, this bonus defaults to 0.
    *   *Floor:* If duration is negative (due to clock skew), it is treated as **0 days** (0 bonus XP). This prevents "negative XP".
*   **Windwalker Bonus**: +250 XP flat bonus if the bug was fixed within 7 days. This bonus defaults to 0 if either the `FirstTime` or `FixTime` timestamps are missing.
*   **Blind Bonus**: 150 XP if the bug had no reproducer (`ReproLevelNone`).

### 3. Leveling
*   **Level 1**: 0 XP
*   **Progressive Level Base**: 1,000 XP per level up to Level 50.
*   **Legendary Scaling**: Starting at Level 50, each subsequent level requires 500 *more* XP than the previous level's requirement (e.g., Level 50 -> 51 costs 1,500 XP, 51 -> 52 costs 2,000 XP).
*   **Mathematical Formula**: The total XP required to reach Level $N$, denoted as $TotalXP(N)$, is calculated strictly by the following piecewise function:
    *   For $N \le 50$: $TotalXP(N) = (N - 1) \times 1000$
    *   For $N > 50$: Let $m = N - 50$. The total XP is defined by the arithmetic series sum:
        $TotalXP(N) = 49000 + 1000m + 250m(m + 1)$
*   **Concrete Threshold Table**:
    *   `Level 1`: 0 XP
    *   `Level 2`: 1,000 XP
    *   `Level 49`: 48,000 XP
    *   `Level 50`: 49,000 XP
    *   `Level 51`: 50,500 XP
    *   `Level 52`: 52,500 XP
    *   `Level 53`: 55,000 XP
*   **Cap**: There is no hard level cap.
*   **Note**: Rapid leveling (e.g., jumping 2.5 levels from a single legendary bug fix) is **intentional** to reward high-impact contributions.

### 4. Inventory (Badges)
Contributors earn badges for specific achievements. **Badges are purely cosmetic** and do not affect XP or Rank.

**General Badge Rules:**
*   All string/title matching is **case-insensitive**.
*   Bugs missing `FirstTime` or `FixTime` fields cannot be evaluated and therefore do not count toward time-based badges.
*   **Dragon Vanquisher** (🐉): Fixed a bug with >1000 crashes.
*   **Necromancer** (💀): Fixed a bug open for >365 days.
*   **Diviner** (👁️): Fixed a bug with no reproducer.
*   **Windwalker** (🪽): Fixed a bug within **7 days** (measured as precise 24-hour duration chunks) of it being reported (based on `FirstTime`).
    *   *Logic:* `FixTime - FirstTime < 7 days`.
    *   *Data Integrity:* This calculation is **skipped** (badge not awarded) if either `FirstTime` or `FixTime` timestamps are missing.
*   **🔥 Hydra Hunter**: Fixed 10 or more bugs overall.
*   **🧌 Troll Crusher**: Fixed 50 or more bugs overall.
*   **🐙 Kraken Bane**: Fixed 100 or more bugs overall.
*   **👹 Demon Slayer**: Fixed 250 or more bugs overall.
*   **🔱 Leviathan Conqueror**: Fixed 500 or more bugs overall.
*   **🏺 Sealer**: Fixed a memory leak.
    *   *Logic:* Title or Fix Commit Title contains tokens `leak`, `leaks`, `memory-leak`, or `memory-leaks` (with word boundaries checking).
*   **📜 Keeper of Secrets**: Fixed an *infoleak* vulnerability.
    *   *Logic:* Title or Fix Commit Title contains `infoleak` (matched as a simple substring, without word boundaries or special character tokenization).
*   **⏳ Master of Time**: Fixed a time-related bug.
    *   *Logic:* Title or Fix Commit Title contains `time:` or `timer:` (matched as a simple substring, without word boundaries or special character tokenization, matching things like `hrtimer:` or `posix-timer:`).
*   **🛶 Pathfinder**: Fixed an *out-of-bounds* error. (String match: `out-of-bounds` anywhere in bug title/commit titles).
*   **🦄 Beast Tamer**: Fixed a *data race* condition. (String match: `data-race` anywhere in bug title/commit titles).
*   **⚒️ Armorer**: Fixed a *general protection fault*. (String match: `general protection fault` anywhere in bug title/commit titles).
*   **🪦 Grave Robber**: Fixed a *use-after-free* error. (String match: `use-after-free` anywhere in bug title/commit titles).
*   **🗝️ Locksmith**: Fixed a *locking* issue. (Matches tokens: `lock`, `deadlock`, `lockup`, `locking`, `mutex`, `unlock`, `locks`, `rwlock`, `spinlock` in bug title/commit titles).
*   **🕯️ Exorcist**: Fixed a *hung task* or *zombie process*. (String match: `hung task`, `task hung`, or `zombie` anywhere in bug title/commit titles).
*   **🕳️ Abyss Walker**: Fixed a *NULL pointer dereference*. (String match: `null-ptr-deref` or `null pointer` anywhere in bug title/commit titles).
*   **⚗️ Alchemist**: Fixed an *uninitialized value* bug. (String match: `uninit` or `kmsan` anywhere in bug title/commit titles).
*   **🪓 Executioner**: Fixed a *double free* bug. (String match: `double-free` or `double free` anywhere in bug title/commit titles).

### 5. General Rules

*   **Alphabetical Tie-Breakers**: Unless otherwise specified, all "alphabetical" sorting and tie-breaking used throughout the Dungeon (for Names, Kingdom Main Classes, Guilds Array, Kingdom Ranks, etc.) is strictly **case-sensitive** and **lexicographically ascending**. This guarantees absolute determinism derived from underlying ASCII/UTF-8 byte representations (e.g., uppercase 'Z' sorts before lowercase 'a').

### 6. Kingdoms

Players can view aggregate statistics via two toggles in the dashboard menu:

*   **Entities**: Choose between viewing the standard individual **Heroes** leaderboard, or the **Kingdoms** ranking.
*   **Kingdoms**: View aggregated points and heroic classes across different organizations playing the dungeon.
    *   Clicking a Kingdom's name takes you to the **Kingdom Profile Page** where you can see their overall Trophies, Hero Count, Total XP, and established Guilds.
    *   Employees are assigned to their company based on a curated list of email domains. The matching rule requires an **exact string match** against the entire portion of the email address following the `@` symbol (e.g., `developer@corp.company.com` will *not* match `company.com`).
        *   **The Google Kingdom**: `google.com`, `chromium.org`
        *   **The Red Hat Kingdom**: `redhat.com`
        *   **The Huawei Kingdom**: `huawei.com`, `hisilicon.com`
        *   **The Linux Foundation Kingdom**: `linuxfoundation.org`, `kernel.org`
        *   **The Meta Kingdom**: `meta.com`, `fb.com`
        *   **The Intel Kingdom**: `intel.com`, `linux.intel.com`
        *   **The AMD Kingdom**: `amd.com`
        *   **The ARM Kingdom**: `arm.com`
        *   **The Oracle Kingdom**: `oracle.com`
        *   **The SUSE Kingdom**: `suse.com`, `suse.de`, `suse.cz`
        *   **The Linaro Kingdom**: `linaro.org`
        *   **The Alibaba Kingdom**: `linux.alibaba.com`
        *   **The NVIDIA Kingdom**: `nvidia.com`, `mellanox.com`
        *   **The IBM Kingdom**: `linux.ibm.com`, `linux.vnet.ibm.com`
        *   **The Bytedance Kingdom**: `bytedance.com`
        *   **The Canonical Kingdom**: `canonical.com`, `ubuntu.com`
        *   **The Amazon Kingdom**: `amazon.com`, `amazon.de`, `amazon.co.uk`, `amazon.co.jp`
        *   **The Tencent Kingdom**: `tencent.com`
        *   **The Samsung Kingdom**: `samsung.com`
    *   Any hero not in the curated list belongs to `The Independent Mercenaries`.
    *   **Royal Champion**: A Kingdom's Royal Champion is determined by finding the single hero associated with that Kingdom who has the highest `Score` (XP) contribution in the given Era. The Champion's Name, XP contribution, and a link to their profile are featured on the Kingdom's Profile Page.
    *   **Total Hero XP**: A Kingdom's total `Score` is purely the combined sum of the `Score` of all its affiliated `Heroes`. This means all dynamic bug bonuses (like the Boss Bonus for crashes, Ancient Evil bonus for old bugs, etc.) earned by a hero directly benefit their aligned Kingdom. However, the Kingdom's hero count and specific class composition metric will correctly reflect all distinct individuals who participated. If the fix is co-authored by heroes from **different** Kingdoms, **both** Kingdoms independently receive full credit for the bug.
    *   **Trophy Deduplication**: To prevent double-counting, if a bug is resolved jointly by multiple heroes who belong to the **same** Kingdom, the Kingdom is credited exactly **1 Trophy** for resolving the bug.
    *   **Stats**: Kingdoms do not possess individual stats like STR, INT, or WIS.
    *   Instead of "Inventory" (Badges), Kingdoms display **"Guilds"**, which details the composition of Hero Classes based on the **total count of players** in the Kingdom (e.g., "3 Weavers", "1 Geomancer"). The array is sorted descending by the count of players, and then alphabetically by the resulting string representation in the event of a tie. Pluralization is handled simply: an `"s"` is appended to the Class Name if the player count is strictly greater than 1.
    *   **Sorting**: Kingdoms are ranked and sorted descending by their **Total XP** (Score). Ties are broken alphabetically by the Kingdom Name.
    *   **Territory Tiers**: A Kingdom evaluates its overall combined `Score` (XP) strictly into one of the following brackets, displaying an associated name and emoji. On the **Kingdom Profile** page, the tier icon is displayed prominently with the tier name below and an XP range tooltip. On the global **Leaderboard**, the tier emoji is displayed as an inline badge next to the Kingdom's name (with a tooltip revealing the tier name).
        *   0 - 49,999: Outpost (⛺)
        *   50,000 - 149,999: Barony (🏘️)
        *   150,000 - 499,999: Duchy (🏛️)
        *   500,000 - 999,999: Kingdom (🏰)
        *   1,000,000+: Empire (👑)


## Technical Implementation

### Backend (`dashboard/app/dungeon.go`)
*   **JSON API**: `/syz-dungeon?json=1` returns the **calculated scaled stats** (RPG range [3-30]) for `str`, `int`, `wis`.
*   **Endpoint**: `/syz-dungeon` (Leaderboard Overview)
*   **Hero Profile Endpoint**: `/syz-dungeon/hero/{id}` (Individual Hero Sheet)
    *   **Parameters**: Supports `?json=1` (JSON dump) and `?era=1y` or `?era=all` (defaults to `all`). Hero pages will display an interactive `[1 YEAR]` | `[ALL TIME]` toggle if the hero has contributions mapped into both era scopes.
    *   **Class Box**: Displays the hero's class emoji, name, and a tooltip containing the class's flavor text (description).
    *   **Attributes Box**: Displays the hero's STR, INT, and WIS properties. Hovering over each stat reveals a tooltip explaining its corresponding metric (e.g., "Max Crashes (Scaled)").
    *   **Badges Box**: Displays earned badges. Hovering over a badge reveals its name and an extended description characterizing the achievement.
    *   **Click-to-Copy ID**: The `ID` displayed in the footer is clickable and will copy the URL to the profile into the user's clipboard.
* **Data Source**: Queries the `Bug` entity in Google Cloud Datastore.
    * **Definition**: `dashboard/app/entities_datastore.go`
    * **Key Fields Used**:
        * `Namespace`, `Status`: For Datastore query filtering. (Note: Only the `upstream` namespace is currently supported).
        * *Logic:* `Status` must be Fixed (or Open if fixing commits are present).
        * *Index:* Requires composite index on `(Namespace, Status)` in `index.yaml`.
        * `FixTime`: To filter bugs within the given period (in **UTC**).
            *   *Decay:* Since the cache refreshes hourly, players viewing the 1-Year Era will see their entire character sheet—including stats, badges, levels, classes, and ranks—actively decay day-to-day as old bugs fall out of the 365-day window. **No notifications** are sent for level down; users monitor their status on the dashboard.
        * `Tags`: For Class determination (instead of Title).
        * `CommitInfo`: For authorship identification (`AuthorName` and `Author` fields).
        * `Title`: For "Sealer", "Keeper of Secrets", and "Master of Time" badge logic.
        * `NumCrashes`: For "Boss Bonus", "Dragon Slayer" badge, and **STR**.
        * `ReproLevel`: For "Blind Bonus", "Diviner" badge, and **INT**.
        * `FirstTime` & `FixTime`: For "Ancient Evil" bonus, "Windwalker"/"Necromancer" badges, and **WIS**.
* **Caching**: Results are cached in shared **App Engine Memcache** (using compressed JSON) for 1 hour. The cache is segregated by the viewer's `AccessLevel` so that privileged bug data (like undisclosed bugs visible to admins) does not leak to public viewers.
    *   *Warm-up/Preheating*: A cron job (`/cron/dungeon_preheat`) runs hourly to precompute and warm the cache for all access levels simultaneously, ensuring fast page loads for all users across multiple live instances.
* **Logic**:
    * **Identity Resolution**: Aggregates bugs strictly by the lowercased **Email** address.
        * *Rule:* "Linus Torvalds <email1>" and "Linus Torvalds <email2>" are treated as separate characters.
        * *Name Selection*: If an author uses multiple names for the same email address across different commits, the system assigns the **most frequently used name** to the Hero. Ties are broken alphabetically.
    * Determines the "Main Spec" (class) based on subsystem counts.
    * Calculates XP and assigns badges.
    * Sorts players by Score (descending), then Name (ascending), then Email (ascending).
    * **Pagination**: The backend server returns the complete active roster of players. The frontend JavaScript dynamically partitions the tables into interactive pages of 100 rows.

### Frontend (`dashboard/app/templates/dungeon.html`)
*   **Style**: Dark mode with `Courier New` / monospace font.
    *   Accent Color: Neon Green (`#0f0`).
    *   Banner: Retro pixel-art PNG image "SYZKALLER DUNGEON" (responsive, located at `/static/dungeon.png`).
* **Interactivity**:
    * **Hover Tooltips**: Hovering over a character row reveals a "Character Sheet":
        * **Desktop Users**: Appears on **Hover**.
        * **Mobile/Touch Users**: Appears on **Click/Tap**. (Tapping a row toggles the sheet; opening a new one closes the previous one).
        * **NAME**: "Name Adjective" (e.g., "Eric Dumazet The Epic")
        * **CLASS**: "Emoji (Class)" (e.g., "🕸️ (Weaver)")
        * **LEVEL**: Current Level
      *   **Stats Scaling**:
    *   Instead of raw counts, metrics are mapped to an RPG-like scale **[3, 30]** using a logarithmic function.
    *   **STR** (Strength): Based on **Max Crashes** of a single fixed bug.
        *   Formula: $STR = \min(30, \max(3, \lfloor 3 + 4 \times \log_{10}(\max(1, \text{MaxCrashes})) \rfloor))$
        *   *Example:* 1 crash = 3, 100 crashes = 11, 1,000,000 crashes = 27.
    *   **INT** (Intelligence): Based on total **Blind Fixes** (no reproducer).
        *   Formula: $INT = \min(30, \max(3, \lfloor 3 + 10 \times \log_{10}(\text{BlindFixes} + 1) \rfloor))$
        *   *Example:* 0 blind fixes = 3, 2 blind fixes = 7, 10 blind fixes = 13, 500 blind fixes = 30.
    *   **WIS** (Wisdom): Based on **Oldest Kill** (maximum duration of a **single** bug).
        *   Formula: $WIS = \min(30, \max(3, \lfloor 3 + 5 \times \log_{10}(\text{DaysOpen} + 1) \rfloor))$
        *   *Example:* 1 day = 4, 100 days = 13, 1000 days = 18, 250,000 days = 30.
    * **Inventory Tooltips**: Hovering over badges shows their name/description.

## Configuration
*   **JSON Output**: The endpoint supports `?json=1` to return the leaderboard data as JSON.
    *   **Schema**:
        ```
/* Detailed source-code truncated for AI context efficiency. */
```
    *   **Hero Profile Schema** (`/syz-dungeon/hero/{id}?json=1`): Returns a single JSON object mirroring the `heroes_1y` / `heroes_all` definition depending on the evaluated `?era=` query parameter.
        ```json
        {
          "id": "string",
          "name": "string",
          "rank": "int",
          "score": "int",
          "level": "int",
          "class_name": "string",
          "class_emoji": "string",
          "class_desc": "string",
          "badges": [{ "emoji": "string", "name": "string", "desc": "string" }],
          "bug_count": "int",
          "str": "int",
          "int": "int",
          "wis": "int"
        }
        ```
    *   **Kingdom Profile Schema** (`/syz-dungeon/kingdom/{id}?json=1`): Returns a single JSON object mirroring the `kingdoms_1y` / `kingdoms_all` definition depending on the evaluated `?era=` query parameter.
        ```json
        {
          "id": "string",
          "name": "string",
          "rank": "int",
          "score": "int",
          "tier": "string",
          "tier_emoji": "string",
          "tier_desc": "string",
          "champion_name": "string",
          "champion_score": "int",
          "champion_id": "string",
          "trophies": "int",
          "heroes": "int",
          "guilds": [{ "emoji": "string", "name": "string", "desc": "string" }]
        }
        ```
*   **Heroic Adjectives**: Hardcoded map in `dungeon.go` for A-Z initials.

---

### Syz Kfuzztest (`docs/syz-kfuzztest.md`)

# `syz-kfuzztest`

`syz-kfuzztest` is a standalone tool for fuzzing KFuzzTest targets from within
the kernel being fuzzed (e.g., a VM).

It is intended to be used for development-time fuzzing rather than continuous
fuzzing like `syz-manager`.

For more information on KFuzzTest, consult the [dedicated readme](kfuzztest.md)
or the Kernel documentation.

## Usage (in-VM fuzzing)

### Getting the Kernel Ready

It is important that the target Kernel image has the correct KConfig options
enabled. Namely

- `CONFIG_KFUZZTEST`
- `CONFIG_DEBUG_FS`
- `CONFIG_DEBUG_KERNEL`
- `CONFIG_KCOV`
- `CONFIG_DWARF4` or `CONFIG_DWARF5`
- `CONFIG_KASAN` _(optional, choose your favorite sanitizers for a better shot
  at finding bugs!)_

Furthermore, as you will need to connect to the VM being tested through SSH and
launch `syz-kfuzztest` _(a Go binary with LIBC dependencies)_, it is recommended
to create an image for the kernel being fuzzed (e.g., a Debian Trixie image).
Detailed instructions on how to do this can be found in
[this setup guide](linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md).

### Building and Launching the Binary

The `syz-kfuzztest` binary is built with `make syz-kfuzztest`, and is intended
to run on the Kernel fuzzed. The common case for this is within a VM _(after
all, the tool is trying to make the Kernel crash)_.

Then, ensure that the `syz-kfuzztest` binary and `vmlinux` image are copied
over into the VM. E.g.,

```sh
scp $KERNEL/vmlinux root@my-vm:~/syz-kfuzztest/vmlinux
scp $SYZKALLER/bin/syz-kfuzztest root@lmy-vm:~/syz-kfuzztest/syz-kfuzztest
```

Then launched like this:

```
usage: ./bin/syz-kfuzztest [flags] [enabled targets]

Args:
  One fuzz test name per enabled fuzz test arg. If empty, defaults to
  all discovered targets.
Example:
  ./syz-kfuzztest -vmlinux ~/kernel/vmlinux fuzz_target_0 fuzz_target_1
Flags:
  -display int
        Number of seconds between console outputs (default 5)
  -threads int
        Number of threads (default 2)
  -timeout int
        Timeout between program executions in seconds (default 0)
  -vmlinux string
        Path to vmlinux binary (default "vmlinux")
  -vv int
        verbosity
```

The enabled targets, which are listed after the flag arguments, are the names of
the enabled fuzz targets. For example given some KFuzzTest targets:

```c
FUZZ_TEST(kfuzztest_target_1, struct input_arg_type)
{
    /* ... */
}

FUZZ_TEST(kfuzztest_target_2, struct input_arg_type)
{
    /* ... */
}

```

Can be fuzzed with:

```bash
./syz-kfuzztest -vmlinux path/to/vmlinux -threads 4 kfuzztest_target_1 kfuzztest_target_2
```

If the enabled targets list is left empty, `syz-kfuzztest` will fuzz all
discovered targets in the kernel.

On exit, `syz-kfuzztest` will write the collected program counters (which are
collected with KCOV) into a file called `pcs.out`. These program counters can
be fed into [`syz-cover`](../tools/syz-cover/syz-cover.go) to generate an HTML
visualization of the lines that were covered during fuzzing. It is recommended
to do this on the host machine rather than the VM.

For example:

```sh
scp root@my-vm:~/syz-kfuzztest/pcs.out .
go run tools/syz-cover -config my.cfg pcs.out # May require the -force flag.
```

---

### Syz Testbed (`docs/syz_testbed.md`)

# syz-testbed

`syz-testbed` is the tool that simplifies the process of evaluating the
performance of different syzkaller versions (or configurations) against each
other. The tool automates checking out syzkaller repos, building them, running
`syz-manager`s and collecting/summarizing their results.

## Configuring syz-testbed

`syz-testbed` requires a JSON config file. An example of such a file:

```json
{
  "workdir": "/tmp/syz-testbed-workdir/",
  "corpus": "/tmp/corpus.db",
  "target": "syz-manager",
  "max_instances": 5,
  "run_time": "24h",
  "http": "0.0.0.0:50000",
  "checkouts": [
    {
      "name": "first",
      "repo": "https://github.com/google/syzkaller.git",
    },
    {
      "name": "second",
      "repo": "https://github.com/google/syzkaller.git",
      "branch": "some-dev-branch",
    }
  ],
  "manager_config": {
	  "target": "linux/amd64",
	  "kernel_obj": "/tmp/linux-stable",
	  "image": "/tmp/kernel-image/trixie.img",
	  "sshkey": "/tmp/kernel-image/trixie.id_rsa",
	  "procs": 8,
	  "type": "qemu",
	  "vm": {
          "count": 2,
          "kernel": "/tmp/linux-stable/arch/x86/boot/bzImage",
          "cpu": 2,
          "mem": 2048
	  }
  }
}
```

Given such a configuration file, `syz-testbed` will do the following:

1. Check out the `master` branch of `https://github.com/google/syzkaller.git`
   into `/tmp/syz-testbed-workdir/checkouts/first/` and build it.
2. Check out the `some-dev-branch` of `https://github.com/google/syzkaller.git`
   into `/tmp/syz-testbed-workdir/checkouts/second/` and build it.
3. Set up and run 3 instances of `first` and 2 instances of `second`
(`max_instances = 5`).

The directory structure looks as follows:
```
/tmp/syz-testbed-workdir/
└── checkouts
    ├── first
    │   ├── run-first-0
    │   │   ├── log.txt
    │   │   ├── manager.cfg
    │   │   └── workdir
    │   ├── run-first-1
    │   │   ├── log.txt
    │   │   ├── manager.cfg
    │   │   └── workdir
    │   └── run-first-4
    │   │   ├── log.txt
    │   │   ├── manager.cfg
    │   │   └── workdir
    └── second
        ├── run-second-2
        │   ├── log.txt
        │   ├── manager.cfg
        │   └── workdir
        └── run-second-3
            ├── log.txt
            ├── manager.cfg
            └── workdir
```
4. After 24 hours (as `run_hours` is 24), stop those 5 instances.
5. Create and run 2 instances of `first` and 3 instances of `second`.
6. *Repeat those steps over and over*

The tool stops after receiving a SIGINT (e.g. after Ctrl+C) or a SIGTERM
signal. Also, if one of the instances has exited due to some error, this also
stops the whole experiment.

## Web interface

The tool has a simple web interface that displays the current information about
the experiment (the number of active and finished instances, the time until
instances are stopped, etc.) and the latest statistics collected from the
`syz-manager`s.

If the `benchmp` parameter points to the `syz-benchcmp` executable, then the web
interface can also generate graphs of various parameters over time or the number
of executions.

In order to enable the interface, set the `http` parameter to the IP address and
port to which `syz-testbed` should bind. E.g. `"http": "0.0.0.0:50000"`.

## Statistics

`syz-testbed` provides two "views" of the statistics:

1. `complete` - only includes data from the finished instances (i.e. those that
   have been running for `run_hours`).
2. `all` - also includes the data from the currently active instances. The
   statistics from the finished instances is winded back to match the current
   uptime of the active instances.

Therefore, the statistics is laid out the following way.

```bash
$ tree -L 2 /tmp/syz-testbed-workdir/
/tmp/syz-testbed-workdir/
├── stats_all
│   ├── benches
│   │   ├── avg_first.txt
│   │   ├── avg_second.txt
│   ├── bugs.csv
│   ├── checkout_stats.csv
│   └── instance_stats.csv
├── stats_completed
│   ├── benches
│   │   ├── avg_first.txt
│   │   ├── avg_second.txt
│   ├── bugs.csv
│   ├── checkout_stats.csv
│   └── instance_stats.csv
└── testbed.csv
```

1. `bugs.csv` contains all the bugs found by the running instances. If a single
   checkout has several instances (i.e. `count` > 1), `syz-testbed` takes a
   union of bugs found by them. The purpose is ultimately to collect all bugs
   that could be found by that version of syzkaller.
2. Statistics that is generated by individual `syz-manager`s is saved into
   `instance_stats.csv`. The same data is also averaged among instances that
   belong to the same checkouts and saved into the `checkout_stats.csv` file.
3. Bench files (see `tools/syz-benchcmp`) of all `syz-manager`s belonging to a
   single checkout are averaged and saved into the corresponding files in the
   `benches` folder.

The statics is updated once every 90 seconds.

## Running syz-testbed

First, checkout the most recent version of syzkaller itself:

```shell
$ git clone https://github.com/google/syzkaller.git
```

Then, build `syz-testbed`:

```shell
$ cd syzkaller/tools/syz-testbed/
$ go build
```

Write and save the configuration file (e.g. into the `config.json` file). Then,
`syz-testbed` can be run using the following command:

```shell
$ ./syz-testbed -config config.json
```

Stopping the `syz-testbed` process results in stopping all the syzkaller instances.

## Testing syz-repro

`syz-testbed` can also be used to test syzkaller's ability to reproduce bugs. To do
so, set the `target` property in the `syz-testbed`'s config file to `syz-repro`.

One can also specify the source of the crash log files. This is either just a folder,
whose files will be treated accordingly or it can be a syzkaller's workdir.
`input_logs` must point to the folder with crash logs - `syz-testbed` will traverse
it and treat each file as an input. Otherwise, `input_workdir` must be used.

For example:

```json
  "repro_config": {
    "input_workdir": "/tmp/some-syzkaller-workdir",
    "crashes_per_bug": 2,
    "skip_bugs": ["SYZFAIL", "no output", "corrupted", "lost connection"]
  },
```

In this case, `syz-testbed` will traverse all bugs found by the syzkaller, skip
those that match "SYZFAIL", "no output", "corrupted" or "lost connection", then
pick 2 random crash logs for each such bug for later processing.

`syz-testbed` will check out and compile the specified syzkaller instances and will
go on executing their `syz-repro`s on each picked up crash log file, as long as
the tool is not stopped.

---

### Syz Verifier (`docs/syz_verifier.md`)

# syz-verifier

Many bugs are easy to detect: they might cause assertions failures, crash our
system, or cause other forms of undefined behaviour detectable by various
dynamic analysis tools. However, certain classes of bugs, referred to as
*semantic bugs*, cause none of these while still resulting in a misbehaving
faulty system.

To find semantic bugs, one needs to establish a specification of the system's
*intended behaviour*. Depending on the complexity of the system, creating and
centralising such specifications can be difficult. For example, the
"specification" of the Linux kernel is not found in one place, but is rather a
collection of documentation, man pages, and the implied expectations of a vast
collection of user space programs. As such, detecting semantic bugs in the
Linux kernel is significantly harder than other classes of bugs. Indeed, many
test suites are meant to detect regressions, but creating and maintaining test
cases, as well as covering new features requires significant amounts of
engineering effort.

One way to automate detection of semantic bugs is to provide the same input to
different implementations, or different versions of the same system, and then
cross-compare the resulting behaviour. In case the systems disagree, at least
one of them is assumed to be wrong.

The current `syz-verifier` is not fuzzing new inputs. Instead, it loads a
corpus of existing syzkaller programs and cross-compares their execution on
different versions of the Linux kernel to detect semantic bugs.

The architecture of `syz-verifier` is shown in the following diagram.



The `syz-verifier` process starts and manages VM instances with the kernels to
be cross-compared. It also starts the `syz-runner` process on the VMs.
Communication between the host and the guest is done via RPCs.

At startup, `syz-verifier` loads programs from a syzkaller corpus database
(`corpus.db`). It then sends each corpus program to `syz-runner` on every VM
via RPCs while `syz-runner` is responsible for starting `syz-executor`
processes and turning the program into input for those.
`syz-executor` processes the input, which triggers a sequence of syscalls in
the kernel. Then, `syz-runner` collects the results and sends them back to the
host.

At the moment, the results contain the errnos returned by each system call.
When `syz-verifier` has received results from all the kernels for a specific
program, it verifies them to ensure they are identical. If a mismatch is found,
`syz-verifier` creates a report for the founded mismatch including the program mismatch details.

# How to use `syz-verifier`

After cloning the repository (see how
[here](/docs/linux/setup.md#go-and-syzkaller)), build the tool as:

```
make verifier runner executor
```

To start using the tool, separate configuration files need to be created for
each kernel you want to include in the verification. An example of Linux
configs can be found [here](/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md#syzkaller). The configuration files
are identical to those used by `syz-manager`.

All compared kernels must use the same `workdir`. `syz-verifier` loads the
corpus from `corpus.db` in that shared `workdir`, so the first config must
point at the workdir whose corpus you want to verify.

If you want to constrain verification to programs that use a specific set of
system calls, list them in the kernel config files using the
`enable_syscalls` option. If you want to disable some system calls, use the
`disable_syscalls` option.

Start `syz-verifier` as:
```
./bin/syz-verifier -configs=kernel0.cfg,kernel1.cfg
```

`syz-verifier` logs its progress throughout execution, including corpus loading
and per-program comparison progress.

# How to interpret the results

Results can be found in `workdir/results`.

When `syz-verifier` finds a mismatch in a program, it will create a report for
that program. The report lists the results returned for each system call, by
each of the cross-compared kernels, highlighting the ones were a mismatch was
found. The system calls are listed in the order they appear in the program.

An extract of such a report is shown below:

```
ERRNO mismatches found for program:

========== ERRNO MISMATCH DETECTED ==========
Between: Kernel 0 (kernel-6.17) and Kernel 1 (kernel-6.2)

Complete Program Sequence:
-------------------------------------------
    [0] capset(&(0x7f0000000380)={0x19980330}, &(0x7f00000003c0))
        Result: errno=0, flags=0x3

>>> [1] r0 = socket$inet6_tcp(0xa, 0x1, 0x0)
>>>     ┌─ : errno=0, flags=0x3
>>>     └─ : errno=2, flags=0x3

>>> [2] setsockopt$inet6_tcp_TCP_CONGESTION(r0, 0x6, 0xd, &(0x7f0000000000)='cubic', 0x3)
>>>     ┌─ : errno=2, flags=0x3
>>>     └─ : errno=9, flags=0x3

-------------------------------------------
Kernel Outputs:
  : ""
  : ""
=============================================
...
```

In this report, lines prefixed with `>>>` highlight the calls whose returned
errnos differed between kernels. The two indented result lines under such a
call show the values returned by each compared kernel for that exact syscall.
The `Kernel Outputs` section records the raw runner output for each kernel,
which is useful when a mismatch is caused by a crash, timeout, or some other
execution problem rather than a pure semantic difference.

---

### Syzbot (`docs/syzbot.md`)

# syzbot

`syzbot` system continuously fuzzes main Linux kernel branches and automatically
reports found bugs to kernel mailing lists.
[syzbot dashboard](https://syzkaller.appspot.com) shows current statuses of
bugs. All `syzbot`-reported bugs are also CCed to
[syzkaller-bugs mailing list](https://groups.google.com/forum/#!forum/syzkaller-bugs).
Direct all questions to `syzkaller@googlegroups.com`.


<div id="bug-status-tracking"/>
<div id="status"/>

## Bug status tracking

`syzbot` needs to know when a bug is fixed in order to (1) verify that it is
in fact fixed and (2) be able to report other similarly-looking crashes
(while a bug is considered open all similarly-looking crashes are merged into
the existing bug). To understand when a bug is fixed `syzbot` needs to know
what commit fixes the bug; once `syzbot` knows the commit it will track when
the commit reaches all kernel builds on all tracked branches. Only when the
commit reaches all builds, the bug is considered closed (new similarly-looking
crashes create a new bug).

## Communication with syzbot

If you fix a bug reported by `syzbot`, please add the provided `Reported-by`
tag to the commit. You can also communicate with `syzbot` by replying
to its emails. The commands are:

- to attach a fixing commit to the bug (if you forgot to add `Reported-by` tag):
```
#syz fix: exact-commit-title
````
It's enough that the commit is merged into any tree or you are reasonably sure
about its final title, in particular, you don't need to wait for the commit to
be merged into upstream tree. `syzbot` only needs to know the title by which
it will appear in tested trees. In case of an error or a title change, you can
override the commit simply by sending another `#syz fix` command.
- to undo a previous fix command and remove any fixing commits:
```
#syz unfix
````
- to mark the bug as a duplicate of another `syzbot` bug:
```
#syz dup: exact-subject-of-another-report
```
- to undo a previous dup command and turn it into an independent bug again:
```
#syz undup
```
- to mark the bug as a one-off invalid report (e.g. induced by a previous memory corruption):
```
#syz invalid
```
**Note**: if the crash happens again, it will cause creation of a new bug report.

**Note**: all commands must start from beginning of the line.

**Note**: please keep at least `syzkaller-bugs@googlegroups.com` mailing list in CC.
It serves as a history of what happened with each bug report. Keeping the main kernel
mailing list (e.g. `linux-kernel@vger.kernel.org `) in CC is useful as well so that
it's searchable in those archives as well.

**Note**: `syzbot` identifies bugs by the `HASH` in the `syzbot+HASH@` receiver email address.
So, strictly saying, you don't need to *reply* to emails (e.g. if you did not receive them),
you can send a new email to the `syzbot+HASH@` email address, which you can find as `Sender`
in email archives or as `Reported-by` email on the dashboard page for each bug.

<div id="testing-patches"/>

## Testing patches

`syzbot` can test patches for bugs *with reproducers*. This can be used for
testing of fix patches, or just for debugging (i.e. adding additional checks to
code and testing with them), or to check if the bug still happens. To test on
a particular git tree and branch reply with:
```
#syz test: git://repo/address.git branch
```
or alternatively, to test on exact commit reply with:
```
#syz test: git://repo/address.git commit-hash
```

You can also completely omit these parameters:
```
#syz test
```

In this case, syzbot will check out the latest commit from the branch where the
issue was detected.

If you also provide a patch with the email, `syzbot` will apply it on top of the
tree before testing. The patch can be provided inline in email text or as
a text attachment (which is more reliable if your email client messes with
whitespaces).

If you want to include the patch directly in the email body, just paste the diff
somewhere under the `#syz test` command line, e.g.

```
#syz test: git://repo/address.git branch

--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
-       current->kasan_depth++;
+       current->kasan_depth--;
```

[Here](https://groups.google.com/g/syzkaller-bugs/search?q=%22%23syz%20test%22) are
some real examples of `#syz test` commands for syzbot-reported bugs.

If you don't provide a patch, `syzbot` will test the tree as is.
This is useful if this is your own tree which already contains the patch,
or to check if the bug is already fixed by some recent commit.

After sending an email you should typically get a reply email with results within
an hour.

**Note**: you may send the request only to `syzbot` email address, as patches sent
to some mailing lists (e.g. netdev, netfilter-devel) will trigger patchwork.

**Note**: when testing a patch, syzbot uses the newest reproducer and the matching
kernel config that are listed on the dashboard for this bug. As a result, specifying
a repo, branch or commit id that are different from the ones that were used for
reproducing, can result in false-positive Tested-by responses. For example this
happens, when the bug is not reproducible on a specified kernel tree, with or without
the supplied patch.

**Note**: see [below](#kmsan-bugs) for `KMSAN` bugs testing.

**Note**: see [below](#usb-bugs) for `USB` bugs testing.

## Subsystems

For all its bugs, `syzbot` automatically assigns kernel subsystems tags. For Linux,
the predefined list of kernel subsystems can be found at
https://syzkaller.appspot.com/upstream/subsystems.

By clicking on a name in the subsystem list or by following a tag after a bug's
title, you can get the full list of bugs belonging to the subsystem. For example,
all `nfc` bugs are listed here: https://syzkaller.appspot.com/upstream/s/nfc.

`syzbot` includes subsystem tags into email subject as well, with `?` indicating
that it's an automatic guess: `[syzbot] [ntfs?] kernel BUG in ntfs_iget`.

Over time, as we improve the classification rules or as syzbot obtains more
information about the bug (e.g. finds a reproducer), `syzbot` will update tags.

You can also manually override the automatic guess by replying to the `syzbot` email:

```
#syz set subsystems: net, mm
```

Names of subsystems must be taken from the subsystem list page on the syzbot web
dashboard.

<div id="labels"/>

## Bug labels

It is possible to assign labels to syzkaller-reported bugs. These labels
are displayed near bug titles on the bug lists and on individual bug pages.

There are two types of labels:
* Flags
  * Send `#syz set <label>` to set the flag.
  * Send `#syz unset <label>` to drop the flag.
* Label with values
  * Send `#syz set <label>: <value>[, <value2> ...]`  to overwrite the value list.
  * `#syz unset <label>` would drop the label with all its values.

There's a fixed list of supported labels (*). Most important ones:
| Key | Description | Values | Example |
| - | - | - | - |
| `subsystems` | A comma-separated list of subsystems of the bug | See [the list](https://syzkaller.appspot.com/upstream/subsystems) on the syzbot dashboard | `#syz set subsystems: mm, reiserfs` |
| `prio` | The priority of the bug | One of `low`, `normal`, `high` | `#syz set prio: low`<br>`#syz unset prio` |
| `no-reminders` | Don't include the bug into monthly reminders | No values, just a flag |  `#syz set no-reminders`<br>`#syz unset no-reminders` |

It is also possible to set and unset labels for individual bugs from a monthly
subsystem report. Let's consider an example.

```
Some of the still happening issues:

Ref Crashes Repro Title
<1> 10      No    WARNING in __brelse (2)
                  https://syzkaller.appspot.com/bug?id=cd9cb7a620dcfbf46a5eaf201031acaf3aeda28e
<2> 3       No    WARNING in kernfs_get (4)
                  https://syzkaller.appspot.com/bug?id=b4278401038872458a20f08210e46f3ab519b786
```

One can send the following email to disable reminders for the first bug and to
change the subsystem of the second bug:

```
#syz set <1> no-reminders
#syz set <2> subsystems: kernfs
```

(*) If you need other labels to facilitate your work, feel free to contact us.

<div id="amend"/>
<div id="linux-next"/>

## Rebuilt trees/amended patches

There are several additional aspects if the tree is rebuilt/rebased or contains
amended/folded patches (namely, `linux-next`).

First, adding `Reported-by` tags to amended commits may be misleading.
A `Reported-by` tag suggests that the commit fixes a bug in some previous
commit, but here it's not the case (it only fixes a bug in a previous version
of itself which is not in the tree). In such case it's recommended to include
a `Tested-by` or a `Reviewed-by` tag with the hash instead. Technically,
`syzbot` accepts any tag, so `With-inputs-from` would work too.

Then, if the guilty commit is completely dropped (actually removed from the
tree during rebuild), then there is effectively no fixing commit. There is no
good way to handle such cases at the moment. One possibility is to mark them
with `#syz invalid`. However this needs to be done only when `syzbot` picks up
the new tree in all builds (current kernel commits can be seen on dashboard).
Otherwise, the occurrences of the crash that are still happening in the current
build will immediately create a new bug report. Another possibility is to mark
it as fixed with some unrelated later commit using
`#syz fix: some-later-commit`. This way `syzbot` will wait until the commit
propagates to all tested trees automatically.

In any case the relation between the report and the fix can later be fixed up
using `#syz fix: commit-title` commands.

<div id="bisection"/>

## Bisection

`syzbot` bisects bugs with reproducers to find commit that introduced the bug.
`syzbot` starts with the commit on which the bug was discovered, ensures that it
can reproduce the bug and then goes back release-by-release to find the first
release where kernel does not crash. Once such release is found, `syzbot` starts
bisection on that range. `syzbot` has limitation of how far back in time it can
go (currently `v4.19`), going back in time is [very hard](/pkg/vcs/linux.go)
because of incompatible compiler/linker/asm/perl/make/libc/etc, kernel
build/boot breakages and large amounts of bugs.

The predicate for bisection is binary (crash/doesn't crash), `syzbot` does not
look at the exact crash and does not try to differentiate them. This is
intentional because lots of bugs can manifest in different ways (sometimes 50+
different ways). For each revision `syzbot` repeats testing 10 times and
a single crash marks revision as bad (lots of bugs are due to races and are
hard to trigger).

During bisection `syzbot` uses different compilers depending on kernel revision
(a single compiler can't build all revisions). These compilers are available
[here](https://storage.googleapis.com/syzkaller/bisect_bin.tar.gz).
Exact compiler used to test a particular revision is specified in the bisection
log.

Bisection is best-effort and may not find the right commit for multiple reasons,
including:

- hard to reproduce bugs that trigger with very low probability
- bug being introduced before the tool that reliably detects it (LOCKDEP, KASAN,
  FAULT_INJECTION, WARNING, etc);\
  such bugs may be bisection to the addition/improvement of the tool
- kernel build/boot errors that force skipping revisions
- some kernel configs are [disabled](/pkg/vcs/linux.go) as bisection goes back
  in time because they build/boot break release tags;\
  bugs in these subsystems may be bisected to release tags
- reproducers triggering multiple kernel bugs at once
- unrelated kernel bugs that break even simple programs

A single incorrect decision during bisection leads to an incorrect result,
so please treat the results with understanding. You may consult the provided
`bisection log` to see how/why `syzbot` has arrived to a particular commit.
Suggestions and patches that improve bisection quality for common cases are
[welcome](https://github.com/google/syzkaller/issues/1051).

`syzbot` supports cause bisection (find the commit that introduces a bug) and
fix bisection (find the commit that fixes a bug).

The web UI for a specific kernel
(say [upstream linux](https://syzkaller.appspot.com/upstream)) shows the
`Bisected` status for all bugs.

<div id="fix-bisection"/>

### Fix bisection
`syzbot` will perform fix bisection on bugs that meet the following criterion:
- The kernel tree corresponding to the bug has fix bisection enabled (for
instance, fix bisection might be disabled on kernel trees that have commits
which are force pushed).
- The bug must have a reproducer.
- The bug must not have occurred for at least 30 days. If the bug still occurs
on HEAD upon fix bisection, it will be retried in another 30 days.

If you receive an email with fix bisection results you think is correct, please
reply with a `#syz fix: commit-title` so that syzbot can close the bug report.

<div id="syzkaller-reproducers"/>

## Running reproducers

*Detailed instructions on running reproducers can be found [here](/docs/reproducing_crashes.md).*

`syzbot` aims at providing stand-alone C reproducers for all reported bugs.
However, sometimes it can't extract a reproducer at all, or can only extract a
syzkaller reproducer. syzkaller reproducers are programs in a special syzkaller
notation and they can be executed on the target system with a little bit more
effort.

A syskaller program can also give you an idea as to what syscalls with what
arguments were executed (note that some calls can actually be executed in
parallel).

A syzkaller program can be converted to an almost equivalent C source using
`syz-prog2c` utility. `syz-prog2c` has lots of flags in common with
[syz-execprog](/docs/reproducing_crashes.md#from-execution-logs),
e.g. `-threaded` which controls if the syscalls are executed sequentially or
concurrently.

An example invocation:

```
syz-prog2c -prog repro.syz.txt -enable=all -threaded -repeat -procs=8 -sandbox=namespace -segv -tmpdir -waitrepeat
```

However, note that if `syzbot` did not provide a C reproducer, it wasn't able to
trigger the bug using the C program (it might also be the case that the bug is
triggered by a rare race condition).

## Downloadable assets

Syzbot shares links to the bootable disk image, kernel object file and other
relevant files that can be used to reproduce and debug the issue locally.

See [this tutorial](/docs/syzbot_assets.md) on how to use them.

## Crash does not reproduce?

If the provided reproducer does not work for you, most likely it is related to the
fact that you have slightly different setup than `syzbot`. `syzbot` has obtained
the provided crash report on the provided reproducer on a freshly-booted
machine, so the reproducer worked for it somehow.

Note: if the report contains `userspace arch: i386`,
then the program needs to be built with `-m32` flag.

`syzbot` uses GCE VMs for testing, but *usually* it is not important.

If the reproducer exits quickly, try to run it several times, or in a loop.
There can be some races involved.

Sometimes it might be important to build the kernel using the exact same
compiler that was used by syzbot. Normally that information is included in every
email report, e.g.:

```
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
```

The latest compilers used by syzbot are contained in the
`gcr.io/syzkaller/syzbot` docker image. For in-tree kernel build in current
directory it can be used as follows:

```
docker pull gcr.io/syzkaller/syzbot
docker run -it --user $(id -u ${USER}):$(id -g ${USER}) \
	--volume "$PWD:/syzkaller/pwd" --workdir /syzkaller/pwd \
	gcr.io/syzkaller/syzbot:latest
make
```

For an out-of-tree build one needs to proxy more host directories using `--volume` flag.

Older compilers used by `syzbot` can be found here:
- [gcc 7.1.1 20170620](https://storage.googleapis.com/syzkaller/gcc-7.tar.gz) (245MB)
- [gcc 8.0.1 20180301](https://storage.googleapis.com/syzkaller/gcc-8.0.1-20180301.tar.gz) (286MB)
- [gcc 8.0.1 20180412](https://storage.googleapis.com/syzkaller/gcc-8.0.1-20180412.tar.gz) (33MB)
- [gcc 9.0.0 20181231](https://storage.googleapis.com/syzkaller/gcc-9.0.0-20181231.tar.gz) (30MB)
- [gcc 10.1.0-syz (20200507)](https://storage.googleapis.com/syzkaller/gcc-10.1.0-syz.tar.xz) (220MB)
- [gcc 10.2.0](https://storage.googleapis.com/syzkaller/gcc-10.2.0.tar.gz) (165MB)
- [clang 7.0.0 (trunk 329060)](https://storage.googleapis.com/syzkaller/clang-kmsan-329060.tar.gz) (44MB)
- [clang 7.0.0 (trunk 334104)](https://storage.googleapis.com/syzkaller/clang-kmsan-334104.tar.gz) (44MB)
- [clang 8.0.0 (trunk 343298)](https://storage.googleapis.com/syzkaller/clang-kmsan-343298.tar.gz) (45MB)
- [clang 10.0.0 (c2443155)](https://storage.googleapis.com/syzkaller/clang_install_c2443155.tar.gz)
- [clang 11.0.0 (git ca2dcbd030e)](https://storage.googleapis.com/syzkaller/clang-11-prerelease-ca2dcbd030e.tar.xz) (682MB)
- [clang 11.0.1](https://github.com/llvm/llvm-project/releases/tag/llvmorg-11.0.1)

A QEMU-suitable Debian Stretch image can be found
[here](https://storage.googleapis.com/syzkaller/images/stretch-amd64.img.gz) (241 MB).
A reference `qemu` command line to run it is as follows:
```
qemu-system-x86_64 -smp 2 -m 4G -enable-kvm -cpu host \
    -net nic -net user,hostfwd=tcp::10022-:22 \
    -kernel arch/x86/boot/bzImage -nographic \
    -device virtio-scsi-pci,id=scsi \
    -device scsi-hd,bus=scsi.0,drive=d0 \
    -drive file=stretch-amd64.img,format=raw,if=none,id=d0 \
    -append "root=/dev/sda1 console=ttyS0 earlyprintk=serial"
```
And then you can ssh into it using:
```
ssh -p 10022 root@localhost
```

Note: before March 25th 2020 Debian Wheezy image was used for testing, so some of the bugs reported before that date
might only be reproducible on Wheezy. That image is [here](https://storage.googleapis.com/syzkaller/wheezy.img)
and the key for it is [here](https://storage.googleapis.com/syzkaller/wheezy.img.key).

## No reproducer at all?

Reproducers are best-effort. `syzbot` always tries to create reproducers, and
once it has one it adds it to the bug. If there is no reproducer referenced in a
bug, a reproducer does not exist. There are multiple reasons why `syzbot` can
fail to create a reproducer: some crashes are caused by subtle races and are
very hard to reproduce in general; some crashes are caused by global accumulated
state in kernel (e.g. lockdep reports); some crashes are caused by
non-reproducible coincidences (e.g. an integer `0x12345` happened to reference an
existing IPC object) and there is long tail of other reasons.

## Moderation queue

Bugs with reproducers are automatically reported to kernel mailing lists.
Bugs without reproducers are first staged in moderation queue to filter out
invalid, unactionable or duplicate reports. Staged bugs are shown on dashboard
in [moderation](https://syzkaller.appspot.com/upstream#moderation2) section
and mailed to
[syzkaller-upstream-moderation](https://groups.google.com/forum/#!forum/syzkaller-upstream-moderation)
mailing list. Staged bugs accept all commands supported for reported bugs
(`fix`, `dup`, `invalid`) with a restriction that bugs reported upstream
can't be `dup`-ed onto bugs in moderation queue. Additionally, staged bugs
accept upstream command:
```
#syz upstream
```
which sends the bug to kernel mailing lists.

## KMSAN bugs

`KMSAN` is a dynamic, compiler-based tool (similar to `KASAN`) that detects
uses of uninitialized values. As compared to (now deleted) `KMEMCHECK` which
simply detected loads of non-stored-to memory, `KMSAN` tracks precise
propagation of uninitialized values through memory and registers and only flags
actual eventual uses of uninitialized values. For example, `KMSAN` will detect
a branch on or a `copy_to_user()` of values that transitively come from
uninitialized memory created by heap/stack allocations. This ensures
/theoretical/ absence of both false positives and false negatives (with some
implementation limitations of course). Note that `KMSAN` requires `clang` compiler.

`KMSAN` is not upstream yet, though, we want to upstream it later. For now,
it lives in [github.com/google/kmsan](https://github.com/google/kmsan) and is
based on a reasonably fresh upstream tree. As the result, any patch testing
requests for `KMSAN` bugs need to go to `KMSAN` tree
(`https://github.com/google/kmsan.git` repo, `master` branch).
A standard way for triggering the test with `KMSAN` tree is to send an
email to `syzbot+HASH` address containing the following line:
```
#syz test: https://github.com/google/kmsan.git master
```
and attach/inline your test patch in the same email.

Report explanation. The first call trace points to the `use` of the uninit value
(which is usually a branching or copying it to userspace). Then there are 0 or
more "Uninit was stored to memory at:" stacks which denote how the unint value
traveled through memory. Finally there is a "Uninit was created at:"
section which points either to a heap allocation or a stack variable which
is the original source of uninitialized-ness.

## USB bugs

syzkaller has an ability to perform fuzzing of the Linux kernel USB stack, see
the details [here](/docs/linux/external_fuzzing_usb.md). As of now all kernel
changes required for USB fuzzing have been merged into the mainline (the last one
during the 5.8-rc1 merge window), so the USB fuzzing instance has been switched
to target the [usb-testing](https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/log/?h=usb-testing) tree.

Testing kernel patches on the USB instance follows the same principle as on the
mainline instances, with a few caveats:

1. You may specify any kernel tree for `syz test` as long as it includes all
mainline patches up to 5.8-rc1.

2. Some of the bugs have reproducers generated on kernel versions with custom
kernel (when fuzzing was performed with non-yet-mainlined kernel patches), thus
those reproducers might no longer work. The recommended workflow is to: first,
execute a `syz test` command on a target tree to make sure that the bug
reproduces, and then execute a `syz test` command with a fix/debug patch.

If the bug was triggered on the `KMSAN` tree, follow the [instructions above](#kmsan-bugs),
with the exception that you must also use `commit-hash` instead of the `master`
branch when testing patches.

## Memory leaks

`syzbot` uses `KMEMLEAK` to find memory leaks in the Linux kernel.
`KMEMLEAK` kernel config is stored [here](/dashboard/config/linux/upstream-leak.config).
See `KMEMLEAK` [docs](https://www.kernel.org/doc/html/latest/dev-tools/kmemleak.html)
for general info, algorithm overview and usage instructions.

Memory leaks may be tricky to debug because we have only the allocation stack,
but we don't see where kernel code forgot to free the object or drop a reference.
`KMEMLEAK` can have some false positives on tricky kernel code that hides
pointers to live objects and due to memory scanning non-atomicity.
But don't write off everything to false positives right away, the rate of
false positives is observed to be very low. In particular, `KMEMLEAK` is
[not confused](https://elixir.bootlin.com/linux/v5.2-rc1/source/mm/kmemleak.c#L1426)
by pointers stored in a middle of another object; and it's
[not confused](https://elixir.bootlin.com/linux/v5.2-rc1/source/mm/kmemleak.c#L440)
if several pointer low bits are used as flags because a pointer into
a middle of an object also marks the target as reachable.

A useful litmus test is to remove `KMEMLEAK` code from the reproducer
and run it for longer and/or multiple times. If memory consumption and number
of live objects in `/proc/slabinfo` steadily grow, most likely the leak is real.

## KCSAN bugs

[The Kernel Concurrency Sanitizer (KCSAN)](https://github.com/google/ktsan/wiki/KCSAN)
is a dynamic data-race detector. Reproduction of data-races is currently
unsupported, and syzbot is unable to test patches.

## No custom patches

While `syzbot` can test patches that fix bugs, it does not support applying
custom patches during fuzzing. It always tests vanilla unmodified git trees.
There are several reasons for this:

- custom patches may not apply tomorrow
- custom patches may not apply to all of the tested git trees
- it's hard to communicate exact state of the code with bug reports (not just hash anymore)
- line numbers won't match in reports (which always brings suspicion as to the quality of reports)
- custom patches can also introduce bugs, and even if they don't a developer may (rightfully)
  question validity of and may not want to spend time on reports obtained
  with a number of out-of-tree patches
- order of patch application generally matters, and at some point patches
  need to be removed, there is nobody to manage this

We've experimented with application of custom patches in the past and it lead
to unrecoverable mess. If you want `syzbot` to pick up patches sooner,
ask tree maintainers for priority handling.

However, syzbot kernel config always includes `CONFIG_DEBUG_AID_FOR_SYZBOT=y` setting,
which is not normally present in kernel. What was used for particularly elusive bugs in the past
is temporary merging some additional debugging code into `linux-next` under this config setting
(e.g. more debug checks and/or debug output) and waiting for new crash reports from syzbot.

One can also always run syzkaller locally on any kernel for better stress testing
of a particular subsystem and/or patch.

## Kernel configs

Kernel configs, sysctls and command line arguments that `syzbot` uses are available in [/dashboard/config](/dashboard/config).

## Is syzbot code available?

Yes, it is [here](/dashboard/app).

---

### Syzbot Ai Patches (`docs/syzbot_ai_patches.md`)

# AI-generated patches

`syzbot` investigates kernel bugs and tries to generate fix patches using AI.

To ensure patch quality and adhere to kernel community standards, the AI
patching process follows a two-stage workflow:

1. **Moderation**: Newly generated patches are first posted to an internal moderation
   list, where human reviewers can collaborate with the AI, provide feedback, and
   trigger automated revisions.
2. **Upstream submission**: Once reviewed and signed off by a human developer
   (in accordance with the kernel's [AI Coding Assistants](https://docs.kernel.org/process/coding-assistants.html)
   guidelines), the patch is sent to the Linux Kernel Mailing List (LKML) and
   relevant subsystem lists.

Once sent upstream, patches follow the standard kernel review process: the developer
who signed off on the patch acts as the submitter and handles reviewer feedback,
discussion, and any follow-up revisions.

## The Intended Workflow

syzbot's AI patch reporting follows a two-stage pipeline to refine the patch
before publishing it to the wider community.

### 1. Moderation Stage

Newly generated patches are first sent to an internal moderation mailing list
(`syzkaller-upstream-moderation@googlegroups.com`) where the bot actively
listens and participates. You can:

* Reply to the patch email with text comments to provide feedback and request
changes. The AI model will read the comments and reply or send a new patch
version (e.g. an RFC v2) if necessary.

* Reject a fundamentally flawed patch:
```
#syz reject
```
You can provide the reason for rejection in the email body for better accounting.
Once a patch is rejected, the AI will stop reacting to further comments on this patch version.

* If you accidentally rejected a patch, you can undo it:
```
#syz unreject
```

* Approve a patch and send it to the public mailing lists:
```
#syz upstream
```

### 2. Linux Kernel Mailing List (LKML)

Once a patch is approved and upstreamed from the moderation list, it is sent to
the public mailing lists (LKML / subsystem lists).

**Important**: `syzbot` does not automatically reply to review comments or send
patch iterations on LKML. The developer who signed off on the patch is
responsible for addressing review feedback, answering questions, and submitting
any necessary follow-up versions.

While syzbot administrators actively monitor upstream patches and can manually
trigger AI iterations internally if appropriate, all interactions and patch
submissions on LKML remain human-driven.

## System Invariants and Rules

`syzbot` maintains strict rules about tracking and handling AI patches based on
email replies.

### Which patch version am I interacting with?

Each patch version (e.g., v1, v2) is sent as a separate email thread. `syzbot`
uses the `In-Reply-To` email header to identify exactly which version of the
patch you are interacting with.

You can reply to any patch version's thread, not just the latest one. Commands
like `#syz upstream` or `#syz reject` will only apply to the specific version
you are replying to.

### Can I upstream multiple versions of the same patch?

No. `syzbot` prevents upstreaming multiple patch iterations for the same bug
simultaneously to avoid spamming the upstream list.

If you upstream "v1" and later decide "v2" is better, an attempt to
`#syz upstream` "v2" will be blocked. You must first reply to the previously
upstreamed version ("v1") with:
```
#syz reject
```
Once rejected, the system clears the conflict, and you can successfully
`#syz upstream` the new version.

### What happens to my tags (Reviewed-by, Acked-by)?

During the review process, reviewers often provide standard tags like
`Reviewed-by:`, `Acked-by:`, `Tested-by:`, `Reported-by:`, or `Suggested-by:`.

`syzbot` automatically parses and accumulates these tags from review comments.
When a newer iteration of the patch is generated, these tags are reliably
preserved and appended to the commit message's trailer.

### Who gets the Signed-off-by tag?

When you approve a patch by replying with `#syz upstream`, `syzbot` incorporates
your email and name into a standard `Signed-off-by:` tag and appends it to the
commit message when sending the patch to the next stage (e.g., LKML).

If the patch goes through further iterations on public mailing lists, this
`Signed-off-by:` tag is preserved.

### What happens if I reply without a command?

* **On the moderation mailing list**: Your reply is recorded as review feedback
  on the AI patch job. `syzbot` triggers an iteration job where the AI evaluates
  your comments, addresses questions or change requests, and sends a new version
  of the patch if appropriate (accumulating any provided tags like `Reviewed-by`).
  A plain reply does not advance (`#syz upstream`) or reject (`#syz reject`) the patch.
* **On LKML / public lists**: `syzbot` does not automatically reply or iterate;
  feedback is handled directly by the developer who signed off on the patch.

### What are the requirements for upstreaming?

The AI job must have successfully produced a patch. You cannot use
`#syz upstream` on an AI run that only replied with a textual comment and no
code changes.

If you send `#syz upstream` and do not receive a reply, the command was
processed successfully. The system does not reply back to confirm; it simply
pushes the patch to the next reporting stage.

---

### Syzbot Assets (`docs/syzbot_assets.md`)

## Reproduce a bug with syzbot's downloadable assets

As a part of every bug report, syzbot shares downloadable assets -- that is,
disk images and kernel binaries on which the bug was originally found.

This document serves as a guide on how to use those assets to reproduce such bugs
locally.

### A sample report

To be more specific, let's take this syzbot report: [[syzbot] [hfs?] kernel BUG
in hfsplus_bnode_put](https://lore.kernel.org/all/000000000000efee7905fe4c9a46@google.com/).

```
syzbot has found a reproducer for the following issue on:

HEAD commit:    40f71e7cd3c6 Merge tag 'net-6.4-rc7' of git://git.kernel.o..
git tree:       upstream
console+strace: https://syzkaller.appspot.com/x/log.txt?x=10482ae3280000
kernel config:  https://syzkaller.appspot.com/x/.config?x=7ff8f87c7ab0e04e
dashboard link: https://syzkaller.appspot.com/bug?extid=005d2a9ecd9fbf525f6a
compiler:       Debian clang version 15.0.7, GNU ld (GNU Binutils for Debian) 2.35.2
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=142e7287280000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=13fd185b280000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/073eea957569/disk-40f71e7c.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/c8a97aaa4cdc/vmlinux-40f71e7c.xz
kernel image: https://storage.googleapis.com/syzbot-assets/f536015eacbd/bzImage-40f71e7c.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/b5f1764cd64d/mount_0.gz
```

There are 4 linked assets:
* The bootable VM disk image on which the bug was found: `https://storage.googleapis.com/syzbot-assets/073eea957569/disk-40f71e7c.raw.xz`
  * **The image is suitable both for GCE and for qemu**.
* The `vmlinux` file that can be used e.g. for report symbolization or for `gdb`-based debugging: `https://storage.googleapis.com/syzbot-assets/c8a97aaa4cdc/vmlinux-40f71e7c.xz`
* The separate `bzImage` file (it is already included in the disk image): `https://storage.googleapis.com/syzbot-assets/f536015eacbd/bzImage-40f71e7c.xz`
* The filesystem image that is mounted in the reproducer: `https://storage.googleapis.com/syzbot-assets/b5f1764cd64d/mount_0.gz`

All these links are also reachable from the web dashboard.

#### Run a C reproducer

Boot a VM:
```
$ wget 'https://storage.googleapis.com/syzbot-assets/073eea957569/disk-40f71e7c.raw.xz'
$ unxz disk-40f71e7c.raw.xz
$ qemu-system-x86_64 -m 2G -smp 2,sockets=2,cores=1 -drive file=./disk-40f71e7c.raw,format=raw -net nic,model=e1000 -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -enable-kvm -nographic -snapshot -machine pc-q35-7.1
```

Build and run the C reproducer:
```
$ wget -O 'repro.c' 'https://syzkaller.appspot.com/x/repro.c?x=13fd185b280000'
$ gcc repro.c -lpthread -static -o repro
$ scp -P 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ./repro root@127.0.0.1:/root/
$ ssh -p 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes root@127.0.0.1 'chmod +x ./repro && ./repro'
```

Wait a minute and notice a crash report in the qemu's serial output:

```
[   91.956238][   T81] ------------[ cut here ]------------
[   91.957508][   T81] kernel BUG at fs/hfsplus/bnode.c:618!
[   91.958645][   T81] invalid opcode: 0000 [#1] PREEMPT SMP KASAN
[   91.959861][   T81] CPU: 0 PID: 81 Comm: kworker/u5:3 Not tainted 6.4.0-rc6-syzkaller-00195-g40f71e7cd3c6 #0
```

#### Run a syz reproducer directly

For some bugs, there's either no C reproducer or it's not reliable enough. In
that case, `syz` reproducers might be useful.

You'll need to [check out and build](/docs/linux/setup.md#go-and-syzkaller)
syzkaller first. The fastest way to do it is as follows (assuming Docker is
installed and configured on your machine):

```
$ git clone https://github.com/google/syzkaller.git
$ cd syzkaller
$ ./tools/syz-env make
```

Then boot a VM exactly like in the previous section.

Download and run the syz reproducer:

```
$ wget -O 'repro.syz' 'https://syzkaller.appspot.com/x/repro.syz?x=142e7287280000'
$ scp -P 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ./bin/linux_amd64/* ./repro.syz root@127.0.0.1:/root/
$ ssh -p 10022 -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no -o IdentitiesOnly=yes root@127.0.0.1 './syz-execprog -enable=all -repeat=0 -procs=6 ./repro.syz'
```

In some time, you'll see the same bug report in the VM's serial output.

The commands above execute the `./syz-execprog -enable=all -repeat=0 -procs=6 ./repro.syz`
command inside the VM. More details can be found in [this document](/docs/reproducing_crashes.md).

#### Use the `tools/syz-crush` tool

The `syz-crush` automatizes the steps above: it sets up and boots a pool of VMs
and runs the given `C` or `syz` reproducer in them.

First, download the disk image and reproducers (see instructions above).

Then, go to the syzkaller checkout and build the `syz-crush` tool:
```
$ make crush
```

Prepare a config file (let it be `config.json`):

```
{
    "name": "test",
    "http": "0.0.0.0:0",
    "target": "linux/amd64",
    "image": "/tmp/disk-40f71e7c.raw",
    "syzkaller": "/tmp/syzkaller",
    "workdir": "/tmp/syzkaller/workdir",
    "type": "qemu",
    "procs": 6,
    "vm": {
      "count": 5,
      "cmdline": "root=/dev/sda1",
      "cpu": 2,
      "mem": 2048,
      "qemu_args": "-machine pc-q35-7.1 -enable-kvm"
    }
}
```

You need to replace `/tmp/syzkaller` with the location of your syzkaller
checkout and `/tmp/disk-40f71e7c.raw` with the location of the bootable disk
image.

Run the tool:
```
$ mkdir workdir
$ ./bin/syz-crush -config config.json repro.syz
```


#### Reproducing ARM64 bugs

If the bug was found on an ARM64 instance (e.g. the manager name is
`ci-upstream-gce-arm64`), you may use the following qemu command as a reference:

```
$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -smp 4 -m 4G -nographic -drive file=disk.raw,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -kernel Image -net user,hostfwd=tcp::10023-:22 -net nic -append "root=/dev/vda2" -accel tcg,thread=multi
```

### Problems

#### The bug doesn't reproduce

If the `C` reproducer did not work, try to run the `syz` reproducer.

If there's still no success, it might be that relatively rare case when the
execution environment becomes important. Syzbot fuzzes kernels on GCE VMs, which
might have a different instruction set / execution speed than locally run qemu
VMs. These changes might be critical for the generated reproducer.

There's unfortunately no universal solution.

Note that you can always ask syzbot to
[apply your git patch and re-run the reproducer](/docs/syzbot.md#testing-patches).
It will be run in the same GCE environment where the bug was originally found.

See also [this document](/docs/syzbot.md#crash-does-not-reproduce).

#### Assets are not downloadable

The downloadable assets are not stored infinitely. Syzbot keeps them until the
bug is fixed or marked as invalid + 30 days after that.

So if you cannot download the assets using the links from the email, this might
be a sign that the bug is actually no longer worth looking at.

#### Qemu doesn't boot

A [recent qemu problem](https://lore.kernel.org/qemu-devel/da39abab9785aea2a2e7652ed6403b6268aeb31f.camel@linux.ibm.com/)
may prevent it from booting large kernel images. Add `-machine pc-q35-7.1` to
the qemu args to make it work.

---

### Syzos (`docs/syzos.md`)

# SYZOS Technical Documentation

## 1. System Overview

### Concept
SYZOS is not a traditional operating system but an **immutable C library** designed to run as a Guest (L1) within a KVM virtual machine. Its primary purpose is to expose an easy-to-fuzz API to the Host (L0) fuzzer (`syzkaller`), allowing for state-aware interactions that are difficult to achieve with raw instruction fuzzing.

In this architecture, the **Host (syz-executor)** acts as the orchestrator, while the **Guest (SYZOS)** acts as the execution engine for a pre-defined sequence of commands.

### Execution Flow
SYZOS leverages syzkaller's standard execution model, where the fuzzer generates a sequence of syscalls (a `syzlang` program) to be executed by the host executor. For SYZOS, this program constructs the VM and defines the guest's internal logic via pseudo-syscalls.

1.  **VM Creation:** The fuzzer calls standard KVM ioctls (e.g., `openat`, `KVM_CREATE_VM`) to create the VM container.
2.  **Environment Setup (`syz_kvm_setup_syzos_vm`):** This pseudo-syscall automates the complex setup of Guest memory, ensuring the VM has valid code and stack regions.
3.  **VCPU & Program Loading (`syz_kvm_add_vcpu`, see 3.2):**
    * Instead of a bare `KVM_CREATE_VCPU`, the fuzzer calls `syz_kvm_add_vcpu` that creates a new VCPU in the VM and initializes its state.
        * This call takes the **entire sequence of SYZOS commands** as an argument. This sequence effectively becomes the "program" the guest will execute.
    * **Concurrency:** SYZOS supports up to 4 separate VCPUs sharing the same address space, allowing the fuzzer to schedule concurrent guest operations.
4.  **Execution (`KVM_RUN`):** The fuzzer triggers execution via standard `KVM_RUN` calls. The Guest executes its pre-loaded commands step-by-step.
    * **Yielding:** When the Guest needs to perform an action that requires Host intervention (e.g., a transition during Nested Virtualization), it yields to L0 via `UEXIT`.
    * **Resumption:** If the program contains multiple `KVM_RUN` calls, they are used to resume the Guest until the pre-loaded program completes.

### Design Philosophy
* **Logical Mutation:** Instead of fuzzing raw assembly bytes, SYZOS exposes high-level primitives to the fuzzer. The fuzzer mutates the arguments of the SYZOS commands.
* **State Validity:** By implementing setup sequences in C, SYZOS ensures that complex structures like IRQ tables or Page Tables are valid enough to reach deep kernel code paths.

---

## 2. Memory Layout & ABI (Communication Interface)

The Host and Guest communicate via a shared memory protocol. The Host writes commands and arguments into specific physical memory addresses, which the Guest maps and reads.

### Communication Interface
* **Command Channel:** A dedicated memory region where the Host writes the commands and their arguments.
* **Result Channel:** Mechanism for the Guest to report status back to the Host, piggybacked on the `UEXIT` mechanism.
* **Scratch Space:** Mutable memory used by the Guest to generate dynamic code blobs or store temporary data needed for operations like `MSR` writes.

### ARM64 Memory Map
The ARM64 implementation relies on a static physical memory layout to ensure the Host knows exactly where to place data.

| Physical Address | Description | Usage |
| :--- | :--- | :--- |
| `0x08000000` | GIC v3 Distributor | Interaction with Generic Interrupt Controller |
| `0x080a0000` | GIC v3 Redistributor | Per-CPU Interrupt Controller interface |
| `0xdddd0000` - `0xeeee0000` | Read-only / Command Page | Host writes SYZOS commands here. Also used to trigger page faults for `UEXIT` |
| `0xeeee8000` - `0xeeef0000` | Code / Scratch Space | Where SYZOS resides. Also used for generated code (e.g., MSR trampolines) |
| `0xffff1000` | EL1 Stack | Stack space for the SYZOS Guest execution |

### x86 Memory Map
While the exact addresses may vary by implementation, the x86 layout follows similar principles:
* **Guest Code:** Allocated via `KVM_SET_USER_MEMORY_REGION` (typically 1 page).
* **Page Tables:** Setup by the Host to allow virtual-to-physical translation required for long mode.
* **IDT (Interrupt Descriptor Table):** Setup by the Host to handle exceptions within the Guest.

---

## 3. Host-Side Implementation (`syz-executor`)

The Host side is responsible for the heavy lifting of VM initialization. This is achieved through "pseudo-syscalls" - functions implemented in `syz-executor` that look like syscalls to the fuzzer but perform complex setup logic.

### 3.1 VM Initialization: `syz_kvm_setup_syzos_vm()`
This pseudo-syscall creates the VM and prepares the environment.
* **Memory Allocation:** Calls `ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg)` multiple times to map the Guest physical memory slots (Code, Stack, MMIO).
* **Image Loading:** Copies the compiled SYZOS C library binary into the allocated Guest Code region.

### 3.2 VCPU Initialization: `syz_kvm_add_vcpu()`
This function adds a virtual CPU to the VM and configures its initial state to jump into the SYZOS entry point.
* **Program Loading:** It parses the `syzlang`-generated argument structure, which contains the sequence of SYZOS commands, and copies them into the Guest's Command Page.
* **Context Setup:**
    * **x86:** Sets guest CPUID to `KVM_GET_SUPPORTED_CPUID`, then sets up SREGS (64-bit mode, Segments, Page Tables) and IDT, and points RIP at `guest_main`. The order matters: KVM validates the EFER/CR4 bits passed to `KVM_SET_SREGS` against guest CPUID (e.g. `EFER.LME` requires `LM`, `EFER.SVME` requires `SVM`), so CPUID must be set first. If any step fails, `syz_kvm_add_vcpu` fails instead of returning a half-initialized VCPU.
    * **ARM64:** Sets PC to the entry point and SP to the stack.

### 3.3 The Handshake Mechanism (`UEXIT`)
The core synchronization primitive is the `UEXIT`.
* **Trigger:** The Guest reads from a specific unmapped or read-only address (e.g., inside `0xdddd0000` on ARM) or executes a specific instruction sequence.
* **Detection:** `KVM_RUN` returns on the Host. The Host may check `kvm_run->exit_reason`.
* **Handling:**
    * If the exit indicates a Page Fault (EPT violation) at the specific `UEXIT` address, the Host treats this as a voluntary yield.
    * The Host reads the exit qualification or register state to retrieve the "return argument" passed by the Guest.

---

## 4. Guest-Side Implementation (SYZOS Library)

### Source Organization & `GUEST_CODE`
SYZOS guest handlers are defined directly in architecture-specific executor headers (e.g., `executor/common_kvm_amd64_syzos.h`).
* **The `GUEST_CODE` Macro:** Functions intended to run inside the guest are marked with `GUEST_CODE` (e.g., `GUEST_CODE static void guest_handle_...`). This instructs the compiler/linker to place these functions in a specific section that `syz-executor` copies into the Guest's physical memory.
* **Header-Based Implementation:** The entire SYZOS codebase is contained within header files included by the executor. This architecture is necessitated by `syz-prog2c`, a tool that converts `syzlang` reproducers into standalone C programs. By concatenating these headers (via `#include` expansion), `syz-prog2c` can produce a single, build-system-independent C source file that compiles anywhere without external dependencies.

### The Dispatch Loop (`guest_main`)
The entry point `guest_main` iterates through the command buffer that was populated by `syz_kvm_add_vcpu`.
* **Command Routing (If/Else Chain):** The routing is strictly implemented as a series of `if/else if` statements rather than a `switch`. The reason for this is that a `switch` statement can be optimized by compilers into a jump table stored in the executable's `.rodata` section. Since the global data sections are not mapped into the Guest address space, accessing a jump table would cause an immediate Page Fault.
* **Argument Parsing:** Commands are cast to specific structures (e.g., `struct api_call_5*`) to access arguments safely.
* **Execution:** The handler performs the logic and the loop advances to the next command in the buffer.

### Core Primitives
* **`SYZOS_API_UEXIT`:** - Triggers a specific exception that the Host recognizes as a "yield". It passes a return value (1 argument) back to the Host to signal success/failure or data.
* **`SYZOS_API_CODE`:** - Executes a raw blob of machine code supplied by the Host. This can be used to emit exact instruction sequences not covered by high-level APIs.

---

## 5. Platform Specifics

### x86 (Intel & AMD)

#### Privileged Operations
SYZOS exposes specific APIs to fuzz privileged x86 instructions:
* **`SYZOS_API_CPUID`:** Executes the `CPUID` instruction.
* **`SYZOS_API_WRMSR` / `SYZOS_API_RDMSR`:** Reads/Writes Model Specific Registers.
* **`SYZOS_API_WR_CRN` / `SYZOS_API_WR_DRN`:** Writes to Control Registers and Debug Registers.
* **`SYZOS_API_IN_DX` / `SYZOS_API_OUT_DX`:** Executes I/O port operations.

#### Nested Virtualization (NV) Engine
SYZOS acts as a lightweight L1 hypervisor to fuzz L2 guests, abstracting the architectural differences between Intel VMX and AMD SVM. It provides a uniform API for the VM lifecycle while offering architecture-specific commands for state mutation.

##### VM Lifecycle & Execution
The following primitives control the nested guest's existence and execution flow:

* **`SYZOS_API_ENABLE_NESTED`:** Enables the virtualization extensions (VMXON on Intel, EFER.SVME on AMD).
* **`SYZOS_API_NESTED_CREATE_VM`:** Initializes the necessary control structures (VMCS for Intel, VMCB for AMD) and sets up Nested Page Tables.
* **`SYZOS_API_NESTED_LOAD_CODE`:** Injects a sequence of instructions into the L2 guest's memory, defining what code the nested machine will execute.
* **`SYZOS_API_NESTED_VMLAUNCH`:** Performs the initial VM Entry, transferring control to the L2 guest.
* **`SYZOS_API_NESTED_VMRESUME`:** Resumes execution of the L2 guest after it has exited back to L1.

##### State Mutation (Architecture Specific)
To stress the host's handling of invalid or edge-case states, SYZOS allows direct mutation of the hardware control structures. This is done by applying the "set/unset/flip" mask logic: `new_val = (old_val & ~unset_mask) | set_mask ^ flip_mask`.
The SYZOS commands are **`SYZOS_API_NESTED_INTEL_VMWRITE_MASK`** (mutates the VMCS fields on Intel) and **`SYZOS_API_NESTED_AMD_VMCB_WRITE_MASK`** (VMCB on AMD).

---

### ARM64

#### Device Emulation
A significant portion of ARM64 KVM code is device emulation. SYZOS provides specialized APIs to fuzz these complex interactions.
* **GICv3 & ITS:**
    * **`SYZOS_API_IRQ_SETUP`:** Sets up the VGICv3 distributor and installs the guest IRQ table.
    * **`SYZOS_API_ITS_SETUP`:** Allocates translation tables and configures the Interrupt Translation Service (ITS) base.
    * **`SYZOS_API_ITS_SEND_CMD`:** Injects structured GIC commands (e.g., `MAPD`, `MOVI`) into the command queue.

#### Hypervisor Interface
SYZOS targets the boundary between the Guest and EL2/Firmware.
* **Hypercalls:**
    * **`SYZOS_API_HVC`:** Executes `hvc #0` with fuzzer-controlled parameters in registers `x0-x5`.
    * **`SYZOS_API_SMC`:** Executes `smc #0` (Secure Monitor Call) with parameters in `x0-x5`.

---

## 6. Developer Guide: How to Add a New Command

This guide details the process of adding a new SYZOS command, using `SYZOS_API_NESTED_AMD_VMCB_WRITE_MASK` as a reference case.

### Step 1: Define API ID and Handler Prototype
Modify the architecture-specific executor header (e.g., `executor/common_kvm_amd64_syzos.h`) to register the new command.

1.  **Add the Enum ID:** Add a new entry to the `syzos_api_id` enum.
    ```c
    typedef enum {
        // ...
        SYZOS_API_NESTED_AMD_VMCB_WRITE_MASK = 380, // New ID
        SYZOS_API_STOP,
    } syzos_api_id;
    ```
2.  **Declare the Handler:** Add a forward declaration using the `GUEST_CODE` macro.
    ```c
    GUEST_CODE static void guest_handle_nested_amd_vmcb_write_mask(struct api_call_5* cmd, uint64 cpu_id);
    ```

Note: make sure to choose the optimal api_call_N structure that exactly matches the number of arguments required by your new primitive (e.g., use struct api_call_2 for a command needing two arguments). If no arguments are required, omit the `cmd` parameter altogether. If the guest code does not access VMCB/VMCS, omit the `cpu_id` parameter.

### Step 2: Implement Guest Logic and Dispatch
In the same file (or corresponding source), implement the guest logic.

1.  **Add Dispatch Case:** Update `guest_main`.
    ```c
    } else if (call == SYZOS_API_NESTED_AMD_VMCB_WRITE_MASK) {
        guest_handle_nested_amd_vmcb_write_mask((struct api_call_5*)cmd, cpu);
    }
    ```
2.  **Implement Handler:** Write the function logic. Strict guest-safe code restrictions apply.
    ```c
    GUEST_CODE static noinline void
    guest_handle_nested_amd_vmcb_write_mask(struct api_call_5* cmd, uint64 cpu_id)
    {
        if (get_cpu_vendor() != CPU_VENDOR_AMD) return;
        // ... parse args and perform logic ...
        vmcb_write64(vmcb_addr, offset, new_value);
    }
    ```

### Step 3: Define syzlang Description
Expose the new command to `syzkaller` in the description file (e.g., `sys/linux/dev_kvm_amd64.txt`).

1.  **Define Structures:** Define any necessary constants or structures.
    ```
    syzos_api_nested_amd_vmcb_write_mask {
	vm_id		syzos_api_vm_id
	offset		vmcb_offset
	set_mask	int64
	unset_mask	int64
	flip_mask	int64
    }
    ```

2.  **Map Command ID:** Add the command to the `syzos_api_call` union. **Crucial:** The ID (e.g., `380`) must match the enum in the C header.
    ```
    syzos_api_call$x86 [
        nested_amd_vmcb_write_mask  syzos_api$x86[380, syzos_api_nested_amd_vmcb_write_mask]
    ] [varlen]
    ```

---

## 7. Validation & Regression Testing

The system includes a regression testing framework located in `sys/linux/test/`. New commands must include a test case to verify they trigger the expected Hypervisor behavior.

### Test File Structure
Tests are `syzlang` programs with special assertions.
* **Header:** Requires metadata, e.g., `# requires: arch=amd64 -threaded`.
* **Setup:** Standard boilerplate creates a VM and enters SYZOS.
* **Logic:** The test configures the guest to perform a specific action (e.g., executing `HLT` in a nested L2 guest).

### Assertions
Tests use specialized pseudo-syscalls to assert the VM's exit state:
* **`syz_kvm_assert_syzos_uexit$x86(fd, code)`:** Asserts that the guest voluntarily yielded with a specific `UEXIT` code (e.g., `0xe2e20001`).
* **`syz_kvm_assert_syzos_kvm_exit$x86(fd, exit_reason)`:** Asserts that the guest triggered a standard KVM exit (e.g., `0x5` for `KVM_EXIT_HLT`) that was trapped by L0.

---

### Talks (`docs/talks.md`)

# Tech talks

_newer first_

* [Head First Reporting of Linux Kernel CVEs: Practical Use of the Kernel Fuzzer](https://static.sched.com/hosted_files/sosscdjapan2024/7a/Head%20First%20Reporting%20of%20Linux%20Kernel%20CVEs%20-%20sosscj24.pdf) at [SOSS Community Day (Japan, 2024)](https://events.linuxfoundation.org/soss-community-day-japan/program/schedule/)
* [Syzbot: 7 years of continuous kernel fuzzing](https://lpc.events/event/17/contributions/1521/attachments/1272/2698/LPC'23_%20Syzbot_%207%20years%20of%20continuous%20kernel%20fuzzing.pdf) at [Linux Plumbers 2023](https://lpc.events/event/17/contributions/1521/)
* [Designing UAPI for Fuzz-ability](https://lpc.events/event/16/contributions/1309/attachments/988/1979/Designing%20subsystems%20for%20testability_fuzzing%20%28PDF%20version%29.pdf) at [Linux Plumbers 2022](https://lpc.events/event/16/contributions/1309/)
* [Making syzbot reports more developer-friendly](https://lpc.events/event/16/contributions/1311/attachments/1013/1951/Making%20syzbot%20reports%20more%20developer-friendly.pdf) at [Linux Plumbers 2022](https://lpc.events/event/16/contributions/1311/)
* [syzkaller: adventures in continuous coverage-guided kernel fuzzing](https://www.youtube.com/watch?v=YwX4UyXnhz0)
at [BlueHatIL 2020](https://www.bluehatil.com)
[[presentation]](https://docs.google.com/presentation/d/e/2PACX-1vRWjOOL45BclKsCPMzdWmvH12hu-Ld1cU5MbB1tqcBhjVIr1M_qxZRE-ObKcVmqpCyqRAO62Sxm0_aW/pub?start=false&loop=false&delayms=3000)
[[slides]](https://msrnd-cdn-stor.azureedge.net/bluehat/bluehatil/2019/assets/doc/syzkaller%20Adventures%20in%20Continuous%20Coverage-guided%20Kernel%20Fuzzing.pdf)
* [Bugs on the Windshield: Fuzzing the Windows Kernel](https://www.youtube.com/watch?v=__7PAzgbprw)
at [BlueHatIL 2020](https://www.bluehatil.com)
[[slides]](https://msrnd-cdn-stor.azureedge.net/bluehat/bluehatil/2019/assets/doc/Bugs%20on%20the%20Windshield%20Fuzzing%20the%20Windows%20Kernel.pdf)
* [Fuzzing the OpenBSD Kernel](https://www.openbsd.org/papers/fuzz-slides.pdf)
* [syzkaller in FreeBSD](https://papers.freebsd.org/2019/octvendorsummit/johnston-syzkaller/)
* [Фаззинг ядра Linux на практике](http://0x1.tv/20191206AG) at ISPRASOPEN-2019 (in Russian)
* [syzbot: update and open problems](https://linuxplumbersconf.org/event/4/contributions/428/attachments/308/515/syzbot__Plumbers_2019.pdf)
at [Linux Plumbers 2019](https://linuxplumbersconf.org/event/4/contributions/428/)
* [GWP-ASAN](https://linuxplumbersconf.org/event/4/contributions/425/attachments/307/513/GWP-ASAN__Plumbers_2019.pdf)
at [Linux Plumbers 2019](https://linuxplumbersconf.org/event/4/contributions/425/)
* [syzkaller: update and open problems](https://static.sched.com/hosted_files/lssna19/16/syzkaller%20LSS%20NA%202019.pdf)
at [Linux Security Summit NA 2019](https://lssna19.sched.com/event/RHaW)
* [WSL Reloaded](https://www.slideshare.net/AnthonyLAOUHINETSUEI/wsl-reloaded)
* [Drill Apple Core: Up and Down](https://www.youtube.com/watch?v=zDXyH8HxTwg)
at Blackhat Europe 2018 [[slides]](https://i.blackhat.com/eu-18/Wed-Dec-5/eu-18-Juwei_Lin-Drill-The-Apple-Core.pdf)
* [Evolution of kernel fuzzers in NetBSD](https://troopers.de/downloads/troopers19/TROOPERS19_AR_Evolution_of_kernel.pdf)
* [syzbot: automated kernel testing](https://linuxplumbersconf.org/event/2/contributions/237/attachments/61/71/syzbot_automated_kernel_testing.pdf)
at [Linux Plumbers 2018](https://linuxplumbersconf.org/event/2/contributions/237/)
* [syzbot and the tale of thousand kernel bugs](https://www.youtube.com/watch?v=qrBVXxZDVQY)
at [Linux Security Summit NA 2018](https://lssna18.sched.com/event/FLYI/syzbot-and-the-tale-of-thousand-kernel-bugs-dmitry-vyukov-google) [[slides]](https://events19.linuxfoundation.org/wp-content/uploads/2017/11/Syzbot-and-the-Tale-of-Thousand-Kernel-Bugs-Dmitry-Vyukov-Google.pdf)
* [syzkaller+KASAN](https://docs.google.com/presentation/d/e/2PACX-1vSEBicdYC8lHHglZeRt8zw-UQHSs8WohvF94X6th9vgNYDXEACla9-0QLf5T4Xgp-ue9I7ceIS-4InI/pub?start=false&loop=false&delayms=3000)
at [SIL2LinuxMP Workshop 2018](http://www.osadl.org/SIL2LinuxMP-Workshop-7-April-17-to-19.sil2linuxmp-workshop7.0.html)
* [ubsan, kasan, syzkaller und co](https://www.youtube.com/watch?v=Acp0A9X1254&t=1699s)
* [syzkaller: the next gen kernel fuzzer](https://www.slideshare.net/DmitryVyukov/syzkaller-the-next-gen-kernel-fuzzer)
at Qualcomm Mobile Security Summit 2017
* [syzkaller: future development](https://www.linuxplumbersconf.net/2016/ocw//system/presentations/3561/original/Syzkaller.pdf)
at [Linux Plumbers 2016](https://blog.linuxplumbersconf.org/2016/ocw/proposals/3561.html)
* [Sanitizers: a new generation of bug finding tools](https://blog.linuxplumbersconf.org/2016/ocw/system/presentations/3471/original/Sanitizers.pdf)
at [Linux Plumbers 2016](https://blog.linuxplumbersconf.org/2016/ocw/proposals/3471.html)
* [Kernel Sanitizers: a new generation of bug finding tools for Linux kernel](https://docs.google.com/presentation/d/e/2PACX-1vQyApzKGeFnrfOETIscmnpvxRz9pVwzNTQE495LnP1MRXQjQmtZGr9LlN2ITplw73h-ma4ZVyq-33OV/pub?start=false&loop=false&delayms=3000)
at GeeKon 2015
* [AddressSanitizer/ThreadSanitizer for Linux Kernel](https://www.youtube.com/watch?v=capbD_aRz40)
at Linux Collaboration Summit 2013

# Articles

* [Your NVMe Had Been Syz’ed: Fuzzing NVMe-oF/TCP Driver for Linux with Syzkaller](https://www.cyberark.com/resources/threat-research-blog/your-nvme-had-been-syzed-fuzzing-nvme-of-tcp-driver-for-linux-with-syzkaller)
* [Looking for Remote Code Execution bugs in the Linux kernel](https://xairy.io/articles/syzkaller-external-network)
* From [Collabora](https://twitter.com/Collabora):
  * [syzkaller: fuzzing the kernel](https://www.collabora.com/news-and-blog/blog/2020/03/26/syzkaller-fuzzing-the-kernel/)
  * [Using syzkaller to detect programming bugs in the Linux kernel](https://www.collabora.com/news-and-blog/blog/2020/04/17/using-syzkaller-to-detect-programming-bugs-in-linux/)
  * [Using syzkaller: fuzzing your changes](https://www.collabora.com/news-and-blog/blog/2020/05/12/using-syzkaller-fuzzing-your-changes/)
* From [HardenedLinux](https://github.com/hardenedlinux) project:
  * [Kernel QA with syzkaller and qemu](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/harbian_qa/fuzz_testing/syzkaller_general.md) (tutorial on how to setup syzkaller with qemu)
  * [Syzkaller crash DEMO](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/harbian_qa/fuzz_testing/syzkaller_crash_demo.md) (tutorial on how to extend syzkaller with new syscalls)
  * [Kernel debug tool with syzkaller](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/harbian_qa/fuzz_testing/syz_debug.md) (debugging qemu VM created by syz-manager with gdb)
  * [Explanation of some syzkaller internals](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/harbian_qa/fuzz_testing/syz_analysis.md)
  * [A example of fuzzing the ceph filesystem](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/tree/master/docs/harbian_qa/fuzz_testing/syz_for_ceph)
* [Exploiting the Linux kernel via packet sockets](https://googleprojectzero.blogspot.com/2017/05/exploiting-linux-kernel-via-packet.html)
* [Coverage-guided kernel fuzzing with syzkaller](https://lwn.net/Articles/677764/) (by David Drysdale)
* [Debugging a kernel crash found by syzkaller](http://vegardno.blogspot.de/2016/08/sync-debug.html) (by Quentin Casasnovas)

Also see [research page](/docs/research.md).

---

### Troubleshooting (`docs/troubleshooting.md`)

# Troubleshooting

Here are some things to check if there are problems running syzkaller.

- Use the `-debug` command line option to make syzkaller print all possible debug output,
  from both the `syz-manager` top-level program and the `syz-executor` instances.
  With this option syzkaller will only run one VM instance.

- Use the `-vv N` command line option to increase the amount of logging output, from both
  the `syz-manager` top-level program and the `syz-executor` instances (which go to the
  output files in the `crashes` subdirectory of the working directory). Higher values of
  N give more output.

- If logging indicates problems with the executor program (e.g. `executor failure`),
  try manually running a short sequence of system calls:
  - Copy `syz-executor` and `syz-execprog` into a running VM.
  - In the VM run `./syz-execprog -executor ./syz-executor -debug sampleprog` where
    sampleprog is a simple system call script (e.g. just containing `getpid()`).
  - For example, if this reports that `clone` has failed, this probably indicates
    that the test kernel does not include support for all of the required namespaces.
    In this case, running the `syz-execprog` test with the `-sandbox=setuid` option fixes the problem,
    so the main configuration needs to be updated to set `sandbox` to `setuid`.

- If syzkaller prints the `failed to copy binary` error shortly after VM has booted:
  - If you're using Buildroot images and the error output contains the `subsystem request
    failed on channel 0` line, this can be due to the [OpenSSH 9.0 changes](https://www.openssh.com/txt/release-9.0)
    that force the use of the SFTP protocol. Upgrade your Buildroot image to the latest version and
    make sure SFTP is enabled there.

Also see [this](linux/troubleshooting.md) for Linux kernel specific troubleshooting advice.

If none of the above helps, file a bug on [the bug tracker](https://github.com/google/syzkaller/issues)
or ask us directly on the syzkaller@googlegroups.com mailing list.
Please include syzkaller commit id that you use and `syz-manager` output with `-debug` flag enabled if applicable.

---

### Usage (`docs/usage.md`)

# How to use syzkaller

## Running

Start the `syz-manager` process as:

```bash
./bin/syz-manager -config my.cfg
```

The `syz-manager` process will wind up VMs and start fuzzing in them.
The `-config` command line option gives the location of the configuration file, which is described [here](configuration.md).
Found crashes, statistics and other information is exposed on the HTTP address specified in the manager config.

## Crashes

Once syzkaller detected a kernel crash in one of the VMs, it will automatically start the process of reproducing this crash (unless you specified `"reproduce": false` in the config).
By default it will use 4 VMs to reproduce the crash and then minimize the program that caused it.
This may stop the fuzzing, since all of the VMs might be busy reproducing detected crashes.

The process of reproducing one crash may take from a few minutes up to an hour depending on whether the crash is easily reproducible or non-reproducible at all.
Since this process is not perfect, there's a way to try to manually reproduce the crash, as described [here](reproducing_crashes.md).

If a reproducer is successfully found, it can be generated in one of the two forms: syzkaller program or C program.
Syzkaller always tries to generate a more user-friendly C reproducer, but sometimes fails for various reasons (for example slightly different timings).
In case syzkaller only generated a syzkaller program, there's [a way to execute them](reproducing_crashes.md) to reproduce and debug the crash manually.

## Hub

In case you're running multiple `syz-manager` instances, there's a way to connect them together and allow to exchange programs and reproducers, see the details [here](hub.md).

## Reporting bugs

Check [here](linux/reporting_kernel_bugs.md) for the instructions on how to report Linux kernel bugs.

---

### Darwin Found Bugs (`docs/darwin/found_bugs.md`)

# Found bugs

[panicall](https://twitter.com/panicaII) has ported
([[1]](https://i.blackhat.com/eu-18/Wed-Dec-5/eu-18-Juwei_Lin-Drill-The-Apple-Core.pdf)
([video](https://www.youtube.com/watch?v=zDXyH8HxTwg)),
[[2]](https://conference.hitb.org/hitbsecconf2019ams/materials/D2T2%20-%20PanicXNU%203.0%20-%20Juwei%20Lin%20&%20Junzhi%20Lu.pdf))
syzkaller to `Darwin/XNU` and that has found more than
[50 bugs](https://twitter.com/panicaII/status/1070696972326133760) including
`CVE-2018-4447` and `CVE-2018-4435` mentioned in
[Apple security updates](https://support.apple.com/en-us/HT209341). However he
didn't upstream his work.

Since 2021 Syzkaller is able to fuzz macOS, however it's not integrated into
syzbot for licensing reasons.

---

### Freebsd Found Bugs (`docs/freebsd/found_bugs.md`)

# Found Bugs

Newer bugs come first

- [Fix udp_output() lock inconsistency.](https://reviews.freebsd.org/rS346595)
- [Fix IPV6_CHECKSUM computation.](https://reviews.freebsd.org/rS346402)
- [When sending a routing message, don't allow the user to set the RTF_RNH_LOCKED flag in rtm_flags.](https://reviews.freebsd.org/rS346197)
- [Fix an SCTP related locking issue.](https://reviews.freebsd.org/rS346134)
- [Reinitialize multicast source filter structures after invalidation.](https://reviews.freebsd.org/rS346118)
- [Fix a small locking bug in tcp_log_id().](https://reviews.freebsd.org/rS346094)
- [Fix a double free of an SCTP association in an error path.](https://reviews.freebsd.org/rS345525)
- [Reject F_SETLK_REMOTE commands when sysid == 0.](https://reviews.freebsd.org/rS345513)
- [Initialize scheduler specific data for the FCFS scheduler.](https://reviews.freebsd.org/rS345505)
- [Improve locking when tearing down an SCTP association.](https://reviews.freebsd.org/rS345504)
- [Fix more signed unsigned issues in SCTP.](https://reviews.freebsd.org/rS345466)
- [Fix a signed/unsigned bug when receiving SCTP messages.](https://reviews.freebsd.org/rS345465)
- [Limit the size of messages sent on 1-to-many style SCTP sockets with the SCTP_SENDALL flag.](https://reviews.freebsd.org/rS345461)
- [Limit the number of bytes which can be queued for SCTP sockets.](https://reviews.freebsd.org/rS345460)
- [Fix a KASSERT() in tcp_output().](https://reviews.freebsd.org/rS345441)
- [Disallow preemptive creation of wired superpage mappings.](https://reviews.freebsd.org/rS345382)
- [vm_fault_copy_entry: accept invalid source pages.](https://reviews.freebsd.org/rS345324)
- [Fix a bug in the SCTP stream schedulers.](https://reviews.freebsd.org/rS344872)
- [Allocate an association id and register the stcb with holding the lock.](https://reviews.freebsd.org/rS344742)
- [Allow SCTP stream reconfiguration operations only in ESTABLISHED state.](https://reviews.freebsd.org/rS344724)
- [Fix handling of the SCTP_STATUS socket option in early states.](https://reviews.freebsd.org/rS344723)
- [Honor the memory limits provided when processing the SCTP_GET_LOCAL_ADDRESSES socket option.](https://reviews.freebsd.org/rS344708)
- [Check the index hasn't changed after writing the cmp entry.](https://reviews.freebsd.org/rS344517)
- [Improve input validation for raw IPv4 socket using the IP_HDRINCL option.](https://reviews.freebsd.org/rS344048)
- [Fix a locking issue in the IPPROTO_SCTP level SCTP_PEER_ADDR_THLDS socket.](https://reviews.freebsd.org/rS343960)
- [Fix a locking bug in the IPPROTO_SCTP level SCTP_EVENT socket option.](https://reviews.freebsd.org/rS343954)
- [Fix locking for IPPROTO_SCTP level SCTP_DEFAULT_PRINFO socket option.](https://reviews.freebsd.org/rS343951)
- [Fix an off-by-one error in the input validation of the SCTP_RESET_STREAMS socketoption.](https://reviews.freebsd.org/rS343769)
- [Limit the user-controllable amount of memory the kernel allocates via IPPROTO_SCTP level socket options.](https://reviews.freebsd.org/rS343089)
- [Fix getsockopt() for IP_OPTIONS/IP_RETOPTS.](https://reviews.freebsd.org/rS342879)
- [Avoid overflow in vtruncbuf().](https://reviews.freebsd.org/rS342857)
- [Limit option_len for the TCP_CCALGOOPT.](https://reviews.freebsd.org/rS341335)
- [Correct vm_fault_copy_entry() handling of backing file truncation after the file mapping was wired.](https://reviews.freebsd.org/rS338999)
- [In vm_fault_copy_entry(), we should not assert that entry is charged if the dst_object is not of swap type.](https://reviews.freebsd.org/rS338998)
- [Handle a guest executing a vm instruction by trapping and raising an undefined instruction exception.](https://reviews.freebsd.org/rS338957)
- [disallow clock_settime too far in the future to avoid panic.](https://reviews.freebsd.org/rS325825)
- [Fix parsing error when processing cmsg in SCTP send calls.](https://reviews.freebsd.org/rS325046)

---

### Linux Coverage (`docs/linux/coverage.md`)

# Coverage

Syzkaller uses [kcov](https://www.kernel.org/doc/html/latest/dev-tools/kcov.html) to collect coverage from the kernel. kcov exports the address of each executed basic block, and syzkaller runtime uses tools from `binutils` (`objdump`, `nm`, `addr2line` and `readelf`) to map these addresses to lines and functions in the source code.

## Binutils

Note that if you are fuzzing in cross-arch environment you need to provide correct `binutils` cross-tools to syzkaller before starting `syz-manager`:

``` bash
mkdir -p ~/bin/mips64le
ln -s `which mips64el-linux-gnuabi64-addr2line` ~/bin/mips64le/addr2line
ln -s `which mips64el-linux-gnuabi64-nm` ~/bin/mips64le/nm
ln -s `which mips64el-linux-gnuabi64-objdump` ~/bin/mips64le/objdump
ln -s `which mips64el-linux-gnuabi64-readelf` ~/bin/mips64le/readelf
export PATH=~/bin/mips64le:$PATH
```

The target-triple prefix is determined based on the `target` config option.

### readelf

`readelf` is used to detect virtual memory offset.

```
readelf -SW kernel_image
```

The meaning of the flags is as follows:

* `-S' - list section headers in the kernel image file
* `-W' - output each section header entry in a single line

Example output of the command:

```
There are 59 section headers, starting at offset 0x3825258:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        ffffffff81000000 200000 e010f7 00  AX  0   0 4096
  [ 2] .rela.text        RELA            0000000000000000 23ff488 684720 18   I 56   1  8
  [ 3] .rodata           PROGBITS        ffffffff82000000 1200000 2df790 00  WA  0   0 4096
  [ 4] .rela.rodata      RELA            0000000000000000 2a83ba8 0d8e28 18   I 56   3  8
  [ 5] .pci_fixup        PROGBITS        ffffffff822df790 14df790 003180 00   A  0   0 16
  [ 6] .rela.pci_fixup   RELA            0000000000000000 2b5c9d0 004a40 18   I 56   5  8
  [ 7] .tracedata        PROGBITS        ffffffff822e2910 14e2910 000078 00   A  0   0  1
  [ 8] .rela.tracedata   RELA            0000000000000000 2b61410 000120 18   I 56   7  8
  [ 9] __ksymtab         PROGBITS        ffffffff822e2988 14e2988 011b68 00   A  0   0  4
  [10] ...
```

Executor truncates PC values into `uint32` before sending them to `syz-manager` and `syz-manager` uses section header information to recover the offset. Only the section headers of type `PROGBITS` are considered. The `Address` field represents the virtual address of a section in memory (for the sections that are loaded). It is required that all `PROGBITS` sections have same upper 32 bits in the `Address` field. These 32 bits are used as recovery offset.


## Reporting coverage data

`MakeReportGenerator` factory creates an object database for the report. It requires target data, as well as information on the location of the source files and build directory. The first step in building this database is
extracting the function data from the target binary.
### nm

`nm` is used to parse address and size of each function in the kernel image

```
nm -Ptx kernel_image
```

The meaning of the flags is as follows:

* `-P` - use the portable output format (Standard Output)
* `-tx` - write the numeric values in the hex format

Output is of the following form:

```
tracepoint_module_nb d ffffffff84509580 0000000000000018
...
udp_lib_hash t ffffffff831a4660 0000000000000007
```

The first column is a symbol name and the second column is its type (e.g. text section, data section, debugging symbol, undefined, zero-init section, etc.). The third column is the symbol value in hex format while the forth column contains its size. The size is always rounded to up to 16 in syzkaller. For the report, we are only interested in the code sections so the `nm` output is filtered for the symbols with type `t` or `T`.
The final result is a map with symbol names as keys, values being starting and ending address of a symbol. This information is used to map coverage data to symbols (functions). This step is needed to find out whether certain functions are called at all.

## Object Dump and Symbolize

In order to provide the necessary information for tracking the coverage information with syzkaller, the compiler is instrumented to insert the `__sanitizer_cov_trace_pc` call into every basic block generated during the build process. These instructions are then used as anchor points to backtrack the covered code lines.

### objdump

`objdump` is used to parse PC value of each call to `__sanitizer_cov_trace_pc` in the kernel image. These PC values are representing all code that is built into kernel image. PC values exported by kcov are compared against these to determine coverage.

The kernel image is disassembled using the following command:

```
objdump -d --no-show-raw-insn kernel_image
```

The meaning of the flags is as follows:

* `-d` - disassemble executable code blocks
* `-no-show-raw-insn` - prevent printing hex alongside symbolic disassembly

Excerpt output looks like this:

```
...
ffffffff81000f41:	callq  ffffffff81382a00 <__sanitizer_cov_trace_pc>
ffffffff81000f46:	lea    -0x80(%r13),%rdx
ffffffff81000f4a:	lea    -0x40(%r13),%rsi
ffffffff81000f4e:	mov    $0x1c,%edi
ffffffff81000f53:	callq  ffffffff813ed680 <perf_trace_buf_alloc>
ffffffff81000f58:	test   %rax,%rax
ffffffff81000f5b:	je     ffffffff8100110e <perf_trace_initcall_finish+0x2ae>
ffffffff81000f61:	mov    %rax,-0xd8(%rbp)
ffffffff81000f68:	callq  ffffffff81382a00 <__sanitizer_cov_trace_pc>
ffffffff81000f6d:	mov    -0x40(%r13),%rdx
ffffffff81000f71:	mov    0x8(%rbp),%rsi
...
```

From this output coverage trace calls are identified to determine the start of the executable block addresses:

```
ffffffff81000f41:	callq  ffffffff81382a00 <__sanitizer_cov_trace_pc>
ffffffff81000f68:	callq  ffffffff81382a00 <__sanitizer_cov_trace_pc>
```

### addr2line

`addr2line` is used for mapping PC values exported by kcov and parsed by `objdump` to source code files and lines.

```
addr2line -afi -e kernel_image
```

The meaning of the flags is as follows:

* `-afi` - means show addresses, function names and unwind inlined functions
* `-e` - is switch for specifying executable instead of using default

`addr2line` reads hexadecimal addresses from standard input and prints the filename
function and line number for each address on standard output. Example usage:

```
>> ffffffff8148ba08
<< 0xffffffff8148ba08
<< generic_file_read_iter
<< /home/user/linux/mm/filemap.c:2363
```

where `>>` represents the query and `<<` is the response from the `addr2line`.

The final goal is to have a hash table of frames where key is a program counter
and value is a frame array consisting of a following information:

* `PC` - 64bit program counter value (same as key)
* `Func` - function name to which the frame belongs
* `File` - file where function/frame code is located
* `Line` - Line in a file to which program counter maps
* `Inline` - boolean inlining information

Multiple frames can be linked to a single program counter value due to inlining.

## Creating report

Once the database of the frames and function address ranges is created the next step is to determine the program coverage. Each program is represented here as a series of program counter values. As the function address ranges are known at this point it is easy to determine which functions were called by simply comparing the program counters against these address intervals. In addition, the coverage information is aggregated over the source files based on the program counters that are keys in the frame hash map. These are marked as `coveredPCs`. The resulting coverage is not line based but the basic block based. The end result is stored in the `file` struct containing the following information:

* `lines` - lines covered in the file
* `totalPCs` - total program counters identified for this file
* `coveredPCs` - the program counters that were executed in the program run
* `totalInline` - total number of program counters mapped to inlined frames
* `coveredInline` - the program counters mapped to inlined frames that were executed in the program run

---

### Linux External Fuzzing Network (`docs/linux/external_fuzzing_network.md`)

External network fuzzing for Linux kernel
=========================================

syzkaller has support for external fuzzing of the network stack.
This is achieved by using the [TUN/TAP](https://www.kernel.org/doc/Documentation/networking/tuntap.txt) interface.
It allows to set up a virtual network interface and send packets to the kernel as they are being received from an external network.
This triggers the same paths as a real packet delivered through a real network interface (except for the driver layer).

You need to enable the `CONFIG_TUN` kernel config to enable external network fuzzing.
See `initialize_tun()` in [executor/common_linux.h](/executor/common_linux.h) for the exact way the virtual interface is set up.

The template descriptions can be found in [sys/linux/vnet.txt](/sys/linux/vnet.txt).
At this moment there are 2 fake syscalls: `syz_emit_ethernet` and `syz_extract_tcp_res`.
The first one externally sends a packet through the virtual interface.
The second one tries to externally receive a packet back and parse TCP sequence numbers from it for use in subsequent packets.
There are many protocols or protocol extensions that are not described yet, so the additions are welcome!

Since fuzzing may be done in multiple executor processes within the same VM instance, we need a way to isolate the virtual networks for different executors.
Right now this is done by creating one virtual interface per executor and assigning different MAC, IPv4 and IPv6 addresses to each of these interfaces.
Then the template descriptions make use of the `proc` type to generate proper addresses for each executor.

Since many network protocols require checksum fields to be embedded into packets, there's a support for describing such fields.
There's a `csum` type, which right now supports two different kinds of checksumming:
[the Internet checksum](https://tools.ietf.org/html/rfc1071): `csum[parent, inet, int16be]`,
and TCP-like pseudo header checksum: `csum[tcp_packet, pseudo, IPPROTO_TCP, int16be]`.
The checksums are computed and embedded right before emitting a packet through the virtual interface.
There's also a nice feature: when syzkaller generates a C reproducer, it generates code to compute checksums in runtime as well.

By using `syz_emit_ethernet` and `syz_extract_tcp_res` the following syzkaller program is able to establish a TCP connection over IPv4:

```
mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r0, &(0x7f0000001000)={0x2, 0x0, @empty=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x10)
listen(r0, 0x5)
syz_emit_ethernet(0x36, &(0x7f0000002000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="4c6112cc15d8", [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}})
syz_extract_tcp_res(&(0x7f0000003000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0)
syz_emit_ethernet(0x38, &(0x7f0000004000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @remote={[0xbb, 0xbb, 0xbb, 0xbb, 0xbb], 0x0}, [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {"0c10"}}}}}})
r3 = accept$inet(r0, &(0x7f0000005000)={0x0, 0x0, @multicast1=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, &(0x7f0000006000)=0x10)
```

```
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:20000           0.0.0.0:*               LISTEN      5477/a.out
tcp        2      0 172.20.0.170:20000      172.20.0.187:20001      ESTABLISHED 5477/a.out
```

Similar program for IPv6:

```
mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = socket$inet6_tcp(0xa, 0x1, 0x0)
bind$inet6(r0, &(0x7f0000000000)={0xa, 0x1, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, 0x1c)
listen(r0, 0x5)
syz_emit_ethernet(0x4a, &(0x7f0000001000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}})
syz_extract_tcp_res(&(0x7f0000002000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0)
syz_emit_ethernet(0x4a, &(0x7f0000003000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}})
r3 = accept$inet6(r0, &(0x7f0000004000)={0x0, 0x0, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, &(0x7f0000005000)=0x1c)
```

```
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::20001                :::*                    LISTEN      5527/a.out
tcp6       0      0 fe80::aa:20001          fe80::bb:20000          ESTABLISHED 5527/a.out
```

---

### Linux External Fuzzing Usb (`docs/linux/external_fuzzing_usb.md`)

External USB fuzzing for Linux kernel
=====================================

syzkaller supports fuzzing the Linux kernel USB subsystem from the external USB device side.
Instead of relying on physical hardware (like [Facedancer](https://github.com/usb-tools/Facedancer)-based boards) or VM management software features (like QEMU [usbredir](https://www.spice-space.org/usbredir.html)), syzkaller fuzzes USB fully within a (potentially-virtualized) environment that runs the Linux kernel.

The USB fuzzing support in syzkaller is based on:

1. [Raw Gadget](https://github.com/xairy/raw-gadget) — a kernel module that implements a low-level interface for the Linux USB Gadget subsystem (now in the mainline kernel);
2. [Dummy HCD/UDC](https://github.com/xairy/raw-gadget/tree/master/dummy_hcd) — a kernel module that sets up virtual USB Device and Host controllers that are connected to each other inside the kernel (existed in the mainline kernel for a long time);
3. KCOV changes that allow collecting coverage [from background kernel threads and interrupts](https://docs.kernel.org/dev-tools/kcov.html#remote-coverage-collection) (now in the mainline kernel);
4. syzkaller changes built on top of the other parts; see the [Internals](/docs/linux/external_fuzzing_usb.md#Internals) section.

Besides this documentation page, for details, see:

- [Coverage-Guided USB Fuzzing with Syzkaller](https://docs.google.com/presentation/d/1z-giB9kom17Lk21YEjmceiNUVYeI6yIaG5_gZ3vKC-M/edit?usp=sharing) talk ([video](https://www.youtube.com/watch?v=1MD5JV6LfxA)) from OffensiveCon 2019 (was given while the USB fuzzing support was a work-in-progress, so some details are outdated);

- [Fuzzing USB with Raw Gadget](https://docs.google.com/presentation/d/1sArf2cN5tAOaovlaL3KBPNDjYOk8P6tRrzfkclsbO_c/edit?usp=sharing) talk ([video](https://www.youtube.com/watch?v=AT3PQjKxa_c)) from BSides Munich 2022 (more up-to-date, but less in-depth);

- [External fuzzing of Linux kernel USB drivers with syzkaller](https://docs.google.com/presentation/d/1ba7Au3Gt6dEQAsfZmjUdzjVWHKxE_EdaJGU9WOSF-Ts/edit?usp=sharing) talk (outlines steps for adding new basic USB descriptions).

See [this page](/docs/linux/found_bugs_usb.md) for the list of bugs found in the Linux kernel USB stack so far.


## Setting up

1. Use the kernel version 5.7 or later.

    It's also recommended to backport all kernel patches that touch `drivers/usb/gadget/legacy/raw_gadget.c`, `drivers/usb/gadget/udc/dummy_hcd.c`, and `kernel/kcov.c`;

2. Enable `CONFIG_USB_RAW_GADGET=y` and `CONFIG_USB_DUMMY_HCD=y` in the kernel config.

    Optionally, also enable the config options for the specific USB drivers that you wish to fuzz.

    As an alternative, you can use the [config](/dashboard/config/linux/upstream-usb.config) from the syzbot USB fuzzing instance.
    This config has many USB drivers commonly-used in distro kernels enabled;

3. Build the kernel;

4. Optionally, update syzkaller descriptions by [extracting the USB IDs](#updating-usb-ids).

    This step is recommended if you wish to just rely on the existing syzlang descriptions to fuzz all USB drivers enabled in your kernel config.

    If you plan to add new syzlang descriptions that target a specific USB driver, this step can be skipped;

5. Optionally, [write](#internals) [syzlang](#dealing-with-complicated-descriptors) [descriptions](#handling-post-enumeration-control-requests) for the USB driver you wish to fuzz;

6. Enable `syz_usb_connect`, `syz_usb_disconnect`, `syz_usb_control_io`, `syz_usb_ep_write` and `syz_usb_ep_read` pseudo-syscalls (or any of their specific variants) in the manager config;

7. Set `sandbox` to `none` in the manager config;

8. Pass `dummy_hcd.num=4` (or whichever number you use for `procs`) to the kernel command-line parameters in the manager config;

9. Run syzkaller.

    Make sure that you see both `USBEmulation` and `ExtraCoverage` enabled in the `machine check` section in the log.

    You should also see a decent amount of coverage in `drivers/usb/core/*` after the first few programs get added to the corpus.


## Internals

syzkaller defines 5 main pseudo-syscalls for fuzzing USB drivers (see the [syzlang descriptions](/sys/linux/vusb.txt) and the [C](/executor/common_usb.h) [implementations](/executor/common_usb_linux.h)):

1. `syz_usb_connect` — handles the enumeration process of a new USB device (in simple terms: connects a new USB device; in detail: handles all control requests up until a `SET_CONFIGURATION` request is received);
2. `syz_usb_disconnect` — disconnects a USB device;
3. `syz_usb_control_io` — handles a post-enumeration control request (`IN` or `OUT`);
4. `syz_usb_ep_write` — handles a non-control `IN` request on an endpoint;
5. `syz_usb_ep_read` — handles a non-control `OUT` request on an endpoint.

Additionally, there is the `syz_usb_connect_ath9k` pseudo-syscall targeted to handle a few [post-enumeration control requests](#handling-post-enumeration-control-requests) the `ath9k` driver expects.

The syzlang descriptions for these pseudo-syscalls are targeted at a few different parts of the USB subsystem:

1. The common USB enumeration code is targeted by the generic `syz_usb_connect` variant.

    In addition, this generic variant also briefly touches the enumeration code in various USB drivers: the USB device descriptor fields get [patched](#usb-ids-patching) during the program generation;

2. The code of the class-specific drivers is targeted by `syz_usb_connect$hid`, `syz_usb_connect$cdc_ecm`, and other variants (accompanied by matching `syz_usb_control_io$*` and `syz_usb_ep_read/write$*` pseudo-syscalls).

    The descriptor fields for these `syz_usb_connect` variants are also intended to be [patched](#usb-ids-patching) during the program generation based on the matching rules specific to the driver class (to exercise various driver quirks).
So far, this has only been implemented for the HID ([see](/sys/linux/init_vusb.go) `generateUsbHidDeviceDescriptor`) and the printer ([see](/sys/linux/init_vusb.go) `generateUsbPrinterDeviceDescriptor`) classes;

3. The code of the device-specific drivers is intended to be targeted by more `syz_usb_connect` variants whose descriptors do not get patched and are fully defined in syzlang instead. (However, they can be patched as well for drivers that define quirks.)

    So far, the only such (partial) descriptions have been added for the `ath9k`, `rtl8150`, `sierra_net`, and `lan78xx`  drivers.


## Dealing with complicated descriptors

Many USB drivers expect a fixed USB descriptors structure from the connected USB device.
Writing syzlang descriptions for these drivers is straightforward: just describe the required structures in syzlang.

However, some drivers allow various permutations of the interface/endpoint descriptors (typically the case for class-specific drivers like UVC).

Describing a fixed descriptor structure for such drivers in syzlang would allow passing the driver descriptor checks and efficiently fuzz the post-enumeration communication.
But it would also prevent syzkaller from exploring the various error-checking paths within the driver's enumeration code.
On the other hand, defining a relaxed structure for the descriptors would make syzkaller often fail the driver's enumeration and thus would not allow efficiently fuzzing the post-enumeration communication.

There are two proposed ways to handle such drivers:

1. Writing relaxed descriptions and adding seed programs (aka runtests).

    This works by only defining a single `syz_usb_connect` variant with the relaxed descriptions of the USB descriptors but also adding a [seed program](#seed-programs) (into `sys/linux/test/`) that contains the `syz_usb_connect` pseudo-syscall with the specific fixed values to pass the driver's enumeration checks;

2. Adding two `syz_usb_connect` variants.

    One with relaxed descriptions to explore the error-checking paths; and the other with fixed descriptions to allow fuzzing the post-enumeration communication.


## Handling post-enumeration control requests

Many USB drivers finish their enumeration procedure with the `SET_CONFIGURATION` request.
Following this, these drivers start functioning normally and are ready to accept both control and non-control requests.

However, some USB drivers expect certain control requests to be handled by the device directly following the `SET_CONFIGURATION` request.
Without these requests being handled, these drivers abort their execution and disconnect the device.

There are two proposed ways to handle such drivers:

1. Adding seed programs (aka runtests).

    This works by adding a [seed program](#seed-programs) (into `sys/linux/test/`) that contains both the `syz_usb_connect` pseudo-syscall for the specific driver and a few `syz_usb_control_io` pseudo-sycalls that handle the required control requests.

    This is the currently recommended way of handling such drivers, as it allows syzkaller to permute the expected post-`SET_CONFIGURATION` control requests and thus possibly trigger unexpected driver behavior during their handling.

    See [#6283](https://github.com/google/syzkaller/pull/6283) for a reference implementation of this approach;

2. Modifying the behavior of the `syz_usb_connect` pseudo-syscall.

    An alternative approach is to modify the C implementation of the `syz_usb_connect` pseudo-syscall (or add a similar new pseudo-syscall) to handle the required post-`SET_CONFIGURATION` requests directly from C.

    Right now, this approach is only implemented for the `ath9k` driver via `syz_usb_connect_ath9k`.
Unlike `syz_usb_connect`, `syz_usb_connect_ath9k` also handles the post-`SET_CONFIGURATION` firmware download requests expected by `ath9k`.

    If this approach is to be used for other drivers, the proper implementation should rework and extend `syz_usb_connect_ath9k` instead of adding more similar pseudo-syscalls.
For example, add a new argument to `syz_usb_connect` that allows specifying (in syzlang) the responses to post-`SET_CONFIGURATION` control requests and which one of them is the last one (i.e., the condition for exiting the pseudo-syscall).
And then port the hardcoded responses from the C implementation of `syz_usb_connect_ath9k` into syzlang and extend the functionality based on the specific new encountered cases.

Note: There is also a way to describe unusual pre-`SET_CONFIGURATION` `GET_DESCRIPTOR` requests via the `conn_descs` argument of `syz_usb_connect`, but none of the class/driver-specific descriptions use this feature at the moment.
However, this approach does not allow specifying the order of the responses if there are multiple requests of the same type and also does not allow handling pre-`SET_CONFIGURATION` non-`GET_DESCRIPTOR` requests, as no described drivers required this so far.


## USB IDs patching

Many USB drivers implement various quirks depending of which device is connected.
Such quirks are either defined in the matching rule table for the driver (a table of `usb_device_id` structures; [see](https://elixir.bootlin.com/linux/v6.16/source/sound/usb/card.c#L1263) e.g. `usb_audio_ids`) or hardcoded in the driver code (by manually checking e.g. the Vendor and Product IDs against certain values; [see](https://elixir.bootlin.com/linux/v6.16/source/drivers/usb/class/usblp.c#L213) e.g. `quirk_printers`).

To exercise these driver quirks, syzkaller has to provide certain values (aka IDs) within the USB descriptors for the emulated device.
Listing these USB IDs manually in syzlang descriptions is inefficient (there are too many), so syzkaller employs the way of automatically [extracting the IDs](#updating-usb-ids) before building and then [patching them in](/sys/linux/init_vusb.go) during the program generation.

The IDs defined in the driver matching rules can be extracted (and patched in) automatically; see [Updating USB IDs](#updating-usb-ids).

However, the hardcoded IDs need to be specified manually (extracting them automatically is hard, as they are often embedded into the driver code in non-standard ways).
The proposed approach is to read the driver code to find out the hardcoded IDs and then modify the program generation code to embed them into the appropriate USB descriptors ([see](/sys/linux/init_vusb.go) e.g. `generateUsbPrinterDeviceDescriptor`).


## Updating USB IDs

syzkaller relies on a list of automatically-extracted [USB IDs](/sys/linux/init_vusb_ids.go) that are [patched](/sys/linux/init_vusb.go) into `syz_usb_connect` (for the generic, the HID, and the printer variants) during the program generation.

To update the syzkaller USB IDs based on the USB drivers enabled in your kernel config:

1. Apply [this](/tools/syz-usbgen/usb_ids.patch) kernel patch;

2. Build and boot the kernel;

3. Connect a USB HID device.

    Assuming you have `CONFIG_USB_RAW_GADGET=y` enabled, you can just run the [keyboard emulation program](https://raw.githubusercontent.com/xairy/raw-gadget/master/examples/keyboard.c);

4. Use [syz-usbgen](/tools/syz-usbgen/usbgen.go) to update [sys/linux/init_vusb_ids.go](/sys/linux/init_vusb_ids.go):

    ``` bash
    ./bin/syz-usbgen $KERNEL_LOG ./sys/linux/init_vusb_ids.go
    ```

5. Revert the applied kernel patch and rebuild the kernel before starting syzkaller.


## Seed programs

There are a few [seed programs](/sys/linux/test/) (aka runtests) for the USB pseudo-syscalls (named starting with the `vusb` prefix).

These seed programs serve two purposes:

1. Allow syzkaller to [go](#dealing-with-complicated-descriptors) [deeper](#handling-post-enumeration-control-requests) into the driver code without having to write detailed syzlang descriptions;

2. Allow verifying the USB fuzzing functionality and catching potential description-breaking changes by running the seed programs as runtests:

    ``` bash
    ./bin/syz-manager -config usb-manager.cfg -mode run-tests -tests vusb
    ```

## Limitations

Most of the limitations of the USB fuzzing support in syzkaller stem from the features [missing](https://github.com/xairy/raw-gadget/tree/master?tab=readme-ov-file#limitations) from the Raw Gadget and Dummy HCD/UDC implementations (USB 3, isochronous transfers, etc).

In addition, `syz_usb_connect` only supports devices with a single configuration (but this can be fixed).
This is not a critical limitation, as most kernel drivers are tied to specific interfaces and do not care about the configurations.
However, there are USB devices whose drivers assume the device to have multiple specific configurations.


## Things to improve

The core support for USB fuzzing is in place, but there's still space for improvement:

1. Remove the device from `usb_devices` in `syz_usb_disconnect` and don't call `lookup_usb_index` multiple times within `syz_usb_connect`.
Currently, this causes some reproducers to have the `repeat` flag set when it's not required;

2. Add descriptions for more relevant USB classes and drivers and resolve TODOs from [sys/linux/vusb.txt](/sys/linux/vusb.txt);

3. Implement a proper way for dynamically extracting relevant USB ids from the kernel (a related [discussion](https://www.spinics.net/lists/linux-usb/msg187915.html));

4. Add a mode for standalone fuzzing of physical USB hosts (from a Linux-based board with a UDC).
This includes: a. Making sure that the current way `syz_usb_connect` handles the enumeration works properly with different OSes (there are some [differences](https://github.com/RoganDawes/LOGITacker/blob/USB_host_enum/fingerprint_os.md#derive-the-os-from-the-fingerprint));
b. Using USB requests coming from the host as a signal (like coverage) to enable "signal-driven" fuzzing;
c. Making UDC driver name configurable for `syz-execprog` and `syz-prog2c`;

5. Generate syzkaller programs from a `usbmon` trace produced by real USB devices (this should make syzkaller go significantly deeper into the USB drivers code).


## Running reproducers on Linux-based boards

It is possible to run the reproducers for USB bugs generated by syzkaller on a Linux-based board plugged into a physical USB host.

See [Running syzkaller USB reproducers](https://github.com/xairy/raw-gadget/blob/master/docs/syzkaller_reproducers.md) in the Raw Gadget repository for the instructions.

---

### Linux External Fuzzing Usbip (`docs/linux/external_fuzzing_usbip.md`)

# USB/IP Fuzzing for Linux Kernel

Syzkaller supports fuzzing the Linux kernel USB/IP subsystem externally. We can set up a virtual network and send USB/IP packets to the client kernel as they are being received from an external server.
USB/IP fuzzing needs USB/IP configurations to be enabled. You can find the list in the configurations part.

Currently syzkaller only includes support for fuzzing the client side of USB/IP, which consists of 2 main parts:

1. USB/IP pseudo-syscalls.
2. Syzkaller descriptions.

### Configurations

Following configurations should be enabled for USB/IP.

```
CONFIG_USBIP_CORE=y
CONFIG_USBIP_VHCI_HCD=y
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=8
CONFIG_USBIP_HOST=y
CONFIG_USBIP_VUDC=y
CONFIG_USBIP_DEBUG=y
```

### Pseudo-syscalls

Currently syzkaller defines one USB/IP pseudo-syscall and one USB/IP specific write syscall (see [this](/executor/common_linux.h) for the pseudo-syscall and [this](/sys/linux/usbip.txt) for its syzkaller descriptions):

`syz_usbip_server_init` sets up USB/IP server. It creates a pair of connected socket and opens the `/sys/devices/platform/vhci_hcd.0/attach` file. Later, this pseudo-syscall writes the USB/IP client’s socket descriptor as well as port number used for USB/IP connection, USB device id and USB device speed into this file so that the USB/IP communication between client and server can start and client’s kernel can receive USB/IP packets from the server.

`write$usbip_server` sends USB/IP packets to client by using server's socket descriptor. (Particularly, `USBIP_RET_SUBMIT` and `USBIP_RET_UNLINK` packets.) We assume that the server can send arbitrary USB/IP packets instead of emulating a real device. These packets end up in the client's kernel and get parsed there.

### **Further Improvements**

1. Fuzzing the server side of USB/IP.
2. Collect coverage from USB/IP kernel code.

---

### Linux Found Bugs (`docs/linux/found_bugs.md`)

# Found bugs

Most latest bugs are reported by [syzbot](/docs/syzbot.md) and are listed [here](https://groups.google.com/forum/#!forum/syzkaller-bugs) and on the [dashboard](https://syzkaller.appspot.com/upstream).
Additional USB bugs are [here](/docs/linux/found_bugs_usb.md).

_newer first_
* [KASAN: use-after-free Read in screen_glyph_unicode](https://groups.google.com/g/syzkaller/c/114zHXgUIxc/m/HDakO4aDAQAJ)
* [KASAN: use-after-free Read in vc_do_resize](https://groups.google.com/g/syzkaller/c/YxdMWhGfeWw/m/P9bVFhNNBgAJ)
* [KASAN: use-after-free in usb_hcd_unlink_urb](https://groups.google.com/g/syzkaller/c/TVhdYRmqdvU/m/dRD7Rat9IQAJ)
* [KASAN: slab-out-of-bounds Read in gadget_dev_desc_UDC_store](https://groups.google.com/g/syzkaller/c/p-eayxoLmWA/m/x12xTwhwAgAJ)
* [KASAN: use-after-free Write in snd_rawmidi_kernel_write1](https://groups.google.com/g/syzkaller/c/GzOkkJGH6iY/m/2TTi8tdCAAAJ)
* [KASAN: use-after-free Write in config_item_get](https://groups.google.com/g/syzkaller/c/TzmTYZVXk_Q/m/TfFqRdJ4AQAJ)
* [KASAN: use-after-free Read in f_hidg_poll](https://groups.google.com/g/syzkaller/c/-WXXWIlZBu0/m/uhWv9RmMAgAJ)
* [KASAN: use-after-free Read in printer_ioctl](https://groups.google.com/g/syzkaller/c/-e8qjq9mmUk/m/KYZy8SqkAgAJ)
* [KASAN: null-ptr-deref Read in tty_wakeup](https://groups.google.com/g/syzkaller/c/BNzyjDzkYms/m/p9WwoUCpAwAJ)
* [KASAN: use-after-free in afs_wake_up_async_call](https://groups.google.com/g/syzkaller/c/Km3HYdzI7Ng/m/tpC-0d8EBAAJ)
* [KASAN: use-after-free Read in gs_flush_chars](https://groups.google.com/g/syzkaller/c/CtuIx6aFPDE/m/jK9d4529BQAJ)
* [kernel BUG at net/core/skbuff.c](https://lkml.org/lkml/2017/10/2/181)
* [io_uring: avoid page allocation warnings](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d4ef647510b1200fe1c996ff1cbf5ac47eb930cc)
* [io_uring: free allocated io_memory once](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=52e04ef4c9d459cba3afd86ec335a411b40b7fd2)
* [io_uring: fix SQPOLL cpu validation](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=975554b03eddc1df73bda3a764a09e18cadd5f1c)
* [locks: use-after-free in perf_trace_lock_acquire](https://bugzilla.kernel.org/show_bug.cgi?id=205705) [CVE-2019-19769](https://nvd.nist.gov/vuln/detail/CVE-2019-19769)
* [cirrusfb: divide errors in cirrusfb_check_var/cirrusfb_check_pixclock/cirrusfb_set_par_foo](https://groups.google.com/forum/#!topic/syzkaller/_utQWPf5qeY)
* [floppy: fix out-of-bounds read in copy_buffer](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da99466ac243f15fbba65bd261bfc75ffa1532b6)
* [floppy: fix invalid pointer dereference in drive_name](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9b04609b784027968348796a18f601aed9db3789)
* [floppy: fix out-of-bounds read in next_valid_format](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5635f897ed83fd539df78e98ba69ee91592f9bb8)
* [floppy: fix div-by-zero in setup_format_params](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f3554aeb991214cbfafd17d55e2bfddb50282e32)
* [bpf: BPF_PROG_TEST_RUN leads to unkillable process](https://groups.google.com/d/msg/syzkaller/EmqpzlOL164/loUGe070FwAJ)
* [timer_settime leads to unkillable process](https://groups.google.com/d/msg/syzkaller/Q6t7TCcN630/ep3J4BT1FwAJ)
* [UBSAN: Undefined behaviour in drivers/scsi/sr_ioctl.c](https://groups.google.com/d/msg/syzkaller/lfupcWLvlmI/ts9ut9LyEwAJ)
* [KASAN: use-after-free Read in ata_scsi_mode_select_xlat](https://groups.google.com/d/msg/syzkaller/PSlmJbCdKF0/tasiCXl4AgAJ)
* [UBSAN: Undefined behaviour in fs/f2fs/extent_cache.c](https://groups.google.com/d/msg/syzkaller/oAhUsPAO4RI/rivMjuUOCgAJ)
* [UBSAN: Undefined behaviour in drivers/input/misc/uinput.c](https://groups.google.com/d/msg/syzkaller/i64-4xzd-Cs/wJRiNri8CQAJ)
* [general protection fault in spk_ttyio_ldisc_close](https://groups.google.com/d/msg/syzkaller/4VJ9u48qxyc/IrT0N35uDAAJ)
* [rtnetlink: give a user socket to get_target_net()](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f428fe4a04cc339166c8bbd489789760de3a0cee) [CVE-2018-14646](https://nvd.nist.gov/vuln/detail/CVE-2018-14646)
* [tipc: NULL deref in tipc_net_finalize](https://groups.google.com/d/msg/syzkaller/qhg9Gg9cFuY/I-HrdjEICAAJ)
* [Kernel crash at i2cdev_ioctl_rdwr in drivers/i2c/i2c-dev.c](https://groups.google.com/d/msg/syzkaller/YuPOpeuGIKU/oXnZkgmqBgAJ)
* [UBSAN: Undefined behaviour in drivers/input/mousedev.c](https://groups.google.com/d/msg/syzkaller/8A-G6SaGOHQ/vsR3aWLKAwAJ)
* [UBSAN: Undefined behaviour in mm/page_alloc.c](https://groups.google.com/d/msg/syzkaller/STYtgfG49IQ/5g0L0b77BAAJ)
* [WARNING in pkt setup dev](https://groups.google.com/d/msg/syzkaller/jQsAxlSpvCU/xFab0v1wBAAJ)
* [UBSAN: Undefined behaviour in drivers/net/ppp/ppp_generic.c](https://groups.google.com/d/msg/syzkaller/xwZC0Njopck/FiU9Z-rRAgAJ)
* [KASAN: use-after-free Read in raw_cmd_done](https://groups.google.com/d/msg/syzkaller/wylZT5uD_xw/dTiar3qVBgAJ)
* [KMSAN: uninit-value in selinux_socket_bind, selinux_socket_connect_helper](https://groups.google.com/d/msg/syzkaller/elP9WpfcVbY/JHhEmU4BBwAJ)
* [UBSAN: Undefined behaviour in drivers/block/floppy.c](https://groups.google.com/d/msg/syzkaller/eB8DFhbjLyI/4lSR84IiBQAJ)
* [net: BUG still has locks held in unix_stream_splice_read](https://groups.google.com/d/msg/syzkaller/q_BUZHm-Nug/Y0o4RfDJBQAJ)
* [general protection fault in sockfs_setattr](https://groups.google.com/d/msg/syzkaller/y4V_gr5sjsE/GRA81a6EAQAJ) [CVE-2018-12232](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12232)
* [KASAN: slab out of bounds Write in __jfs_setxattr](https://lkml.org/lkml/2018/6/1/829) [CVE-2018-12233](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12233)
* [RDMA/mlx5: Fix NULL dereference while accessing XRC_TGT QPslogin ](https://patchwork.kernel.org/patch/10274675/)
* [KASAN: use-after-free Read in set_page_dirty_lock](https://groups.google.com/forum/#!topic/syzkaller/w-u4MXthFoI)
* [System freeze and NULL pointer dereference](https://groups.google.com/d/msg/syzkaller-bugs/LxPlUEk62IA/OIfFWHr_AgAJ)
* [RDS: WARNING in rds_recv_hs_exthdrs](https://groups.google.com/d/msg/syzkaller/TTR-hlzVO1I/T7ncQ3xjAQAJ)
* [RDS: slab-out-of-bounds Read in rds_rdma_extra_size](https://groups.google.com/d/msg/syzkaller/VxPgmfL9H8k/PJxhMJZiAQAJ)
* [netfilter: fix out-of-bounds accesses in clusterip_tg_check()](https://groups.google.com/d/msg/syzkaller/uyndMVk770k/TXIlWssrAwAJ)
* [net: hang in unregister_netdevice: waiting for lo to become free](https://groups.google.com/d/msg/syzkaller/-06_laheMF0/xqezy58kAwAJ)
* [scsi: sg: assorted memory corruptions](https://groups.google.com/d/msg/syzkaller/9RNr9Gu0MyY/Yyry-0XBDgAJ)
* [kcm: memory leak in kcm_sendmsg](https://groups.google.com/d/msg/syzkaller/3wdPAXqqABY/i-OgV10gDwAJ)
* [AF_KEY: memory leak in key_notify_policy](https://groups.google.com/d/msg/syzkaller/j6H7dPEQv-s/A-ADSd8gDwAJ)
* [sctp: memory leak in sctp_endpoint_init](https://groups.google.com/d/msg/syzkaller/rz5CvX4rTFA/PUCYbwEiDwAJ)
* [tipc: memory leak in tipc_nl_node_get_link](https://groups.google.com/d/msg/syzkaller/6nCOXX58sKw/J91ioe4iDwAJ)
* [tun: memory leak in tun_set_iff](https://groups.google.com/d/msg/syzkaller/ZuubuAQpne0/sSjnZfojDwAJ)
* [net/8021q: memory leak in register_vlan_dev](https://groups.google.com/d/msg/syzkaller/bFkAaOcP-SI/9MSok8IlDwAJ)
* [net: memory leak in socket](https://groups.google.com/d/msg/syzkaller/DMV3fSoKyR0/biGHOQQlDwAJ)
* [scsi: memory leak in sg_start_req](https://groups.google.com/d/msg/syzkaller/GVR3rFTzQzo/kGvdqZgcDwAJ)
* [sunrpc: infinite unkillable console spam in xs_tcp_setup_socket](https://groups.google.com/d/msg/syzkaller/DJmtkqwLCZg/mHJPAJHTAQAJ)
* [fs: possible deadlock in do_iter_write/do_splice](https://groups.google.com/forum/#!topic/syzkaller/f72L3fPD8sY)
* [net/ipv6: warning in __alloc_pages_slowpath/ipip6_tunnel_get_prl](https://groups.google.com/forum/#!topic/syzkaller/VtONA6oTiio)
* [net/ipv6: GPF in rt6_ifdown](https://groups.google.com/forum/#!topic/syzkaller/dQ0r_bHOrJk)
* [net/ipv4: trying to register non-static key in ip_mc_clear_src](https://groups.google.com/forum/#!topic/syzkaller/E60_ya1wNxs)
* [net/can: trying to register non-static key in can_rx_register](https://groups.google.com/forum/#!topic/syzkaller/to2Or4lUrTU)
* [net: general protection fault in deactivate_slab](https://groups.google.com/forum/#!topic/syzkaller/k_Q4h-RPzkQ)
* [net/ipv4: use-after-free in add_grec](https://groups.google.com/forum/#!topic/syzkaller/dlHu8uuZWfg)
* [net/ipv6: use-after-free in ip6_dst_ifdown](https://groups.google.com/forum/#!topic/syzkaller/ZJaqAiFLe3k)
* [tty: possible deadlock in tty_buffer_flush](https://groups.google.com/forum/#!topic/syzkaller/PXe_ekNtIZ8)
* [net/ipv6: general protection fault in skb_release_data](https://groups.google.com/forum/#!topic/syzkaller/e3I2c8X2oWo) CVE-2017-9242
* [drivers/net/hamradio: divide error in hdlcdrv_ioctl](https://groups.google.com/forum/#!topic/syzkaller/Uwy36npUcBQ)
* [tty: fix port buffer locking](https://lkml.org/lkml/2017/5/11/118)
* [kvm: warning in kvm_load_guest_fpu](https://groups.google.com/forum/#!topic/syzkaller/OSNJfH8rNPE)
* [drivers/scsi: GPF in sg_read](https://groups.google.com/forum/#!topic/syzkaller/FqYh6Jks6h0)
* [net/ipv4: use-after-free in ip_mc_drop_socket](https://groups.google.com/forum/#!topic/syzkaller/y3_fsYmwdio) CVE-2017-8890 CVE-2017-9075 CVE-2017-9076 CVE-2017-9077
* [net/ipv6: GPF in rt6_device_match](https://groups.google.com/forum/#!topic/syzkaller/PbCfeuGSoNI)
* [x86: warning: kernel stack regs has bad 'bp' value](https://groups.google.com/forum/#!topic/syzkaller/HQl-x5dWJ9Q)
* [net/key: slab-out-of-bounds in pfkey_compile_policy](https://groups.google.com/forum/#!topic/syzkaller/MHjh-tJo_wE)
* [net/ipv6: warning in inet6_ifa_finish_destroy](https://groups.google.com/forum/#!topic/syzkaller/Rt0pgY4wfiw)
* [net/ipv6: use-after-free in __call_rcu/in6_dev_finish_destroy_rcu](https://groups.google.com/forum/#!topic/syzkaller/OhkhEez1z1A)
* [net/ipv6: slab-out-of-bounds in ip6_tnl_xmit](https://groups.google.com/forum/#!topic/syzkaller/Wr3dZWAO8vw)
* [net/rose: null-ptr-deref in rose_route_frame](https://groups.google.com/forum/#!topic/syzkaller/RWKRCxpbS90)
* [time: hang due to timer_create/timer_settime](https://groups.google.com/forum/#!topic/syzkaller/355tWdc8oHY)
* [net/core: BUG in unregister_netdevice_many](https://groups.google.com/forum/#!topic/syzkaller/3zsXPUh-KzU)
* [net/xfrm: stack-out-of-bounds in xfrm_state_find](https://groups.google.com/forum/#!topic/syzkaller/WA6MdAfCYS0)
* [net/bonding: stack-out-of-bounds in bond_enslave](https://groups.google.com/forum/#!topic/syzkaller/IDoQHFmrnRI)
* [net: ipv6: RTF_PCPU should not be settable from userspace](https://www.spinics.net/lists/netdev/msg430947.html)
* [fs/notify/inotify: slab-out-of-bounds write in strcpy](https://groups.google.com/d/msg/syzkaller/ecGeXh44M50/r7OSshSOCAAJ) [CVE-2017-7533](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7533)
* [net/ipv6: slab-out-of-bounds read in seg6_validate_srh](https://groups.google.com/forum/#!topic/syzkaller/U3NMWDD16PM)
* [kernel BUG at mm/hugetlb.c:742!](https://lkml.org/lkml/2017/4/10/1154)
* [net/key: slab-out-of-bounds in parse_ipsecrequests](https://groups.google.com/forum/#!topic/syzkaller/vG7Cyfx-mvU)
* [net/ipv4: use-after-free in ipv4_datagram_support_cmsg](https://groups.google.com/forum/#!topic/syzkaller/F79HOk-4RhA)
* [net/ipv4: use-after-free in ip_queue_xmit](https://groups.google.com/forum/#!topic/syzkaller/X6L7h46rDsw)
* [net: use-after-free in __ns_get_path](https://groups.google.com/forum/#!topic/syzkaller/Vnf3aEG-wqY)
* [net/ipv4: use-after-free in ip_check_mc_rcu](https://groups.google.com/forum/#!topic/syzkaller/6q5nFux7N2E)
* [net/ipv6: use-after-free in ipv6_sock_ac_close](https://groups.google.com/forum/#!topic/syzkaller/z4Y96bFyq7I)
* [net/ipv4: use-after-free in ipv4_mtu](https://groups.google.com/forum/#!topic/syzkaller/UAjEGZoiAF4)
* [net/dccp: BUG in tfrc_rx_hist_sample_rtt](https://groups.google.com/forum/#!topic/syzkaller/inWmASLpo8Q)
* [net/sctp: list double add warning in sctp_endpoint_add_asoc](https://groups.google.com/forum/#!topic/syzkaller/6_LZGvwjzcA)
* [kvm: use-after-free in srcu_reschedule](https://groups.google.com/d/msg/syzkaller/Sl0POwca6-s/QR_z6AsFCQAJ)
* [ata: WARNING in ata_bmdma_qc_issue](https://groups.google.com/d/msg/syzkaller/Hy5yHjgOri8/0fhs94QXCAAJ)
* [net/sched: GPF in qdisc_hash_add](https://groups.google.com/d/msg/syzkaller/--acxHx5yyo/WsS4Yw7PBwAJ)
* [sg: random memory corruptions](https://groups.google.com/d/msg/syzkaller/wWn_oXRfN7Y/kgtLfy_OBwAJ)
* [fs: GPF in deactivate_locked_super](https://groups.google.com/d/msg/syzkaller/xLJUOccIV48/4yXIAfnIBwAJ)
* [loop: WARNING in sysfs_remove_group](https://groups.google.com/d/msg/syzkaller/nq6tjrQLVo4/IL-lxLHIBwAJ)
* [lib, fs, cgroup: WARNING in percpu_ref_kill_and_confirm](https://groups.google.com/d/msg/syzkaller/sT2NZaIfP_E/B15roGnIBwAJ)
* [ata: WARNING in ata_qc_issue](https://groups.google.com/d/msg/syzkaller/r1iGG9w4a9U/l6FkC0HGBwAJ)
* [security, hugetlbfs: write to user memory in hugetlbfs_destroy_inode](https://groups.google.com/d/msg/syzkaller/GLiqkLgHpc8/RzD3JUTFBwAJ)
* [netlink: NULL timer crash](https://groups.google.com/d/msg/syzkaller/drVyP4zu3SM/yPx2taTEBwAJ)
* [kvm: use-after-free function call in kvm_io_bus_destroy](https://groups.google.com/d/msg/syzkaller/1zn_juvw7Fk/BAqe32_DBwAJ)
* [sound: use-after-free in snd_seq_cell_alloc](https://groups.google.com/d/msg/syzkaller/ZXLFJniQJJE/menSWN_CBwAJ)
* [usb: use-after-free write in usb_hcd_link_urb_to_ep](https://groups.google.com/d/msg/syzkaller/v5ra3_AduC4/8-43yozCBwAJ)
* [net/kcm: double free of kcm inode](https://groups.google.com/d/msg/syzkaller/CFYuMediESc/L31CuijCBwAJ)
* [crypto: out-of-bounds write in pre_crypt](https://groups.google.com/d/msg/syzkaller/ivRlyW1WX10/3M9rSuC9BwAJ)
* [security: double-free in superblock_doinit](https://groups.google.com/d/msg/syzkaller/AXrX3E0YOsg/dvcctKm8BwAJ)
* [kvm: WARNING in kvm_apic_accept_events](https://groups.google.com/d/msg/syzkaller/gBu_q0nPy9o/r3QmSIO6BwAJ)
* [tcp: fix potential double free issue for fastopen_req](https://www.spinics.net/lists/netdev/msg422971.html)
* [net/udp: slab-out-of-bounds Read in udp_recvmsg](https://groups.google.com/d/msg/syzkaller/K6CC1usBuWs/6aYxL79BBQAJ)
* [net: deadlock between ip_expire/sch_direct_xmit](https://groups.google.com/d/msg/syzkaller/e-2ANaCu2fk/zvSg0l4DBQAJ)
* [srcu: BUG in __synchronize_srcu](https://groups.google.com/forum/#!topic/syzkaller/2WSsltbI5Z8)
* [net/sctp: recursive locking in sctp_do_peeloff](https://groups.google.com/d/msg/syzkaller/5NY7KjBKgA0/nMm6k7bwEQAJ)
* [kvm: WARNING in vmx_handle_exit](https://groups.google.com/d/msg/syzkaller/D01HuY1tDhc/UIeC8eXfDQAJ)
* [futex: use-after-free in futex_wait_requeue_pi](https://groups.google.com/d/msg/syzkaller/MrJ5ckRkQBI/pXjdOFztEQAJ)
* [kvm/arm64: use-after-free in kvm_vm_ioctl/vmacache_update](https://groups.google.com/forum/#!topic/syzkaller/QUhNm5patag)
* [kvm/arm64: use-after-free in kvm_unmap_hva_handler/unmap_stage2_pmds](https://groups.google.com/forum/#!topic/syzkaller/Hk9R17J-2tA)
* [local privilege escalation flaw in n_hdlc](http://seclists.org/oss-sec/2017/q1/569) CVE-2017-2636
* [netlink: GPF in netlink_unicast](https://groups.google.com/d/msg/syzkaller/AN-WbVHU0hw/iMmJEUSbEAAJ)
* [perf: use-after-free in perf_release](https://groups.google.com/d/msg/syzkaller/_P-SyZtwVXk/RhO-VB2YEAAJ)
* [net/ipv6: null-ptr-deref in ip6mr_sk_done](https://groups.google.com/forum/#!topic/syzkaller/H8hyTRfCClI)
* [bpf: kernel NULL pointer dereference in map_get_next_key](https://groups.google.com/d/msg/syzkaller/nyr1SaxHfyo/gp21-xhaEAAJ)
* [crypto: deadlock between crypto_alg_sem/rtnl_mutex/genl_mutex](https://groups.google.com/d/msg/syzkaller/jtz84qFQ_3s/vzFV8YhaEAAJ)
* [kvm: use-after-free in vmx_check_nested_events/vmcs12_guest_cr0](https://groups.google.com/d/msg/syzkaller/_e1uwkRRVfk/CqEIKj9SEAAJ)
* [sound: another deadlock in snd_seq_pool_done](https://groups.google.com/d/msg/syzkaller/GAUhiTjyDfI/XcIntncQEAAJ)
* [rcu: WARNING in rcu_seq_end](https://groups.google.com/d/msg/syzkaller/M4UEuqSTMR8/JoEPLtQOEAAJ)
* [fs: use-after-free in path_lookupat](https://groups.google.com/d/msg/syzkaller/_8MZkKL2-QU/PA0q5XULEAAJ)
* [ucount: use-after-free read in inc_ucount & dec_ucount](https://groups.google.com/d/msg/syzkaller/xB_UphO1T7w/me1WddQAEAAJ)
* [net/ipv4: division by 0 in tcp_select_window](https://groups.google.com/d/msg/syzkaller/TFH8rl8yTrU/9PzPjkfHDwAJ)
* [net: heap out-of-bounds in fib6_clean_node/rt6_fill_node/fib6_age/fib6_prune_clone](https://groups.google.com/d/msg/syzkaller/3SS80JbVPKA/2tfIAcW7DwAJ)
* [mm: use-after-free in zap_page_range](https://groups.google.com/d/msg/syzkaller/-e9ZYxL9zts/6ip-8FK5DwAJ)
* [net/kcm: use-after-free in kcm_wq](https://groups.google.com/d/msg/syzkaller/c_jOLx9FEgk/nz2PJROtDwAJ)
* [idr: use-after-free write in ida_get_new_above](https://groups.google.com/d/msg/syzkaller/23J2nN6syEE/gFFk_xSsDwAJ)
* [sg: stack out-of-bounds write in sg_write](https://groups.google.com/d/msg/syzkaller/fvvhyYQHiT8/UOnInaajDwAJ) CVE-2017-7187
* [cgroup: WARNING in cgroup_kill_sb](https://groups.google.com/d/msg/syzkaller/pWKI4ZQeOoI/SmTmQEF8DwAJ)
* [net/rds: use-after-free in rds_find_bound/memcmp](https://groups.google.com/d/msg/syzkaller/ZBEXtkNoG9o/kgQVbjjXDgAJ)
* [net: sleeping function called from invalid context in net_enable_timestamp](https://groups.google.com/d/msg/syzkaller/k5qJRYKqIgQ/EfJBkqwvDwAJ)
* [net: use-after-free in neigh_timer_handler/sock_wfree](https://groups.google.com/d/msg/syzkaller/2REBGTmpSTE/pT95olUuDwAJ)
* [net/sctp: use-after-free in sctp_association_put](https://groups.google.com/d/msg/syzkaller/AA_hWiHcgrs/4lIAQ94tDwAJ)
* [fs: use-after-free in userfaultfd_exit](https://groups.google.com/d/msg/syzkaller/Uu0ZwFPrmu8/WRWYCC8sDwAJ)
* [net/ipv4: inconsistent lock state in tcp_conn_request/inet_ehash_insert](https://groups.google.com/forum/#!topic/syzkaller/OnwnEEhZap8)
* [net/ipv4: suspicious RCU usage in ip_ra_control](https://groups.google.com/d/msg/syzkaller/mS6hi72YPkc/FwCYiR7JDwAJ)
* [net/ipv4: deadlock in ip_ra_control](https://groups.google.com/d/msg/syzkaller/mS6hi72YPkc/jZyjMMgRDwAJ)
* [net/dccp: dccp_create_openreq_child freed held lock](https://groups.google.com/d/msg/syzkaller/0jXubCbCmeQ/OXoQEjgODwAJ)
* [nested_vmx_merge_msr_bitmap](https://groups.google.com/d/msg/syzkaller/2631gzzWnA4/jm91h6HeDgAJ)
* [ipc: use-after-free in shm_get_unmapped_area](https://groups.google.com/d/msg/syzkaller/Kv2bIHYA8N8/kZqVCqXaDgAJ)
* [sounds: deadlocked processed in snd_seq_pool_done](https://groups.google.com/d/msg/syzkaller/ZARHLaXAmYQ/eSfeP-HVDgAJ)
* [net/atm: vcc_sendmsg calls kmem_cache_alloc in non-blocking context](https://groups.google.com/d/msg/syzkaller/5gb5kxihtps/oy4pVZ3SDgAJ)
* [ata: WARNING in ata_sff_qc_issue](https://groups.google.com/d/msg/syzkaller/0v1qHkmM-VU/6InmOLvPDgAJ)
* [net/rds: use-after-free in inet_create](https://groups.google.com/d/msg/syzkaller/ZBEXtkNoG9o/s46xtB7PDgAJ)
* [mm: fault in __do_fault](https://groups.google.com/d/msg/syzkaller/CRQxZS4nck0/6DD2SyfODgAJ)
* [kvm: WARNING in nested_vmx_vmexit](https://groups.google.com/d/msg/syzkaller/w3EBRlb2h6s/GdIi_y3IDgAJ)
* [net: GPF in rt6_nexthop_info](https://groups.google.com/d/msg/syzkaller/AMyOvIrf--c/RB-mpPjFDgAJ)
* [sound: spinlock lockup in snd_timer_user_tinterrupt](https://groups.google.com/d/msg/syzkaller/3efGwZt0nLI/pPt4WoGVDgAJ)
* [mm: GPF in bdi_put](https://groups.google.com/d/msg/syzkaller/ixaSKtOoO7k/UjxnRr2JDgAJ)
* [net/sctp: use-after-free in sctp_hash_transport](https://groups.google.com/forum/#!topic/syzkaller/Ew5hrZI7Obs)
* [net/bridge: warning in br_fdb_find](https://groups.google.com/forum/#!topic/syzkaller/d9XyhdJXwa0)
* [net/ipv6: null-ptr-deref in ip6_route_del/lock_acquire](https://groups.google.com/forum/#!topic/syzkaller/gEoL2QX519c)
* [net: possible deadlock in skb_queue_tail](https://groups.google.com/forum/#!topic/syzkaller/XEp_9K8FmIM)
* [DCCP double-free vulnerability (local root)](http://seclists.org/oss-sec/2017/q1/471) CVE-2017-6074
* [net: warning in inet_sock_destruct](https://groups.google.com/forum/#!topic/syzkaller/QwkU6JMkjBg)
* [net/pptp: use-after-free in dst_release](https://groups.google.com/forum/#!topic/syzkaller/ZR9QP3JNE18)
* [net/udp: slab-out-of-bounds in udp_recvmsg/do_csum](https://groups.google.com/forum/#!topic/syzkaller/vCUAq86bJaA) CVE-2017-6347
* [WARNING in skb_warn_bad_offload](https://patchwork.ozlabs.org/patch/722135/)
* [tty: panic in tty_ldisc_restore](https://groups.google.com/d/msg/syzkaller/ty5IhaYWVp8/aTN_hZ8qBQAJ)
* [net: BUG in __skb_gso_segment](https://groups.google.com/forum/#!topic/syzkaller/wLAp3HzIXSo)
* [net/dccp: use-after-free in dccp_feat_activate_values](https://groups.google.com/forum/#!topic/syzkaller/hyM_oK9QOXU)
* [net/kcm: GPF in kcm_sendmsg](https://groups.google.com/d/msg/syzkaller/8YB3cFmKRqs/DYu7vJiCCAAJ)
* [net/xfrm: stack out-of-bounds in xfrm_flowi_sport](https://groups.google.com/d/msg/syzkaller/J2qVz4ZJpPg/Fw0QURWBCAAJ)
* [net/llc: BUG in llc_sap_state_process/skb_set_owner_r](https://groups.google.com/forum/#!topic/syzkaller/c1SOlcflXz8) CVE-2017-6345
* [net/llc: bug in llc_pdu_init_as_xid_cmd/skb_over_panic](https://groups.google.com/forum/#!topic/syzkaller/mVs8KWoW4d8)
* [net/packet: use-after-free in packet_rcv_fanout](https://groups.google.com/d/msg/syzkaller/nOwR6_b4rmw/ocp21bZBBwAJ)
* [net: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected in skb_array_produce](https://groups.google.com/d/msg/syzkaller/eHfRFbBg4LE/stDU3KYyBwAJ)
* [net/ipv4: null-ptr-deref in udp_rmem_release/sk_memory_allocated_sub](https://groups.google.com/forum/#!topic/syzkaller/8BMdxIXdH4g)
* [net/sctp: null-ptr-deref in sctp_put_port/sctp_endpoint_destroy](https://groups.google.com/forum/#!topic/syzkaller/S79Ss7ZUje8)
* [net/ipv4: warning in nf_nat_ipv4_fn](https://groups.google.com/forum/#!topic/syzkaller/5VxeBb85Ddg)
* [net/ipv6: double free in ipip6_dev_free](https://groups.google.com/d/msg/syzkaller/ZN9Ihlsum_s/4UuXXmn1BgAJ)
* [sound: use-after-free in snd_seq_queue_alloc](https://groups.google.com/d/msg/syzkaller/dhaTlAjxHVs/TXyPrX_nBgAJ)
* [loop: divide error in transfer_xor](https://groups.google.com/d/msg/syzkaller/1f1ziDbOTiQ/cFC0_wfnBgAJ)
* [net/xfrm: use of uninit spinlock in xfrm_policy_flush](https://groups.google.com/d/msg/syzkaller/vp1neyeoA8A/Is8aPdrpBgAJ)
* [mm: double-free in cgwb_bdi_init](https://groups.google.com/d/msg/syzkaller/tIx42qCVklk/fh0qjUboBgAJ)
* [packet: round up linear to header len](http://patchwork.ozlabs.org/patch/725335/)
* [net/icmp: null-ptr-deref in ping_v4_push_pending_frames](https://groups.google.com/forum/#!topic/syzkaller/DYyq0NyEY4g)
* [net/kcm: WARNING in kcm_write_msgs](https://groups.google.com/d/msg/syzkaller/vsh_MSFHizg/Uf-GzB1UBgAJ)
* [tcp: avoid infinite loop in tcp_splice_read()](https://www.mail-archive.com/netdev@vger.kernel.org/msg151936.html) CVE-2017-6214
* [tun: read vnet_hdr_sz once](http://patchwork.ozlabs.org/patch/723964/)
* [macvtap: read vnet_hdr_size once](http://patchwork.ozlabs.org/patch/723965/)
* [udp: properly cope with csum errors](https://patchwork.ozlabs.org/patch/724263/)
* [ipv6: tcp: add a missing tcp_v6_restore_cb()](https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=7892032cfe67f4bde6fc2ee967e45a8fbaf33756)
* [ip6_gre: fix ip6gre_err() invalid reads](https://patchwork.ozlabs.org/patch/724187/) CVE-2017-5897
* [ipv4: keep skb->dst around in presence of IP options](https://patchwork.ozlabs.org/patch/724136/) CVE-2017-5970
* [net: use a work queue to defer net_disable_timestamp() work](https://patchwork.ozlabs.org/patch/723251/)
* [netlabel: out of bound access in cipso_v4_validate()](https://patchwork.ozlabs.org/patch/723457/)
* [ipv6: pointer math error in ip6_tnl_parse_tlv_enc_lim()](https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git/+/63117f09c768be05a0bf465911297dc76394f686)
* [net: heap out-of-bounds in ip6_fragment](https://groups.google.com/d/msg/syzkaller/zakUQXz8ums/lNcDLtARBQAJ) CVE-2017-9074
* [tcp: fix 0 divide in __tcp_select_window()](https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=06425c308b92eaf60767bc71d359f4cbc7a561f8)
* [keys: GPF in request_key](https://groups.google.com/d/msg/syzkaller/As2A-xeNp0g/eu50sRnKBAAJ)
* [net/tcp: warning in tcp_try_coalesce/skb_try_coalesce](https://groups.google.com/forum/#!topic/syzkaller/oeZW04VAQBM)
* [crypto: NULL deref in sha512_mb_mgr_get_comp_job_avx2](https://groups.google.com/d/msg/syzkaller/4nGqh82OL7g/0lU1zpp-BAAJ)
* [sound: unable to handle kernel paging request snd_seq_prioq_cell_out](https://groups.google.com/d/msg/syzkaller/wn-_0zA8ka4/kLB6BSR0BAAJ)
* [scsi: BUG in scsi_init_io](https://groups.google.com/d/msg/syzkaller/p2MBG9oRNdo/4MxGbWFwBAAJ)
* [mm: sleeping function called from invalid context shmem_undo_range](https://groups.google.com/d/msg/syzkaller/j8Zj72bs2xE/HjPk2dduBAAJ)
* [timerfd: use-after-free in timerfd_remove_cancel](https://groups.google.com/d/msg/syzkaller/bryiI66Pxxg/78NqwMhBBAAJ)
* [scsi: use-after-free in sg_start_req](https://groups.google.com/d/msg/syzkaller/Nft7hrE_CyM/QvEjMuUcBAAJ)
* [mm: deadlock between get_online_cpus/pcpu_alloc](https://groups.google.com/d/msg/syzkaller/G40CCUkkyDE/9Y3u-rXfAwAJ)
* [BUG at net/sctp/socket.c:7425](https://groups.google.com/d/msg/syzkaller/V2WPJ1BiXs0/-NO5Yea3AwAJ)
* [kvm: use-after-free in irq_bypass_register_consumer](https://groups.google.com/d/msg/syzkaller/UHiABsxXVaI/lQQ36P5eAwAJ)
* [net: suspicious RCU usage in nf_hook](https://groups.google.com/d/msg/syzkaller/9876JHd_awE/xqvU9HFeAwAJ)
* [kvm: fix page struct leak in handle_vmon](https://www.spinics.net/lists/kernel/msg2428945.html) CVE-2017-2596
* [ipv6: fix ip6_tnl_parse_tlv_enc_lim()](https://patchwork.ozlabs.org/patch/718842/)
* [kvm: WARNING in mmu_spte_clear_track_bits](https://groups.google.com/d/msg/syzkaller/Ii09l8gpFO4/ZXcevV8NAgAJ)
* [perf: use-after-free in perf_event_for_each](https://groups.google.com/d/msg/syzkaller/UjDJeCgt3_M/xsv0cLUKAgAJ)
* [net: use-after-free in tw_timer_handler](https://groups.google.com/d/msg/syzkaller/p1tn-_Kc6l4/smuL_FMAAgAJ)
* [namespace: deadlock in dec_pid_namespaces](https://groups.google.com/d/msg/syzkaller/uhFVBGnXzHQ/-kZya8AdAQAJ)
* [sctp: kernel memory overwrite attempt detected in sctp_getsockopt_assoc_stats](https://groups.google.com/d/msg/syzkaller/Ok2fotcCSsg/10Tak7X0EQAJ)
* [kvm: deadlock in kvm_vgic_map_resources](https://groups.google.com/d/msg/syzkaller/7E0b8H0nJm8/-aoPnGW_EAAJ)
* [net/atm: warning in alloc_tx/__might_sleep](https://groups.google.com/forum/#!topic/syzkaller/3WJGPLm6FmQ)
* [net/ipv6: use-after-free in sock_wfree](https://groups.google.com/forum/#!topic/syzkaller/BhyN5OFd7sQ)
* [kvm: kvm: BUG in loaded_vmcs_init](https://groups.google.com/d/msg/syzkaller/VrcANKRU3iQ/KdZDHdIiDwAJ)
* [kvm: NULL deref in vcpu_enter_guest](https://groups.google.com/d/msg/syzkaller/6V-KXaMDYi8/rOvBl-69DAAJ)
* [kvm: use-after-free in complete_emulated_mmio](https://groups.google.com/d/msg/syzkaller/-Pl63SQ63FA/pYO4cRkUDAAJ) CVE-2017-2584
* [kvm: BUG in kvm_unload_vcpu_mmu](https://groups.google.com/d/msg/syzkaller/VbGoa1nALVw/x7hPnUMXDAAJ)
* [x86: warning in unwind_get_return_address](https://groups.google.com/forum/#!topic/syzkaller/BQBlYH-dNNM)
* [ipc: BUG: sem_unlock unlocks non-locked lock](https://groups.google.com/d/msg/syzkaller/u_ldPlYJSxk/Iu6CmEmlCAAJ)
* [kvm: WARNING in mmu_spte_clear_track_bits](https://groups.google.com/d/msg/syzkaller/Ii09l8gpFO4/HOkydz_bBwAJ)
* [sctp: suspicious rcu_dereference_check() usage in sctp_epaddr_lookup_transport](https://groups.google.com/d/msg/syzkaller/4V6zHuGzYuM/sLQkIJTVBwAJ)
* [kvm: use-after-free in process_srcu](https://groups.google.com/d/msg/syzkaller/i48YZ8mwePY/0PQ8GkQTBwAJ)
* [kvm: assorted bugs after OOMs](https://groups.google.com/d/msg/syzkaller/ytVPh93HLnI/KhZdengZBwAJ)
* [kvm: deadlock between kvm_io_bus_register_dev/kvm_hv_set_msr_common](https://groups.google.com/d/msg/syzkaller/KYU8Ru7P2wo/fHM0gbuUBgAJ)
* [netlink: GPF in netlink_dump](https://groups.google.com/d/msg/syzkaller/wXVYTkQqmeM/KJFTDTE2BgAJ)
* [fs, net: deadlock between bind/splice on af_unix](https://groups.google.com/d/msg/syzkaller/E3_YC5Ac-dY/Wr42pcVBBgAJ)
* [net: use-after-free in worker_thread](https://groups.google.com/forum/#!topic/syzkaller/RCnXAyhFBZs)
* [net: signed overflows in SO_{SND|RCV}BUFFORCE sockopts](https://groups.google.com/forum/#!topic/syzkaller/rXpw5jXjGBM) CVE-2016-9793 CVE-2012-6704
* [net/can: warning in raw_setsockopt/__alloc_pages_slowpath](https://groups.google.com/forum/#!topic/syzkaller/6ceFXDer0ik)
* [net/ipv6: null-ptr-deref in ip6_rt_cache_alloc](https://groups.google.com/forum/#!topic/syzkaller/ryLwIsiKnmA)
* [net/dccp: use-after-free in dccp_invalid_packet](https://groups.google.com/forum/#!topic/syzkaller/5uW1cV_WjIQ)
* [net/sctp: vmalloc allocation failure in sctp_setsockopt/xt_alloc_table_info](https://groups.google.com/forum/#!topic/syzkaller/TMlGTPkIlFU)
* [net: BUG in unix_notinflight](https://groups.google.com/d/msg/syzkaller/4PFR0zm8JdU/XIGam5-dAgAJ)
* [net: GPF in eth_header](https://groups.google.com/d/msg/syzkaller/GFbGpX7nTEo/96LNG7KbAgAJ) CVE-2016-9755
* [net: deadlock on genl_mutex](https://groups.google.com/d/msg/syzkaller/-YGhBYeg8Ew/jf9uD0maAgAJ)
* [net: GPF in rt6_get_cookie](https://groups.google.com/d/msg/syzkaller/3uDn6P5bwzA/gdzgPxeYAgAJ)
* [netlink: GPF in sock_sndtimeo](https://groups.google.com/d/msg/syzkaller/R_KZuzEDLeg/SkANc-yVAgAJ)
* [scsi: use-after-free in bio_copy_from_iter](https://groups.google.com/d/msg/syzkaller/Ut8nZJIJoEs/lhPdzXlSAgAJ) CVE-2016-9576
* [net/udp: bug in skb_pull_rcsum](https://groups.google.com/forum/#!topic/syzkaller/fVj7UJ6nOow)
* [net/icmp: null-ptr-deref in icmp6_send](https://groups.google.com/forum/#!topic/syzkaller/exfKDuH5sLI) CVE-2016-9919
* [net/can: use-after-free in bcm_rx_thr_flush](https://groups.google.com/forum/#!topic/syzkaller/1kM2GFIzSBU)
* [kvm: slab-out-of-bounds write in __apic_accept_irq](https://groups.google.com/d/msg/syzkaller/YWVsTBlRljk/xMwrqdOgCAAJ) CVE-2016-9777
* [mm: BUG in pgtable_pmd_page_dtor](https://groups.google.com/d/msg/syzkaller/JGNtVzSymvw/6VbQla2gCAAJ)
* [logfs: GPF in logfs_alloc_inode](https://groups.google.com/d/msg/syzkaller/jj5WiCBNDh4/tYlsqCegCAAJ)
* [mm, floppy: unkillable task faulting on fd0](https://groups.google.com/d/msg/syzkaller/v6X8nr-XMqY/AKvXMjqdCAAJ)
* [kvm: deadlock between kvm_vm_ioctl_get_dirty_log/kvm_hv_set_msr_common/kvm_create_pit](https://groups.google.com/d/msg/syzkaller/AMBA62hsVnQ/vtH4SEeoBwAJ)
* [kvm: WARNING in em_jmp_far](https://groups.google.com/d/msg/syzkaller/vlC9IzBqaEs/S5sZl9ejBwAJ) CVE-2016-9756
* [kvm: WARNING in rtc_status_pending_eoi_check_valid](https://groups.google.com/d/msg/syzkaller/WuAv_qE8dI8/jJd6E3ClBwAJ)
* [kvm: GPF in kvm_ioapic_set_irq](https://groups.google.com/d/msg/syzkaller/yOvg84HBx6E/6db4LE6jBwAJ)
* [mm: BUG in munlock_vma_pages_range](https://groups.google.com/d/msg/syzkaller/YrHKOMostEc/3Arq3dCiBwAJ)
* [kvm: WARNING in kvm_arch_vcpu_ioctl_run](https://groups.google.com/d/msg/syzkaller/24wCim9x3mI/RoV24W5yBwAJ)
* [kvm: use-after-free/GPF in kvm_irq_delivery_to_apic_fast](https://groups.google.com/d/msg/syzkaller/sue3X3IQanU/ypLWfHTpBgAJ)
* [kvm: out-of-bounds write in __rtc_irq_eoi_tracking_restore_one](https://groups.google.com/d/msg/syzkaller/8IXfmLUSkbA/8bbm6hbqBgAJ)
* [kvm: BUG in pte_list_remove](https://groups.google.com/d/msg/syzkaller/IqkesiRS-t0/aLcJuMXqBgAJ)
* [kvm: recursive lock in kvm_clear_async_pf_completion_queue](https://groups.google.com/d/msg/syzkaller/dGfcd0P7J-E/XD0h8n_rBgAJ)
* [kvm: WARNING in em_ret_far](https://groups.google.com/d/msg/syzkaller/o5ZftARBhrs/r1ivQ-HtBgAJ)
* [kvm: GPF in irqfd_shutdown/eventfd_ctx_remove_wait_queue](https://groups.google.com/d/msg/syzkaller/Zubs2yePdiY/svec5qrtBgAJ)
* [kvm: GPF in gfn_to_rmap](https://groups.google.com/d/msg/syzkaller/sHBCmfktDGg/dAhz7M7vBgAJ)
* [kvm: paging fault in kvm_gfn_to_hva_cache_init](https://groups.google.com/d/msg/syzkaller/ETU_E6Sc-rk/-iWFPpTwBgAJ)
* [kvm: suspicious RCU usage/missed lock in kvm_lapic_set_vapic_addr](https://groups.google.com/d/msg/syzkaller/Zw7Usg-FnDQ/QvHU6P69BgAJ)
* [kvm: use-after-free in irq_bypass_register_consumer](https://groups.google.com/d/msg/syzkaller/NKlClJzOOww/zX1sXW24BgAJ)
* [kvm: WARNING in kvm_load_guest_fpu](https://groups.google.com/d/msg/syzkaller/PeDBKPqz19o/VckGWlW0BgAJ)
* [kvm: GPF in kvm_pic_set_irq](https://groups.google.com/d/msg/syzkaller/T4ZFHqpmwKM/V_X9W8awBgAJ)
* [kvm: GPF in irq_bypass_unregister_consumer](https://groups.google.com/d/msg/syzkaller/Dz__GySpVr8/UQ5kpdWrBgAJ)
* [kvm: GPF in __get_kvmclock_ns](https://groups.google.com/d/msg/syzkaller/A5cpi35KlkQ/a35IrBmoBgAJ)
* [kvm: WARNING In kvm_apic_accept_events](https://groups.google.com/d/msg/syzkaller/1qxx4nU4hpE/qJlIQcWtBgAJ)
* [kvm: WARNING in __x86_set_memory_region](https://groups.google.com/d/msg/syzkaller/F3xBpkDRAiE/jdmpOIKtBgAJ)
* [tcp: take care of truncations done by sk_filter()](https://patchwork.ozlabs.org/patch/693484/)
* [net/l2tp: use-after-free write in l2tp_ip6_close](https://groups.google.com/forum/#!topic/syzkaller/rXbAbqydmsw)
* [net/sctp: null-ptr-deref in sctp_inet_listen](https://groups.google.com/forum/#!topic/syzkaller/rngiXb8aNVk)
* [net/tcp: warning in tcp_recvmsg](https://groups.google.com/forum/#!topic/syzkaller/xpNRe_86Dog)
* [net/netlink: another global-out-of-bounds in genl_family_rcv_msg/validate_nla](https://groups.google.com/forum/#!topic/syzkaller/BTjwhbtc9QE)
* [bpf: kernel BUG in htab_elem_free](https://groups.google.com/d/msg/syzkaller/NcK5XXQA-_o/DYskkVn1AwAJ)
* [net/netlink: global-out-of-bounds in genl_family_rcv_msg/validate_nla](https://groups.google.com/forum/#!topic/syzkaller/6k-N84V-Z88)
* [net/ipv6: null-ptr-deref in inet6_bind](https://groups.google.com/forum/#!topic/syzkaller/AdbicmLlFHk)
* [net/dccp: null-ptr-deref in dccp_parse_options](https://groups.google.com/forum/#!topic/syzkaller/_vGUxJLcdKY)
* [net/dccp: null-ptr-deref in dccp_v4_rcv/selinux_socket_sock_rcv_skb](https://groups.google.com/forum/#!topic/syzkaller/nyrJEo2pUJs)
* [net/tcp: null-ptr-deref in __inet_lookup_listener/inet_exact_dif_match](https://groups.google.com/forum/#!topic/syzkaller/zfXVCzJTXzQ)
* [net/dccp: warning in dccp_feat_clone_sp_val/__might_sleep](https://groups.google.com/forum/#!topic/syzkaller/GDvJr49XK7g)
* [net/can: warning in bcm_connect/proc_register](https://groups.google.com/forum/#!topic/syzkaller/ltCQQCE44pQ)
* [net/ipv4: warning in inet_sock_destruct](https://groups.google.com/forum/#!topic/syzkaller/8tMiUcdWx78)
* [net/sctp: slab-out-of-bounds in sctp_sf_ootb](https://groups.google.com/forum/#!topic/syzkaller/pAUcHsUJbjk) CVE-2016-9555
* [net/dccp: warning in dccp_set_state](https://groups.google.com/forum/#!topic/syzkaller/JdYwfv_22lA)
* [net/netlink: bad unlock balance in netlink_diag_dump](https://groups.google.com/forum/#!topic/syzkaller/Pk4VwBtZD2Y)
* [net/netlink: null-ptr-deref in netlink_dump/lock_acquire](https://groups.google.com/forum/#!topic/syzkaller/Pk4VwBtZD2Y)
* [net/ipx: null-ptr-deref in ipxrtr_route_packet](https://groups.google.com/forum/#!topic/syzkaller/xqRSxMxPVq0)
* [net/sctp: use-after-free in __sctp_connect](https://groups.google.com/forum/#!topic/syzkaller/W0swoIe25Eg)
* [fs: WARNING in locks_unlink_lock_ctx (not holding proper lock)](https://groups.google.com/d/msg/syzkaller/9DFicr6njUw/aaX3dVtNBQAJ)
* [kernel BUG in dio_get_page](https://groups.google.com/d/msg/syzkaller/rCCyOHJHflI/Ik7IhXWzBAAJ)
* [drm: GPF in drm_getcap](https://groups.google.com/d/msg/syzkaller/dxVHCovRzhg/7QPBBqi4BwAJ)
* [fs: GPF in bd_mount](https://groups.google.com/d/msg/syzkaller/Z7OCclqCuq0/--YUa8QrBgAJ)
* [tty, fbcon: use-after-free in fbcon_invert_region](https://groups.google.com/d/msg/syzkaller/1DU69JpJwJg/n-6V4Wr5BQAJ)
* [drm: NULL pointer dereference in drm_mode_object_find()](https://groups.google.com/d/msg/syzkaller/7kyIupsNz-c/dWIIMpJXAQAJ)
* [6pack: stack-out-of-bounds in sixpack_receive_buf](https://groups.google.com/d/msg/syzkaller/A1x5I2hxcew/DjzZX7_mBQAJ)
* [logfs: GPF in logfs_init_inode](https://groups.google.com/d/msg/syzkaller/sU52_tpOsxQ/QTmqrIjlBQAJ)
* [tty: use-after-free in n_tty_receive_buf_fast](https://groups.google.com/d/msg/syzkaller/wz0PXUAcE7g/QN-MnqnjBQAJ)
* [sound: divide by 0 in snd_hrtimer_callback (or hang)](https://groups.google.com/d/msg/syzkaller/YZDD4SOU2Lk/LwRAiknjBQAJ)
* [mm: GPF in __insert_vmap_area](https://groups.google.com/d/msg/syzkaller/dTC7VpMKBu0/Aasz9zHiBQAJ)
* [fs, tty: WARNING in devpts_get_priv](https://groups.google.com/d/msg/syzkaller/qz7_4jCFPvw/nm19yTfbBQAJ)
* [fanotify: unkillable hanged processes](https://groups.google.com/d/msg/syzkaller/kY_ml6TCm9A/wDd5fYFXBQAJ)
* [drm: GPF in drm_context_switch_complete](https://groups.google.com/d/msg/syzkaller/ZB879NphOvw/ZDzsirsgBAAJ)
* [drm: GPF in drm_legacy_lock_free](https://groups.google.com/d/msg/syzkaller/VsfDwjS-Vk8/HOxWf1cgBAAJ)
* [sound: division by 0 in snd_hrtimer_callback](https://groups.google.com/d/msg/syzkaller/HOTZlap4aZ8/E9EnyqwfBAAJ)
* [perf: WARNING in perf_event_read](https://groups.google.com/d/msg/syzkaller/nQl0TADtoXc/qwp8erUdBAAJ)
* [drm: WARNING in drm_irq_by_busid](https://groups.google.com/d/msg/syzkaller/1ckoC7WPx3c/-JO150EIBAAJ)
* [dri: WARNING in idr_remove](https://groups.google.com/d/msg/syzkaller/wOfaszMuYSQ/2a5fyjkSBAAJ)
* [mm: use-after-free in collapse_huge_page](https://groups.google.com/d/msg/syzkaller/eFgUtJ_WbmM/yBQp-6QFBAAJ)
* [kcm: use-after-free in fput of kcm socket](https://groups.google.com/d/msg/syzkaller/1S98uAzWBLg/c9ANduUDBAAJ)
* [bdev: fix NULL pointer dereference in sync()/close() race](https://groups.google.com/d/msg/syzkaller/Gu28cO5tVSw/uAwLAuKrAwAJ)
* [bdev: fix NULL pointer dereference](https://groups.google.com/forum/#!topic/syzkaller/VF7tNBDWFMI)
* [BUG: sleeping function called from invalid context at mm/mempolicy.c:553](http://pastebin.com/uNQW3afN)
* [use-after-free in ppp_unregister_channel](http://review.cyanogenmod.org/#/c/145489/)
* [net/tipc: NULL-ptr dereference in tipc_nl_publ_dump](http://lists.openwall.net/netdev/2016/05/14/35)
* [HID: i2c-hid: fix OOB write in i2c_hid_set_or_send_report()](https://patchwork.kernel.org/patch/8583981/)
* [mm: memory corruption on mmput](http://lists.openwall.net/linux-kernel/2016/04/17/72)
* [perf: WARNING in perf_event_read](https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1214159.html)
* [9p2000.L stat/unlink race (WARNING: fs/inode.c:280 drop_nlink)](https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1214157.html)
* [mm: page fault in __do_huge_pmd_anonymous_page](https://groups.google.com/d/msg/syzkaller/Ihm6d1NmRk8/WG-qZ6aMCQAJ)
* [usb: memory allocation WARNING in hcd_buffer_alloc](https://groups.google.com/d/msg/syzkaller/svY2Ac1RYCM/wD9pZHeJCQAJ)
* [dccp: potential deadlock in dccp_v4_ctl_send_reset](https://groups.google.com/d/msg/syzkaller/yrxEaY_QQEM/Xtx0LrSICQAJ)
* [mm: GPF in find_get_pages_tag](https://groups.google.com/d/msg/syzkaller/9XYmMfpNxCg/jl1EgpmHCQAJ)
* [mm: BUG in page_move_anon_rmap](https://groups.google.com/d/msg/syzkaller/E21YB1m9Fb4/yrj55fZZCAAJ)
* [block: GPF in get_task_ioprio](https://groups.google.com/d/msg/syzkaller/pCqmZTOvf7g/foAZqH71BwAJ)
* [tty: stall in n_tty_ioctl/inq_canon](https://groups.google.com/d/msg/syzkaller/JEOgcphr_FQ/zt5eiRfUBQAJ)
* [random: negative entropy/overflow: pool input count -40000](https://groups.google.com/d/msg/syzkaller/LvdDTS5Om_g/zJmN7RfOBQAJ)
* [bpf: use after free in array_map_alloc](http://seclists.org/oss-sec/2016/q2/332) CVE-2016-4794
* [kvm: use-after-free in kvm_irqfd_release](https://groups.google.com/d/msg/syzkaller/mLrF0hWNsA0/qN0CYvVABQAJ)
* [kvm: GPF in kvm_lapic_set_tpr](https://groups.google.com/d/msg/syzkaller/kQW1tyy6vjc/0xbWT-JABQAJ)
* [sound: use-after-free in hrtimer_cancel](https://groups.google.com/d/msg/syzkaller/HMNrvp-Dt2g/kaQMrGQEAwAJ)
* [sound: hang in snd_timer_interrupt](https://groups.google.com/d/msg/syzkaller/s_OkwAWjJ1Q/8k7zhhEbAgAJ)
* [sound: deadlock involving snd_hrtimer_callback](https://groups.google.com/d/msg/syzkaller/s_OkwAWjJ1Q/O852Mz3HAQAJ)
* [fs: GPF in locked_inode_to_wb_and_lock_list](https://groups.google.com/d/msg/syzkaller/XvxH3cBQ134/F0-0r3MxAAAJ)
* [x86: bad pte in pageattr_test](https://groups.google.com/d/msg/syzkaller/Fu6BruqUHOU/nuJxpW7EAwAJ)
* [tty: memory leak in tty_open](https://groups.google.com/d/msg/syzkaller/wZUev9AXzDY/Nt4ih4B7EgAJ)
* [net: memory leak due to CLONE_NEWNET](https://groups.google.com/d/msg/syzkaller/dLbu8taoWVY/w3myILDuEQAJ)
* [lockdep WARNING in get_online_cpus](https://groups.google.com/d/msg/syzkaller/MHXa-o8foyc/o-mB1L_rEQAJ)
* [mm: BUG in khugepaged_scan_mm_slot](https://groups.google.com/d/msg/syzkaller/GNB2k9vLYc4/9Cu_fy7hEQAJ)
* [sound: use-after-free in snd_timer_interrupt](https://groups.google.com/d/msg/syzkaller/eIjELqsnpcE/xX-R8APfEQAJ)
* [scsi: machine hang due to write to /dev/sg0](https://groups.google.com/d/msg/syzkaller/oQ3Hg-JUVKA/8zwovr9lDAAJ)
* [AMD newest ucode 0x06000832 for Piledriver-based CPUs seems to behave in a problematic way](http://seclists.org/oss-sec/2016/q1/450)
* [sound: uninterruptible hang in snd_seq_oss_writeq_sync](https://groups.google.com/d/msg/syzkaller/bUvgnh0owos/Ps7Rep4XCAAJ)
* [fs: uninterruptible hang in handle_userfault](https://groups.google.com/d/msg/syzkaller/dSd90m_8O9w/-SAlwCUUCAAJ)
* [net: memory leak in N_6PACK driver](https://groups.google.com/d/msg/syzkaller/555eacbu6QQ/_3PGUrCbBQAJ)
* [net: memory leak in lapb_register](https://groups.google.com/d/msg/syzkaller/PqiopMXpNwU/8ChRtB6bBQAJ)
* [net: memory leak in mkiss_open](https://groups.google.com/d/msg/syzkaller/ylPCtzQr_jc/z_x_9uKaBQAJ)
* [sound: list corruption in delete_and_unsubscribe_port](https://groups.google.com/d/msg/syzkaller/XcYfdFeeyK8/R49jRCLCAwAJ)
* [kvm: GPF in kvm_pic_clear_all](https://groups.google.com/d/msg/syzkaller/FzqGSkRKwm0/h4Yz2CSBAwAJ)
* [kvm: GPF in kvm_irq_map_gsi](https://groups.google.com/d/msg/syzkaller/Rg4Y2Z6HbHI/w9zXygeAAwAJ)
* [tty: memory leak in tty_register_driver](https://groups.google.com/d/msg/syzkaller/iPxmOCKQLbU/0yLjf9x2AwAJ)
* [sound: memory leak in snd_seq_pool_init](https://groups.google.com/d/msg/syzkaller/hpzw94zvlLI/HBqrHjJzAwAJ)
* [tty: deadlock between tty_buffer_flush/n_tracesink_open](https://groups.google.com/d/msg/syzkaller/HX5NRBC8ubw/w4XgLENBAwAJ)
* [sound: heap out-of-bounds write in dummy_systimer_prepare](https://groups.google.com/d/msg/syzkaller/PBGF26zn2DY/8PdCofDMAAAJ)
* [fs: NULL deref in atime_needs_update](https://groups.google.com/d/msg/syzkaller/0SW33jMcrXQ/7qZfeV-HAAAJ)
* [sound: spinlock lockup in snd_seq_oss_write](https://groups.google.com/d/msg/syzkaller/aSwFzmSY7Rc/zIKYuKczAAAJ)
* [net: memory leak in ip_cmsg_send](https://groups.google.com/d/msg/syzkaller/keQktFmhfBM/UDsS4tEACAAJ)
* [net/irda: BUG: looking up invalid subclass: 4294967295](https://groups.google.com/d/msg/syzkaller/RSwLEwkWag8/S2kSuPn-BwAJ) CVE-2017-6348
* [sound: use-after-free in snd_timer_start1](https://groups.google.com/d/msg/syzkaller/zF-7vhuSc9o/O89UIO3HBwAJ)
* [tty: tty_struct memory leak](https://groups.google.com/d/msg/syzkaller/ZPlLcAxOFSw/NyFyCAjIBwAJ)
* [gigaset: memory leak in gigaset_initcshw](https://groups.google.com/d/msg/syzkaller/wu3NyQ5ZJFE/sat9DwTFBwAJ)
* [sound: out-of-bounds write in snd_rawmidi_kernel_write1](https://groups.google.com/d/msg/syzkaller/Au60AgpecfQ/a3eWMIevBwAJ)
* [mm: uninterruptable tasks hanged on mmap_sem](https://groups.google.com/d/msg/syzkaller/6M2Z5r28UDA/nYPsJ1KIBwAJ)
* [sound: another WARNING in rawmidi_transmit_ack](https://groups.google.com/d/msg/syzkaller/FEjR2q-Ri-s/IXSua74aBwAJ)
* [sound: use-after-free in snd_seq_deliver_single_event](https://groups.google.com/d/msg/syzkaller/c8bhbCQP-XA/Abeq8ToXBwAJ)
* [sound: WARNING in snd_rawmidi_kernel_write1](https://groups.google.com/d/msg/syzkaller/BI280LemTW8/KgcuDJYWBwAJ)
* [sound: deadlock between snd_pcm_oss_write/snd_pcm_oss_mmap](https://groups.google.com/forum/#!topic/syzkaller/MlIO0DbOtsA)
* [ata: BUG in ata_sff_hsm_move](https://groups.google.com/d/msg/syzkaller/GyV2KfwtfTg/PiTmmqngBQAJ)
* [WARNING in set_restore_sigmask](https://groups.google.com/d/msg/syzkaller/unp9iTQ4IKc/bvJO8A4oBgAJ)
* [BUG: bad unlock balance detected in vma_unlock_anon_vma](https://groups.google.com/d/msg/syzkaller/SaJgfpbKTlg/kSdMBKWPBQAJ)
* [bluetooth: use-after-free in vhci_send_frame](https://groups.google.com/d/msg/syzkaller/oWvyWrgd3M4/nAu5XTMmBgAJ)
* [mm: another VM_BUG_ON_PAGE(PageTail(page))](https://groups.google.com/d/msg/syzkaller/boW7sZ0HoYA/j8hH8-vcBQAJ)
* [scsi: NULL deref in sg_start_req](https://groups.google.com/d/msg/syzkaller/8Fg8X9iguFM/u6sUrAvcBQAJ)
* [mm: BUG in expand_downwards](https://groups.google.com/d/msg/syzkaller/SaJgfpbKTlg/kSdMBKWPBQAJ)
* [sound: heap out-of-bounds write in dummy_systimer_prepare](https://groups.google.com/d/msg/syzkaller/PBGF26zn2DY/YMstW6CMBQAJ)
* [WARNING in do_jobctl_trap](https://groups.google.com/d/msg/syzkaller/67Ipm9Q3dN4/Mn1ZM1pPBQAJ)
* [mm: VM_BUG_ON_PAGE(PageTail(page)) in mbind](https://groups.google.com/d/msg/syzkaller/rUdHl1uq8GU/fd2lDLFHBQAJ)
* [net/bluetooth: workqueue destruction WARNING in hci_unregister_dev](https://groups.google.com/d/msg/syzkaller/uVXU3InAfRY/U7AuPXdEBQAJ)
* [gpu: kmalloc size WARNING in vga_arb_write](https://groups.google.com/d/msg/syzkaller/To4N4VWHTNU/k-5QDrk_BQAJ)
* [net/rfkill: WARNING in rfkill_fop_read](https://groups.google.com/d/msg/syzkaller/hijZUVUav8E/7tjnCAM-BQAJ)
* [sound: use-after-free in _snd_timer_stop](https://groups.google.com/d/msg/syzkaller/DjSwFNnJZn8/flxXWywRBQAJ)
* [net/irda: use-after-free in ircomm_param_request](https://groups.google.com/d/msg/syzkaller/p_WWX0G_UXQ/zGKfw04DBQAJ)
* [net/sctp: out-of-bounds access in sctp_add_bind_addr](https://groups.google.com/d/msg/syzkaller/BhOYz2ZBraw/-k3iDvD8BAAJ)
* [ext4: BUG: scheduling while atomic in ext4_commit_super](https://groups.google.com/d/msg/syzkaller/vIc3Dz_TTRI/dBNrj2G3BAAJ)
* [sound: WARNING in snd_rawmidi_transmit_ack](https://groups.google.com/d/msg/syzkaller/NJZR4sUggm8/ld5OCVu2BAAJ)
* [floppy: GPF in floppy_rb0_cb](https://groups.google.com/d/msg/syzkaller/AWXjFnnBN_s/RyzWTaKrBAAJ)
* [tty: kmalloc size WARNING in vc_do_resize](https://groups.google.com/d/msg/syzkaller/ufjvr5j0URo/6PSRe7mlBAAJ)
* [mm: WARNING in __delete_from_page_cache](https://groups.google.com/d/msg/syzkaller/w41UMMBPWRo/dyQTUcGjBAAJ)
* [sound: WARNING in snd_seq_oss_synth_cleanup](https://groups.google.com/d/msg/syzkaller/vfGuMIyOw1E/9-UwD5SiBAAJ)
* [sound: deadlock between snd_rawmidi_kernel_open/snd_seq_port_connect](https://groups.google.com/d/msg/syzkaller/T33gMP-856o/EyGhSkagBAAJ)
* [net: GPF in netlink_getsockbyportid](https://groups.google.com/d/msg/syzkaller/VlgAydM9Zu4/ts6sdhVuBAAJ)
* [fs: use-after-free in link_path_walk](https://groups.google.com/d/msg/syzkaller/t2QMO6N5F8s/MuY0RQ4tBAAJ)
* [fs: sandboxed process brings host down](https://groups.google.com/d/msg/syzkaller/gCyxNiVGGds/WP27JlAoBAAJ)
* [net: use-after-free in recvmmsg](https://groups.google.com/d/msg/syzkaller/amvYsa-I8yE/YRHrDOAmBAAJ)
* [struct pid memory leak](https://groups.google.com/d/msg/syzkaller/j7ld8eOG1OQ/7IJSStAUBAAJ)
* [net: WARNING in dccp_set_state](https://groups.google.com/d/msg/syzkaller/kWaUYryuwSY/9jbwNyRlAwAJ)
* [mm: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected in split_huge_page_to_list](https://groups.google.com/d/msg/syzkaller/zezMs3b7Vsc/Vo-6bujTAgAJ)
* [sound: BUG in snd_ctl_find_numid](https://groups.google.com/d/msg/syzkaller/rc3dZwnu5ZI/uRWvc2XUAgAJ)
* [net: GPF in __netlink_ns_capable](https://groups.google.com/forum/#!topic/syzkaller/daN8eU9ttSg)
* [crypto: slab-out-of-bounds in skcipher_recvmsg](https://groups.google.com/d/msg/syzkaller/VBcr-fy-t0w/KJo9r0r5AQAJ)
* [net: hang in ip_finish_output](https://groups.google.com/d/msg/syzkaller/OM7CXieBCoY/etzvFPX3AQAJ)
* [kvm: access to invalid memory in mmu_zap_unsync_children](https://groups.google.com/d/msg/syzkaller/4wAzRPswgQ8/IWGjISZQFQAJ)
* [kvm: using uninitialized var in tdp_page_fault](https://groups.google.com/d/msg/syzkaller/4u4EokUaq8U/jEkM-ZZQFQAJ)
* [sound: spinlock lockup in sound/core/timer.c](https://groups.google.com/d/msg/syzkaller/bbtG9_h1ONU/CPLblMC6FAAJ)
* [sound: GPF in snd_timer_user_params](https://groups.google.com/d/msg/syzkaller/pGyQMx7Fq84/Kzzp1yytFAAJ)
* [sound: use-after-free in snd_timer_interrupt](https://groups.google.com/d/msg/syzkaller/_jsbNkayw7w/vbivwMWsFAAJ)
* [sound: use-after-free in snd_timer_user_ioctl](https://groups.google.com/d/msg/syzkaller/9mIp43V-OS8/uCHNBiSsFAAJ)
* [crypto: use-after-free in skcipher_sock_destruct](https://groups.google.com/d/msg/syzkaller/GdqfroKSD8Q/goTM-tyiFAAJ)
* [net/sctp: use-after-free in __sctp_connect](https://groups.google.com/d/msg/syzkaller/wB2VUZcQRkE/NlNJBvybFAAJ)
* [net: WARNING in tcp_recvmsg](https://groups.google.com/d/msg/syzkaller/tDe2SCAzirE/ar2v6cZQFAAJ)
* [sound: use-after-free in snd_timer_stop](https://groups.google.com/d/msg/syzkaller/IAjJAaJOHZg/s1Ud2wVPFAAJ)
* [sound: GPF in snd_seq_fifo_clear](https://groups.google.com/d/msg/syzkaller/KbVqGu3WcPs/dYdSgjVOFAAJ)
* [crypto: ablk_decrypt causes BUG in scatterwalk](https://groups.google.com/d/msg/syzkaller/J5BIP1NxPVc/V5RQhCRMFAAJ)
* [kvm: GPF in native_set_debugreg](https://groups.google.com/d/msg/syzkaller/E_simxTrAxM/K70SOr4wEwAJ)
* [kvm: GPF in kvm_lapic_latched_init](https://groups.google.com/d/msg/syzkaller/Sw8voIm9wN4/AV_6rPsvEwAJ)
* [kvm: WARNING in kvm_apic_accept_events](https://groups.google.com/d/msg/syzkaller/qING1Xy24JY/v9sxuVErEwAJ)
* [kvm: vmalloc allocation failure in kvm_vm_ioctl](https://groups.google.com/d/msg/syzkaller/K47NvuAAPz4/PO9mb4c4EwAJ)
* [kvm: vmalloc allocation failure in kvm_vcpu_ioctl_set_cpuid](https://groups.google.com/d/msg/syzkaller/58wqKq6iCXk/qQsxAH8pEwAJ)
* [kvm: WARNING in __x86_set_memory_region](https://groups.google.com/d/msg/syzkaller/tYgkwrDQjkg/jTllLeYmEwAJ)
* [kvm: WARNING in exception_type](https://groups.google.com/d/msg/syzkaller/NVYxVRSPan4/WCVzMTImEwAJ)
* [mm: possible deadlock in mm_take_all_locks](https://groups.google.com/d/msg/syzkaller/AxduklbKrfc/VQ2r5VQqEwAJ)
* [net/nfc: GPF in llcp_sock_getname](https://groups.google.com/d/msg/syzkaller/uj-hx-eBQ28/KCztJ2z6EAAJ)
* [net/netlink: memory leak in netlink_sendmsg](https://groups.google.com/d/msg/syzkaller/UUAHYw5MtjA/JEEHUuykEAAJ)
* [net/tipc: memory leak in tipc_release](https://groups.google.com/d/msg/syzkaller/5-GmaFy2BUI/Z1RBMsigEAAJ)
* [memory leak in lapb_create_cb](https://groups.google.com/d/msg/syzkaller/A-AnLCJnfIM/TCX4G1N0EAAJ)
* [net/sctp: sctp_datamsg memory leak](https://groups.google.com/d/msg/syzkaller/hLdAYS7j_tM/rwo6p5x1EAAJ)
* [net/sctp: sock memory leak](https://groups.google.com/d/msg/syzkaller/rB_bD-M8ijs/m44UxFNzEAAJ)
* [net/nfc: user-controllable kmalloc size in nfc_llcp_send_ui_frame](https://groups.google.com/d/msg/syzkaller/D9S8Ji0HJtM/9nJc3SdTEAAJ)
* [tty: deadlock between n_tracerouter_receivebuf and flush_to_ldisc](https://groups.google.com/d/msg/syzkaller/YrV0bzdfa-g/n5Eyi6tSEAAJ)
* [crypto: use-after-free in alg_bind](https://groups.google.com/d/msg/syzkaller/exVfK_05eqU/hszZrHwjEAAJ)
* [crypto: deadlock in alg_setsockopt](https://groups.google.com/d/msg/syzkaller/t3fOIUvQRR0/Xf8Jw9sdEAAJ)
* [crypto: use-after-free in rng_recvmsg](https://groups.google.com/d/msg/syzkaller/4Ivvjq4KGhM/EbQX8Ze_DwAJ)
* [use-after-free in skcipher_bind](https://groups.google.com/d/msg/syzkaller/frb2XrB5aWk/iFcu_0R8DgAJ)
* [9p: sleeping function called from invalid context in v9fs_vfs_atomic_open_dotl](https://groups.google.com/d/msg/syzkaller/1YncbDVfdow/JudLnO49DgAJ)
* [fs: WARNING in locks_free_lock_context](https://groups.google.com/d/msg/syzkaller/AxzCz8bJPko/A6iFq0IsDgAJ)
* [net: user-controllable kmalloc size in __sctp_setsockopt_connectx](https://groups.google.com/d/msg/syzkaller/mv8Iaz0oHAs/b3dwSCD9DQAJ)
* [GPF in gf128mul_64k_bbe](https://groups.google.com/d/msg/syzkaller/BIjLNIO1g7k/6FTkQpFcDAAJ)
* [use-after-free in hash_sock_destruct](https://groups.google.com/d/msg/syzkaller/XSCcDfuj3Cw/cplfjIlcDAAJ)
* [GPF in lrw_crypt](https://groups.google.com/d/msg/syzkaller/frb2XrB5aWk/xCXzkIBcDAAJ)
* [bad page state due to PF_ALG socket](https://groups.google.com/d/msg/syzkaller/OEaEMF5cRpc/AyYAGndcDAAJ)
* [use-after-free in skcipher_sock_destruct](https://groups.google.com/d/msg/syzkaller/Oi2d1GRRnPY/rbZZ5lZcDAAJ)
* [use-after-free in sixpack_close](https://groups.google.com/d/msg/syzkaller/QRZjzAzG0wg/pvnCAZNWDAAJ)
* [net: heap-out-of-bounds in sock_setsockopt](https://groups.google.com/d/msg/syzkaller/5J4lQcwp0x4/ATAqYNZ0CwAJ)
* [BUG_ON(!PageLocked(page)) in munlock_vma_page](https://groups.google.com/d/msg/syzkaller/8KEw1_E05zs/-HzQwaQlCwAJ)
* [perf: stalls in perf_install_in_context/perf_remove_from_context](https://groups.google.com/d/msg/syzkaller/NyMvU8ClQEM/7PjQ1csQCwAJ)
* [Information leak in sco_sock_bind](https://groups.google.com/d/msg/syzkaller/L2DGhEYtnQo/e0pj2sQpCwAJ) CVE-2015-8575
* [Information leak in llcp_sock_bind/llcp_raw_sock_bind](https://groups.google.com/d/msg/syzkaller/DHI06NjAnBw/02kKZKYnCwAJ)
* [Information leak in pptp_bind](https://groups.google.com/d/msg/syzkaller/fSqTaDjzcIo/HGa4cGi6CgAJ)
* [use-after-free in pptp_connect](https://groups.google.com/d/msg/syzkaller/w238o__gw7M/RrGhpOJ0CgAJ)
* [GPF in keyctl](https://bugzilla.redhat.com/show_bug.cgi?id=1290370) CVE-2015-7550
* [another use-after-free in sctp_do_sm](https://groups.google.com/d/msg/syzkaller/OUaLglyQNYM/RQu4vcQ-CQAJ)
* [use-after-free in inet6_destroy_sock](https://groups.google.com/d/msg/syzkaller/u1NA-bgkR18/cMqpYl09CQAJ)
* [WARNING in crypto_wait_for_test](https://groups.google.com/d/msg/syzkaller/WZWajo0A2J4/K93w98fkCAAJ)
* [int overflow in io_getevents](https://groups.google.com/d/msg/syzkaller/UldJpka5MbA/riM5IbqTCAAJ)
* [use-after-free in ip6_xmit](https://groups.google.com/d/msg/syzkaller/YpU1_PMV_gU/FmLVGHqTCAAJ)
* [use-after-free in __perf_install_in_context](https://groups.google.com/d/msg/syzkaller/3Tk4BmoHxIk/x-EOZH_HBwAJ)
* [undefined shift in __bpf_prog_run](https://groups.google.com/d/msg/syzkaller/H7o2oz9CcKg/uzaiF7eqBwAJ)
* [signed integer overflow in ktime_add_safe](https://groups.google.com/d/msg/syzkaller/1R5FD_PtR1A/dVv99hGqBwAJ)
* [jump label: negative count!](https://groups.google.com/d/msg/syzkaller/OUaLglyQNYM/hCg9HfHjDgAJ)
* [memory leak in alloc_huge_page](https://groups.google.com/d/msg/syzkaller/zg4TVSy6Ri8/qs99M-bJDwAJ)
* [memory leak in do_ipv6_setsockopt](https://groups.google.com/d/msg/syzkaller/xWavbbgt0qg/SpY86JLEDwAJ)
* [heap out-of-bounds access in array_map_update_elem](https://groups.google.com/d/msg/syzkaller/5NHTQ3U60-s/Xlnq60JwDwAJ)
* [deadlock in perf_ioctl](https://groups.google.com/d/msg/syzkaller/pOiDJIU5zI4/UXIsO9BrDwAJ)
* [user-controllable kmalloc size in bpf syscall](https://groups.google.com/d/msg/syzkaller/vhm-Av765TY/VzjC4zMqDwAJ)
* [net: use after free in ip6_make_skb](https://groups.google.com/d/msg/syzkaller/Pa8ovVaYL9c/Mw32fULmDgAJ)
* [user-controllable kmalloc size in sctp_getsockopt_local_addrs](https://groups.google.com/d/msg/syzkaller/WWpkIGBC0ts/kpMmnYfZDgAJ)
* [use-after-free in ip6_setup_cork](https://groups.google.com/d/msg/syzkaller/fHZ42YrQM-Y/Z4Xf-BbUDgAJ)
* [gigaset: freeing an active object](https://groups.google.com/d/msg/syzkaller/bOJJJcbKtjM/IGkN5ZyTDgAJ)
* [Freeing active kobject in pps_device_destruct](https://groups.google.com/forum/#!topic/syzkaller/rueDAZYv5v0)
* [GPF in process_one_work (flush_to_ldisc)](https://groups.google.com/d/msg/syzkaller/z3WIRnS2q9g/_TXY3LBBDgAJ)
* [use-after-free in tty_check_change](https://groups.google.com/d/msg/syzkaller/PGnPGgljA8A/5yfiRls1DgAJ)
* [WARNING in tcp_recvmsg](https://groups.google.com/d/msg/syzkaller/vlk-2b1hAVQ/JpkM7K36DQAJ)
* [use-after-free in irtty_open](https://groups.google.com/d/msg/syzkaller/foW6EoJnc9Y/q0gKZ3f3DQAJ)
* [use-after-free in sock_wake_async](https://groups.google.com/forum/#!topic/syzkaller/IjAetA6uvIc)
* [WARNING in handle_mm_fault](https://groups.google.com/forum/#!topic/syzkaller/o8VqvYNEu_I)
* [WARNING in gsm_cleanup_mux](https://groups.google.com/d/msg/syzkaller/zAvZnQBWGac/IPU35GyYDQAJ)
* [use-after-free in sctp_do_sm](https://groups.google.com/d/msg/syzkaller/OUaLglyQNYM/UWs4GxGUDQAJ)
* [yet another uninterruptable hang in sendfile](https://groups.google.com/forum/#!topic/syzkaller/Jy08esFVw9k)
* [GPF in add_key](https://bugzilla.redhat.com/show_bug.cgi?id=1284059)
* [another uninterruptable hang in sendfile](https://groups.google.com/forum/#!topic/syzkaller/sjA9DrBQviw)
* [deadlock during fuseblk shutdown](https://groups.google.com/forum/#!topic/syzkaller/w-B4OeANKu8)
* [tty,net: use-after-free in x25_asy_open_tty](https://groups.google.com/d/msg/syzkaller/kYOghurchCg/aVg9hBBpDAAJ)
* [deadlock between tty_write and tty_send_xchar](https://groups.google.com/forum/#!topic/syzkaller/X12P_8jITAM)
* [WARNING in shmem_evict_inode](https://groups.google.com/forum/#!topic/syzkaller/HeT_3b2HIrs)
* [Deadlock between setsockopt/getsockopt](https://groups.google.com/forum/#!topic/syzkaller/46AwIkaOclk)
* [Deadlock between bind and splice](https://groups.google.com/forum/#!topic/syzkaller/HSofF04GVCA)
* [Use-after-free in ipv4_conntrack_defrag](https://groups.google.com/forum/#!topic/syzkaller/k62o6Fiu124)
* [Use-after-free in selinux_ip_postroute_compat](https://groups.google.com/forum/#!topic/syzkaller/eu-3LPXgdok)
* [Use-after-free in unshare](https://patchwork.ozlabs.org/patch/539061/)
* [GPF in tcp_sk_init/icmp_sk_init](https://patchwork.ozlabs.org/patch/539018/)
* [lockdep warning in ip_mc_msfget](https://groups.google.com/forum/#!topic/syzkaller/ScMRWhgAsbM)
* [WARNING in task_participate_group_stop](https://groups.google.com/forum/#!topic/syzkaller/p5ailXs8eEc)
* [Resource leak in unshare](https://groups.google.com/forum/#!topic/syzkaller/cdJvHvazRJk)
* [Paging fault with hard IRQs disabled in getsockopt](https://groups.google.com/forum/#!topic/syzkaller/AegFEboavHM)
* [Unkillable processes due to PTRACE_TRACEME](https://groups.google.com/forum/#!msg/syzkaller/uGzwvhlCXAw/E-cfY2ejAgAJ)
* [Use-after-free in ep_remove_wait_queue](https://groups.google.com/forum/#!topic/syzkaller/3twDUI4Cpm8) CVE-2013-7446
* [GPF in shm_lock](https://groups.google.com/forum/#!topic/syzkaller/4jVzR278N9k)
* [GPF in rt6_uncached_list_flush_dev](https://groups.google.com/forum/#!topic/syzkaller/XmcaDo9DnSg)
* [Infinite loop in ip6_fragment](https://groups.google.com/forum/#!topic/syzkaller/PoD9yGkY1y8)
* [Uninterruptable hang in sendfile](https://groups.google.com/forum/#!topic/syzkaller/zfuHHRXL7Zg)
* [GPF in keyring_destroy](https://groups.google.com/forum/#!topic/syzkaller/E2DRBbUDEg8) [CVE-2015-7872](https://bugzilla.redhat.com/show_bug.cgi?id=1272371)

---

### Linux Found Bugs Usb (`docs/linux/found_bugs_usb.md`)

# Found Linux kernel USB bugs

## Reported by syzbot

Starting from early 2019, bugs in the USB drivers are being automatically reported by the USB fuzzing instance of syzbot and can be found [here](https://syzkaller.appspot.com/upstream?manager=ci2-upstream-usb). A list of CVEs for some of those can be found here [here](https://www.openwall.com/lists/oss-security/2019/08/20/2).

Some of the USB bugs are reported by the KMSAN fuzzing instance and can be either found [here](https://groups.google.com/forum/#!searchin/syzkaller-bugs/%22kmsan%22$20%22usb%22%7Csort:date) or [here](https://syzkaller.appspot.com/upstream?manager=ci-upstream-kmsan-gce) (via a manual search, e.g. for `kernel-usb-infoleak`).

## Manually reported

These are the bugs that were manually reported before USB fuzzing was integrated into syzbot.

### USB drivers

* usb/core: memory corruption due to an out-of-bounds access in usb_destroy_configuration [[fix](https://www.spinics.net/lists/linux-usb/msg163644.html)] [CVE-2017-17558]
* [usb/net/zd1211rw: possible deadlock in zd_chip_disable_rxtx](https://groups.google.com/forum/#!topic/syzkaller/w_qXxIJfwmE)
* [usb/sound: use-after-free in __uac_clock_find_source](https://groups.google.com/forum/#!topic/syzkaller/FwYGmsC6c6E) [[fix](https://www.spinics.net/lists/alsa-devel/msg69833.html)]
* [usb/sound: slab-out-of-bounds in parse_audio_unit](https://groups.google.com/forum/#!topic/syzkaller/RJtoiisdruo) [[fix](https://www.spinics.net/lists/alsa-devel/msg69836.html)]
* [usb/media/em28xx: use-after-free in dvb_unregister_frontend](https://groups.google.com/forum/#!topic/syzkaller/wYG12peh1G4) [[fix](https://patchwork.linuxtv.org/patch/45219/)]
* [usb/media/technisat: slab-out-of-bounds in technisat_usb2_rc_query](https://groups.google.com/forum/#!topic/syzkaller/V-GvHOmJXO0)
* [usb/media/tm6000: use-after-free in tm6000_read_write_usb](https://groups.google.com/forum/#!topic/syzkaller/XLNeGPycipA)
* [usb/net/qmi_wwan: divide error in qmi_wwan_probe/usbnet_probe](https://groups.google.com/forum/#!topic/syzkaller/0e0gmaX9R0g) [[fix1](https://github.com/torvalds/linux/commit/2cb80187ba065d7decad7c6614e35e07aec8a974), [fix2](https://github.com/torvalds/linux/commit/7fd078337201cf7468f53c3d9ef81ff78cb6df3b)] [CVE-2017-16649, CVE-2017-16650]
* [usb/media/uvc: slab-out-of-bounds in uvc_probe](https://groups.google.com/forum/#!topic/syzkaller/Ot1fOE6v1d8)
* [usb/media/em28xx: use-after-free in em28xx_dvb_fini](https://groups.google.com/forum/#!topic/syzkaller/GcS_S4zY2ZQ)
* [usb/media/em28xx: use-after-free in v4l2_fh_init](https://groups.google.com/forum/#!topic/syzkaller/FnJq_QkwCLQ)
* [usb/media/pvrusb2: WARNING in pvr2_i2c_core_done/sysfs_remove_group](https://groups.google.com/forum/#!topic/syzkaller/0rKk1nKucQA)
* [usb/sound/usx2y: WARNING in usb_stream_start](https://groups.google.com/forum/#!topic/syzkaller/Gspr1ddXgHA) [[fix](https://github.com/torvalds/linux/commit/f9a1c372299fed53d4b72bb601f7f3bfe6f9999c)]
* [usb/net/hfa384x: WARNING in submit_rx_urb/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/hO1s_STq2II)
* [usb/media/dw2102: null-ptr-deref in dvb_usb_adapter_frontend_init/tt_s2_4600_frontend_attach](https://groups.google.com/forum/#!topic/syzkaller/kmNvrHHgVg4)
* [usb/net/asix: kernel hang in asix_phy_reset](https://groups.google.com/forum/#!topic/syzkaller/3yQVZuxIO-w)
* [usb/media/dtt200u: use-after-free in __dvb_frontend_free](https://groups.google.com/forum/#!topic/syzkaller/0HJQqTm0G_g) [[fix](https://github.com/torvalds/linux/commit/b1cb7372fa822af6c06c8045963571d13ad6348b)] [CVE-2017-16648]
* [usb/media/mxl111sf: trying to register non-static key in mxl111sf_ctrl_msg](https://groups.google.com/forum/#!topic/syzkaller/Xlvm_cnulFA)
* [usb/media/au0828: use-after-free in au0828_rc_unregister](https://groups.google.com/forum/#!topic/syzkaller/3yL32uggAT0)
* [usb/input/gtco: slab-out-of-bounds in parse_hid_report_descriptor](https://groups.google.com/forum/#!topic/syzkaller/McWFcOsA47Y) [[fix](https://github.com/torvalds/linux/commit/a50829479f58416a013a4ccca791336af3c584c7)] [CVE-2017-16643]
* [usb/core: slab-out-of-bounds in usb_get_bos_descriptor](https://groups.google.com/forum/#!topic/syzkaller/tzdz2fTB1K0) [[fix](https://github.com/torvalds/linux/commit/1c0edc3633b56000e18d82fc241e3995ca18a69e)] [CVE-2017-16535]
* [usb/net/asix: null-ptr-deref in asix_suspend](https://groups.google.com/forum/#!topic/syzkaller/_9a6pd-p_0E) [[fix](https://patchwork.ozlabs.org/patch/834686/)] [CVE-2017-16647]
* [usb/net/rt2x00: warning in rt2800_eeprom_word_index](https://groups.google.com/forum/#!topic/syzkaller/8vWPJ_maXQY)
* [usb/irda: global-out-of-bounds in irda_qos_bits_to_value](https://groups.google.com/forum/#!topic/syzkaller/PzxkGCumhwA)
* [usb/media/imon: global-out-of-bounds in imon_probe/imon_init_intf0](https://groups.google.com/forum/#!topic/syzkaller/o0LHaEe8Alg)
* [usb/sound: use-after-free in snd_usb_mixer_interrupt](https://groups.google.com/forum/#!topic/syzkaller/jf7GTr_g2CU) [[fix](https://github.com/torvalds/linux/commit/124751d5e63c823092060074bd0abaae61aaa9c4)] [CVE-2017-16527]
* [usb/net/rtlwifi: trying to register non-static key in rtl_c2hcmd_launcher](https://groups.google.com/forum/#!topic/syzkaller/vCTFZwPpmps)
* [usb/net/prism2usb: warning in hfa384x_usbctlxq_run/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/Bm5IO2dlcxA)
* [usb/nfs/pn533: use-after-free in pn533_send_complete](https://groups.google.com/forum/#!topic/syzkaller/-EkDbzlSuOY)
* [usb/media/imon: null-ptr-deref in imon_probe](https://groups.google.com/forum/#!topic/syzkaller/bBFN8imrjjo) [[fix](https://github.com/torvalds/linux/commit/58fd55e838276a0c13d1dc7c387f90f25063cbf3)] [CVE-2017-16537]
* [usb/net/prism2usb: warning in hfa384x_drvr_start/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/rPui1tYcrR0)
* [usb/net/ath6kl: GPF in ath6kl_usb_alloc_urb_from_pipe](https://groups.google.com/forum/#!topic/syzkaller/_ZE7_2A82Go)
* [usb/net/ar5523: warning in ar5523_submit_rx_cmd/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/5V7rYXYCuI4)
* [usb/media/uvc: BUG in uvc_mc_create_links/media_create_pad_link](https://groups.google.com/forum/#!topic/syzkaller/BOv81nh75TM)
* [usb/media/v4l2: use-after-free in video_unregister_device/device_del](https://groups.google.com/forum/#!topic/syzkaller/C2RyOxjhxh4)
* [usb/serial/visor: slab-out-of-bounds in palm_os_3_probe](https://groups.google.com/forum/#!topic/syzkaller/G5hNiJG2RXo) [[fix](https://groups.google.com/d/msg/syzkaller/G5hNiJG2RXo/Vu6_fuWJBAAJ) on the way]
* [usb/misc/usbtest: null-ptr-deref in usbtest_probe/get_endpoints](https://groups.google.com/forum/#!topic/syzkaller/l3870gs3LhA) [[fix](https://github.com/torvalds/linux/commit/7c80f9e4a588f1925b07134bb2e3689335f6c6d8)] [CVE-2017-16532]
* [usb/misc/ims-pcu: slab-out-of-bounds in ims_pcu_parse_cdc_data](https://groups.google.com/forum/#!topic/syzkaller/q6jjr1OhqO8) [[fix](https://github.com/torvalds/linux/commit/ea04efee7635c9120d015dcdeeeb6988130cb67a)] [CVE-2017-16645]
* [usb/serial: use-after-free in usb_serial_disconnect/__lock_acquire](https://groups.google.com/forum/#!topic/syzkaller/cMACrmo1x0k) [[fix1](https://github.com/torvalds/linux/commit/bd998c2e0df0469707503023d50d46cf0b10c787), [fix2](https://github.com/torvalds/linux/commit/299d7572e46f98534033a9e65973f13ad1ce9047)] [CVE-2017-16525]
* [usb/misc/rio500: double-free or invalid-free in disconnect_rio](https://groups.google.com/forum/#!topic/syzkaller/7JmbWaXqaIQ)
* [usb/sound/caiaq: warning in init_card/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/juLOtVudBkQ) [[fix](https://github.com/torvalds/linux/commit/58fc7f73a85d45a47057dad2af53502fdf6cf778)]
* [usb/input/aiptek: warning in aiptek_open/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/F7dVa-5YFlQ)
* [usb/net/lan78xx: use-after-free in lan78xx_write_reg](https://groups.google.com/forum/#!topic/syzkaller/5dEtqOKkv54)
* [usb/media/b2c2: GPF in flexcop_usb_transfer_init](https://groups.google.com/forum/#!topic/syzkaller/ToOkJ0Ox-HA)
* [usb/media/uvc: warning in uvc_scan_chain_forward/__list_add](https://groups.google.com/forum/#!topic/syzkaller/cEn3pmrYye4)
* [usb/sound/line6: trying to register non-static key in podhd_disconnect](https://groups.google.com/forum/#!topic/syzkaller/wEY6yXp-zC8)
* [usb/sound/line6: warning in line6_start_listen/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/33v4K1orrPk) [[fix](https://github.com/torvalds/linux/commit/2a4340c57717162c6bf07a0860d05711d4de994b)]
* [usb/media/lmedm04: GPF in lme2510_int_read/usb_pipe_endpoint](https://groups.google.com/forum/#!topic/syzkaller/XwNidsl4X04) [[fix1](https://patchwork.linuxtv.org/patch/44566/), [fix2](https://patchwork.linuxtv.org/patch/44567/)] [CVE-2017-16538]
* [usb/sound/bcd2000: warning in bcd2000_idrivers/usb/serial/usb-serial.cnit_device](https://groups.google.com/forum/#!topic/syzkaller/uU0anmKkD1w) [[fix](https://github.com/torvalds/linux/commit/6815a0b444572527256f0d0efd8efe3ddede6018)]
* [usb/wireless/rsi_91x: use-after-free write in __run_timers](https://groups.google.com/forum/#!topic/syzkaller/9IV2cQldrx0)
* [usb/media/zr364xx: GPF in zr364xx_vidioc_querycap/strlcpy](https://groups.google.com/forum/#!topic/syzkaller/-EuMlzvOHGo)
* [usb/media/stkwebcam: use-after-free in v4l2_ctrl_handler_free](https://groups.google.com/forum/#!topic/syzkaller/5kLo7aPtx1w)
* [usb/media/dib0700: BUG in stk7070p_frontend_attach/symbol_put_addr](https://groups.google.com/forum/#!topic/syzkaller/-d6ilzbVu_g) [[fix](https://patchwork.linuxtv.org/patch/45291/)] [CVE-2017-16646]
* [usb/sounds: slab-out-of-bounds read in snd_usb_create_streams](https://groups.google.com/forum/#!topic/syzkaller/rDzv5RP_f2M) [[fix](https://github.com/torvalds/linux/commit/bfc81a8bc18e3c4ba0cbaa7666ff76be2f998991)] [CVE-2017-16529]
* [usb/media/hdpvr: trying to register non-static key in hdpvr_probe](https://groups.google.com/forum/#!topic/syzkaller/ngC5SLvxPm4) [[fix](https://patchwork.kernel.org/patch/9966135/)] [CVE-2017-16644]
* [usb/net/hso: warning in hso_free_net_device](https://groups.google.com/forum/#!topic/syzkaller/J4Ua_T43Tjw)
* [usb/net/hso: global-out-of-bounds in hso_probe](https://groups.google.com/forum/#!topic/syzkaller/TDPcSXI2nBA)
* [usb/media/smsusb: use-after-free in worker_thread](https://groups.google.com/forum/#!topic/syzkaller/RS7QUTKo23s)
* [usb/storage/uas: slab-out-of-bounds in uas_probe](https://groups.google.com/forum/#!topic/syzkaller/pCswO77gRlM) [[fix](https://github.com/torvalds/linux/commit/786de92b3cb26012d3d0f00ee37adf14527f35c4)] [CVE-2017-16530]
* [usb/sound/usx2y: warning in usb_stream_new/__alloc_pages_slowpath](https://groups.google.com/forum/#!topic/syzkaller/vGwGJW_H-0I) [[fix](https://github.com/torvalds/linux/commit/7682e399485fe19622b6fd82510b1f4551e48a25)]
* [usb/media/pvrusb2: warning in pvr2_send_request_ex/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/M2GeMYS0f6E) [[fix](https://www.spinics.net/lists/kernel/msg2639143.html)]
* [usb/media/smsusb: null-ptr-deref in smsusb_init_device](https://groups.google.com/forum/#!topic/syzkaller/yvhFawNoqxE)
* [usb/media/cx231xx: null-ptr-deref in cx231xx_usb_probe](https://groups.google.com/forum/#!topic/syzkaller/WlUAVfDvpRk) [[fix](https://patchwork.kernel.org/patch/9963527/)] [CVE-2017-16536]
* [usb/net/p54: trying to register non-static key in p54_unregister_leds](https://groups.google.com/forum/#!topic/syzkaller/H6mX3aQPvvQ) [[fix](https://patchwork.kernel.org/patch/9972281/)]
* [usb/core: slab-out-of-bounds read in cdc_parse_cdc_header](https://groups.google.com/forum/#!topic/syzkaller/nXnjqI73uPo) [[fix](https://github.com/torvalds/linux/commit/2e1c42391ff2556387b3cb6308b24f6f65619feb)] [CVE-2017-16534]
* [usb/hid: slab-out-of-bounds read in usbhid_parse](https://groups.google.com/forum/#!topic/syzkaller/CxkJ9QZgwlM) [[fix](https://github.com/torvalds/linux/commit/f043bfc98c193c284e2cd768fefabe18ac2fed9b)] [CVE-2017-16533]
* [usb/core: slab-out-of-bounds in usb_set_configuration](https://groups.google.com/forum/#!topic/syzkaller/hP6L-m59m_8) [[fix](https://github.com/torvalds/linux/commit/bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb)] [CVE-2017-16531]
* [usb/uwb: WARNING in hwarc_neep_init/usb_submit_urb](https://groups.google.com/forum/#!topic/syzkaller/kxql4awIiR4) [[fix](https://github.com/torvalds/linux/commit/70e743e4cec3733dc13559f6184b35d358b9ef3f)]
* [usb/uwb: GPF in uwbd_start](https://groups.google.com/forum/#!topic/syzkaller/zROBxKXzHDk) [[fix](https://github.com/torvalds/linux/commit/bbf26183b7a6236ba602f4d6a2f7cade35bba043)] [CVE-2017-16526]
* [usb/joystick: warnings in xpad_start_input and xpad_try_sending_next_out_packet](https://groups.google.com/forum/#!topic/syzkaller/nMIkggZOUxA) [[fix](https://github.com/torvalds/linux/commit/122d6a347329818419b032c5a1776e6b3866d9b9)]
* [usb/midi: use-after-free in snd_rawmidi_dev_seq_free](https://groups.google.com/forum/#!topic/syzkaller/kuZzDHGkQu8) [[fix](https://github.com/torvalds/linux/commit/fc27fe7e8deef2f37cba3f2be2d52b6ca5eb9d57)] [CVE-2017-16528]
* [usb/core: warning in usb_create_ep_devs/sysfs_create_dir_ns](https://groups.google.com/forum/#!topic/syzkaller/wvB_W78nTh0) [[fix](https://github.com/torvalds/linux/commit/0a8fd1346254974c3a852338508e4a4cddbb35f1)]

### GadgetFS

* [usb/gadget: stalls in dummy_timer / usbtouch_probe](https://groups.google.com/forum/#!topic/syzkaller/9MKj0sRWn3Y) [[fix](https://github.com/torvalds/linux/commit/0173a68bfb0ad1c72a6ee39cc485aa2c97540b98)]
* [usb/gadget: null-ptr-deref in dev_ioctl](https://groups.google.com/forum/#!topic/syzkaller/ShlQyQLCe60) [[fix](https://github.com/torvalds/linux/commit/520b72fc64debf8a86c3853b8e486aa5982188f0)]
* [usb/gadget: copy_to_user called with spinlock held](https://groups.google.com/forum/#!topic/syzkaller/xmFE5DTHkME) [[fix](https://github.com/torvalds/linux/commit/6e76c01e71551cb221c1f3deacb9dcd9a7346784)]
* [usb/gadget: potential deadlock in gadgetfs_suspend](https://groups.google.com/forum/#!topic/syzkaller/J_It9ipKXhk) [[fix](https://github.com/torvalds/linux/commit/f16443a034c7aa359ddf6f0f9bc40d01ca31faea)]
* [usb/gadget: another GPF in usb_gadget_unregister_driver](https://groups.google.com/forum/#!topic/syzkaller/I6t-ToS5cxE) [[fix](https://github.com/torvalds/linux/commit/f50b878fed33e360d01dcdc31a8eeb1815d033d5)]
* [usb/gadget: warning in ep_write_iter/__alloc_pages_nodemask](https://groups.google.com/forum/#!topic/syzkaller/d2FD55alPqY) [[fix](https://github.com/torvalds/linux/commit/bb1107f7c6052c863692a41f78c000db792334bf)]
* [usb/gadget: slab-out-of-bounds write in dev_config](https://groups.google.com/forum/#!topic/syzkaller/Y4hEomcJgjY) [[fix](https://github.com/torvalds/linux/commit/faab50984fe6636e616c7cc3d30308ba391d36fd)]
* [usb/gadget: warning in dummy_free_request](https://groups.google.com/forum/#!topic/syzkaller/nNVKOT0fdaY) [[fix](https://github.com/torvalds/linux/commit/bcdbeb844773333d2d1c08004f3b3e25921040e5)]
* [usb/gadget: poor checks of wTotalLength in config descriptors](https://groups.google.com/forum/#!topic/syzkaller/PBWoEbmzrto) [[fix](https://github.com/torvalds/linux/commit/1c069b057dcf64fada952eaa868d35f02bb0cfc2)]
* [usb/gadget: use-after-free in gadgetfs_setup](https://groups.google.com/forum/#!topic/syzkaller/PBWoEbmzrto) [[fix](https://github.com/torvalds/linux/commit/add333a81a16abbd4f106266a2553677a165725f)]
* [usb/gadget: GPF in usb_gadget_unregister_driver](https://groups.google.com/forum/#!topic/syzkaller/HDawLBeeORI) [[fix](https://github.com/torvalds/linux/commit/7b01738112608ce47083178ae2b9ebadf02d32cc)]
* [usb/gadget: warning in dev_config/memdup_user](https://groups.google.com/forum/#!topic/syzkaller/bt6m57DyKLk) [[fix](https://github.com/torvalds/linux/commit/0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1)]

---

### Linux Internals (`docs/linux/internals.md`)

# Linux-specific syzkaller internals

It's possible to fuzz some external Linux kernel interfaces with syzkaller:

* See [this](external_fuzzing_network.md) for details about the networking stack.
* See [this](external_fuzzing_usb.md) for details about the USB stack.

---

### Linux Kernel Configs (`docs/linux/kernel_configs.md`)

# Linux kernel configs

List of recommended kernel configs for `syzkaller`. See [syzbot config](/dashboard/config/linux/upstream-apparmor-kasan.config) for a reference config.

## Syzkaller features

To enable coverage collection, which is extremely important for effective fuzzing:
```
CONFIG_KCOV=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_DEBUG_FS=y
```
Note that `CONFIG_KCOV_ENABLE_COMPARISONS` feature also requires `gcc8+` and the following commits if you are testing an old kernel:
```
    kcov: support comparison operands collection
    kcov: fix comparison callback signature
```

To detect memory leaks using the [Kernel Memory Leak Detector
(kmemleak)](https://www.kernel.org/doc/html/latest/dev-tools/kmemleak.html):

```
CONFIG_DEBUG_KMEMLEAK=y
```

To show code coverage in web interface:

For Linux < 5.12
```
CONFIG_DEBUG_INFO=y
```
For Linux >= 5.12
```
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
```

For detection of enabled syscalls and kernel bitness:
```
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
```

For better sandboxing:
```
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CGROUP_PIDS=y
CONFIG_MEMCG=y
```

For `namespace` sandbox:
```
CONFIG_USER_NS=y
```

For running in VMs `make kvm_guest.config` is generally required.

Debian images produced by [tools/create-image.sh](/tools/create-image.sh) also require:
```
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
```

It is recommended to disable the following config (and required if your kernel doesn't have commits [arm64: setup: introduce kaslr_offset()](https://github.com/torvalds/linux/commit/7ede8665f27cde7da69e8b2fbeaa1ed0664879c5)
 and [kcov: make kcov work properly with KASLR enabled](https://github.com/torvalds/linux/commit/4983f0ab7ffaad1e534b21975367429736475205)):
```
# CONFIG_RANDOMIZE_BASE is not set
```

It is also recommended to disable the Predictable Network Interface Names mechanism. This can be done
either via syzkaller configuration (see details [here](troubleshooting.md)) or by adjusting the following configs:
```
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="net.ifnames=0"
```

## Bug detection configs

Syzkaller is meant to be used with
[KASAN](https://kernel.org/doc/html/latest/dev-tools/kasan.html) (available upstream with `CONFIG_KASAN=y`),
[KTSAN](https://github.com/google/ktsan) (prototype available),
[KMSAN](https://github.com/google/kmsan) (prototype available),
or [KUBSAN](https://kernel.org/doc/html/latest/dev-tools/ubsan.html) (available upstream with `CONFIG_UBSAN=y`).

Enable `KASAN` for use-after-free and out-of-bounds detection:
```
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
```

For testing with fault injection enable the following configs (syzkaller will pick it up automatically):
```
CONFIG_FAULT_INJECTION=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_USERCOPY=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
```
Note: you also need the following commits if you are testing an old kernel:
```
    fault-inject: support systematic fault injection
    fault-inject: simplify access check for fail-nth
    fault-inject: fix wrong should_fail() decision in task context
    fault-inject: add /proc/<pid>/fail-nth
```

Any other debugging configs, the more the better, here are some that proved to be especially useful:
```
CONFIG_LOCKDEP=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_PROVE_RCU=y
CONFIG_DEBUG_VM=y
CONFIG_REFCOUNT_FULL=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_WQ_WATCHDOG=y
```

Increase hung/stall timeout to reduce false positive rate:
```
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=140
CONFIG_RCU_CPU_STALL_TIMEOUT=100
```

---

### Linux Reporting Kernel Bugs (`docs/linux/reporting_kernel_bugs.md`)

# Reporting Linux kernel bugs

Before reporting a bug **make sure nobody else has already reported it**. The easiest way to do
this is to search through the [syzkaller mailing list](https://groups.google.com/forum/#!forum/syzkaller),
[syzkaller-bugs mailing list](https://groups.google.com/forum/#!forum/syzkaller-bugs),
[syzbot dashboard](https://syzkaller.appspot.com/upstream),
and [kernel mailing lists](https://lore.kernel.org/) for key frames present in the kernel stack traces.

**Do NOT report bugs on old kernel versions**.
Old kernel generally means older than a week. Reports on old kernels are typically not considered as valid,
and asked to be reproduced on a fresh kernel. Do not report bugs found on stable/LTS kernels.
Bugs on stable/LTS kernels should be reproduced on a fresh upstream kernel, and reported as such.
Or, if they are already fixed upstream, the fix commit should be
[submitted to stable](https://www.kernel.org/doc/html/next/process/stable-kernel-rules.html).

Please **report bugs to the Linux kernel maintainers**.
To find out the list of maintainers responsible for a particular kernel subsystem, use the [get_maintainer.pl](https://github.com/torvalds/linux/blob/master/scripts/get_maintainer.pl) script: `./scripts/get_maintainer.pl -f guilty_file.c`. Please add `syzkaller@googlegroups.com` to the CC list.

**Minimal info** to include in the report:
 - exact kernel branch and revision where the bug occurred
 - exact kernel .config
 - kernel OOPS message (BUG, KASAN report, etc), **preferably with source files and line numbers**
 - reproducer, if known (see below)

**Properly configure the kernel**.
An improperly-configured kernel may lead to bad, and even false reports. There is no official way to get
proper config for testing/fuzzing. You need to tune timeouts, enable debug info, enable lots of debug configs,
disable some other debug configs, etc. You may use one of
[syzbot configs](/dashboard/config/linux/upstream-apparmor-kasan.config), or check guidelines for
[individual settings](/dashboard/config/linux/bits).

Your email client should be configured in **plain text mode** when sending bug reports.
Kernel mailing lists reject HTML formatted messages. For example, if you use GMail set "Plain text mode" option.

**Do NOT mimic [syzbot](/docs/syzbot.md) reports**.
For example, don't say "syzbot has found". However, you should mention that the bug is found with syzkaller.

Think of what you report. Today, Linux maintainers are overwhelmed with bug reports, so increasing the incoming flow won't help to fix all the bugs.
The more actionable your report is, the higher the chance that it will be addressed.
Note that people are more likely to care about kernel crashes (e.g. use-after-frees or panics) than of INFO: messages and such, unless it is clearly visible from the report what exactly is wrong.
If there are stalls or hangs, only report them if they are frequent enough or have a reliable reproducer.

Overall, bugs without reproducers are way less likely to be triaged and fixed.
If the bug is reproducible, include the reproducer (C source if possible, otherwise a syzkaller program) and the `.config` you used for your kernel.
If the reproducer is available only in the form of a syzkaller program, please link [the instructions on how to execute them](/docs/reproducing_crashes.md#using-a-c-reproducer) in your report.
Check that the reproducer works if you run it manually.
Syzkaller tries to simplify the reproducer, but the result might not be ideal.
You can try to simplify or annotate the reproducer manually, that greatly helps kernel developers to figure out why the bug occurs.

If you want to get extra credit, you can try to understand the bug and develop a fix yourself.
If you can't figure out the right fix, but have some understanding of the bug, please add your thoughts and conclusions to the report, that will save some time for kernel developers.

## Reporting security bugs

If you believe that a found bug poses potential security threat, consider following the instructions below.
Note, that these instructions are a work-in-progress and based on my current understanding of the disclosure process.
This instruction is now being discussed [here](http://seclists.org/oss-sec/2017/q3/242).

If you don't want to deal with this complex disclosure process you can either:

1. Report the bug privately to `security@kernel.org`. In this case it should be fixed in the upstream kernel, but there are no guarantees that the fix will be propagated to stable or distro kernels. The maximum embargo on this list is 7 days.
2. Report the bug privately to a vendor such as Red Hat (`secalert@redhat.com`) or SUSE (`security@suse.com`). They should fix the bug, assign a CVE, and notify other vendors. The maximum embargo on these lists is 5 weeks.
3. Report the bug publicly to `oss-security@lists.openwall.com`.

If you want to deal with the disclosure yourself, read below.

The three main mailing lists for reporting and disclosing Linux kernel security issues are `security@kernel.org`, `linux-distros@vs.openwall.org` and `oss-security@lists.openwall.com`.
The links for the guidelines for these lists are below, please read them carefully before sending anything to these lists.

1. `security@kernel.org` - https://www.kernel.org/doc/html/latest/admin-guide/security-bugs.html
2. `linux-distros@vs.openwall.org` - http://oss-security.openwall.org/wiki/mailing-lists/distros
3. `oss-security@lists.openwall.com` - http://oss-security.openwall.org/wiki/mailing-lists/oss-security

### Reporting minor security bugs

To report minor security bugs (such as local DOS or local info leak):

1. Report the bug publicly to kernel developers as described above and wait until a fix is committed. Alternatively, you can develop and send a fix yourself.
2. Request a CVE from MITRE through [the web form](https://cveform.mitre.org/). Describe the bug details and add a link to the fix (from `patchwork.kernel.org`, `git.kernel.org` or `github.com`) in the request.
3. Once a CVE is assigned, send the bug details, the CVE number and a link to the fix to `oss-security@lists.openwall.com`.

### Reporting major security bugs

To report major security bugs (such as LPE, remote DOS, remote info leak or RCE):

1. Understand the bug and develop a patch with a fix if possible. Optionally develop a proof-of-concept exploit.
2. Notify `security@kernel.org`:
    * Describe vulnerability details, include the proposed patch and optionally the exploit.
    * Ask for 7 days of embargo.
    * Work on the patch together with the `security@kernel.org` members.
3. Notify `linux-distros@vs.openwall.org`:
    * Describe vulnerability details, include the proposed patch and optionally the exploit.
    * Ask them to assign a CVE number.
    * Ask for 7 days of embargo.
4. Wait 7 days for linux distros to apply the patch.
5. Ask `linux-distros@vs.openwall.org` to make the CVE description public and roll out the updated kernels.
6. Send the fix upstream:
    * Mention the CVE number in the commit message.
    * Mention syzkaller in the commit message.
7. Notify `oss-security@lists.openwall.com`:
    * Describe vulnerability details, include a link to the committed patch.
8. Wait 1-3 days for people to update their kernels.
9. Optionally publish the exploit on `oss-security@lists.openwall.com`.

A few notes:

* There should ideally be no delay between reports to `security@kernel.org` and `linux-distros@vs.openwall.org`.
* When working on the patch together with the `security@kernel.org` members and upstream maintainers, keep the linux-distros aware of the progress.
* There should ideally be no delay between CVE description publication, distros' updates, upstream commit and notification to `oss-security@lists.openwall.com`. All of these should be on the same day, at worst.
* The moment the issue is made public (e.g. patch is submitted upstream, CVE description published, etc.) it must be reported to `oss-security@lists.openwall.com` right away.

A good example of an LPE announcement structure on `oss-security@lists.openwall.com` can be found [here](http://seclists.org/oss-sec/2016/q4/607), however the timeline doesn't look right there: public announcement should have occurred right after the patch was submitted to netdev.

---

### Linux Setup (`docs/linux/setup.md`)

# How to set up syzkaller

Generic instructions on how to set up Linux kernel fuzzing with syzkaller are [below](setup.md#install).

Instructions for a particular VM type or kernel architecture can be found on these pages:

- [Setup: Ubuntu host, QEMU vm, x86-64 kernel](setup_ubuntu-host_qemu-vm_x86-64-kernel.md)
- [Setup: Linux host, QEMU vm, arm64 kernel](setup_linux-host_qemu-vm_arm64-kernel.md)
- [Setup: Linux host, QEMU vm, arm kernel](setup_linux-host_qemu-vm_arm-kernel.md)
- [Setup: Linux host, QEMU vm, loongarch64 kernel](setup_linux-host_qemu-vm_loongarch64-kernel.md)
- [Setup: Linux host, QEMU vm, riscv64 kernel](setup_linux-host_qemu-vm_riscv64-kernel.md)
- [Setup: Linux host, QEMU vm, s390x kernel](setup_linux-host_qemu-vm_s390x-kernel.md)
- [Setup: Linux host, Android device, arm32/64 kernel](setup_linux-host_android-device_arm-kernel.md)
- [Setup: Linux host, Android virtual device, x86-64 kernel](setup_linux-host_android-virtual-device_x86-64-kernel.md)
- [Setup: Linux isolated host](setup_linux-host_isolated.md)
- [Setup: Ubuntu host, VMware vm, x86-64 kernel](setup_ubuntu-host_vmware-vm_x86-64-kernel.md)
- [Setup: Ubuntu host, VirtualBox vm, x86-64 kernel](setup_ubuntu-host_virtualbox-vm_x86-64-kernel.md)

## Install

The following components are needed to use syzkaller:

 - Go compiler and syzkaller itself
 - C compiler with coverage support
 - Linux kernel with coverage additions
 - Virtual machine or a physical device

If you encounter any troubles, check the [troubleshooting](/docs/troubleshooting.md) page.

### Go and syzkaller

`syzkaller` is written in [Go](https://golang.org), and `Go 1.23+` toolchain is required for build.
Generally we aim at supporting 2 latest releases of Go.
The toolchain can be installed with:

```
wget https://dl.google.com/go/go1.23.6.linux-amd64.tar.gz
tar -xf go1.23.6.linux-amd64.tar.gz
export GOROOT=`pwd`/go
export PATH=$GOROOT/bin:$PATH
```

See [Go: Download and install](https://golang.org/doc/install) for other options.

To download and build `syzkaller`:

``` bash
git clone https://github.com/google/syzkaller
cd syzkaller
make
```

As the result compiled binaries should appear in the `bin/` dir.

Note: if you want to do cross-OS/arch testing, you need to specify `TARGETOS`,
`TARGETVMARCH` and `TARGETARCH` arguments to `make`. See the [Makefile](/Makefile) for details.

### Environment

You might need to properly setup `binutils` if you're fuzzing in a cross-arch environment as described [here](coverage.md#binutils).

### C Compiler

Syzkaller is a coverage-guided fuzzer and therefore it needs the kernel to be built with coverage support, which requires a recent GCC version.
Coverage support was submitted to GCC, released in GCC 6.1.0 or later.
Make sure that your GCC meets this requirement, or get a GCC that [syzbot](/docs/syzbot.md) uses [here](/docs/syzbot.md#crash-does-not-reproduce).

### Linux Kernel

Besides coverage support in GCC, you also need support for it on the kernel side.
KCOV was added into mainline Linux kernel in version 4.6 and is be enabled by `CONFIG_KCOV=y` kernel configuration option.
For older kernels you need to at least backport commit [kernel: add kcov code coverage](https://github.com/torvalds/linux/commit/5c9a8750a6409c63a0f01d51a9024861022f6593).
Besides that, it's recommended to backport all kernel patches that touch `kernel/kcov.c`.

To enable more syzkaller features and improve bug detection abilities, it's recommended to use additional config options.
See [this page](kernel_configs.md) for details.

### VM Setup

Syzkaller performs kernel fuzzing on worker virtual machines or physical devices.
These worker environments are referred to as VMs.
Out-of-the-box syzkaller supports QEMU, kvmtool and GCE virtual machines, Android devices and Odroid C2 boards.

These are the generic requirements for a syzkaller VM:

 - The fuzzing processes communicate with the outside world, so the VM image needs to include
   networking support.
 - The program files for the fuzzer processes are transmitted into the VM using SSH, so the VM image
   needs a running SSH server.
 - The VM's SSH configuration should be set up to allow root access for the identity that is
   included in the `syz-manager`'s configuration.  In other words, you should be able to do `ssh -i
   $SSHID -p $PORT root@localhost` without being prompted for a password (where `SSHID` is the SSH
   identification file and `PORT` is the port that are specified in the `syz-manager` configuration
   file).
 - The kernel exports coverage information via a debugfs entry, so the VM image needs to mount
   the debugfs filesystem at `/sys/kernel/debug`.

To use QEMU syzkaller VMs you have to install QEMU on your host system, see [QEMU docs](http://wiki.qemu.org/Manual) for details.
The [create-image.sh](/tools/create-image.sh) script can be used to create a suitable Linux image.

See the links at the top of the document for instructions on setting up syzkaller for QEMU, Android and some other types of VMs.

### Troubleshooting

* QEMU requires root for `-enable-kvm`.

    Solution: add your user to the `kvm` group (`sudo usermod -a -G kvm` and relogin).

* QEMU crashes with:

    ```
    qemu-system-x86_64: error: failed to set MSR 0x48b to 0x159ff00000000
    qemu-system-x86_64: /build/qemu-EmNSP4/qemu-4.2/target/i386/kvm.c:2947: kvm_put_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.
   ```

    Solution: remove `-cpu host,migratable=off` from the QEMU command line. The easiest way to do that is to set `qemu_args` to `-enable-kvm` in the `syz-manager` config file.

---

### Linux Setup Linux Host Android Device Arm Kernel (`docs/linux/setup_linux-host_android-device_arm-kernel.md`)

# Setup: Linux host, Android device, arm32/64 kernel

**Note: fuzzing the kernel on a real Android device may brick it.**

This document details the steps involved in setting up a syzkaller instance fuzzing an `arm32/64` linux kernel on an Android device.

Some features of syzkaller may not yet work properly on `arm32`. For example, not all debugging and test coverage features are available in the Linux kernel for `arm32`, limiting the efficacy of syskaller in finding bugs fast.

These were tested on an NXP Pico-Pi-IMX7D following the instructions [here](https://developer.android.com/things/hardware/developer-kits.html).

You may find additional details in syzkaller's `adb` vm implementation [here](/vm/adb/adb.go).

## Device setup

Follow the instructions for your board to install Android and make sure the device boots properly.

Set up the adb bridge so that adb and fastboot work.

Set up a serial port, following the instructions for your device so that you can monitor kernel log messages. On Android-based boards the serial port is typically exposed as a USB (or some custom) port, or over GPIO pins. On phones you can use Android Serial Cable or [Suzy-Q](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/docs/case_closed_debugging.md). syzkaller can work without a dedicated serial port as well (by falling back to `adb shell dmesg -w`), but that is unreliable and turns lots of crashes into "lost connection to test machine" crashes with no additional info.

Get the proper compiler toolchain for your device.

Recompile and reinstall the Linux kernel with [debugging kernel options](https://github.com/xairy/syzkaller/blob/up-docs/docs/linux/kernel_configs.md) available on your board. You might benefit from backporting KCOV or KASAN patches.

## Building syzkaller

Get syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller).

Then build it for either `arm` or `arm64` target architecture depending on the device you're using.

``` bash
make TARGETOS=linux TARGETARCH=arm
```

``` bash
make TARGETOS=linux TARGETARCH=arm64
```

In case you have old Android `/dev/ion` driver (kernel <= 3.18) before building syzkaller copy old `/dev/ion` descriptions:

``` bash
cp sys/android/* sys/linux
```

## Manager config

Create a manager config `android.cfg`:

```
{
	"target": "linux/arm",
	"http": "127.0.0.1:56741",
	"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
	"kernel_obj": "$KERNEL",
	"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
	"cover": true,
	"type": "adb",
	"vm": {
		"devices": [$DEVICES],
		"battery_check": true,
		"boot_service": "systemui"
	}
}
```

Replace the variables `$GOPATH`, `$KERNEL` (path to kernel build directory), and `$DEVICES` (the device ID for your board as reported by adb devices, e.g. `ABCD000010`) with their actual values.

For `arm64` use `"target": "linux/arm64"`.

If your kernel doesn't support coverage collection (e.g. `arm32` without KCOV patches) set `"cover": false`.

Turn off `battery_check` if your device doesn't have battery service, see the comment [here](/vm/adb/adb.go) for details.

The `boot_service` parameter specifies which service to wait for during boot completion. The default value is `"systemui"`, which waits for the `com.android.systemui` process. For AOSP builds without SystemUI (e.g., when testing QEMU Android), you can use `"servicemanager"` or other services instead.

## Running syzkaller

Run syzkaller manager:

``` bash
./bin/syz-manager -config=android.cfg
```

Now syzkaller should be running, you can check manager status with your web browser at `127.0.0.1:56741`.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.

Also see [this page](/docs/troubleshooting.md) for troubleshooting tips and [Building a Pixel kernel with KASAN+KCOV](https://source.android.com/devices/tech/debug/kasan-kcov) or [Building a PH-1 kernel with KASAN+KCOV](https://github.com/EssentialOpenSource/kernel-manifest/blob/master/README.md) for kernel build/boot instructions.

---

### Linux Setup Linux Host Android Virtual Device X86 64 Kernel (`docs/linux/setup_linux-host_android-virtual-device_x86-64-kernel.md`)

# Setup: Linux host, Android virtual device, x86-64 kernel

This document details the steps involved in setting up a syzkaller instance fuzzing an `x86-64` linux kernel on an Android virtual device.

In the instructions below, the `$VAR` notation (e.g. `$GSI`, `$GKI`, etc.) is used to denote paths to directories that are either created when executing the instructions, or that you have to create yourself before running the instructions. Substitute the values for those variables manually.

Note:
- All commands below assume root privileges.
- It is recommended to have at least 64 GB of RAM and 500 GB of free disk space.

## Install prerequisites

Command:
``` bash
apt update
apt install sudo git wget curl repo libncurses5 vim gcc make bison bc zip rsync language-pack-en-base
```

## Cuttlefish

It is recommended to use [Cuttlefish](https://github.com/google/android-cuttlefish) to emulate Android devices. Build and install it from source (v1.16.0 as an example):

Command:
``` bash
apt install git devscripts equivs config-package-dev debhelper-compat golang curl
git clone -b v1.16.0 https://github.com/google/android-cuttlefish
cd android-cuttlefish
tools/buildutils/build_packages.sh
dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -y -f
dpkg -i ./cuttlefish-user_*_*64.deb || sudo apt-get install -y -f
usermod -aG kvm,cvdnetwork,render root
reboot
```

## Generic System Images (GSI)

### Checkout GSI source

The GSI source checkout is close to 90 GB, and the build can take up about 300 GB of disk space.

Command:
``` bash
mkdir android13-gsi
cd android13-gsi
repo init -u https://android.googlesource.com/platform/manifest -b android13-gsi
repo sync -c
```

### Build GSI

Refresh the build environment and select the build target:

Command:
``` bash
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
```

The output should be as follows (may vary depending on the host):

``` text
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=13
TARGET_PRODUCT=aosp_cf_x86_64_phone
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=silvermont
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=silvermont
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-6.8.0-65-generic-x86_64-Ubuntu-22.04.4-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=TP1A.220624.019
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=device/generic/goldfish-opengl device/generic/goldfish device/generic/goldfish-opengl hardware/google/camera hardware/google/camera/devices/EmulatedCamera device/google/cuttlefish/apex/com.google.cf.wifi_hwsim external/mesa3d vendor/google_devices/common/proprietary/confirmatioui_hal
============================================
```

Start building:

Command:
``` bash
m
```

You can test your setup by launching the virtual device:

Command:
```bash
launch_cvd
```

Open [http://localhost:8443](http://localhost:8443) in your browser, you should see a virtual device. Click `Connect` to interact with it as you would with a real phone. Press `Ctrl-C` in the terminal to stop the simulator.

## Kernel

### Checkout Android Generic Kernel Image (GKI) source

Command:
``` bash
mkdir common-android13-5.15
cd common-android13-5.15
repo init -u https://android.googlesource.com/kernel/manifest -b common-android13-5.15
repo sync -c
```

### Build GKI

We need to build the Android Kernel with KASAN and KCOV so that syzkaller can get coverage and bug information during fuzzing.

Command:
``` bash
BUILD_CONFIG=common/build.config.gki_kasan.x86_64 build/build.sh
```

Build vendor modules with KASAN and KCOV:

Command:
``` bash
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device_kasan.x86_64 build/build.sh
```

## syzkaller

### Build syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller).
Then create a manager config like the following, replacing the environment
variables `$GOPATH` and `$GKI` with their actual values.

``` json
{
	"target": "linux/amd64",
	"http": "127.0.0.1:56741",
	"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir/android/out",
	"kernel_obj": "$GKI/out/android13-5.15/dist",
	"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
	"cover": true,
	"type": "adb",
	"vm": {
		"devices": ["0.0.0.0:6520"],
		"battery_check": true,
		"boot_service": "systemui"
	}
}
```

The boot_service parameter specifies which service to wait for during boot completion. The default value is "systemui", which waits for the com.android.systemui process. For AOSP builds without SystemUI, you can use "servicemanager" or other services instead. This is particularly useful when testing minimal Android configurations in QEMU.

### Launch the virtual device

Launch the Android system with the KASAN and KCOV kernel.

Command:
``` bash
cd $GSI
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
launch_cvd -daemon -kernel_path=$GKI/out/android13-5.15/dist/bzImage -initramfs_path=$GKI/out/android13-5.15/dist/initramfs.img
```

Connect to the virtual device with adb:

Command:
``` bash
adb connect 0.0.0.0:6520
```

List available virtual devices:

Command:
``` bash
adb devices
```

### Run syzkaller

Run syzkaller manager:

Command:
```bash
cd $GOPATH/src/github.com/google/syzkaller
./bin/syz-manager -config=android.cfg
```

Now syzkaller should be running, you can check manager status with your web browser at `127.0.0.1:56741`.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.

Here are some useful links:

- [github - google/android-cuttlefish](https://github.com/google/android-cuttlefish)
- [AOSP - Cuttlefish virtual Android devices](https://source.android.com/docs/devices/cuttlefish)
- [AOSP - Cuttlefish: Get started](https://source.android.com/docs/devices/cuttlefish/get-started)
- [AOSP - Download the Android source](https://source.android.com/docs/setup/download)
- [AOSP - Build Android](https://source.android.com/docs/setup/build/building)
- [AOSP - Generic system images](https://source.android.com/docs/core/tests/vts/gsi#building-gsis)
- [AOSP - Architecture overview](https://source.android.com/docs/core/architecture)
- [AOSP - Build kernels](https://source.android.com/docs/setup/build/building-kernels)
- [AOSP - Kernel branches and their build systems](https://source.android.com/docs/setup/reference/bazel-support)

---

### Linux Setup Linux Host Isolated (`docs/linux/setup_linux-host_isolated.md`)

# Setup: Linux isolated host

These are the instructions on how to fuzz the kernel on isolated machines.
Isolated machines are separated in a way that limits remote management. They can
be interesting to fuzz due to specific hardware setups.

This syzkaller configuration uses only ssh to launch and monitor an isolated
machine.

## Setup reverse proxy support

Given only ssh may work, a reverse ssh proxy will be used to allow the fuzzing
instance and the manager to communicate.

Ensure the sshd configuration on the target machine has AllowTcpForwarding to yes.
```
machine:~# grep Forwarding /etc/ssh/sshd_config
AllowTcpForwarding yes
```

## Kernel

The isolated VM does not deploy kernel images so ensure the kernel on the target
machine is build with these options:
```
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
```

Code coverage works better when KASLR Is disabled too:
```
# CONFIG_RANDOMIZE_BASE is not set
```

## Optional: Reuse existing ssh connection

In most scenarios, you should use an ssh key to connect to the target machine.
The isolated configuration supports ssh keys as described in the generic
[setup](setup.md).

If you cannot use an ssh key, you should configure your manager machine to reuse
existing ssh connections.

Add these lines to your ~/.ssh/config file:
```
Host *
	ControlMaster auto
	ControlPath ~/.ssh/control:%h:%p:%r
```

Before fuzzing, connect to the machine and keep the connection open so all scp
and ssh usage will reuse it.

# Optional: Pstore support

If the device under test (DUT) has Pstore support, it is possible to configure syzkaller to
fetch crashlogs from /sys/fs/pstore. You can do this by setting `"pstore": true` within
the `vm` section of the syzkaller configuration file.

# Optional: Startup script

To execute commands on the DUT before fuzzing (re-)starts,
`startup_script` can be used.

## Syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller).

Use the following config:
```
{
	"target": "linux/amd64",
	"http": "127.0.0.1:56741",
	"rpc": "127.0.0.1:0",
	"sshkey" : "/path/to/optional/sshkey",
	"workdir": "/syzkaller/workdir",
	"kernel_obj": "/linux-next",
	"syzkaller": "/go/src/github.com/google/syzkaller",
	"sandbox": "setuid",
	"type": "isolated",
	"vm": {
		"targets" : [ "10.0.0.1" ],
		"pstore": false,
		"target_dir" : "/home/user/tmp/syzkaller",
                "target_reboot" : false
	}
}
```

Don't forget to update:
 - `target` (target OS/arch)
 - `workdir` (path to the workdir)
 - `kernel_obj` (path to kernel build directory)
 - `sshkey` You can setup an sshkey (optional)
 - `vm.targets` List of hosts to use for fuzzing
 - `vm.target_dir` Working directory on the target host
 - `vm.target_reboot` Reboot the machine if remote process hang (useful for wide fuzzing, false by default)

Run syzkaller manager:
``` bash
./bin/syz-manager -config=my.cfg
```

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.
Also see [this page](/docs/troubleshooting.md) for troubleshooting tips.

---

### Linux Setup Linux Host Qemu Vm Arm Kernel (`docs/linux/setup_linux-host_qemu-vm_arm-kernel.md`)

# Setup: Debian host, QEMU vm, arm kernel

# GCC

Obtain a fresh `arm-linux-gnueabihf-gcc`. Latest Debian distributions provide
version 7.2.0, which should be enough. Otherwise you can download Linaro
compiler [here](https://www.linaro.org/downloads).

# Kernel

The instructions are tested with `v4.16.1`. Check that you have/backport
["arm: port KCOV to arm"](https://groups.google.com/d/msg/syzkaller/zLThPHplyIc/9ncfpRvVCAAJ)
patch. Create kernel config with:

```shell
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig
```

Then enable the following configs on top:

```
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
```

Also check out general kernel configuration [recommendations](/docs/linux/kernel_configs.md).

Then build kernel with:

```
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
```

# Image

We will use buildroot to create the disk image. You can obtain buildroot
[here](https://buildroot.uclibc.org/download.html). Instructions were tested
with buildroot `c665c7c9cd6646b135cdd9aa7036809f7771ab80`. First run:

```
make qemu_arm_vexpress_defconfig
make menuconfig
```

Choose the following options:

```
    Target packages
	    Networking applications
	        [*] dhcpcd
	        [*] iproute2
	        [*] openssh
    Filesystem images
	        exact size - 1g
```

Unselect:

```
    Kernel
	    Linux Kernel
```

Run `make`.

Then add the following line to `output/target/etc/fstab`:

```
debugfs	/sys/kernel/debug	debugfs	defaults	0	0
```

Then replace `output/target/etc/ssh/sshd_config` with the following contents:

```
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords yes
```

Run `make` again.

# Test kernel and image

Run:

```
qemu-system-arm -m 512 -smp 2 -net nic -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -display none -serial stdio -machine vexpress-a15 -dtb /linux/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -sd /buildroot/output/images/rootfs.ext2 -snapshot -kernel /linux/arch/arm/boot/zImage -append "earlyprintk=serial console=ttyAMA0 root=/dev/mmcblk0"
```

This should boot the kernel. Wait for login prompt, then in another console run:

```
ssh -p 10022 root@localhost
```

ssh should succeed.

# syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller), with `arm` target:

```
make TARGETOS=linux TARGETARCH=arm
```

Create manager config `arm.cfg` similar to the following one (changing paths as necessary):

```
{
	"name": "arm",
	"target": "linux/arm",
	"http": ":12345",
	"workdir": "/workdir",
	"kernel_obj": "/linux",
	"syzkaller": "/gopath/src/github.com/google/syzkaller",
	"image": "/buildroot/output/images/rootfs.ext2",
	"sandbox": "none",
	"reproduce": false,
	"procs": 4,
	"type": "qemu",
	"vm": {
		"count": 10,
		"qemu_args": "-machine vexpress-a15 -dtb /linux/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb",
		"cmdline": "console=ttyAMA0 root=/dev/mmcblk0",
		"kernel": "/linux/arch/arm/boot/zImage",
		"image_device": "sd",
		"mem": 512,
		"cpu": 2
	}
}
```

Finally, run `bin/syz-manager -config arm.cfg`.

---

### Linux Setup Linux Host Qemu Vm Arm64 Kernel (`docs/linux/setup_linux-host_qemu-vm_arm64-kernel.md`)

# Setup: Linux host, QEMU vm, arm64 kernel

This document will detail the steps involved in setting up a Syzkaller instance fuzzing any ARM64 linux kernel of your choice.

## Create a disk image

We will use buildroot to create the disk image.
You can obtain buildroot from [here](https://buildroot.org/download.html).
Extract the tarball and perform a `make menuconfig` inside it.
Choose the following options.

    Target options
	    Target Architecture - Aarch64 (little endian)
    Toolchain type
	    External toolchain - Linaro AArch64
    System Configuration
    [*] Enable root login with password
            ( ) Root password = set your password using this option
    [*] Run a getty (login prompt) after boot  --->
	    TTY port - ttyAMA0
    Target packages
	    [*]   Show packages that are also provided by busybox
	    Networking applications
	        [*] dhcpcd
	        [*] iproute2
	        [*] openssh
    Filesystem images
	    [*] ext2/3/4 root filesystem
	        ext2/3/4 variant - ext3
	        exact size in blocks - 6000000
	    [*] tar the root filesystem

Run `make`. After the build, confirm that `output/images/rootfs.ext3` exists.

If you're experiencing a very slow sshd start up time with arm64 qemu running on x86, the reason is probably low entropy and it be "fixed" with installing `haveged`. It can be found in the buildroot `menuconfig`:

```
    Target packages
	    Miscellaneous
	        [*] haveged
```

## Get the ARM64 toolchain from Linaro

You will require an ARM64 kernel with gcc plugin support.
If not, obtain the ARM64 toolchain from Linaro.
Get `gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu.tar.xz` from [here](https://releases.linaro.org/components/toolchain/binaries/6.1-2016.08/aarch64-linux-gnu/).
Extract and add its `bin/` to your `PATH`.
If you have another ARM64 toolchain on your machine, ensure that this newly downloaded toolchain takes precedence.

## Compile the kernel

Get the source code of the Linux kernel version you want to fuzz, and do the following.

    $ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig
    $ vim .config

Change the following options :
```
    CONFIG_KCOV=y
    CONFIG_KASAN=y
    CONFIG_DEBUG_INFO=y
    CONFIG_CMDLINE="console=ttyAMA0"
    CONFIG_KCOV_INSTRUMENT_ALL=y
    CONFIG_DEBUG_FS=y
    CONFIG_NET_9P=y
    CONFIG_NET_9P_VIRTIO=y
    CONFIG_CROSS_COMPILE="aarch64-linux-gnu-"
```
```
    $ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j40
```

If the build was successful, you should have a `arch/arm64/boot/Image` file.

## Obtain qemu for ARM64

Obtain the QEMU source from git or from the latest source release.

    $ ./configure
    $ make -j40

If the build was successful, you should have a `aarch64-softmmu/qemu-system-aarch64` binary.

## Boot up manually

You should be able to start up the kernel as follows.

    $ /path/to/aarch64-softmmu/qemu-system-aarch64 \
      -machine virt \
      -cpu cortex-a57 \
      -nographic -smp 1 \
      -hda /path/to/rootfs.ext3 \
      -kernel /path/to/arch/arm64/boot/Image \
      -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ" \
      -m 2048 \
      -net user,hostfwd=tcp::10023-:22 -net nic

At this point, you should be able to see a login prompt.

## Set up the QEMU disk

Now that we have a shell, let us add a few lines to existing init scripts so that they are executed each time Syzkaller brings up the VM.

At the top of /etc/init.d/S50sshd add the following lines:

    ifconfig eth0 up
    dhcpcd
    mount -t debugfs none /sys/kernel/debug
    chmod 777 /sys/kernel/debug/kcov

Comment out the line

    /usr/bin/ssh-keygen -A

Next we set up ssh. Create an ssh keypair locally and copy the public key to `/authorized_keys` in `/`. Ensure that you do not set a passphrase when creating this key.

Open `/etc/ssh/sshd_config` and modify the following lines as shown below.

    PermitRootLogin yes
    PubkeyAuthentication yes
    AuthorizedKeysFile      /authorized_keys
    PasswordAuthentication yes

Reboot the machine, and ensure that you can ssh from host to guest as.

    $ ssh -i /path/to/id_rsa root@localhost -p 10023

## Build syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller), with `arm64` target:

```
CC=gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
make TARGETARCH=arm64
```


## Modify your config file and start off syzkaller

A sample config file that exercises the required options are shown below. Modify according to your needs.

```
{
    "name": "QEMU-aarch64",
    "target": "linux/arm64",
    "http": ":56700",
    "workdir": "/path/to/a/dir/to/store/syzkaller/corpus",
    "kernel_obj": "/path/to/linux/build/dir",
    "syzkaller": "/path/to/syzkaller/arm64/",
    "image": "/path/to/rootfs.ext3",
    "sshkey": "/path/to/id_rsa",
    "procs": 8,
    "type": "qemu",
    "vm": {
        "count": 1,
        "qemu": "/path/to/qemu-system-aarch64",
        "cmdline": "console=ttyAMA0 root=/dev/vda",
        "kernel": "/path/to/Image",
        "cpu": 2,
        "mem": 2048
    }
}
```

At this point, you should be able to visit `localhost:56700` and view the results of the fuzzing.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.
Also see [this page](/docs/troubleshooting.md) for troubleshooting tips.

---

### Linux Setup Linux Host Qemu Vm Loongarch64 Kernel (`docs/linux/setup_linux-host_qemu-vm_loongarch64-kernel.md`)

# Setup: Linux host, QEMU vm, loongarch64 kernel

This document describes a Linux/QEMU setup for fuzzing a LoongArch64 Linux
kernel with syzkaller.

## Toolchain

You need:

- a Go toolchain supported by syzkaller,
- `loongarch64-linux-gnu-gcc`/`loongarch64-linux-gnu-g++`,
- `qemu-system-loongarch64`,
- Buildroot or another way to build an SSH-capable root filesystem.

The syzkaller target architecture is `loong64`, while the external Linux and
toolchain names remain `loongarch*`.
Use `TARGETARCH=loong64` and `TARGETVMARCH=loong64` when building syzkaller
target binaries.

## Kernel

Build a LoongArch kernel with KCOV and debugfs enabled. The following example
uses a GNU cross toolchain:

```shell
make ARCH=loongarch CROSS_COMPILE=loongarch64-linux-gnu- loongson64_defconfig

scripts/config \
	--enable KCOV \
	--enable KCOV_ENABLE_COMPARISONS \
	--enable KCOV_INSTRUMENT_ALL \
	--enable DEBUG_FS \
	--enable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT \
	--enable VIRTIO_NET \
	--disable RANDOMIZE_BASE

make ARCH=loongarch CROSS_COMPILE=loongarch64-linux-gnu- olddefconfig
make ARCH=loongarch CROSS_COMPILE=loongarch64-linux-gnu- -j$(nproc)
```

The `loongson64_defconfig` uses 16 KiB pages. Confirm that the final config
contains:

```shell
grep '^CONFIG_PAGE_SIZE_16KB=y' .config
```

See the [recommended Linux kernel config options](kernel_configs.md) for more
coverage and bug-detection settings.

The QEMU setup below uses the EFI kernel image:

```
arch/loongarch/boot/vmlinux.efi
```

## Image

Buildroot provides a LoongArch virt defconfig:

```shell
make O=/buildroot-output qemu_loongarch64_virt_efi_defconfig
make O=/buildroot-output menuconfig
```

Choose the following options:

```
Target packages
	Networking applications
		[*] iproute2
		[*] openssh
Filesystem images
	[*] ext2/3/4 root filesystem
		ext2/3/4 variant - ext4
		exact size - 1g
```

Unselect:

```
Kernel
	Linux Kernel
```

Build the image once to populate `/buildroot-output/target`:

```shell
make O=/buildroot-output -j$(nproc)
```

Create an SSH key without a passphrase:

```shell
ssh-keygen -t rsa -N '' -f /image/id_rsa
chmod 0600 /image/id_rsa
```

Add the following lines to `/buildroot-output/target/etc/fstab`:

```
debugfs /sys/kernel/debug debugfs defaults 0 0
securityfs /sys/kernel/security securityfs defaults 0 0
```

Install the public key in the target filesystem:

```shell
install -Dm0600 /image/id_rsa.pub \
	/buildroot-output/target/root/.ssh/authorized_keys
```

Then replace `/buildroot-output/target/etc/ssh/sshd_config` with:

```
PermitRootLogin yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
```

Run Buildroot again so these changes are included in the filesystem image:

```shell
make O=/buildroot-output -j$(nproc)
```

Use `/buildroot-output/images/rootfs.ext2` as the syzkaller `image` file.

## Test kernel and image

Run the kernel manually before starting syzkaller:

```shell
qemu-system-loongarch64 \
	-machine virt \
	-nographic \
	-m 2048 \
	-smp 2 \
	-kernel /linux/arch/loongarch/boot/vmlinux.efi \
	-append "root=/dev/vda console=ttyS0 rw nokaslr" \
	-object rng-random,filename=/dev/urandom,id=rng0 \
	-device virtio-rng-pci,rng=rng0 \
	-drive file=/buildroot-output/images/rootfs.ext2,if=none,format=raw,id=hd0 \
	-device virtio-blk-pci,drive=hd0 \
	-netdev user,id=net0,hostfwd=tcp::10022-:22 \
	-device virtio-net-pci,netdev=net0
```

Wait for the login prompt, then test SSH from another terminal:

```shell
ssh -i /image/id_rsa -p 10022 root@localhost
```

Inside the guest, confirm that KCOV is available:

```shell
mount -t debugfs none /sys/kernel/debug 2>/dev/null || true
mount -t securityfs none /sys/kernel/security 2>/dev/null || true
ls -l /sys/kernel/debug/kcov
```

## syzkaller

Build syzkaller as described in the generic [Linux setup guide](setup.md#go-and-syzkaller):

```shell
make TARGETOS=linux TARGETARCH=loong64 TARGETVMARCH=loong64 target
make manager
```

Create a manager config similar to the following one:

```json
{
	"name": "loong64",
	"target": "linux/loong64",
	"http": ":56700",
	"workdir": "/workdir",
	"kernel_obj": "/linux",
	"syzkaller": "/syzkaller",
	"image": "/buildroot-output/images/rootfs.ext2",
	"sshkey": "/image/id_rsa",
	"procs": 8,
	"type": "qemu",
	"vm": {
		"count": 1,
		"qemu": "qemu-system-loongarch64",
		"kernel": "/linux/arch/loongarch/boot/vmlinux.efi",
		"cmdline": "nokaslr",
		"cpu": 2,
		"mem": 2048
	}
}
```

Finally, run:

```shell
bin/syz-manager -config loong64.cfg
```

If startup fails, re-run with `-debug` and check the QEMU command line.

---

### Linux Setup Linux Host Qemu Vm Riscv64 Kernel (`docs/linux/setup_linux-host_qemu-vm_riscv64-kernel.md`)

# Setup: Debian/Ubuntu host, QEMU vm, riscv64 kernel

# GCC

Obtain `riscv64-linux-gnu-gcc` at least GCC version 8. The latest Debian/Ubuntu distributions should
provide both cross-compilers in a recent enough version in the `gcc-riscv64-linux-gnu` package.
Alternatively, you can also build your own
[RISC-V GNU compiler toolchain](https://github.com/riscv/riscv-gnu-toolchain) from source.

# Kernel

The following instructions were tested with Linux Kernel `v5.9-rc1`. Create a kernel config with:

```shell
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
```

Also enable the [recommended Kconfig options for syzkaller](/docs/linux/kernel_configs.md).

Then build kernel with:

```
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j $(nproc)
```

# OpenSBI

Clone the OpenSBI repository and build the bootable OpenSBI image containing the kernel:

```shell
git clone https://github.com/riscv/opensbi
cd opensbi
make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM_RISCV_XLEN=64 PLATFORM=generic
```

See the OpenSBI documentation for booting on the
[QEMU RISC-V Virt Machine Platform](https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md)
for more information.

# Image

We will use buildroot to create the disk image. You can obtain buildroot
[here](https://buildroot.org/download.html). The following instructions
were tested with buildroot version 2020.05. First run:

```shell
make qemu_riscv64_virt_defconfig
make menuconfig
```

Choose the following options:

```
    Target packages
	    Networking applications
	        [*] iproute2
	        [*] openssh
    Filesystem images
                ext2/3/4 variant - ext4
	        exact size - 1g
```

Unselect:

```
    Kernel
	    Linux Kernel
```

Run `make`.

Then add the following line to `output/target/etc/fstab`:

```
debugfs	/sys/kernel/debug	debugfs	defaults	0	0
```

Then replace `output/target/etc/ssh/sshd_config` with the following contents:

```
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords yes
```

Run `make` again.

# QEMU

The following instructions were tested with QEMU 5.0. At least QEMU 4.1 is needed.

# Test kernel and image

Run:

```shell
qemu-system-riscv64 \
	-machine virt \
	-nographic \
	-bios /opensbi/build/platform/generic/firmware/fw_jump.bin \
	-kernel /linux/arch/riscv/boot/Image \
	-append "root=/dev/vda ro console=ttyS0" \
	-object rng-random,filename=/dev/urandom,id=rng0 \
	-device virtio-rng-device,rng=rng0 \
	-drive file=/buildroot/output/images/rootfs.ext2,if=none,format=raw,id=hd0 \
	-device virtio-blk-device,drive=hd0 \
	-netdev user,id=net0,host=10.0.2.10,hostfwd=tcp::10022-:22 \
	-device virtio-net-device,netdev=net0
```

This should boot the kernel. Wait for login prompt, then in another console run:

```
ssh -p 10022 root@localhost
```

ssh should succeed.

# syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller), with `riscv64` target:

```
make TARGETOS=linux TARGETARCH=riscv64
```

Create the manager config `riscv64.cfg` similar to the following one (adjusting paths as necessary):

```
{
	"name": "riscv64",
	"target": "linux/riscv64",
	"http": ":56700",
	"workdir": "/workdir",
	"kernel_obj": "/linux",
	"syzkaller": "/gopath/src/github.com/google/syzkaller",
	"image": "/buildroot/output/images/rootfs.ext2",
	"procs": 8,
	"type": "qemu",
	"vm": {
		"count": 1,
		"qemu_args": "-machine virt -bios /opensbi/build/platform/generic/firmware/fw_jump.bin",
		"kernel": "/linux/arch/riscv/boot/Image",
		"cpu": 2,
		"mem": 2048
	}
}
```

Alternatively, you may try to use the default OpenSBI firmware provided with QEMU 4.1 and newer by
specifying `-machine virt -bios default` in `qemu_args` and pass the kernel image in the `kernel`
config option:

```
{
	"name": "riscv64",
	"target": "linux/riscv64",
	"http": ":56700",
	"workdir": "/workdir",
	"kernel_obj": "/linux",
	"syzkaller": "/gopath/src/github.com/google/syzkaller",
	"image": "/buildroot/output/images/rootfs.ext2",
	"procs": 8,
	"type": "qemu",
	"vm": {
		"count": 1,
		"qemu_args": "-machine virt -bios default",
		"kernel": "/linux/arch/riscv/boot/Image",
		"cpu": 2,
		"mem": 2048
	}
}
```

This would allow to boot a different kernel without having to re-compile OpenSBI. However, on some
distributions the default OpenSBI firmware required by the `-bios default` option might not be
available yet.

Finally, run `bin/syz-manager -config riscv64.cfg`. After it successfully starts, you should be able
to visit `localhost:56700` to view the fuzzing results.

In case you encounter issues with starting `syz-manager`, use the `-debug` flag and refer to the
[troubleshooting guide](/docs/troubleshooting.md).

---

### Linux Setup Linux Host Qemu Vm S390x Kernel (`docs/linux/setup_linux-host_qemu-vm_s390x-kernel.md`)

# Setup: Debian/Ubuntu/Fedora host, QEMU vm, s390x kernel

## GCC

Obtain `s390x-linux-gnu-gcc` at least GCC version 9. The latest Debian/Ubuntu/Fedora distributions
should provide a recent enough version of a cross-compiler in the `gcc-s390x-linux-gnu` package.

## Kernel

Checkout Linux kernel source:

``` bash
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $KERNEL
```

Generate default configs:

``` bash
cd $KERNEL
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- defconfig
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- kvm_guest.config
```

Enable kernel config options required for syzkaller as described [here](kernel_configs.md).

```
./scripts/config --file .config \
                 -d MODULES \
                 -e KCOV \
                 -e KCOV_INSTRUMENT_ALL \
                 -e KCOV_ENABLE_COMPARISONS \
                 -e KASAN \
                 -e KASAN_INLINE \
                 -e CONFIGFS_FS \
                 -e SECURITYFS \
                 -e DEBUG_INFO \
                 -e GDB_SCRIPTS \
                 -e PRINTK \
                 -e EARLY_PRINTK \
                 -e DEVTMPFS \
                 -e TUN \
                 -e VIRTIO_PCI \
                 -e VIRTIO_NET \
                 -e NET_9P_VIRTIO \
                 -e NET_9P \
                 -e 9P_FS \
                 -e BINFMT_MISC \
                 -e FAULT_INJECTION \
                 -e FAILSLAB \
                 -e FAIL_PAGE_ALLOC \
                 -e FAIL_MAKE_REQUEST \
                 -e FAIL_IO_TIMEOUT \
                 -e FAIL_FUTEX \
                 -e FAULT_INJECTION_DEBUG_FS \
                 -e FAULT_INJECTION_STACKTRACE_FILTER \
                 -e DEBUG_KMEMLEAK
```

Edit `.config` file manually and enable them (or do that through `make menuconfig` if you prefer).

Since enabling these options results in more sub options being available, we need to regenerate config:

``` bash
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
```

Build the kernel:

```
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- -j$(nproc)
```

Now you should have `vmlinux` (kernel binary) and `bzImage` (packed kernel image):

``` bash
$ ls $KERNEL/vmlinux
$KERNEL/vmlinux
$ ls $KERNEL/arch/s390/boot/bzImage
$KERNEL/arch/s390/boot/bzImage
```

## Image

### Debian

To create a Debian Linux image with the minimal set of required packages do:

```
cd $IMAGE/
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
chmod +x create-image.sh
./create-image.sh -a s390x
```

The result should be `$IMAGE/trixie.img` disk image.

For additional options of `create-image.sh`, please refer to `./create-image.sh -h`

## QEMU

### Debian

Run:

```shell
qemu-system-s390x \
	-M s390-ccw-virtio -cpu max,zpci=on -m 4G -smp 2 \
	-kernel $KERNEL/arch/s390/boot/bzImage \
	-drive file=$IMAGE/trixie.img,if=virtio,format=raw \
	-append "rootwait root=/dev/vda net.ifnames=0 biosdevname=0" \
	-net nic,model=virtio -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
	-display none -serial mon:stdio \
	-pidfile vm.pid 2>&1 | tee vm.log
```

After that you should be able to ssh to QEMU instance in another terminal:

``` bash
ssh -i $IMAGE/trixie.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
```

If this fails with "too many tries", ssh may be passing default keys before
the one explicitly passed with `-i`. Append option `-o "IdentitiesOnly yes"`.

To kill the running QEMU instance press `Ctrl+A` and then `X` or run:

``` bash
kill $(cat vm.pid)
```

If QEMU works, the kernel boots and ssh succeeds, you can shutdown QEMU and try to run syzkaller.

## syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller), with `s390x` target:

```
make TARGETOS=linux TARGETARCH=s390x
```

Then create a manager config like the following, replacing the environment
variables `$GOPATH`, `$KERNEL` and `$IMAGE` with their actual values.

```
{
	"target": "linux/s390x",
	"http": "127.0.0.1:56741",
	"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
	"kernel_obj": "$KERNEL",
	"image": "$IMAGE/trixie.img",
	"sshkey": "$IMAGE/trixie.id_rsa",
	"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
	"procs": 8,
	"type": "qemu",
	"vm": {
		"count": 4,
		"kernel": "$KERNEL/arch/s390/boot/bzImage",
		"cpu": 2,
		"mem": 2048
	}
}
```

Run syzkaller manager:

``` bash
mkdir workdir
./bin/syz-manager -config=my.cfg
```

Now syzkaller should be running, you can check manager status with your web browser at `127.0.0.1:56741`.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.
Also see [this page](/docs/troubleshooting.md) for troubleshooting tips.

---

### Linux Setup Ubuntu Host Qemu Vm X86 64 Kernel (`docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md`)

# Setup: Ubuntu host, QEMU vm, x86-64 kernel

These are the instructions on how to fuzz the x86-64 kernel in a QEMU with Ubuntu on the host machine and Debian Trixie in the QEMU instances.

In the instructions below, the `$VAR` notation (e.g. `$GCC`, `$KERNEL`, etc.) is used to denote paths to directories that are either created when executing the instructions (e.g. when unpacking GCC archive, a directory will be created), or that you have to create yourself before running the instructions. Substitute the values for those variables manually.


## Install Prerequisites

Command:
``` bash
sudo apt update
sudo apt install make gcc flex bison libncurses-dev libelf-dev libssl-dev
```


## GCC

If your distro's GCC is older, it's preferable to get the latest GCC from [this](/docs/syzbot.md#crash-does-not-reproduce) list. Download and unpack into `$GCC`, and you should have GCC binaries in `$GCC/bin/`

>**Ubuntu 20.04 LTS**: You can ignore this section. GCC is up-to-date.

Command:
``` bash
ls $GCC/bin/
# Sample output:
# cpp     gcc-ranlib  x86_64-pc-linux-gnu-gcc        x86_64-pc-linux-gnu-gcc-ranlib
# gcc     gcov        x86_64-pc-linux-gnu-gcc-9.0.0
# gcc-ar  gcov-dump   x86_64-pc-linux-gnu-gcc-ar
# gcc-nm  gcov-tool   x86_64-pc-linux-gnu-gcc-nm
```

## Kernel

### Checkout Linux Kernel source

Command:
``` bash
git clone --branch v6.2 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $KERNEL
```

>We recommend to start with the latest stable version. v6.2 is an example here.

### Generate default configs

Command:
``` bash
cd $KERNEL
make defconfig
make kvm_guest.config
```

Or if you want to specify a compiler.

Command:
``` bash
cd $KERNEL
make CC="$GCC/bin/gcc" defconfig
make CC="$GCC/bin/gcc" kvm_guest.config
```

### Enable required config options

Enable kernel config options required for syzkaller as described [here](kernel_configs.md).
It's not required to enable all of them, but at the very least you need:

``` make
# Coverage collection.
CONFIG_KCOV=y

# Debug info for symbolization.
CONFIG_DEBUG_INFO_DWARF4=y

# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

# Required for Debian Stretch and later
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
```

Edit `.config` file manually and enable them (or do that through `make menuconfig` if you prefer).

Since enabling these options results in more sub options being available, we need to regenerate config:

Command:
``` bash
make olddefconfig
```

Or if you want to specify a compiler.

Command:
``` bash
make CC="$GCC/bin/gcc" olddefconfig
```

You might also be interested in disabling the Predictable Network Interface Names mechanism. This can be disabled either in the syzkaller configuration (see details [here](troubleshooting.md)) or by updating these kernel configuration parameters:

``` make
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="net.ifnames=0"
```

### Build the Kernel

Command:
``` bash
make -j`nproc`
```

Or if you want to specify a compiler.

Command:
``` bash
make CC="$GCC/bin/gcc" -j`nproc`
```

Now you should have `vmlinux` (kernel binary) and `bzImage` (packed kernel image):

Command:
``` bash
ls $KERNEL/vmlinux
# sample output - $KERNEL/vmlinux
ls $KERNEL/arch/x86/boot/bzImage
# sample output - $KERNEL/arch/x86/boot/bzImage
```

## Image

### Install debootstrap

Command:
``` bash
sudo apt install debootstrap
```

### Create Debian Trixie Linux image

Create a Debian Trixie Linux image with the minimal set of required packages.

Command:
``` bash
mkdir $IMAGE
cd $IMAGE/
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
chmod +x create-image.sh
./create-image.sh
```

The result should be `$IMAGE/trixie.img` disk image.

### OR Create Debian Linux image with a different version

To create a Debian image with a different version (e.g. bookworm, bullseye, sid), specify the `--distribution` option.

Command:
``` bash
./create-image.sh --distribution bookworm
```

### Image extra tools

Sometimes it's useful to have some additional packages and tools available in the VM even though they are not required to run syzkaller. To install a set of tools we find useful do (feel free to edit the list of tools in the script):

Command:
``` bash
./create-image.sh --feature full
```

To install perf (not required to run syzkaller; requires `$KERNEL` to point to the kernel sources):

Command:
``` bash
./create-image.sh --add-perf
```

For additional options of `create-image.sh`, please refer to `./create-image.sh -h`

## QEMU

### Install QEMU

Command:
``` bash
sudo apt install qemu-system-x86
```

### Verify

Make sure the kernel boots and `sshd` starts.

Command:
``` bash
qemu-system-x86_64 \
	-m 2G \
	-smp 2 \
	-kernel $KERNEL/arch/x86/boot/bzImage \
	-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
	-drive file=$IMAGE/trixie.img,format=raw \
	-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
	-net nic,model=e1000 \
	-enable-kvm \
	-nographic \
	-pidfile vm.pid \
	2>&1 | tee vm.log
```

``` text
early console in setup code
early console in extract_kernel
input_data: 0x0000000005d9e276
input_len: 0x0000000001da5af3
output: 0x0000000001000000
output_len: 0x00000000058799f8
kernel_total_size: 0x0000000006b63000

Decompressing Linux... Parsing ELF... done.
Booting the kernel.
[    0.000000] Linux version 4.12.0-rc3+ ...
[    0.000000] Command line: console=ttyS0 root=/dev/sda debug earlyprintk=serial
...
[ ok ] Starting enhanced syslogd: rsyslogd.
[ ok ] Starting periodic command scheduler: cron.
[ ok ] Starting OpenBSD Secure Shell server: sshd.
```

After that you should be able to ssh to QEMU instance in another terminal.

Command:
``` bash
ssh -i $IMAGE/trixie.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
```

### Troubleshooting

If this fails with "too many tries", ssh may be passing default keys before
the one explicitly passed with `-i`. Append option `-o "IdentitiesOnly yes"`.

To kill the running QEMU instance press `Ctrl+A` and then `X` or run:

Command:
``` bash
kill $(cat vm.pid)
```

If QEMU works, the kernel boots and ssh succeeds, you can shutdown QEMU and try to run syzkaller.

## syzkaller

Build syzkaller as described [here](/docs/linux/setup.md#go-and-syzkaller).
Then create a manager config like the following, replacing the environment
variables `$GOPATH`, `$KERNEL` and `$IMAGE` with their actual values.

``` json
{
	"target": "linux/amd64",
	"http": "127.0.0.1:56741",
	"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
	"kernel_obj": "$KERNEL",
	"image": "$IMAGE/trixie.img",
	"sshkey": "$IMAGE/trixie.id_rsa",
	"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
	"procs": 8,
	"type": "qemu",
	"vm": {
		"count": 4,
		"kernel": "$KERNEL/arch/x86/boot/bzImage",
		"cpu": 2,
		"mem": 2048
	}
}
```

Run syzkaller manager:

``` bash
mkdir workdir
./bin/syz-manager -config=my.cfg
```

Now syzkaller should be running, you can check manager status with your web browser at `127.0.0.1:56741`.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.
Also see [this page](/docs/troubleshooting.md) for troubleshooting tips.

---

### Linux Setup Ubuntu Host Virtualbox Vm X86 64 Kernel (`docs/linux/setup_ubuntu-host_virtualbox-vm_x86-64-kernel.md`)

# Setup: Ubuntu host, VirtualBox vm, x86-64 kernel

These are the instructions on how to fuzz the x86-64 kernel in VirtualBox with Ubuntu on the host machine and Debian Trixie in the virtual machines.

In the instructions below, the `$VAR` notation (e.g. `$GCC`, `$KERNEL`, etc.) is used to denote paths to directories that are either created when executing the instructions (e.g. when unpacking GCC archive, a directory will be created), or that you have to create yourself before running the instructions. Substitute the values for those variables manually.

## GCC and Kernel

You can follow the same [instructions](/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md) for obtaining GCC and building the Linux kernel as when using QEMU.

## Image

Install debootstrap:

``` bash
sudo apt-get install debootstrap
```

To create a Debian Trixie Linux user space in the $USERSPACE dir do:
```
sudo mkdir -p $USERSPACE
sudo debootstrap --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc,selinux-utils,policycoreutils,checkpolicy,selinux-policy-default,firmware-atheros,open-vm-tools --components=main,contrib,non-free trixie $USERSPACE
```

Note: it is important to include the `open-vm-tools` package in the user space as it provides better VM management.

To create a Debian Trixie Linux VMDK do:

```
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-gce-image.sh -O create-gce-image.sh
chmod +x create-gce-image.sh
./create-gce-image.sh $USERSPACE $KERNEL/arch/x86/boot/bzImage
qemu-img convert -f raw -O vdi disk.raw disk.vdi
```

The result should be `disk.vdi` for the disk image. You can delete `disk.raw` if you want.

## VirtualBox

Open VirtualBox and start the New Virtual Machine Wizard.
Assuming you want to create the new VM in `$VMPATH`, complete the wizard as follows:

* Create New Virtual Machine
* Virtual Machine Name and Location: select `$VMPATH` as location and "debian" as name
* Guest OS type: Debian 64-bit
* Disk: select "Use an existing virtual disk"
* Import the `disk.vdi` file, and select the imported `.vdi` file as an Hard Disk File.

When you complete the wizard, you should have `$VMPATH/debian.vbox`. From this point onward, you no longer need the VirtualBox UI.

To test the fuzzing environment before getting started, follow the instructions below:
Forwarding port 2222 on your host machine to port 22:
``` bash
VBoxManage modifyvm debian --natpf1 "test,tcp,,2222,,22"
```

Starting the Debian VM (headless):
``` bash
VBoxManage startvm debian --type headless
```

SSH into the VM:
``` bash
ssh -p 2222 root@127.0.0.1
```

Stopping the VM:
``` bash
VBoxManage controlvm debian poweroff
```

If all of the above `VBoxManage` commands work, then you can proceed to running syzkaller.

## syzkaller

Create a manager config like the following, replacing the environment variables $GOPATH, $KERNEL and $VMPATH with their actual values.

```
{
    "target": "linux/amd64",
    "http": "127.0.0.1:56741",
    "workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
    "kernel_obj": "$KERNEL",
    "sshkey": "$IMAGE/key",
    "syzkaller": "$GOPATH/src/github.com/google/syzkaller",
    "procs": 8,
    "type": "virtualbox",
    "vm": {
        "count": 4,
        "base_vm_name": "debian"
    }
}
```

Run syzkaller manager:

``` bash
mkdir workdir
./bin/syz-manager -config=my.cfg
```

Syzkaller will create full clone VMs from the `debian` VM and then use ssh to copy and execute programs in them.
The `debian` VM will not be started and its disk will remain unmodified.

If you get issues after `syz-manager` starts, consider running it with the `-debug` flag.
Also see [this page](/docs/troubleshooting.md) for troubleshooting tips.

---

--- METRICS ---
- Files Extracted: 93
- Estimated Token Budget: ~125034 tokens
- Canonical Reference: https://codewiki.google/github.com/google/syzkaller
