xref: /aosp_15_r20/external/AFLplusplus/include/forkserver.h (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - forkserver header
3    ----------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Forkserver design by Jann Horn <[email protected]>
8 
9    Now maintained by Marc Heuse <[email protected]>,
10                      Heiko Eißfeldt <[email protected]>,
11                      Andrea Fioraldi <[email protected]>,
12                      Dominik Maier <[email protected]>>
13 
14    Copyright 2016, 2017 Google Inc. All rights reserved.
15    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
16 
17    Licensed under the Apache License, Version 2.0 (the "License");
18    you may not use this file except in compliance with the License.
19    You may obtain a copy of the License at:
20 
21      https://www.apache.org/licenses/LICENSE-2.0
22 
23    Shared code that implements a forkserver. This is used by the fuzzer
24    as well the other components like afl-tmin.
25 
26  */
27 
28 #ifndef __AFL_FORKSERVER_H
29 #define __AFL_FORKSERVER_H
30 
31 #include <stdio.h>
32 #include <stdbool.h>
33 
34 #include "types.h"
35 
36 #ifdef __linux__
37 /**
38  * Nyx related typedefs taken from libnyx.h
39  */
40 
41 typedef enum NyxReturnValue {
42 
43   Normal,
44   Crash,
45   Asan,
46   Timeout,
47   InvalidWriteToPayload,
48   Error,
49   IoError,
50   Abort,
51 
52 } NyxReturnValue;
53 
54 typedef enum NyxProcessRole {
55 
56   StandAlone,
57   Parent,
58   Child,
59 
60 } NyxProcessRole;
61 
62 typedef struct {
63 
64   void *(*nyx_config_load)(const char *sharedir);
65   void (*nyx_config_set_workdir_path)(void *config, const char *workdir);
66   void (*nyx_config_set_input_buffer_size)(void    *config,
67                                            uint32_t input_buffer_size);
68   void (*nyx_config_set_input_buffer_write_protection)(
69       void *config, bool input_buffer_write_protection);
70   void (*nyx_config_set_hprintf_fd)(void *config, int32_t hprintf_fd);
71   void (*nyx_config_set_process_role)(void *config, enum NyxProcessRole role);
72   void (*nyx_config_set_reuse_snapshot_path)(void       *config,
73                                              const char *reuse_snapshot_path);
74 
75   void *(*nyx_new)(void *config, uint32_t worker_id);
76   void (*nyx_shutdown)(void *qemu_process);
77   void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable);
78   void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec,
79                                  uint32_t timeout_usec);
80   void (*nyx_option_apply)(void *qemu_process);
81   void (*nyx_set_afl_input)(void *qemu_process, uint8_t *buffer, uint32_t size);
82   enum NyxReturnValue (*nyx_exec)(void *qemu_process);
83   uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process);
84   size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process);
85   uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer,
86                                  uint32_t size);
87 
88   bool (*nyx_remove_work_dir)(const char *workdir);
89   bool (*nyx_config_set_aux_buffer_size)(void    *config,
90                                          uint32_t aux_buffer_size);
91 
92 } nyx_plugin_handler_t;
93 
94 /* Imports helper functions to enable Nyx mode (Linux only )*/
95 nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary);
96 
97 #endif
98 
99 typedef struct afl_forkserver {
100 
101   /* a program that includes afl-forkserver needs to define these */
102 
103   u8 *trace_bits;                       /* SHM with instrumentation bitmap  */
104 
105   s32 fsrv_pid,                         /* PID of the fork server           */
106       child_pid,                        /* PID of the fuzzed program        */
107       child_status,                     /* waitpid result for the child     */
108       out_dir_fd;                       /* FD of the lock file              */
109 
110   s32 out_fd,                           /* Persistent fd for fsrv->out_file */
111       dev_urandom_fd,                   /* Persistent fd for /dev/urandom   */
112 
113       dev_null_fd,                      /* Persistent fd for /dev/null      */
114       fsrv_ctl_fd,                      /* Fork server control pipe (write) */
115       fsrv_st_fd;                       /* Fork server status pipe (read)   */
116 
117   u32 exec_tmout;                       /* Configurable exec timeout (ms)   */
118   u32 init_tmout;                       /* Configurable init timeout (ms)   */
119   u32 map_size;                         /* map size used by the target      */
120   u32 real_map_size;                    /* real map size, unaligned         */
121   u32 snapshot;                         /* is snapshot feature used         */
122   u64 mem_limit;                        /* Memory cap for child (MB)        */
123 
124   u64 total_execs;                      /* How often run_target was called  */
125 
126   u8 *out_file,                         /* File to fuzz, if any             */
127       *target_path;                     /* Path of the target               */
128 
129   FILE *plot_file,                      /* Gnuplot output file              */
130       *det_plot_file;
131 
132   /* Note: last_run_timed_out is u32 to send it to the child as 4 byte array */
133   u32 last_run_timed_out;               /* Traced process timed out?        */
134 
135   u8 last_kill_signal;                  /* Signal that killed the child     */
136 
137   bool use_shmem_fuzz;                  /* use shared mem for test cases    */
138 
139   bool support_shmem_fuzz;              /* set by afl-fuzz                  */
140 
141   bool use_fauxsrv;                     /* Fauxsrv for non-forking targets? */
142 
143   bool qemu_mode;                       /* if running in qemu mode or not   */
144 
145   bool frida_mode;                     /* if running in frida mode or not   */
146 
147   bool frida_asan;                    /* if running with asan in frida mode */
148 
149   bool cs_mode;                      /* if running in CoreSight mode or not */
150 
151   bool use_stdin;                       /* use stdin for sending data       */
152 
153   bool no_unlink;                       /* do not unlink cur_input          */
154 
155   bool uses_asan;                       /* Target uses ASAN?                */
156 
157   bool debug;                           /* debug mode?                      */
158 
159   bool uses_crash_exitcode;             /* Custom crash exitcode specified? */
160   u8   crash_exitcode;                  /* The crash exitcode specified     */
161 
162   u32 *shmem_fuzz_len;                  /* length of the fuzzing test case  */
163 
164   u8 *shmem_fuzz;                       /* allocated memory for fuzzing     */
165 
166   char *cmplog_binary;                  /* the name of the cmplog binary    */
167 
168   /* persistent mode replay functionality */
169   u32 persistent_record;                /* persistent replay setting        */
170 #ifdef AFL_PERSISTENT_RECORD
171   u32  persistent_record_idx;           /* persistent replay cache ptr      */
172   u32  persistent_record_cnt;           /* persistent replay counter        */
173   u8  *persistent_record_dir;
174   u8 **persistent_record_data;
175   u32 *persistent_record_len;
176   s32  persistent_record_pid;
177 #endif
178 
179   /* Function to kick off the forkserver child */
180   void (*init_child_func)(struct afl_forkserver *fsrv, char **argv);
181 
182   u8 *afl_ptr;                          /* for autodictionary: afl ptr      */
183 
184   void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
185 
186   u8 child_kill_signal;
187   u8 fsrv_kill_signal;
188 
189   u8 persistent_mode;
190 
191 #ifdef __linux__
192   nyx_plugin_handler_t *nyx_handlers;
193   char                 *out_dir_path;    /* path to the output directory     */
194   u8                    nyx_mode;        /* if running in nyx mode or not    */
195   bool                  nyx_parent;      /* create initial snapshot          */
196   bool                  nyx_standalone;  /* don't serialize the snapshot     */
197   void                 *nyx_runner;      /* nyx runner object                */
198   u32                   nyx_id;          /* nyx runner id (0 -> master)      */
199   u32                   nyx_bind_cpu_id; /* nyx runner cpu id                */
200   char                 *nyx_aux_string;
201   u32                   nyx_aux_string_len;
202   bool                  nyx_use_tmp_workdir;
203   char                 *nyx_tmp_workdir_path;
204   s32                   nyx_log_fd;
205 #endif
206 
207 } afl_forkserver_t;
208 
209 typedef enum fsrv_run_result {
210 
211   /* 00 */ FSRV_RUN_OK = 0,
212   /* 01 */ FSRV_RUN_TMOUT,
213   /* 02 */ FSRV_RUN_CRASH,
214   /* 03 */ FSRV_RUN_ERROR,
215   /* 04 */ FSRV_RUN_NOINST,
216   /* 05 */ FSRV_RUN_NOBITS,
217 
218 } fsrv_run_result_t;
219 
220 void afl_fsrv_init(afl_forkserver_t *fsrv);
221 void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from);
222 void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
223                     volatile u8 *stop_soon_p, u8 debug_child_output);
224 u32  afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv,
225                           volatile u8 *stop_soon_p, u8 debug_child_output);
226 void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len);
227 fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
228                                       volatile u8 *stop_soon_p);
229 void              afl_fsrv_killall(void);
230 void              afl_fsrv_deinit(afl_forkserver_t *fsrv);
231 void              afl_fsrv_kill(afl_forkserver_t *fsrv);
232 
233 #ifdef __APPLE__
234   #define MSG_FORK_ON_APPLE                                                    \
235     "    - On MacOS X, the semantics of fork() syscalls are non-standard and " \
236     "may\n"                                                                    \
237     "      break afl-fuzz performance optimizations when running "             \
238     "platform-specific\n"                                                      \
239     "      targets. To fix this, set AFL_NO_FORKSRV=1 in the environment.\n\n"
240 #else
241   #define MSG_FORK_ON_APPLE ""
242 #endif
243 
244 #ifdef RLIMIT_AS
245   #define MSG_ULIMIT_USAGE "      ( ulimit -Sv $[%llu << 10];"
246 #else
247   #define MSG_ULIMIT_USAGE "      ( ulimit -Sd $[%llu << 10];"
248 #endif                                                        /* ^RLIMIT_AS */
249 
250 #endif
251 
252