xref: /aosp_15_r20/external/AFLplusplus/utils/persistent_mode/persistent_demo.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - persistent mode example
3    --------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Copyright 2015 Google Inc. All rights reserved.
8 
9    Licensed under the Apache License, Version 2.0 (the "License");
10    you may not use this file except in compliance with the License.
11    You may obtain a copy of the License at:
12 
13      http://www.apache.org/licenses/LICENSE-2.0
14 
15    This file demonstrates the high-performance "persistent mode" that may be
16    suitable for fuzzing certain fast and well-behaved libraries, provided that
17    they are stateless or that their internal state can be easily reset
18    across runs.
19 
20    To make this work, the library and this shim need to be compiled in LLVM
21    mode using afl-clang-fast (other compiler wrappers will *not* work).
22 
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <limits.h>
31 
32 /* Main entry point. */
33 
34 /* To ensure checks are not optimized out it is recommended to disable
35    code optimization for the fuzzer harness main() */
36 #pragma clang optimize off
37 #pragma GCC            optimize("O0")
38 
main(int argc,char ** argv)39 int main(int argc, char **argv) {
40 
41   ssize_t len;                               /* how much input did we read? */
42   char buf[100]; /* Example-only buffer, you'd replace it with other global or
43                     local variables appropriate for your use case. */
44 
45   /* The number passed to __AFL_LOOP() controls the maximum number of
46      iterations before the loop exits and the program is allowed to
47      terminate normally. This limits the impact of accidental memory leaks
48      and similar hiccups. */
49 
50   __AFL_INIT();
51   while (__AFL_LOOP(UINT_MAX)) {
52 
53     /*** PLACEHOLDER CODE ***/
54 
55     /* STEP 1: Fully re-initialize all critical variables. In our example, this
56                involves zeroing buf[], our input buffer. */
57 
58     memset(buf, 0, 100);
59 
60     /* STEP 2: Read input data. When reading from stdin, no special preparation
61                is required. When reading from a named file, you need to close
62                the old descriptor and reopen the file first!
63 
64                Beware of reading from buffered FILE* objects such as stdin. Use
65                raw file descriptors or call fopen() / fdopen() in every pass. */
66 
67     len = read(0, buf, 100);
68 
69     /* STEP 3: This is where we'd call the tested library on the read data.
70                We just have some trivial inline code that faults on 'foo!'. */
71 
72     /* do we have enough data? */
73     if (len < 8) continue;
74 
75     if (buf[0] == 'f') {
76 
77       printf("one\n");
78       if (buf[1] == 'o') {
79 
80         printf("two\n");
81         if (buf[2] == 'o') {
82 
83           printf("three\n");
84           if (buf[3] == '!') {
85 
86             printf("four\n");
87             if (buf[4] == '!') {
88 
89               printf("five\n");
90               if (buf[5] == '!') {
91 
92                 printf("six\n");
93                 abort();
94 
95               }
96 
97             }
98 
99           }
100 
101         }
102 
103       }
104 
105     }
106 
107     /*** END PLACEHOLDER CODE ***/
108 
109   }
110 
111   /* Once the loop is exited, terminate normally - AFL will restart the process
112      when this happens, with a clean slate when it comes to allocated memory,
113      leftover file descriptors, etc. */
114 
115   return 0;
116 
117 }
118 
119