From 52c8379f77b5f292e2d527c66dfe17a899381d20 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 7 Oct 2021 10:52:29 +0000 Subject: docs: update docs to reflect the new `async` flag --- docs/executing_syzkaller_programs.md | 31 +++++++++++----- docs/program_syntax.md | 22 ++++++++++++ docs/reproducing_crashes.md | 70 ++++++++++++++++++++++++++---------- docs/syzbot.md | 4 +-- 4 files changed, 98 insertions(+), 29 deletions(-) (limited to 'docs') diff --git a/docs/executing_syzkaller_programs.md b/docs/executing_syzkaller_programs.md index 215abcde7..f06f01c86 100644 --- a/docs/executing_syzkaller_programs.md +++ b/docs/executing_syzkaller_programs.md @@ -16,6 +16,9 @@ export GOPATH=$HOME/gopath GO111MODULE=off go get -u -d github.com/google/syzkaller/prog ``` +Note that your syzkaller revision must be the same as the one that generated the +program you're trying to execute. + 3. Build necessary syzkaller binaries: ``` bash cd $GOPATH/src/github.com/google/syzkaller @@ -35,8 +38,6 @@ scp -P 10022 -i stretch.img.key bin/linux_amd64/syz-execprog bin/linux_amd64/syz Several useful `syz-execprog` flags: ``` - -collide - collide syscalls to provoke data races (default true) -procs int number of parallel processes to execute programs (default 1) -repeat int @@ -47,12 +48,26 @@ Several useful `syz-execprog` flags: use threaded mode in executor (default true) ``` -If you pass `-threaded=0 -collide=0`, programs will be executed as a simple single-threaded sequence of syscalls. `-threaded=1` forces execution of each syscall in a separate thread, so that execution can proceed over blocking syscalls. `-collide=1` forces second round of execution of syscalls when pairs of syscalls are executed concurrently. +If you pass `-threaded=0`, programs will be executed as a simple single-threaded +sequence of syscalls. `-threaded=1` forces execution of each syscall in a +separate thread, so that execution can proceed over blocking syscalls. + +Older syzkaller versions also had 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. You might need to use this flag if you're running an +old reproducer. + -If you are replaying a reproducer program that contains a header along the following lines: +If you are replaying a reproducer program that contains a header along the +following lines: ``` -#{Threaded:true Collide:true Repeat:true Procs:8 Sandbox:namespace - Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true - HandleSegv:true WaitRepeat:true Debug:false Repro:false} +# {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`/`Collide`/`Procs`/`Sandbox` directly relate to `-threaded`/`-collide`/`-procs`/`-sandbox` flags. If `Repeat` is set to `true`, add `-repeat=0` flag to `syz-execprog`. +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`. diff --git a/docs/program_syntax.md b/docs/program_syntax.md index bf1775c4d..2b1fb3c0d 100644 --- a/docs/program_syntax.md +++ b/docs/program_syntax.md @@ -91,3 +91,25 @@ 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. diff --git a/docs/reproducing_crashes.md b/docs/reproducing_crashes.md index 679e6ba88..64e8356c1 100644 --- a/docs/reproducing_crashes.md +++ b/docs/reproducing_crashes.md @@ -1,24 +1,56 @@ # How to reproduce 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. - -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`. - -`tools/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 `syz-execprog` and `syz-executor` into a VM with the test kernel and run it there. - -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. - -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 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/collide mode as if each syscall is executed in its own thread. To mode 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.cfg). +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. + +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`. + +`tools/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 +`syz-execprog` and `syz-executor` into a VM with the test kernel and run it +there. + +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. + +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 +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.cfg). ``` ./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. +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. diff --git a/docs/syzbot.md b/docs/syzbot.md index 77fff12ee..d001b76ba 100644 --- a/docs/syzbot.md +++ b/docs/syzbot.md @@ -221,11 +221,11 @@ 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/executing_syzkaller_programs.md), -e.g. `-threaded`/`-collide` which control if the syscalls are executed sequentially or in parallel. +e.g. `-threaded` which controls if the syscalls are executed sequentially or in parallel. An example invocation: ``` -syz-prog2c -prog repro.syz.txt -enable=all -threaded -collide -repeat -procs=8 -sandbox=namespace -segv -tmpdir -waitrepeat +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 (though, it can be just because the bug is triggered by a subtle race condition). -- cgit mrf-deployment