xref: /aosp_15_r20/external/AFLplusplus/instrumentation/README.persistent_mode.md (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker# llvm_mode persistent mode
2*08b48e0bSAndroid Build Coastguard Worker
3*08b48e0bSAndroid Build Coastguard Worker## 1) Introduction
4*08b48e0bSAndroid Build Coastguard Worker
5*08b48e0bSAndroid Build Coastguard WorkerIn persistent mode, AFL++ fuzzes a target multiple times in a single forked
6*08b48e0bSAndroid Build Coastguard Workerprocess, instead of forking a new process for each fuzz execution. This is the
7*08b48e0bSAndroid Build Coastguard Workermost effective way to fuzz, as the speed can easily be x10 or x20 times faster
8*08b48e0bSAndroid Build Coastguard Workerwithout any disadvantages. *All professional fuzzing uses this mode.*
9*08b48e0bSAndroid Build Coastguard Worker
10*08b48e0bSAndroid Build Coastguard WorkerPersistent mode requires that the target can be called in one or more functions,
11*08b48e0bSAndroid Build Coastguard Workerand that it's state can be completely reset so that multiple calls can be
12*08b48e0bSAndroid Build Coastguard Workerperformed without resource leaks, and that earlier runs will have no impact on
13*08b48e0bSAndroid Build Coastguard Workerfuture runs. An indicator for this is the `stability` value in the `afl-fuzz`
14*08b48e0bSAndroid Build Coastguard WorkerUI. If this decreases to lower values in persistent mode compared to
15*08b48e0bSAndroid Build Coastguard Workernon-persistent mode, then the fuzz target keeps state.
16*08b48e0bSAndroid Build Coastguard Worker
17*08b48e0bSAndroid Build Coastguard WorkerExamples can be found in [utils/persistent_mode](../utils/persistent_mode).
18*08b48e0bSAndroid Build Coastguard Worker
19*08b48e0bSAndroid Build Coastguard Worker## 2) TL;DR:
20*08b48e0bSAndroid Build Coastguard Worker
21*08b48e0bSAndroid Build Coastguard WorkerExample `fuzz_target.c`:
22*08b48e0bSAndroid Build Coastguard Worker
23*08b48e0bSAndroid Build Coastguard Worker```c
24*08b48e0bSAndroid Build Coastguard Worker#include "what_you_need_for_your_target.h"
25*08b48e0bSAndroid Build Coastguard Worker
26*08b48e0bSAndroid Build Coastguard Worker__AFL_FUZZ_INIT();
27*08b48e0bSAndroid Build Coastguard Worker
28*08b48e0bSAndroid Build Coastguard Workermain() {
29*08b48e0bSAndroid Build Coastguard Worker
30*08b48e0bSAndroid Build Coastguard Worker  // anything else here, e.g. command line arguments, initialization, etc.
31*08b48e0bSAndroid Build Coastguard Worker
32*08b48e0bSAndroid Build Coastguard Worker#ifdef __AFL_HAVE_MANUAL_CONTROL
33*08b48e0bSAndroid Build Coastguard Worker  __AFL_INIT();
34*08b48e0bSAndroid Build Coastguard Worker#endif
35*08b48e0bSAndroid Build Coastguard Worker
36*08b48e0bSAndroid Build Coastguard Worker  unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;  // must be after __AFL_INIT
37*08b48e0bSAndroid Build Coastguard Worker                                                 // and before __AFL_LOOP!
38*08b48e0bSAndroid Build Coastguard Worker
39*08b48e0bSAndroid Build Coastguard Worker  while (__AFL_LOOP(10000)) {
40*08b48e0bSAndroid Build Coastguard Worker
41*08b48e0bSAndroid Build Coastguard Worker    int len = __AFL_FUZZ_TESTCASE_LEN;  // don't use the macro directly in a
42*08b48e0bSAndroid Build Coastguard Worker                                        // call!
43*08b48e0bSAndroid Build Coastguard Worker
44*08b48e0bSAndroid Build Coastguard Worker    if (len < 8) continue;  // check for a required/useful minimum input length
45*08b48e0bSAndroid Build Coastguard Worker
46*08b48e0bSAndroid Build Coastguard Worker    /* Setup function call, e.g. struct target *tmp = libtarget_init() */
47*08b48e0bSAndroid Build Coastguard Worker    /* Call function to be fuzzed, e.g.: */
48*08b48e0bSAndroid Build Coastguard Worker    target_function(buf, len);
49*08b48e0bSAndroid Build Coastguard Worker    /* Reset state. e.g. libtarget_free(tmp) */
50*08b48e0bSAndroid Build Coastguard Worker
51*08b48e0bSAndroid Build Coastguard Worker  }
52*08b48e0bSAndroid Build Coastguard Worker
53*08b48e0bSAndroid Build Coastguard Worker  return 0;
54*08b48e0bSAndroid Build Coastguard Worker
55*08b48e0bSAndroid Build Coastguard Worker}
56*08b48e0bSAndroid Build Coastguard Worker```
57*08b48e0bSAndroid Build Coastguard Worker
58*08b48e0bSAndroid Build Coastguard WorkerAnd then compile:
59*08b48e0bSAndroid Build Coastguard Worker
60*08b48e0bSAndroid Build Coastguard Worker```
61*08b48e0bSAndroid Build Coastguard Workerafl-clang-fast -o fuzz_target fuzz_target.c -lwhat_you_need_for_your_target
62*08b48e0bSAndroid Build Coastguard Worker```
63*08b48e0bSAndroid Build Coastguard Worker
64*08b48e0bSAndroid Build Coastguard WorkerAnd that is it! The speed increase is usually x10 to x20.
65*08b48e0bSAndroid Build Coastguard Worker
66*08b48e0bSAndroid Build Coastguard WorkerIf you want to be able to compile the target without afl-clang-fast/lto, then
67*08b48e0bSAndroid Build Coastguard Workeradd this just after the includes:
68*08b48e0bSAndroid Build Coastguard Worker
69*08b48e0bSAndroid Build Coastguard Worker```c
70*08b48e0bSAndroid Build Coastguard Worker#ifndef __AFL_FUZZ_TESTCASE_LEN
71*08b48e0bSAndroid Build Coastguard Worker  ssize_t fuzz_len;
72*08b48e0bSAndroid Build Coastguard Worker  #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
73*08b48e0bSAndroid Build Coastguard Worker  unsigned char fuzz_buf[1024000];
74*08b48e0bSAndroid Build Coastguard Worker  #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
75*08b48e0bSAndroid Build Coastguard Worker  #define __AFL_FUZZ_INIT() void sync(void);
76*08b48e0bSAndroid Build Coastguard Worker  #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
77*08b48e0bSAndroid Build Coastguard Worker  #define __AFL_INIT() sync()
78*08b48e0bSAndroid Build Coastguard Worker#endif
79*08b48e0bSAndroid Build Coastguard Worker```
80*08b48e0bSAndroid Build Coastguard Worker
81*08b48e0bSAndroid Build Coastguard Worker## 3) Deferred initialization
82*08b48e0bSAndroid Build Coastguard Worker
83*08b48e0bSAndroid Build Coastguard WorkerAFL++ tries to optimize performance by executing the targeted binary just once,
84*08b48e0bSAndroid Build Coastguard Workerstopping it just before `main()`, and then cloning this "main" process to get a
85*08b48e0bSAndroid Build Coastguard Workersteady supply of targets to fuzz.
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard WorkerAlthough this approach eliminates much of the OS-, linker- and libc-level costs
88*08b48e0bSAndroid Build Coastguard Workerof executing the program, it does not always help with binaries that perform
89*08b48e0bSAndroid Build Coastguard Workerother time-consuming initialization steps - say, parsing a large config file
90*08b48e0bSAndroid Build Coastguard Workerbefore getting to the fuzzed data.
91*08b48e0bSAndroid Build Coastguard Worker
92*08b48e0bSAndroid Build Coastguard WorkerIn such cases, it's beneficial to initialize the forkserver a bit later, once
93*08b48e0bSAndroid Build Coastguard Workermost of the initialization work is already done, but before the binary attempts
94*08b48e0bSAndroid Build Coastguard Workerto read the fuzzed input and parse it; in some cases, this can offer a 10x+
95*08b48e0bSAndroid Build Coastguard Workerperformance gain. You can implement delayed initialization in LLVM mode in a
96*08b48e0bSAndroid Build Coastguard Workerfairly simple way.
97*08b48e0bSAndroid Build Coastguard Worker
98*08b48e0bSAndroid Build Coastguard WorkerFirst, find a suitable location in the code where the delayed cloning can take
99*08b48e0bSAndroid Build Coastguard Workerplace. This needs to be done with *extreme* care to avoid breaking the binary.
100*08b48e0bSAndroid Build Coastguard WorkerIn particular, the program will probably malfunction if you select a location
101*08b48e0bSAndroid Build Coastguard Workerafter:
102*08b48e0bSAndroid Build Coastguard Worker
103*08b48e0bSAndroid Build Coastguard Worker- The creation of any vital threads or child processes - since the forkserver
104*08b48e0bSAndroid Build Coastguard Worker  can't clone them easily.
105*08b48e0bSAndroid Build Coastguard Worker
106*08b48e0bSAndroid Build Coastguard Worker- The initialization of timers via `setitimer()` or equivalent calls.
107*08b48e0bSAndroid Build Coastguard Worker
108*08b48e0bSAndroid Build Coastguard Worker- The creation of temporary files, network sockets, offset-sensitive file
109*08b48e0bSAndroid Build Coastguard Worker  descriptors, and similar shared-state resources - but only provided that their
110*08b48e0bSAndroid Build Coastguard Worker  state meaningfully influences the behavior of the program later on.
111*08b48e0bSAndroid Build Coastguard Worker
112*08b48e0bSAndroid Build Coastguard Worker- Any access to the fuzzed input, including reading the metadata about its size.
113*08b48e0bSAndroid Build Coastguard Worker
114*08b48e0bSAndroid Build Coastguard WorkerWith the location selected, add this code in the appropriate spot:
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker```c
117*08b48e0bSAndroid Build Coastguard Worker#ifdef __AFL_HAVE_MANUAL_CONTROL
118*08b48e0bSAndroid Build Coastguard Worker  __AFL_INIT();
119*08b48e0bSAndroid Build Coastguard Worker#endif
120*08b48e0bSAndroid Build Coastguard Worker```
121*08b48e0bSAndroid Build Coastguard Worker
122*08b48e0bSAndroid Build Coastguard WorkerYou don't need the #ifdef guards, but including them ensures that the program
123*08b48e0bSAndroid Build Coastguard Workerwill keep working normally when compiled with a tool other than afl-clang-fast/
124*08b48e0bSAndroid Build Coastguard Workerafl-clang-lto/afl-gcc-fast.
125*08b48e0bSAndroid Build Coastguard Worker
126*08b48e0bSAndroid Build Coastguard WorkerFinally, recompile the program with afl-clang-fast/afl-clang-lto/afl-gcc-fast
127*08b48e0bSAndroid Build Coastguard Worker(afl-gcc or afl-clang will *not* generate a deferred-initialization binary) -
128*08b48e0bSAndroid Build Coastguard Workerand you should be all set!
129*08b48e0bSAndroid Build Coastguard Worker
130*08b48e0bSAndroid Build Coastguard Worker## 4) Persistent mode
131*08b48e0bSAndroid Build Coastguard Worker
132*08b48e0bSAndroid Build Coastguard WorkerSome libraries provide APIs that are stateless, or whose state can be reset in
133*08b48e0bSAndroid Build Coastguard Workerbetween processing different input files. When such a reset is performed, a
134*08b48e0bSAndroid Build Coastguard Workersingle long-lived process can be reused to try out multiple test cases,
135*08b48e0bSAndroid Build Coastguard Workereliminating the need for repeated `fork()` calls and the associated OS overhead.
136*08b48e0bSAndroid Build Coastguard Worker
137*08b48e0bSAndroid Build Coastguard WorkerThe basic structure of the program that does this would be:
138*08b48e0bSAndroid Build Coastguard Worker
139*08b48e0bSAndroid Build Coastguard Worker```c
140*08b48e0bSAndroid Build Coastguard Worker  while (__AFL_LOOP(1000)) {
141*08b48e0bSAndroid Build Coastguard Worker
142*08b48e0bSAndroid Build Coastguard Worker    /* Read input data. */
143*08b48e0bSAndroid Build Coastguard Worker    /* Call library code to be fuzzed. */
144*08b48e0bSAndroid Build Coastguard Worker    /* Reset state. */
145*08b48e0bSAndroid Build Coastguard Worker
146*08b48e0bSAndroid Build Coastguard Worker  }
147*08b48e0bSAndroid Build Coastguard Worker
148*08b48e0bSAndroid Build Coastguard Worker  /* Exit normally. */
149*08b48e0bSAndroid Build Coastguard Worker```
150*08b48e0bSAndroid Build Coastguard Worker
151*08b48e0bSAndroid Build Coastguard WorkerThe numerical value specified within the loop controls the maximum number of
152*08b48e0bSAndroid Build Coastguard Workeriterations before AFL++ will restart the process from scratch. This minimizes
153*08b48e0bSAndroid Build Coastguard Workerthe impact of memory leaks and similar glitches; 1000 is a good starting point,
154*08b48e0bSAndroid Build Coastguard Workerand going much higher increases the likelihood of hiccups without giving you any
155*08b48e0bSAndroid Build Coastguard Workerreal performance benefits.
156*08b48e0bSAndroid Build Coastguard Worker
157*08b48e0bSAndroid Build Coastguard WorkerA more detailed template is shown in
158*08b48e0bSAndroid Build Coastguard Worker[utils/persistent_mode](../utils/persistent_mode). Similarly to the deferred
159*08b48e0bSAndroid Build Coastguard Workerinitialization, the feature works only with afl-clang-fast; `#ifdef` guards can
160*08b48e0bSAndroid Build Coastguard Workerbe used to suppress it when using other compilers.
161*08b48e0bSAndroid Build Coastguard Worker
162*08b48e0bSAndroid Build Coastguard WorkerNote that as with the deferred initialization, the feature is easy to misuse; if
163*08b48e0bSAndroid Build Coastguard Workeryou do not fully reset the critical state, you may end up with false positives
164*08b48e0bSAndroid Build Coastguard Workeror waste a whole lot of CPU power doing nothing useful at all. Be particularly
165*08b48e0bSAndroid Build Coastguard Workerwary of memory leaks and of the state of file descriptors.
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard WorkerWhen running in this mode, the execution paths will inherently vary a bit
168*08b48e0bSAndroid Build Coastguard Workerdepending on whether the input loop is being entered for the first time or
169*08b48e0bSAndroid Build Coastguard Workerexecuted again.
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker## 5) Shared memory fuzzing
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard WorkerYou can speed up the fuzzing process even more by receiving the fuzzing data via
174*08b48e0bSAndroid Build Coastguard Workershared memory instead of stdin or files. This is a further speed multiplier of
175*08b48e0bSAndroid Build Coastguard Workerabout 2x.
176*08b48e0bSAndroid Build Coastguard Worker
177*08b48e0bSAndroid Build Coastguard WorkerSetting this up is very easy:
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard WorkerAfter the includes set the following macro:
180*08b48e0bSAndroid Build Coastguard Worker
181*08b48e0bSAndroid Build Coastguard Worker```c
182*08b48e0bSAndroid Build Coastguard Worker__AFL_FUZZ_INIT();
183*08b48e0bSAndroid Build Coastguard Worker```
184*08b48e0bSAndroid Build Coastguard Worker
185*08b48e0bSAndroid Build Coastguard WorkerDirectly at the start of main - or if you are using the deferred forkserver with
186*08b48e0bSAndroid Build Coastguard Worker`__AFL_INIT()`, then *after* `__AFL_INIT()`:
187*08b48e0bSAndroid Build Coastguard Worker
188*08b48e0bSAndroid Build Coastguard Worker```c
189*08b48e0bSAndroid Build Coastguard Worker  unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
190*08b48e0bSAndroid Build Coastguard Worker```
191*08b48e0bSAndroid Build Coastguard Worker
192*08b48e0bSAndroid Build Coastguard WorkerThen as first line after the `__AFL_LOOP` while loop:
193*08b48e0bSAndroid Build Coastguard Worker
194*08b48e0bSAndroid Build Coastguard Worker```c
195*08b48e0bSAndroid Build Coastguard Worker  int len = __AFL_FUZZ_TESTCASE_LEN;
196*08b48e0bSAndroid Build Coastguard Worker```
197*08b48e0bSAndroid Build Coastguard Worker
198*08b48e0bSAndroid Build Coastguard WorkerAnd that is all!