xref: /aosp_15_r20/external/AFLplusplus/docs/best_practices.md (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker# Best practices
2*08b48e0bSAndroid Build Coastguard Worker
3*08b48e0bSAndroid Build Coastguard Worker## Contents
4*08b48e0bSAndroid Build Coastguard Worker
5*08b48e0bSAndroid Build Coastguard Worker### Targets
6*08b48e0bSAndroid Build Coastguard Worker
7*08b48e0bSAndroid Build Coastguard Worker* [Fuzzing a target with source code available](#fuzzing-a-target-with-source-code-available)
8*08b48e0bSAndroid Build Coastguard Worker* [Fuzzing a target with dlopen() instrumented libraries](#fuzzing-a-target-with-dlopen-instrumented-libraries)
9*08b48e0bSAndroid Build Coastguard Worker* [Fuzzing a binary-only target](#fuzzing-a-binary-only-target)
10*08b48e0bSAndroid Build Coastguard Worker* [Fuzzing a GUI program](#fuzzing-a-gui-program)
11*08b48e0bSAndroid Build Coastguard Worker* [Fuzzing a network service](#fuzzing-a-network-service)
12*08b48e0bSAndroid Build Coastguard Worker
13*08b48e0bSAndroid Build Coastguard Worker### Improvements
14*08b48e0bSAndroid Build Coastguard Worker
15*08b48e0bSAndroid Build Coastguard Worker* [Improving speed](#improving-speed)
16*08b48e0bSAndroid Build Coastguard Worker* [Improving stability](#improving-stability)
17*08b48e0bSAndroid Build Coastguard Worker
18*08b48e0bSAndroid Build Coastguard Worker## Targets
19*08b48e0bSAndroid Build Coastguard Worker
20*08b48e0bSAndroid Build Coastguard Worker### Fuzzing a target with source code available
21*08b48e0bSAndroid Build Coastguard Worker
22*08b48e0bSAndroid Build Coastguard WorkerTo learn how to fuzz a target if source code is available, see
23*08b48e0bSAndroid Build Coastguard Worker[fuzzing_in_depth.md](fuzzing_in_depth.md).
24*08b48e0bSAndroid Build Coastguard Worker
25*08b48e0bSAndroid Build Coastguard Worker### Fuzzing a target with dlopen instrumented libraries
26*08b48e0bSAndroid Build Coastguard Worker
27*08b48e0bSAndroid Build Coastguard WorkerIf a source code based fuzzing target loads instrumented libraries with
28*08b48e0bSAndroid Build Coastguard Workerdlopen() after the forkserver has been activated and non-colliding coverage
29*08b48e0bSAndroid Build Coastguard Workerinstrumentation is used (PCGUARD (which is the default), or LTO), then this
30*08b48e0bSAndroid Build Coastguard Workeran issue, because this would enlarge the coverage map, but afl-fuzz doesn't
31*08b48e0bSAndroid Build Coastguard Workerknow about it.
32*08b48e0bSAndroid Build Coastguard Worker
33*08b48e0bSAndroid Build Coastguard WorkerThe solution is to use `AFL_PRELOAD` for all dlopen()'ed libraries to
34*08b48e0bSAndroid Build Coastguard Workerensure that all coverage targets are present on startup in the target,
35*08b48e0bSAndroid Build Coastguard Workereven if accessed only later with dlopen().
36*08b48e0bSAndroid Build Coastguard Worker
37*08b48e0bSAndroid Build Coastguard WorkerFor PCGUARD instrumentation `abort()` is called if this is detected, for LTO
38*08b48e0bSAndroid Build Coastguard Workerthere will either be no coverage for the instrumented dlopen()'ed libraries or
39*08b48e0bSAndroid Build Coastguard Workeryou will see lots of crashes in the UI.
40*08b48e0bSAndroid Build Coastguard Worker
41*08b48e0bSAndroid Build Coastguard WorkerNote that this is not an issue if you use the inferiour `afl-gcc-fast`,
42*08b48e0bSAndroid Build Coastguard Worker`afl-gcc` or`AFL_LLVM_INSTRUMENT=CLASSIC/NGRAM/CTX afl-clang-fast`
43*08b48e0bSAndroid Build Coastguard Workerinstrumentation.
44*08b48e0bSAndroid Build Coastguard Worker
45*08b48e0bSAndroid Build Coastguard Worker### Fuzzing a binary-only target
46*08b48e0bSAndroid Build Coastguard Worker
47*08b48e0bSAndroid Build Coastguard WorkerFor a comprehensive guide, see
48*08b48e0bSAndroid Build Coastguard Worker[fuzzing_binary-only_targets.md](fuzzing_binary-only_targets.md).
49*08b48e0bSAndroid Build Coastguard Worker
50*08b48e0bSAndroid Build Coastguard Worker### Fuzzing a GUI program
51*08b48e0bSAndroid Build Coastguard Worker
52*08b48e0bSAndroid Build Coastguard WorkerIf the GUI program can read the fuzz data from a file (via the command line, a
53*08b48e0bSAndroid Build Coastguard Workerfixed location or via an environment variable) without needing any user
54*08b48e0bSAndroid Build Coastguard Workerinteraction, then it would be suitable for fuzzing.
55*08b48e0bSAndroid Build Coastguard Worker
56*08b48e0bSAndroid Build Coastguard WorkerOtherwise, it is not possible without modifying the source code - which is a
57*08b48e0bSAndroid Build Coastguard Workervery good idea anyway as the GUI functionality is a huge CPU/time overhead for
58*08b48e0bSAndroid Build Coastguard Workerthe fuzzing.
59*08b48e0bSAndroid Build Coastguard Worker
60*08b48e0bSAndroid Build Coastguard WorkerSo create a new `main()` that just reads the test case and calls the
61*08b48e0bSAndroid Build Coastguard Workerfunctionality for processing the input that the GUI program is using.
62*08b48e0bSAndroid Build Coastguard Worker
63*08b48e0bSAndroid Build Coastguard Worker### Fuzzing a network service
64*08b48e0bSAndroid Build Coastguard Worker
65*08b48e0bSAndroid Build Coastguard WorkerFuzzing a network service does not work "out of the box".
66*08b48e0bSAndroid Build Coastguard Worker
67*08b48e0bSAndroid Build Coastguard WorkerUsing a network channel is inadequate for several reasons:
68*08b48e0bSAndroid Build Coastguard Worker- it has a slow-down of x10-20 on the fuzzing speed
69*08b48e0bSAndroid Build Coastguard Worker- it does not scale to fuzzing multiple instances easily,
70*08b48e0bSAndroid Build Coastguard Worker- instead of one initial data packet often a back-and-forth interplay of packets
71*08b48e0bSAndroid Build Coastguard Worker  is needed for stateful protocols (which is totally unsupported by most
72*08b48e0bSAndroid Build Coastguard Worker  coverage aware fuzzers).
73*08b48e0bSAndroid Build Coastguard Worker
74*08b48e0bSAndroid Build Coastguard WorkerThe established method to fuzz network services is to modify the source code to
75*08b48e0bSAndroid Build Coastguard Workerread from a file or stdin (fd 0) (or even faster via shared memory, combine this
76*08b48e0bSAndroid Build Coastguard Workerwith persistent mode
77*08b48e0bSAndroid Build Coastguard Worker[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
78*08b48e0bSAndroid Build Coastguard Workerand you have a performance gain of x10 instead of a performance loss of over x10
79*08b48e0bSAndroid Build Coastguard Worker- that is a x100 difference!).
80*08b48e0bSAndroid Build Coastguard Worker
81*08b48e0bSAndroid Build Coastguard WorkerIf modifying the source is not an option (e.g., because you only have a binary
82*08b48e0bSAndroid Build Coastguard Workerand perform binary fuzzing) you can also use a shared library with AFL_PRELOAD
83*08b48e0bSAndroid Build Coastguard Workerto emulate the network. This is also much faster than the real network would be.
84*08b48e0bSAndroid Build Coastguard WorkerSee [utils/socket_fuzzing/](../utils/socket_fuzzing/).
85*08b48e0bSAndroid Build Coastguard Worker
86*08b48e0bSAndroid Build Coastguard WorkerThere is an outdated AFL++ branch that implements networking if you are
87*08b48e0bSAndroid Build Coastguard Workerdesperate though:
88*08b48e0bSAndroid Build Coastguard Worker[https://github.com/AFLplusplus/AFLplusplus/tree/networking](https://github.com/AFLplusplus/AFLplusplus/tree/networking)
89*08b48e0bSAndroid Build Coastguard Worker- however, a better option is AFLnet
90*08b48e0bSAndroid Build Coastguard Worker([https://github.com/aflnet/aflnet](https://github.com/aflnet/aflnet)) which
91*08b48e0bSAndroid Build Coastguard Workerallows you to define network state with different type of data packets.
92*08b48e0bSAndroid Build Coastguard Worker
93*08b48e0bSAndroid Build Coastguard Worker## Improvements
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker### Improving speed
96*08b48e0bSAndroid Build Coastguard Worker
97*08b48e0bSAndroid Build Coastguard Worker1. Use [llvm_mode](../instrumentation/README.llvm.md): afl-clang-lto (llvm >=
98*08b48e0bSAndroid Build Coastguard Worker   11) or afl-clang-fast (llvm >= 9 recommended).
99*08b48e0bSAndroid Build Coastguard Worker2. Use [persistent mode](../instrumentation/README.persistent_mode.md) (x2-x20
100*08b48e0bSAndroid Build Coastguard Worker   speed increase).
101*08b48e0bSAndroid Build Coastguard Worker3. Instrument just what you are interested in, see
102*08b48e0bSAndroid Build Coastguard Worker   [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
103*08b48e0bSAndroid Build Coastguard Worker4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to put the input
104*08b48e0bSAndroid Build Coastguard Worker   file directory on a tempfs location, see
105*08b48e0bSAndroid Build Coastguard Worker   [env_variables.md](env_variables.md).
106*08b48e0bSAndroid Build Coastguard Worker5. Improve Linux kernel performance: modify `/etc/default/grub`, set
107*08b48e0bSAndroid Build Coastguard Worker   `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off
108*08b48e0bSAndroid Build Coastguard Worker   mitigations=off no_stf_barrier noibpb noibrs nopcid nopti
109*08b48e0bSAndroid Build Coastguard Worker   nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off
110*08b48e0bSAndroid Build Coastguard Worker   spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then
111*08b48e0bSAndroid Build Coastguard Worker   `update-grub` and `reboot` (warning: makes the system less secure).
112*08b48e0bSAndroid Build Coastguard Worker6. Running on an `ext2` filesystem with `noatime` mount option will be a bit
113*08b48e0bSAndroid Build Coastguard Worker   faster than on any other journaling filesystem.
114*08b48e0bSAndroid Build Coastguard Worker7. Use your cores
115*08b48e0bSAndroid Build Coastguard Worker   ([fuzzing_in_depth.md:3c) Using multiple cores](fuzzing_in_depth.md#c-using-multiple-cores))!
116*08b48e0bSAndroid Build Coastguard Worker
117*08b48e0bSAndroid Build Coastguard Worker### Improving stability
118*08b48e0bSAndroid Build Coastguard Worker
119*08b48e0bSAndroid Build Coastguard WorkerFor fuzzing, a 100% stable target that covers all edges is the best case. A 90%
120*08b48e0bSAndroid Build Coastguard Workerstable target that covers all edges is, however, better than a 100% stable
121*08b48e0bSAndroid Build Coastguard Workertarget that ignores 10% of the edges.
122*08b48e0bSAndroid Build Coastguard Worker
123*08b48e0bSAndroid Build Coastguard WorkerWith instability, you basically have a partial coverage loss on an edge, with
124*08b48e0bSAndroid Build Coastguard Workerignored functions you have a full loss on that edges.
125*08b48e0bSAndroid Build Coastguard Worker
126*08b48e0bSAndroid Build Coastguard WorkerThere are functions that are unstable, but also provide value to coverage, e.g.,
127*08b48e0bSAndroid Build Coastguard Workerinit functions that use fuzz data as input. If, however, a function that has
128*08b48e0bSAndroid Build Coastguard Workernothing to do with the input data is the source of instability, e.g., checking
129*08b48e0bSAndroid Build Coastguard Workerjitter, or is a hash map function etc., then it should not be instrumented.
130*08b48e0bSAndroid Build Coastguard Worker
131*08b48e0bSAndroid Build Coastguard WorkerTo be able to exclude these functions (based on AFL++'s measured stability), the
132*08b48e0bSAndroid Build Coastguard Workerfollowing process will allow to identify functions with variable edges.
133*08b48e0bSAndroid Build Coastguard Worker
134*08b48e0bSAndroid Build Coastguard WorkerNote that this is only useful for non-persistent targets!
135*08b48e0bSAndroid Build Coastguard WorkerIf a persistent target is unstable whereas when run non-persistent is fine,
136*08b48e0bSAndroid Build Coastguard Workerthen this means that the target is keeping internal state, which is bad for
137*08b48e0bSAndroid Build Coastguard Workerfuzzing. Fuzz such targets **without** persistent mode.
138*08b48e0bSAndroid Build Coastguard Worker
139*08b48e0bSAndroid Build Coastguard WorkerFour steps are required to do this and it also requires quite some knowledge of
140*08b48e0bSAndroid Build Coastguard Workercoding and/or disassembly and is effectively possible only with `afl-clang-fast`
141*08b48e0bSAndroid Build Coastguard Worker`PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
142*08b48e0bSAndroid Build Coastguard Worker
143*08b48e0bSAndroid Build Coastguard Worker  1. Instrument to be able to find the responsible function(s):
144*08b48e0bSAndroid Build Coastguard Worker
145*08b48e0bSAndroid Build Coastguard Worker     a) For LTO instrumented binaries, this can be documented during compile
146*08b48e0bSAndroid Build Coastguard Worker        time, just set `export AFL_LLVM_DOCUMENT_IDS=/path/to/a/file`. This file
147*08b48e0bSAndroid Build Coastguard Worker        will have one assigned edge ID and the corresponding function per line.
148*08b48e0bSAndroid Build Coastguard Worker
149*08b48e0bSAndroid Build Coastguard Worker     b) For PCGUARD instrumented binaries, it is much more difficult. Here you
150*08b48e0bSAndroid Build Coastguard Worker        can either modify the `__sanitizer_cov_trace_pc_guard` function in
151*08b48e0bSAndroid Build Coastguard Worker        `instrumentation/afl-llvm-rt.o.c` to write a backtrace to a file if the
152*08b48e0bSAndroid Build Coastguard Worker        ID in `__afl_area_ptr[*guard]` is one of the unstable edge IDs. (Example
153*08b48e0bSAndroid Build Coastguard Worker        code is already there). Then recompile and reinstall `llvm_mode` and
154*08b48e0bSAndroid Build Coastguard Worker        rebuild your target. Run the recompiled target with `afl-fuzz` for a
155*08b48e0bSAndroid Build Coastguard Worker        while and then check the file that you wrote with the backtrace
156*08b48e0bSAndroid Build Coastguard Worker        information. Alternatively, you can use `gdb` to hook
157*08b48e0bSAndroid Build Coastguard Worker        `__sanitizer_cov_trace_pc_guard_init` on start, check to which memory
158*08b48e0bSAndroid Build Coastguard Worker        address the edge ID value is written, and set a write breakpoint to that
159*08b48e0bSAndroid Build Coastguard Worker        address (`watch 0x.....`).
160*08b48e0bSAndroid Build Coastguard Worker
161*08b48e0bSAndroid Build Coastguard Worker     c) In other instrumentation types, this is not possible. So just recompile
162*08b48e0bSAndroid Build Coastguard Worker        with the two mentioned above. This is just for identifying the functions
163*08b48e0bSAndroid Build Coastguard Worker        that have unstable edges.
164*08b48e0bSAndroid Build Coastguard Worker
165*08b48e0bSAndroid Build Coastguard Worker  2. Identify which edge ID numbers are unstable.
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker     Run the target with `export AFL_DEBUG=1` for a few minutes then terminate.
168*08b48e0bSAndroid Build Coastguard Worker     The out/fuzzer_stats file will then show the edge IDs that were identified
169*08b48e0bSAndroid Build Coastguard Worker     as unstable in the `var_bytes` entry. You can match these numbers directly
170*08b48e0bSAndroid Build Coastguard Worker     to the data you created in the first step. Now you know which functions are
171*08b48e0bSAndroid Build Coastguard Worker     responsible for the instability
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard Worker  3. Create a text file with the filenames/functions
174*08b48e0bSAndroid Build Coastguard Worker
175*08b48e0bSAndroid Build Coastguard Worker     Identify which source code files contain the functions that you need to
176*08b48e0bSAndroid Build Coastguard Worker     remove from instrumentation, or just specify the functions you want to skip
177*08b48e0bSAndroid Build Coastguard Worker     for instrumentation. Note that optimization might inline functions!
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker     Follow this document on how to do this:
180*08b48e0bSAndroid Build Coastguard Worker     [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
181*08b48e0bSAndroid Build Coastguard Worker
182*08b48e0bSAndroid Build Coastguard Worker     If `PCGUARD` is used, then you need to follow this guide (needs llvm 12+!):
183*08b48e0bSAndroid Build Coastguard Worker     [https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation](https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation)
184*08b48e0bSAndroid Build Coastguard Worker
185*08b48e0bSAndroid Build Coastguard Worker     Only exclude those functions from instrumentation that provide no value for
186*08b48e0bSAndroid Build Coastguard Worker     coverage - that is if it does not process any fuzz data directly or
187*08b48e0bSAndroid Build Coastguard Worker     indirectly (e.g., hash maps, thread management etc.). If, however, a
188*08b48e0bSAndroid Build Coastguard Worker     function directly or indirectly handles fuzz data, then you should not put
189*08b48e0bSAndroid Build Coastguard Worker     the function in a deny instrumentation list and rather live with the
190*08b48e0bSAndroid Build Coastguard Worker     instability it comes with.
191*08b48e0bSAndroid Build Coastguard Worker
192*08b48e0bSAndroid Build Coastguard Worker  4. Recompile the target
193*08b48e0bSAndroid Build Coastguard Worker
194*08b48e0bSAndroid Build Coastguard Worker     Recompile, fuzz it, be happy :)
195*08b48e0bSAndroid Build Coastguard Worker
196*08b48e0bSAndroid Build Coastguard Worker     This link explains this process for
197*08b48e0bSAndroid Build Coastguard Worker     [Fuzzbench](https://github.com/google/fuzzbench/issues/677).
198