github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/docs/reproducing_crashes.md (about) 1 # How to reproduce syzkaller crashes 2 3 ## Using a C reproducer 4 5 If the bug was reported by syzbot, you first need to build the kernel used by 6 the tool. Syzbot provides the necessary information in its report: 7 8 ``` 9 Hello, 10 11 syzbot found the following issue on: 12 13 HEAD commit: ae58226b89ac Add linux-next specific files for 20241118 14 git tree: linux-next 15 console+strace: https://syzkaller.appspot.com/x/log.txt?x=14a67378580000 16 kernel config: https://syzkaller.appspot.com/x/.config?x=45719eec4c74e6ba 17 dashboard link: https://syzkaller.appspot.com/bug?extid=2159cbb522b02847c053 18 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 19 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=137beac0580000 20 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=177beac0580000 21 ``` 22 23 In this case, you would run: 24 ``` 25 $ git checkout ae58226b89ac 26 $ wget -O '.config' 'https://syzkaller.appspot.com/x/.config?x=45719eec4c74e6ba` 27 $ make CC=clang LD=ld.lld olddefconfig 28 $ make CC=clang LD=ld.lld -j$(nproc) 29 ``` 30 31 You also need a bootable disk image. Syzbot currently uses small Buildroot-based 32 images that you can either [build locally](/tools/create-buildroot-image.sh) or 33 [download](https://storage.googleapis.com/syzkaller/images/buildroot_amd64_2024.09.gz). 34 35 Download and build the reproducer: 36 ``` 37 $ wget -O 'repro.c' 'https://syzkaller.appspot.com/x/repro.c?x=177beac0580000' 38 $ gcc repro.c -lpthread -static -o repro 39 ``` 40 41 Run the VM: 42 ``` 43 $ export DISK_IMAGE='buildroot_amd64_2024.09' 44 $ 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 45 ``` 46 47 Run the reproducer: 48 ``` 49 $ scp -P 10022 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ./repro root@127.0.0.1:/root/ 50 $ ssh -p 10022 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes root@127.0.0.1 'chmod +x ./repro && ./repro' 51 ``` 52 53 54 ## Using a Syz reproducer 55 56 Syzkaller always generates a "Syz" reproducer first (in [Syzkaller 57 DSL](/docs/program_syntax.md)). Afterwards, syzkaller attempts to convert the 58 Syz reproducer into C code. The process does not always succeed due to the 59 differences between the `syz-executor` environment and the environment emulated 60 in the C reproducer. Therefore, in some cases, only the Syz version is 61 available. 62 63 To run a Syz reproducer locally, the required actions are mostly similar to 64 those in the previous section. 65 66 Download and [build](/docs/linux/setup.md#go-and-syzkaller) syzkaller. If you 67 have Docker installed, the instructions are simpler: 68 ``` 69 $ git clone https://github.com/google/syzkaller.git 70 $ cd syzkaller 71 $ ./tools/syz-env make 72 ``` 73 74 Build the kernel and boot the VM as described in the section above. 75 76 Download the reproducer: 77 ``` 78 $ wget -O 'repro.syz' 'https://syzkaller.appspot.com/x/repro.syz?x=137beac0580000' 79 ``` 80 81 Copy the reproducer and the syzkaller binaries to the test machine: 82 ``` 83 $ export SYZKALLER_PATH="~/syzkaller" 84 $ 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/ 85 ``` 86 87 Now you can use the `syz-execprog` tool to actually execute the program. 88 89 ``` 90 $ 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' 91 ``` 92 93 Several useful `syz-execprog` flags: 94 ``` 95 -procs int 96 number of parallel processes to execute programs (default 1) 97 -repeat int 98 repeat execution that many times (0 for infinite loop) (default 1) 99 -sandbox string 100 sandbox for fuzzing (none/setuid/namespace) (default "setuid") 101 -threaded 102 use threaded mode in executor (default true) 103 ``` 104 105 If you pass `-threaded=0`, all syscalls will be executed in the same thread. 106 `-threaded=1` forces execution of each syscall in a separate thread, so that 107 execution can proceed over blocking syscalls. 108 109 Before 2021, `syz-execprog` also supported the following flag: 110 ``` 111 -collide 112 collide syscalls to provoke data races (default true) 113 ``` 114 `-collide=1` forced second round of execution of syscalls when pairs of syscalls 115 are executed concurrently. 116 117 Starting from the revision 118 [fd8caa54](https://github.com/google/syzkaller/commit/fd8caa5462e64f37cb9eebd75ffca1737dde447d), 119 the behavior is controlled [directly in syzlang](/docs/program_syntax.md#async). 120 If you are running older reproducers, you might still need to set the `-collide=1` flag. 121 122 123 If you are replaying a reproducer program that contains a header along the 124 following lines: 125 ``` 126 # {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}} 127 ``` 128 then you need to adjust `syz-execprog` flags based on the values in the 129 header. Namely, `Threaded`/`Procs`/`Sandbox` directly relate to 130 `-threaded`/`-procs`/`-sandbox` flags. If `Repeat` is set to `true`, add 131 `-repeat=0` flag to `syz-execprog`. 132 133 ## Using ktest 134 135 [ktest](https://evilpiepirate.org/git/ktest.git/tree/README.md) is a collection 136 of tests for Linux and an infrastructure that simplifies running them locally. 137 138 Ktest includes a special `syzbot-repro.ktest` test that automates building the 139 kernel, booting the VM, fetching syzbot bug report details and running the 140 reproducer. 141 142 **Installation instructions:** 143 ``` 144 $ git clone git://evilpiepirate.org/ktest.git 145 $ cd ktest 146 $ export KTEST_PATH=$(pwd) 147 $ sudo ./root_image init 148 $ sudo ./root_image create 149 $ cargo install --path $KTEST_PATH 150 ``` 151 152 **Instructions to reproduce a syzbot bug:** 153 ``` 154 $ cd ~/linux 155 $ git checkout <kernel-commit> 156 $ $KTEST_PATH/build-test-kernel run $KTEST_PATH/tests/syzbot-repro.ktest <bug-id> 157 ``` 158 159 `<bug-id>` can be taken from syzbot bug reports: 160 161 ``` 162 dashboard link: https://syzkaller.appspot.com/bug?extid=2159cbb522b02847c053 163 ``` 164 165 In this case, `bug-id` is `2159cbb522b02847c053`. 166 167 168 ## Using downloadable assets 169 170 In each report, syzbot shares the exact disk image, kernel image and the vmlinux 171 file that were used to find it. 172 173 See [the corresponding documentation](/docs/syzbot_assets.md) on how you can 174 use those files to reproduce bugs locally. 175 176 ## From execution logs 177 178 The process of creating reproducer programs for syzkaller bugs is automated, but 179 it's not perfect. In some cases, the tool cannot narrow down the kernel crash to 180 a single program. 181 182 ### Obtaining execution logs 183 * **A local syzkaller instance** \ 184 Crash logs created in manager `workdir/crashes` dir contain programs executed 185 just before a crash. In parallel execution mode (when `procs` parameter in 186 manager config is set to value larger than 1), program that caused the crash 187 does not necessary immediately precedes it; the guilty program can be somewhere 188 before. 189 190 * **Syzbot** shares execution logs in its reports: 191 ``` 192 console output: https://syzkaller.appspot.com/x/log.txt?x=148914c0580000 193 ``` 194 195 ### Crafting reproducers manually 196 197 There are two tools that can help you identify and minimize the program that 198 causes a crash: `syz-execprog` and `syz-prog2c`. You can build them with `make 199 execprog` and `make prog2c`, respectively. 200 201 `syz-execprog` executes a single syzkaller program or a set of programs in 202 various modes (once or loop indefinitely; in threaded/collide mode (see below), 203 with or without coverage collection). 204 205 You can start by running all programs in the crash log in a loop to check that 206 at least one of them indeed crashes kernel: 207 208 ``` 209 ./syz-execprog -executor=./syz-executor -repeat=0 -procs=8 -cover=0 crash-log-file.txt 210 ``` 211 **Note: `syz-execprog` executes programs locally. So you need to copy 212 `syz-execprog` and `syz-executor` into a VM with the test kernel and run it 213 there.** See the [Using a Syz reproducer](#Using-a-Syz-reproducer) section. 214 215 To identify the single program that causes the crash, you can cut out individual 216 programs from `crash-log-file.txt` and run `syz-execprog` separately. 217 218 Once you have a single program that causes the crash, you can try to minimize it by: 219 * Removing individual syscalls from the program (you can comment out single lines 220 with `#` at the beginning of line) 221 * By removing unnecessary data (e.g. replacing `&(0x7f0000001000)="73656c6600"` 222 syscall argument with `&(0x7f0000001000)=nil`). 223 * You can also try to coalesce all mmap calls into a single mmap call that maps 224 whole required area. 225 226 Don't forget to test minimization results with the `syz-execprog` tool. 227 228 Now that you have a minimized program, check if the crash still reproduces with 229 `./syz-execprog -threaded=0 -collide=0` flags. If not, then you will need to do 230 some additional work later. 231 232 Now, run the `syz-prog2c` tool on the program. It will give you an executable C 233 source code. If the crash reproduces with `-threaded/collide=0` flags, then this C 234 program should cause the crash as well. 235 236 If the crash is not reproducible with `-threaded/collide=0` flags, then you need 237 this last step. You can think of threaded mode as if each syscall is 238 executed in its own thread. To model such execution mode, move individual 239 syscalls into separate threads. You can see an example here: 240 https://groups.google.com/d/msg/syzkaller/fHZ42YrQM-Y/Z4Xf-BbUDgAJ. 241 242 This process is automated to some degree in the `syz-repro` utility. You need to 243 give it your manager config and a crash report file. And you can refer to the 244 [example config file](/pkg/mgrconfig/testdata/qemu-example.cfg). 245 ``` 246 ./syz-repro -config my.cfg crash-qemu-1-1455745459265726910 247 ``` 248 It will try to find the offending program and minimize it. But since there are 249 lots of factors that can affect reproducibility, it does not always work.