diff options
Diffstat (limited to 'include/forkserver.h')
-rw-r--r-- | include/forkserver.h | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/include/forkserver.h b/include/forkserver.h new file mode 100644 index 00000000..5b66e7ec --- /dev/null +++ b/include/forkserver.h @@ -0,0 +1,225 @@ +/* + american fuzzy lop++ - forkserver header + ---------------------------------------- + + Originally written by Michal Zalewski + + Forkserver design by Jann Horn <jannhorn@googlemail.com> + + Now maintained by Marc Heuse <mh@mh-sec.de>, + Heiko Eißfeldt <heiko.eissfeldt@hexco.de>, + Andrea Fioraldi <andreafioraldi@gmail.com>, + Dominik Maier <mail@dmnk.co>> + + Copyright 2016, 2017 Google Inc. All rights reserved. + Copyright 2019-2022 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + https://www.apache.org/licenses/LICENSE-2.0 + + Shared code that implements a forkserver. This is used by the fuzzer + as well the other components like afl-tmin. + + */ + +#ifndef __AFL_FORKSERVER_H +#define __AFL_FORKSERVER_H + +#include <stdio.h> +#include <stdbool.h> + +#include "types.h" + +#ifdef __linux__ +/** + * Nyx related typedefs taken from libnyx.h + */ + +typedef enum NyxReturnValue { + + Normal, + Crash, + Asan, + Timout, + InvalidWriteToPayload, + Error, + IoError, + Abort, + +} NyxReturnValue; + +typedef struct { + + void *(*nyx_new)(const char *sharedir, const char *workdir, uint32_t cpu_id, + uint32_t input_buffer_size, + bool input_buffer_write_protection); + void *(*nyx_new_parent)(const char *sharedir, const char *workdir, + uint32_t cpu_id, uint32_t input_buffer_size, + bool input_buffer_write_protection); + void *(*nyx_new_child)(const char *sharedir, const char *workdir, + uint32_t cpu_id, uint32_t worker_id); + void (*nyx_shutdown)(void *qemu_process); + void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable); + void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec, + uint32_t timeout_usec); + void (*nyx_option_apply)(void *qemu_process); + void (*nyx_set_afl_input)(void *qemu_process, uint8_t *buffer, uint32_t size); + enum NyxReturnValue (*nyx_exec)(void *qemu_process); + uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process); + size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process); + uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, + uint32_t size); + +} nyx_plugin_handler_t; + +#endif + +typedef struct afl_forkserver { + + /* a program that includes afl-forkserver needs to define these */ + + u8 *trace_bits; /* SHM with instrumentation bitmap */ + + s32 fsrv_pid, /* PID of the fork server */ + child_pid, /* PID of the fuzzed program */ + child_status, /* waitpid result for the child */ + out_dir_fd; /* FD of the lock file */ + + s32 out_fd, /* Persistent fd for fsrv->out_file */ + dev_urandom_fd, /* Persistent fd for /dev/urandom */ + + dev_null_fd, /* Persistent fd for /dev/null */ + fsrv_ctl_fd, /* Fork server control pipe (write) */ + fsrv_st_fd; /* Fork server status pipe (read) */ + + u32 exec_tmout; /* Configurable exec timeout (ms) */ + u32 init_tmout; /* Configurable init timeout (ms) */ + u32 map_size; /* map size used by the target */ + u32 real_map_size; /* real map size, unaligned */ + u32 snapshot; /* is snapshot feature used */ + u64 mem_limit; /* Memory cap for child (MB) */ + + u64 total_execs; /* How often run_target was called */ + + u8 *out_file, /* File to fuzz, if any */ + *target_path; /* Path of the target */ + + FILE *plot_file; /* Gnuplot output file */ + + /* Note: last_run_timed_out is u32 to send it to the child as 4 byte array */ + u32 last_run_timed_out; /* Traced process timed out? */ + + u8 last_kill_signal; /* Signal that killed the child */ + + bool use_shmem_fuzz; /* use shared mem for test cases */ + + bool support_shmem_fuzz; /* set by afl-fuzz */ + + bool use_fauxsrv; /* Fauxsrv for non-forking targets? */ + + bool qemu_mode; /* if running in qemu mode or not */ + + bool frida_mode; /* if running in frida mode or not */ + + bool frida_asan; /* if running with asan in frida mode */ + + bool cs_mode; /* if running in CoreSight mode or not */ + + bool use_stdin; /* use stdin for sending data */ + + bool no_unlink; /* do not unlink cur_input */ + + bool uses_asan; /* Target uses ASAN? */ + + bool debug; /* debug mode? */ + + bool uses_crash_exitcode; /* Custom crash exitcode specified? */ + u8 crash_exitcode; /* The crash exitcode specified */ + + u32 *shmem_fuzz_len; /* length of the fuzzing test case */ + + u8 *shmem_fuzz; /* allocated memory for fuzzing */ + + char *cmplog_binary; /* the name of the cmplog binary */ + + /* persistent mode replay functionality */ + u32 persistent_record; /* persistent replay setting */ +#ifdef AFL_PERSISTENT_RECORD + u32 persistent_record_idx; /* persistent replay cache ptr */ + u32 persistent_record_cnt; /* persistent replay counter */ + u8 * persistent_record_dir; + u8 **persistent_record_data; + u32 *persistent_record_len; + s32 persistent_record_pid; +#endif + + /* Function to kick off the forkserver child */ + void (*init_child_func)(struct afl_forkserver *fsrv, char **argv); + + u8 *afl_ptr; /* for autodictionary: afl ptr */ + + void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len); + + u8 kill_signal; + u8 persistent_mode; + +#ifdef __linux__ + nyx_plugin_handler_t *nyx_handlers; + char * out_dir_path; /* path to the output directory */ + u8 nyx_mode; /* if running in nyx mode or not */ + bool nyx_parent; /* create initial snapshot */ + bool nyx_standalone; /* don't serialize the snapshot */ + void * nyx_runner; /* nyx runner object */ + u32 nyx_id; /* nyx runner id (0 -> master) */ + u32 nyx_bind_cpu_id; /* nyx runner cpu id */ + char * nyx_aux_string; +#endif + +} afl_forkserver_t; + +typedef enum fsrv_run_result { + + /* 00 */ FSRV_RUN_OK = 0, + /* 01 */ FSRV_RUN_TMOUT, + /* 02 */ FSRV_RUN_CRASH, + /* 03 */ FSRV_RUN_ERROR, + /* 04 */ FSRV_RUN_NOINST, + /* 05 */ FSRV_RUN_NOBITS, + +} fsrv_run_result_t; + +void afl_fsrv_init(afl_forkserver_t *fsrv); +void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from); +void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, + volatile u8 *stop_soon_p, u8 debug_child_output); +u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, + volatile u8 *stop_soon_p, u8 debug_child_output); +void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len); +fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, + volatile u8 *stop_soon_p); +void afl_fsrv_killall(void); +void afl_fsrv_deinit(afl_forkserver_t *fsrv); +void afl_fsrv_kill(afl_forkserver_t *fsrv); + +#ifdef __APPLE__ + #define MSG_FORK_ON_APPLE \ + " - On MacOS X, the semantics of fork() syscalls are non-standard and " \ + "may\n" \ + " break afl-fuzz performance optimizations when running " \ + "platform-specific\n" \ + " targets. To fix this, set AFL_NO_FORKSRV=1 in the environment.\n\n" +#else + #define MSG_FORK_ON_APPLE "" +#endif + +#ifdef RLIMIT_AS + #define MSG_ULIMIT_USAGE " ( ulimit -Sv $[%llu << 10];" +#else + #define MSG_ULIMIT_USAGE " ( ulimit -Sd $[%llu << 10];" +#endif /* ^RLIMIT_AS */ + +#endif + |