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.