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