aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-11-22 15:04:27 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-11-25 17:02:45 +0000
commit11dbc2540722df00e9c113b3e27c5ea707844273 (patch)
tree92dda0808c1ad937778ae86c99132cfae37fea08 /docs
parent02832ca35ded902878eb2a3aa43a1235de5f8ac4 (diff)
docs: rewrite reproducing_crashes.md
Let's list all the possible ways of reproducing syzkaller crashes locally and keep the instructions of how to manually craft a reproducer at the bottom. Add information about the ktest tooling - now it also automates the reproduction of syzbot bugs. See the discussion at: https://groups.google.com/g/syzkaller/c/UTPrWcJfS8Q/m/K1YXz-f1AQAJ
Diffstat (limited to 'docs')
-rw-r--r--docs/reproducing_crashes.md194
1 files changed, 169 insertions, 25 deletions
diff --git a/docs/reproducing_crashes.md b/docs/reproducing_crashes.md
index 64e8356c1..9a76a899e 100644
--- a/docs/reproducing_crashes.md
+++ b/docs/reproducing_crashes.md
@@ -1,43 +1,187 @@
-# How to reproduce crashes
+# How to reproduce syzkaller crashes
-The process of creating reproducer programs for syzkaller bugs is automated,
-however it's not perfect, so syzkaller provides a few tools for executing and
-reproducing programs manually.
+## 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:
+```
+$ 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:
+```
+$ wget -O 'repro.c' 'https://syzkaller.appspot.com/x/repro.c?x=177beac0580000'
+$ gcc repro.c -lpthread -static -o repro
+```
+
+Run the VM:
+```
+$ 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:
+```
+$ 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:
+```
+$ git clone https://github.com/google/syzkaller.git
+$ cd syzkaller
+$ ./tools/syz-env make
+```
+
+Build the kernel and boot the VM as described above.
+
+Download and run the reproducer:
+```
+$ export SYZKALLER_PATH="~/syzkaller"
+$ wget -O 'repro.syz' 'https://syzkaller.appspot.com/x/repro.syz?x=137beac0580000'
+$ 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/
+$ 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'
+```
+
+## 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:**
+```
+$ 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:**
+```
+$ 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. There are two tools that can help you identify and minimize the program
-that causes a crash: `tools/syz-execprog` and `tools/syz-prog2c`.
+before.
+
+* **Syzbot** shares execution logs in its reports:
+```
+console output: https://syzkaller.appspot.com/x/log.txt?x=148914c0580000
+```
+
+### Crafting reproducers manually
-`tools/syz-execprog` executes a single syzkaller program or a set of programs in
+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: `./syz-execprog -executor=./syz-executor -repeat=0 -procs=16 -cover=0
-crash-log`. Then try to identify the single program that causes the crash, you
-can test programs with `./syz-execprog -executor=./syz-executor -repeat=0
--procs=16 -cover=0 file-with-a-single-program`.
-
-Note: `syz-execprog` executes programs locally. So you need to copy
+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:
+
+```
+./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.
+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.
-Once you have a single program that causes the crash, try to minimize it by
-removing individual syscalls from the program (you can comment out single lines
-with `#` at the beginning of line), and 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. Again, test minimization with
-`syz-execprog` tool.
+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 `syz-prog2c` tool on the program. It will give you executable C
-source. If the crash reproduces with `-threaded/collide=0` flags, then this C
+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