xref: /qemu/docs/devel/testing/fuzzing.rst (revision c0f86125c38599e5d4b39a0bb9161252623de694)
1f3a0208fSAlexander Bulekov========
2f3a0208fSAlexander BulekovFuzzing
3f3a0208fSAlexander Bulekov========
4f3a0208fSAlexander Bulekov
5f3a0208fSAlexander BulekovThis document describes the virtual-device fuzzing infrastructure in QEMU and
6f3a0208fSAlexander Bulekovhow to use it to implement additional fuzzers.
7f3a0208fSAlexander Bulekov
8f3a0208fSAlexander BulekovBasics
9f3a0208fSAlexander Bulekov------
10f3a0208fSAlexander Bulekov
11f3a0208fSAlexander BulekovFuzzing operates by passing inputs to an entry point/target function. The
12f3a0208fSAlexander Bulekovfuzzer tracks the code coverage triggered by the input. Based on these
13f3a0208fSAlexander Bulekovfindings, the fuzzer mutates the input and repeats the fuzzing.
14f3a0208fSAlexander Bulekov
15f3a0208fSAlexander BulekovTo fuzz QEMU, we rely on libfuzzer. Unlike other fuzzers such as AFL, libfuzzer
16f3a0208fSAlexander Bulekovis an *in-process* fuzzer. For the developer, this means that it is their
17f3a0208fSAlexander Bulekovresponsibility to ensure that state is reset between fuzzing-runs.
18f3a0208fSAlexander Bulekov
19f3a0208fSAlexander BulekovBuilding the fuzzers
20f3a0208fSAlexander Bulekov--------------------
21f3a0208fSAlexander Bulekov
22f3a0208fSAlexander BulekovTo build the fuzzers, install a recent version of clang:
23f3a0208fSAlexander BulekovConfigure with (substitute the clang binaries with the version you installed).
24*c0f86125SMatheus Tavares BernardinoHere, enable-asan and enable-ubsan are optional but they allow us to reliably
25*c0f86125SMatheus Tavares Bernardinodetect bugs such as out-of-bounds accesses, uses-after-free, double-frees
26*c0f86125SMatheus Tavares Bernardinoetc.::
27f3a0208fSAlexander Bulekov
28cb771ac1SRichard Henderson    CC=clang-8 CXX=clang++-8 /path/to/configure \
29cb771ac1SRichard Henderson        --enable-fuzzing --enable-asan --enable-ubsan
30f3a0208fSAlexander Bulekov
31f3a0208fSAlexander BulekovFuzz targets are built similarly to system targets::
32f3a0208fSAlexander Bulekov
33e6a3e132SAlexander Bulekov    make qemu-fuzz-i386
34f3a0208fSAlexander Bulekov
35e6a3e132SAlexander BulekovThis builds ``./qemu-fuzz-i386``
36f3a0208fSAlexander Bulekov
37f3a0208fSAlexander BulekovThe first option to this command is: ``--fuzz-target=FUZZ_NAME``
38f3a0208fSAlexander BulekovTo list all of the available fuzzers run ``qemu-fuzz-i386`` with no arguments.
39f3a0208fSAlexander Bulekov
40f3a0208fSAlexander BulekovFor example::
41f3a0208fSAlexander Bulekov
42e6a3e132SAlexander Bulekov    ./qemu-fuzz-i386 --fuzz-target=virtio-scsi-fuzz
43f3a0208fSAlexander Bulekov
44f3a0208fSAlexander BulekovInternally, libfuzzer parses all arguments that do not begin with ``"--"``.
45f3a0208fSAlexander BulekovInformation about these is available by passing ``-help=1``
46f3a0208fSAlexander Bulekov
47f3a0208fSAlexander BulekovNow the only thing left to do is wait for the fuzzer to trigger potential
48f3a0208fSAlexander Bulekovcrashes.
49f3a0208fSAlexander Bulekov
50f3a0208fSAlexander BulekovUseful libFuzzer flags
51f3a0208fSAlexander Bulekov----------------------
52f3a0208fSAlexander Bulekov
53f3a0208fSAlexander BulekovAs mentioned above, libFuzzer accepts some arguments. Passing ``-help=1`` will
54f3a0208fSAlexander Bulekovlist the available arguments. In particular, these arguments might be helpful:
55f3a0208fSAlexander Bulekov
56f3a0208fSAlexander Bulekov* ``CORPUS_DIR/`` : Specify a directory as the last argument to libFuzzer.
57f3a0208fSAlexander Bulekov  libFuzzer stores each "interesting" input in this corpus directory. The next
58f3a0208fSAlexander Bulekov  time you run libFuzzer, it will read all of the inputs from the corpus, and
59f3a0208fSAlexander Bulekov  continue fuzzing from there. You can also specify multiple directories.
60f3a0208fSAlexander Bulekov  libFuzzer loads existing inputs from all specified directories, but will only
61f3a0208fSAlexander Bulekov  write new ones to the first one specified.
62f3a0208fSAlexander Bulekov
63f3a0208fSAlexander Bulekov* ``-max_len=4096`` : specify the maximum byte-length of the inputs libFuzzer
64f3a0208fSAlexander Bulekov  will generate.
65f3a0208fSAlexander Bulekov
66f3a0208fSAlexander Bulekov* ``-close_fd_mask={1,2,3}`` : close, stderr, or both. Useful for targets that
67f3a0208fSAlexander Bulekov  trigger many debug/error messages, or create output on the serial console.
68f3a0208fSAlexander Bulekov
69f3a0208fSAlexander Bulekov* ``-jobs=4 -workers=4`` : These arguments configure libFuzzer to run 4 fuzzers in
70f3a0208fSAlexander Bulekov  parallel (4 fuzzing jobs in 4 worker processes). Alternatively, with only
71f3a0208fSAlexander Bulekov  ``-jobs=N``, libFuzzer automatically spawns a number of workers less than or equal
72f3a0208fSAlexander Bulekov  to half the available CPU cores. Replace 4 with a number appropriate for your
73f3a0208fSAlexander Bulekov  machine. Make sure to specify a ``CORPUS_DIR``, which will allow the parallel
74f3a0208fSAlexander Bulekov  fuzzers to share information about the interesting inputs they find.
75f3a0208fSAlexander Bulekov
76f3a0208fSAlexander Bulekov* ``-use_value_profile=1`` : For each comparison operation, libFuzzer computes
77f3a0208fSAlexander Bulekov  ``(caller_pc&4095) | (popcnt(Arg1 ^ Arg2) << 12)`` and places this in the
78f3a0208fSAlexander Bulekov  coverage table. Useful for targets with "magic" constants. If Arg1 came from
79f3a0208fSAlexander Bulekov  the fuzzer's input and Arg2 is a magic constant, then each time the Hamming
80f3a0208fSAlexander Bulekov  distance between Arg1 and Arg2 decreases, libFuzzer adds the input to the
81f3a0208fSAlexander Bulekov  corpus.
82f3a0208fSAlexander Bulekov
83f3a0208fSAlexander Bulekov* ``-shrink=1`` : Tries to make elements of the corpus "smaller". Might lead to
84f3a0208fSAlexander Bulekov  better coverage performance, depending on the target.
85f3a0208fSAlexander Bulekov
86f3a0208fSAlexander BulekovNote that libFuzzer's exact behavior will depend on the version of
87f3a0208fSAlexander Bulekovclang and libFuzzer used to build the device fuzzers.
88f3a0208fSAlexander Bulekov
89f3a0208fSAlexander BulekovGenerating Coverage Reports
90f3a0208fSAlexander Bulekov---------------------------
91f3a0208fSAlexander Bulekov
92f3a0208fSAlexander BulekovCode coverage is a crucial metric for evaluating a fuzzer's performance.
93f3a0208fSAlexander BulekovlibFuzzer's output provides a "cov: " column that provides a total number of
94f3a0208fSAlexander Bulekovunique blocks/edges covered. To examine coverage on a line-by-line basis we
95f3a0208fSAlexander Bulekovcan use Clang coverage:
96f3a0208fSAlexander Bulekov
97f3a0208fSAlexander Bulekov 1. Configure libFuzzer to store a corpus of all interesting inputs (see
98f3a0208fSAlexander Bulekov    CORPUS_DIR above)
99f3a0208fSAlexander Bulekov 2. ``./configure`` the QEMU build with ::
100f3a0208fSAlexander Bulekov
101f3a0208fSAlexander Bulekov    --enable-fuzzing \
102f3a0208fSAlexander Bulekov    --extra-cflags="-fprofile-instr-generate -fcoverage-mapping"
103f3a0208fSAlexander Bulekov
104f3a0208fSAlexander Bulekov 3. Re-run the fuzzer. Specify $CORPUS_DIR/* as an argument, telling libfuzzer
105f3a0208fSAlexander Bulekov    to execute all of the inputs in $CORPUS_DIR and exit. Once the process
106f3a0208fSAlexander Bulekov    exits, you should find a file, "default.profraw" in the working directory.
107f3a0208fSAlexander Bulekov 4. Execute these commands to generate a detailed HTML coverage-report::
108f3a0208fSAlexander Bulekov
109f3a0208fSAlexander Bulekov      llvm-profdata merge -output=default.profdata default.profraw
110f3a0208fSAlexander Bulekov      llvm-cov show ./path/to/qemu-fuzz-i386 -instr-profile=default.profdata \
111f3a0208fSAlexander Bulekov      --format html -output-dir=/path/to/output/report
112f3a0208fSAlexander Bulekov
113f3a0208fSAlexander BulekovAdding a new fuzzer
114f3a0208fSAlexander Bulekov-------------------
115f3a0208fSAlexander Bulekov
116f3a0208fSAlexander BulekovCoverage over virtual devices can be improved by adding additional fuzzers.
117f3a0208fSAlexander BulekovFuzzers are kept in ``tests/qtest/fuzz/`` and should be added to
11892381157SAlexander Bulekov``tests/qtest/fuzz/meson.build``
119f3a0208fSAlexander Bulekov
120f3a0208fSAlexander BulekovFuzzers can rely on both qtest and libqos to communicate with virtual devices.
121f3a0208fSAlexander Bulekov
122f3a0208fSAlexander Bulekov1. Create a new source file. For example ``tests/qtest/fuzz/foo-device-fuzz.c``.
123f3a0208fSAlexander Bulekov
124f3a0208fSAlexander Bulekov2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers
125f3a0208fSAlexander Bulekov   for reference.
126f3a0208fSAlexander Bulekov
12792381157SAlexander Bulekov3. Add the fuzzer to ``tests/qtest/fuzz/meson.build``.
128f3a0208fSAlexander Bulekov
129f3a0208fSAlexander BulekovFuzzers can be more-or-less thought of as special qtest programs which can
130f3a0208fSAlexander Bulekovmodify the qtest commands and/or qtest command arguments based on inputs
131f3a0208fSAlexander Bulekovprovided by libfuzzer. Libfuzzer passes a byte array and length. Commonly the
132f3a0208fSAlexander Bulekovfuzzer loops over the byte-array interpreting it as a list of qtest commands,
133f3a0208fSAlexander Bulekovaddresses, or values.
134f3a0208fSAlexander Bulekov
135f3a0208fSAlexander BulekovThe Generic Fuzzer
136f3a0208fSAlexander Bulekov------------------
137f3a0208fSAlexander Bulekov
138f3a0208fSAlexander BulekovWriting a fuzz target can be a lot of effort (especially if a device driver has
139f3a0208fSAlexander Bulekovnot be built-out within libqos). Many devices can be fuzzed to some degree,
140f3a0208fSAlexander Bulekovwithout any device-specific code, using the generic-fuzz target.
141f3a0208fSAlexander Bulekov
142f3a0208fSAlexander BulekovThe generic-fuzz target is capable of fuzzing devices over their PIO, MMIO,
143f3a0208fSAlexander Bulekovand DMA input-spaces. To apply the generic-fuzz to a device, we need to define
144f3a0208fSAlexander Bulekovtwo env-variables, at minimum:
145f3a0208fSAlexander Bulekov
146f3a0208fSAlexander Bulekov* ``QEMU_FUZZ_ARGS=`` is the set of QEMU arguments used to configure a machine, with
147f3a0208fSAlexander Bulekov  the device attached. For example, if we want to fuzz the virtio-net device
148f3a0208fSAlexander Bulekov  attached to a pc-i440fx machine, we can specify::
149f3a0208fSAlexander Bulekov
150f3a0208fSAlexander Bulekov    QEMU_FUZZ_ARGS="-M pc -nodefaults -netdev user,id=user0 \
151f3a0208fSAlexander Bulekov    -device virtio-net,netdev=user0"
152f3a0208fSAlexander Bulekov
153f3a0208fSAlexander Bulekov* ``QEMU_FUZZ_OBJECTS=`` is a set of space-delimited strings used to identify
154f3a0208fSAlexander Bulekov  the MemoryRegions that will be fuzzed. These strings are compared against
155f3a0208fSAlexander Bulekov  MemoryRegion names and MemoryRegion owner names, to decide whether each
156f3a0208fSAlexander Bulekov  MemoryRegion should be fuzzed. These strings support globbing. For the
157f3a0208fSAlexander Bulekov  virtio-net example, we could use one of ::
158f3a0208fSAlexander Bulekov
159f3a0208fSAlexander Bulekov    QEMU_FUZZ_OBJECTS='virtio-net'
160f3a0208fSAlexander Bulekov    QEMU_FUZZ_OBJECTS='virtio*'
161f3a0208fSAlexander Bulekov    QEMU_FUZZ_OBJECTS='virtio* pcspk' # Fuzz the virtio devices and the speaker
162f3a0208fSAlexander Bulekov    QEMU_FUZZ_OBJECTS='*' # Fuzz the whole machine``
163f3a0208fSAlexander Bulekov
164f3a0208fSAlexander BulekovThe ``"info mtree"`` and ``"info qom-tree"`` monitor commands can be especially
165f3a0208fSAlexander Bulekovuseful for identifying the ``MemoryRegion`` and ``Object`` names used for
166f3a0208fSAlexander Bulekovmatching.
167f3a0208fSAlexander Bulekov
168f3a0208fSAlexander BulekovAs a generic rule-of-thumb, the more ``MemoryRegions``/Devices we match, the
169f3a0208fSAlexander Bulekovgreater the input-space, and the smaller the probability of finding crashing
170f3a0208fSAlexander Bulekovinputs for individual devices. As such, it is usually a good idea to limit the
171f3a0208fSAlexander Bulekovfuzzer to only a few ``MemoryRegions``.
172f3a0208fSAlexander Bulekov
173f3a0208fSAlexander BulekovTo ensure that these env variables have been configured correctly, we can use::
174f3a0208fSAlexander Bulekov
175f3a0208fSAlexander Bulekov    ./qemu-fuzz-i386 --fuzz-target=generic-fuzz -runs=0
176f3a0208fSAlexander Bulekov
177f3a0208fSAlexander BulekovThe output should contain a complete list of matched MemoryRegions.
178f3a0208fSAlexander Bulekov
1793ca45fb4SAlexander BulekovOSS-Fuzz
1803ca45fb4SAlexander Bulekov--------
181450e0f28SJohn SnowQEMU is continuously fuzzed on `OSS-Fuzz
182450e0f28SJohn Snow<https://github.com/google/oss-fuzz>`_.  By default, the OSS-Fuzz build
183450e0f28SJohn Snowwill try to fuzz every fuzz-target. Since the generic-fuzz target
184450e0f28SJohn Snowrequires additional information provided in environment variables, we
185450e0f28SJohn Snowpre-define some generic-fuzz configs in
1863ca45fb4SAlexander Bulekov``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
1873ca45fb4SAlexander Bulekov
1883ca45fb4SAlexander Bulekov- ``.name``: To identify the fuzzer config
1893ca45fb4SAlexander Bulekov
1903ca45fb4SAlexander Bulekov- ``.args`` OR ``.argfunc``: A string or pointer to a function returning a
1913ca45fb4SAlexander Bulekov  string.  These strings are used to specify the ``QEMU_FUZZ_ARGS``
1923ca45fb4SAlexander Bulekov  environment variable.  ``argfunc`` is useful when the config relies on e.g.
1933ca45fb4SAlexander Bulekov  a dynamically created temp directory, or a free tcp/udp port.
1943ca45fb4SAlexander Bulekov
1953ca45fb4SAlexander Bulekov- ``.objects``: A string that specifies the ``QEMU_FUZZ_OBJECTS`` environment
1963ca45fb4SAlexander Bulekov  variable.
1973ca45fb4SAlexander Bulekov
1983ca45fb4SAlexander BulekovTo fuzz additional devices/device configuration on OSS-Fuzz, send patches for
1993ca45fb4SAlexander Bulekoveither a new device-specific fuzzer or a new generic-fuzz config.
2003ca45fb4SAlexander Bulekov
2013ca45fb4SAlexander BulekovBuild details:
2023ca45fb4SAlexander Bulekov
2033ca45fb4SAlexander Bulekov- The Dockerfile that sets up the environment for building QEMU's
2043ca45fb4SAlexander Bulekov  fuzzers on OSS-Fuzz can be fund in the OSS-Fuzz repository
2053ca45fb4SAlexander Bulekov  __(https://github.com/google/oss-fuzz/blob/master/projects/qemu/Dockerfile)
2063ca45fb4SAlexander Bulekov
2073ca45fb4SAlexander Bulekov- The script responsible for building the fuzzers can be found in the
2083ca45fb4SAlexander Bulekov  QEMU source tree at ``scripts/oss-fuzz/build.sh``
2093ca45fb4SAlexander Bulekov
21056f8f888SAlexander BulekovBuilding Crash Reproducers
21156f8f888SAlexander Bulekov-----------------------------------------
21256f8f888SAlexander BulekovWhen we find a crash, we should try to create an independent reproducer, that
21356f8f888SAlexander Bulekovcan be used on a non-fuzzer build of QEMU. This filters out any potential
21456f8f888SAlexander Bulekovfalse-positives, and improves the debugging experience for developers.
21556f8f888SAlexander BulekovHere are the steps for building a reproducer for a crash found by the
21656f8f888SAlexander Bulekovgeneric-fuzz target.
21756f8f888SAlexander Bulekov
21856f8f888SAlexander Bulekov- Ensure the crash reproduces::
21956f8f888SAlexander Bulekov
22056f8f888SAlexander Bulekov    qemu-fuzz-i386 --fuzz-target... ./crash-...
22156f8f888SAlexander Bulekov
22256f8f888SAlexander Bulekov- Gather the QTest output for the crash::
22356f8f888SAlexander Bulekov
22456f8f888SAlexander Bulekov    QEMU_FUZZ_TIMEOUT=0 QTEST_LOG=1 FUZZ_SERIALIZE_QTEST=1 \
22556f8f888SAlexander Bulekov    qemu-fuzz-i386 --fuzz-target... ./crash-... &> /tmp/trace
22656f8f888SAlexander Bulekov
22756f8f888SAlexander Bulekov- Reorder and clean-up the resulting trace::
22856f8f888SAlexander Bulekov
22956f8f888SAlexander Bulekov    scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py /tmp/trace > /tmp/reproducer
23056f8f888SAlexander Bulekov
23156f8f888SAlexander Bulekov- Get the arguments needed to start qemu, and provide a path to qemu::
23256f8f888SAlexander Bulekov
23356f8f888SAlexander Bulekov    less /tmp/trace # The args should be logged at the top of this file
23456f8f888SAlexander Bulekov    export QEMU_ARGS="-machine ..."
23556f8f888SAlexander Bulekov    export QEMU_PATH="path/to/qemu-system"
23656f8f888SAlexander Bulekov
23756f8f888SAlexander Bulekov- Ensure the crash reproduces in qemu-system::
23856f8f888SAlexander Bulekov
23956f8f888SAlexander Bulekov    $QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer
24056f8f888SAlexander Bulekov
24156f8f888SAlexander Bulekov- From the crash output, obtain some string that identifies the crash. This
24256f8f888SAlexander Bulekov  can be a line in the stack-trace, for example::
24356f8f888SAlexander Bulekov
24456f8f888SAlexander Bulekov    export CRASH_TOKEN="hw/usb/hcd-xhci.c:1865"
24556f8f888SAlexander Bulekov
24656f8f888SAlexander Bulekov- Minimize the reproducer::
24756f8f888SAlexander Bulekov
24856f8f888SAlexander Bulekov    scripts/oss-fuzz/minimize_qtest_trace.py -M1 -M2 \
24956f8f888SAlexander Bulekov      /tmp/reproducer /tmp/reproducer-minimized
25056f8f888SAlexander Bulekov
25156f8f888SAlexander Bulekov- Confirm that the minimized reproducer still crashes::
25256f8f888SAlexander Bulekov
25356f8f888SAlexander Bulekov    $QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer-minimized
25456f8f888SAlexander Bulekov
25556f8f888SAlexander Bulekov- Create a one-liner reproducer that can be sent over email::
25656f8f888SAlexander Bulekov
25756f8f888SAlexander Bulekov    ./scripts/oss-fuzz/output_reproducer.py -bash /tmp/reproducer-minimized
25856f8f888SAlexander Bulekov
25956f8f888SAlexander Bulekov- Output the C source code for a test case that will reproduce the bug::
26056f8f888SAlexander Bulekov
26156f8f888SAlexander Bulekov    ./scripts/oss-fuzz/output_reproducer.py -owner "John Smith <john@smith.com>"\
26256f8f888SAlexander Bulekov      -name "test_function_name" /tmp/reproducer-minimized
26356f8f888SAlexander Bulekov
26456f8f888SAlexander Bulekov- Report the bug and send a patch with the C reproducer upstream
26556f8f888SAlexander Bulekov
266f3a0208fSAlexander BulekovImplementation Details / Fuzzer Lifecycle
267f3a0208fSAlexander Bulekov-----------------------------------------
268f3a0208fSAlexander Bulekov
269f3a0208fSAlexander BulekovThe fuzzer has two entrypoints that libfuzzer calls. libfuzzer provides it's
270f3a0208fSAlexander Bulekovown ``main()``, which performs some setup, and calls the entrypoints:
271f3a0208fSAlexander Bulekov
272f3a0208fSAlexander Bulekov``LLVMFuzzerInitialize``: called prior to fuzzing. Used to initialize all of the
273f3a0208fSAlexander Bulekovnecessary state
274f3a0208fSAlexander Bulekov
275f3a0208fSAlexander Bulekov``LLVMFuzzerTestOneInput``: called for each fuzzing run. Processes the input and
276f3a0208fSAlexander Bulekovresets the state at the end of each run.
277f3a0208fSAlexander Bulekov
278f3a0208fSAlexander BulekovIn more detail:
279f3a0208fSAlexander Bulekov
280f3a0208fSAlexander Bulekov``LLVMFuzzerInitialize`` parses the arguments to the fuzzer (must start with two
281f3a0208fSAlexander Bulekovdashes, so they are ignored by libfuzzer ``main()``). Currently, the arguments
282f3a0208fSAlexander Bulekovselect the fuzz target. Then, the qtest client is initialized. If the target
283f3a0208fSAlexander Bulekovrequires qos, qgraph is set up and the QOM/LIBQOS modules are initialized.
284f3a0208fSAlexander BulekovThen the QGraph is walked and the QEMU cmd_line is determined and saved.
285f3a0208fSAlexander Bulekov
286bab6a301SAkihiko OdakiAfter this, the ``vl.c:main`` is called to set up the guest. There are
287bab6a301SAkihiko Odakitarget-specific hooks that can be called before and after main, for
288f3a0208fSAlexander Bulekovadditional setup(e.g. PCI setup, or VM snapshotting).
289f3a0208fSAlexander Bulekov
290f3a0208fSAlexander Bulekov``LLVMFuzzerTestOneInput``: Uses qtest/qos functions to act based on the fuzz
291f3a0208fSAlexander Bulekovinput. It is also responsible for manually calling ``main_loop_wait`` to ensure
292f3a0208fSAlexander Bulekovthat bottom halves are executed and any cleanup required before the next input.
293f3a0208fSAlexander Bulekov
294f3a0208fSAlexander BulekovSince the same process is reused for many fuzzing runs, QEMU state needs to
2957d9e5f18SAlexander Bulekovbe reset at the end of each run. For example, this can be done by rebooting the
2967d9e5f18SAlexander BulekovVM, after each run.
297f3a0208fSAlexander Bulekov
298f3a0208fSAlexander Bulekov  - *Pros*: Straightforward and fast for simple fuzz targets.
299f3a0208fSAlexander Bulekov
300f3a0208fSAlexander Bulekov  - *Cons*: Depending on the device, does not reset all device state. If the
301f3a0208fSAlexander Bulekov    device requires some initialization prior to being ready for fuzzing (common
302f3a0208fSAlexander Bulekov    for QOS-based targets), this initialization needs to be done after each
303f3a0208fSAlexander Bulekov    reboot.
304f3a0208fSAlexander Bulekov
305f3a0208fSAlexander Bulekov  - *Example target*: ``i440fx-qtest-reboot-fuzz``
306