aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDominik Maier <domenukk@gmail.com>2020-03-09 11:24:10 +0100
committerGitHub <noreply@github.com>2020-03-09 11:24:10 +0100
commitdba3595c0ae26795a78753ea33ff0c3edf9d6328 (patch)
tree03bcaf132705d6de222ef8d6eff9b5bc2f03ce54 /include
parentc159b872ef17d4c09238f99ac11021e12975cb3a (diff)
downloadafl++-dba3595c0ae26795a78753ea33ff0c3edf9d6328.tar.gz
AFL without globals (#220)
* moved globals to afl, shm and fsrv * moved argv to afl state, less bugs * fixed unicorn docu * lists everywhere * merged custom mutators * fixed leaks in afl-fuzz
Diffstat (limited to 'include')
-rw-r--r--include/afl-fuzz.h761
-rw-r--r--include/afl-prealloc.h101
-rw-r--r--include/common.h11
-rw-r--r--include/forkserver.h41
-rw-r--r--include/list.h133
-rw-r--r--include/sharedmem.h29
6 files changed, 694 insertions, 382 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index d5ad4653..c773d085 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -46,6 +46,7 @@
#include "sharedmem.h"
#include "forkserver.h"
#include "common.h"
+#include "list.h"
#include <stdio.h>
#include <unistd.h>
@@ -106,6 +107,11 @@
#define CASE_PREFIX "id_"
#endif /* ^!SIMPLE_FILES */
+extern s8 interesting_8[INTERESTING_8_LEN];
+extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN];
+extern s32 interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN];
+
+
struct queue_entry {
u8* fname; /* File name for the test case */
@@ -198,45 +204,10 @@ enum {
};
-/* MOpt:
- Lots of globals, but mostly for the status UI and other things where it
- really makes no sense to haul them around as function parameters. */
-extern u64 limit_time_puppet, orig_hit_cnt_puppet, last_limit_time_start,
- tmp_pilot_time, total_pacemaker_time, total_puppet_find, temp_puppet_find,
- most_time_key, most_time, most_execs_key, most_execs, old_hit_count;
-
-extern s32 SPLICE_CYCLES_puppet, limit_time_sig, key_puppet, key_module;
-
-extern double w_init, w_end, w_now;
-
-extern s32 g_now;
-extern s32 g_max;
-
#define operator_num 16
#define swarm_num 5
#define period_core 500000
-extern u64 tmp_core_time;
-extern s32 swarm_now;
-
-extern double x_now[swarm_num][operator_num], L_best[swarm_num][operator_num],
- eff_best[swarm_num][operator_num], G_best[operator_num],
- v_now[swarm_num][operator_num], probability_now[swarm_num][operator_num],
- swarm_fitness[swarm_num];
-
-extern u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per
- fuzz stage */
- stage_finds_puppet_v2[swarm_num][operator_num],
- stage_cycles_puppet_v2[swarm_num][operator_num],
- stage_cycles_puppet_v3[swarm_num][operator_num],
- stage_cycles_puppet[swarm_num][operator_num],
- operator_finds_puppet[operator_num],
- core_operator_finds_puppet[operator_num],
- core_operator_finds_puppet_v2[operator_num],
- core_operator_cycles_puppet[operator_num],
- core_operator_cycles_puppet_v2[operator_num],
- core_operator_cycles_puppet_v3[operator_num]; /* Execs per fuzz stage */
-
#define RAND_C (rand() % 1000 * 0.001)
#define v_max 1
#define v_min 0.05
@@ -249,37 +220,6 @@ extern u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per
#define STAGE_OverWrite75 15
#define period_pilot 50000
-extern double period_pilot_tmp;
-extern s32 key_lv;
-
-extern u8 *in_dir, /* Input directory with test cases */
- *out_dir, /* Working & output directory */
- *tmp_dir, /* Temporary directory for input */
- *sync_dir, /* Synchronization directory */
- *sync_id, /* Fuzzer ID */
- *power_name, /* Power schedule name */
- *use_banner, /* Display banner */
- *in_bitmap, /* Input bitmap */
- *file_extension, /* File extension */
- *orig_cmdline, /* Original command line */
- *doc_path, /* Path to documentation dir */
- *infoexec, /* Command to execute on a new crash */
- *out_file; /* File to fuzz, if any */
-
-extern u32 exec_tmout; /* Configurable exec timeout (ms) */
-extern u32 hang_tmout; /* Timeout used for hang det (ms) */
-
-extern u64 mem_limit; /* Memory cap for child (MB) */
-
-extern u8 cal_cycles, /* Calibration cycles defaults */
- cal_cycles_long, /* Calibration cycles defaults */
- no_unlink, /* do not unlink cur_input */
- use_stdin, /* use stdin for sending data */
- debug, /* Debug mode */
- custom_only; /* Custom mutator only mode */
-
-extern u32 stats_update_freq; /* Stats update frequency (execs) */
-
enum {
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
@@ -293,172 +233,316 @@ enum {
};
-extern char* power_names[POWER_SCHEDULES_NUM];
+extern u8 *doc_path; /* gath to documentation dir */
+
+/* Python stuff */
+#ifdef USE_PYTHON
-extern u8 schedule; /* Power schedule (default: EXPLORE)*/
-extern u8 havoc_max_mult;
-
-extern u8 use_radamsa;
-extern size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32);
-
-extern u8 skip_deterministic, /* Skip deterministic stages? */
- force_deterministic, /* Force deterministic stages? */
- use_splicing, /* Recombine input files? */
- dumb_mode, /* Run in non-instrumented mode? */
- score_changed, /* Scoring for favorites changed? */
- kill_signal, /* Signal that killed the child */
- resuming_fuzz, /* Resuming an older fuzzing job? */
- timeout_given, /* Specific timeout given? */
- not_on_tty, /* stdout is not a tty */
- term_too_small, /* terminal dimensions too small */
- no_forkserver, /* Disable forkserver? */
- crash_mode, /* Crash mode! Yeah! */
- in_place_resume, /* Attempt in-place resume? */
- autoresume, /* Resume if out_dir exists? */
- auto_changed, /* Auto-generated tokens changed? */
- no_cpu_meter_red, /* Feng shui on the status screen */
- no_arith, /* Skip most arithmetic ops */
- shuffle_queue, /* Shuffle input queue? */
- bitmap_changed, /* Time to update bitmap? */
- qemu_mode, /* Running in QEMU mode? */
- unicorn_mode, /* Running in Unicorn mode? */
- use_wine, /* Use WINE with QEMU mode */
- skip_requested, /* Skip request, via SIGUSR1 */
- run_over10m, /* Run time over 10 minutes? */
- persistent_mode, /* Running in persistent mode? */
- deferred_mode, /* Deferred forkserver mode? */
- fixed_seed, /* do not reseed */
- fast_cal, /* Try to calibrate faster? */
- uses_asan, /* Target uses ASAN? */
- disable_trim; /* Never trim in fuzz_one */
-
-extern s32 out_fd, /* Persistent fd for out_file */
-#ifndef HAVE_ARC4RANDOM
- dev_urandom_fd, /* Persistent fd for /dev/urandom */
+// because Python sets stuff it should not ...
+#ifdef _POSIX_C_SOURCE
+#define _SAVE_POSIX_C_SOURCE _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
#endif
- dev_null_fd, /* Persistent fd for /dev/null */
- fsrv_ctl_fd, /* Fork server control pipe (write) */
- fsrv_st_fd; /* Fork server status pipe (read) */
-
-extern s32 forksrv_pid, /* PID of the fork server */
- child_pid, /* PID of the fuzzed program */
- out_dir_fd; /* FD of the lock file */
-
-extern u8* trace_bits; /* SHM with instrumentation bitmap */
-
-extern u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
- virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */
- virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */
-
-extern u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
-
-extern volatile u8 stop_soon, /* Ctrl-C pressed? */
- clear_screen, /* Window resized? */
- child_timed_out; /* Traced process timed out? */
-
-extern u32 queued_paths, /* Total number of queued testcases */
- queued_variable, /* Testcases with variable behavior */
- queued_at_start, /* Total number of initial inputs */
- queued_discovered, /* Items discovered during this run */
- queued_imported, /* Items imported via -S */
- queued_favored, /* Paths deemed favorable */
- queued_with_cov, /* Paths with new coverage bytes */
- pending_not_fuzzed, /* Queued but not done yet */
- pending_favored, /* Pending favored paths */
- cur_skipped_paths, /* Abandoned inputs in cur cycle */
- cur_depth, /* Current path depth */
- max_depth, /* Max path depth */
- useless_at_start, /* Number of useless starting paths */
- var_byte_count, /* Bitmap bytes with var behavior */
- current_entry, /* Current queue entry ID */
- havoc_div; /* Cycle count divisor for havoc */
-
-extern u64 total_crashes, /* Total number of crashes */
- unique_crashes, /* Crashes with unique signatures */
- total_tmouts, /* Total number of timeouts */
- unique_tmouts, /* Timeouts with unique signatures */
- unique_hangs, /* Hangs with unique signatures */
- total_execs, /* Total execve() calls */
- slowest_exec_ms, /* Slowest testcase non hang in ms */
- start_time, /* Unix start time (ms) */
- last_path_time, /* Time for most recent path (ms) */
- last_crash_time, /* Time for most recent crash (ms) */
- last_hang_time, /* Time for most recent hang (ms) */
- last_crash_execs, /* Exec counter at last crash */
- queue_cycle, /* Queue round counter */
- cycles_wo_finds, /* Cycles without any new paths */
- trim_execs, /* Execs done to trim input files */
- bytes_trim_in, /* Bytes coming into the trimmer */
- bytes_trim_out, /* Bytes coming outa the trimmer */
- blocks_eff_total, /* Blocks subject to effector maps */
- blocks_eff_select; /* Blocks selected as fuzzable */
-
-extern u32 subseq_tmouts; /* Number of timeouts in a row */
-
-extern u8 *stage_name, /* Name of the current fuzz stage */
- *stage_short, /* Short stage name */
- *syncing_party; /* Currently syncing with... */
-
-extern s32 stage_cur, stage_max; /* Stage progression */
-extern s32 splicing_with; /* Splicing with which test case? */
-
-extern u32 master_id, master_max; /* Master instance job splitting */
-
-extern u32 syncing_case; /* Syncing with case #... */
-
-extern s32 stage_cur_byte, /* Byte offset of current stage op */
- stage_cur_val; /* Value used for stage op */
-
-extern u8 stage_val_type; /* Value type (STAGE_VAL_*) */
-
-extern u64 stage_finds[32], /* Patterns found per fuzz stage */
- stage_cycles[32]; /* Execs per fuzz stage */
-
-#ifndef HAVE_ARC4RANDOM
-extern u32 rand_cnt; /* Random number counter */
+#ifdef _XOPEN_SOURCE
+#define _SAVE_XOPEN_SOURCE _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
#endif
-extern u32 rand_seed[2];
-extern s64 init_seed;
+#include <Python.h>
-extern u64 total_cal_us, /* Total calibration time (us) */
- total_cal_cycles; /* Total calibration cycles */
+#ifdef _SAVE_POSIX_C_SOURCE
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+#define _POSIX_C_SOURCE _SAVE_POSIX_C_SOURCE
+#endif
+#ifdef _SAVE_XOPEN_SOURCE
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE
+#endif
-extern u64 total_bitmap_size, /* Total bit count for all bitmaps */
- total_bitmap_entries; /* Number of bitmaps counted */
-extern s32 cpu_core_count; /* CPU core count */
+enum {
+
+ /* 00 */ PY_FUNC_INIT,
+ /* 01 */ PY_FUNC_FUZZ,
+ /* 02 */ PY_FUNC_PRE_SAVE,
+ /* 03 */ PY_FUNC_INIT_TRIM,
+ /* 04 */ PY_FUNC_POST_TRIM,
+ /* 05 */ PY_FUNC_TRIM,
+ /* 06 */ PY_FUNC_HAVOC_MUTATION,
+ /* 07 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY,
+ /* 08 */ PY_FUNC_QUEUE_GET,
+ /* 09 */ PY_FUNC_QUEUE_NEW_ENTRY,
+ PY_FUNC_COUNT
+
+};
+
+#endif
+
+typedef struct MOpt_globals {
+
+ u64* finds;
+ u64* finds_v2;
+ u64* cycles;
+ u64* cycles_v2;
+ u64* cycles_v3;
+ u32 is_pilot_mode;
+ u64* pTime;
+ u64 period;
+ char* havoc_stagename;
+ char* splice_stageformat;
+ char* havoc_stagenameshort;
+ char* splice_stagenameshort;
+
+} MOpt_globals_t;
+
+extern char* power_names[POWER_SCHEDULES_NUM];
+
+typedef struct afl_state {
+
+ /* Position of this state in the global states list */
+ u32 _id;
+
+ afl_forkserver_t fsrv;
+ sharedmem_t shm;
+
+ char** argv; /* argv if needed */
+
+ /* MOpt:
+ Lots of globals, but mostly for the status UI and other things where it
+ really makes no sense to haul them around as function parameters. */
+ u64 limit_time_puppet, orig_hit_cnt_puppet, last_limit_time_start,
+ tmp_pilot_time, total_pacemaker_time, total_puppet_find, temp_puppet_find,
+ most_time_key, most_time, most_execs_key, most_execs, old_hit_count;
+
+ MOpt_globals_t mopt_globals_core, mopt_globals_pilot;
+
+ s32 SPLICE_CYCLES_puppet, limit_time_sig, key_puppet, key_module;
+
+ double w_init, w_end, w_now;
+
+ s32 g_now;
+ s32 g_max;
+
+ u64 tmp_core_time;
+ s32 swarm_now;
+
+ double x_now[swarm_num][operator_num], L_best[swarm_num][operator_num],
+ eff_best[swarm_num][operator_num], G_best[operator_num],
+ v_now[swarm_num][operator_num], probability_now[swarm_num][operator_num],
+ swarm_fitness[swarm_num];
+
+ u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per
+ fuzz stage */
+ stage_finds_puppet_v2[swarm_num][operator_num],
+ stage_cycles_puppet_v2[swarm_num][operator_num],
+ stage_cycles_puppet_v3[swarm_num][operator_num],
+ stage_cycles_puppet[swarm_num][operator_num],
+ operator_finds_puppet[operator_num],
+ core_operator_finds_puppet[operator_num],
+ core_operator_finds_puppet_v2[operator_num],
+ core_operator_cycles_puppet[operator_num],
+ core_operator_cycles_puppet_v2[operator_num],
+ core_operator_cycles_puppet_v3[operator_num]; /* Execs per fuzz stage */
+
+ double period_pilot_tmp;
+ s32 key_lv;
+
+ u8 *in_dir, /* Input directory with test cases */
+ *out_dir, /* Working & output directory */
+ *tmp_dir, /* Temporary directory for input */
+ *sync_dir, /* Synchronization directory */
+ *sync_id, /* Fuzzer ID */
+ *power_name, /* Power schedule name */
+ *use_banner, /* Display banner */
+ *in_bitmap, /* Input bitmap */
+ *file_extension, /* File extension */
+ *orig_cmdline, /* Original command line */
+ *infoexec; /* Command to execute on a new crash */
+
+ u32 hang_tmout; /* Timeout used for hang det (ms) */
+
+ u8 cal_cycles, /* Calibration cycles defaults */
+ cal_cycles_long, /* Calibration cycles defaults */
+ no_unlink, /* do not unlink cur_input */
+ debug, /* Debug mode */
+ custom_only, /* Custom mutator only mode */
+ python_only; /* Python-only mode */
+
+ u32 stats_update_freq; /* Stats update frequency (execs) */
+
+ u8 schedule; /* Power schedule (default: EXPLORE)*/
+ u8 havoc_max_mult;
+
+ u8 use_radamsa;
+ size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32);
+
+ u8 skip_deterministic, /* Skip deterministic stages? */
+ force_deterministic, /* Force deterministic stages? */
+ use_splicing, /* Recombine input files? */
+ dumb_mode, /* Run in non-instrumented mode? */
+ score_changed, /* Scoring for favorites changed? */
+ kill_signal, /* Signal that killed the child */
+ resuming_fuzz, /* Resuming an older fuzzing job? */
+ timeout_given, /* Specific timeout given? */
+ not_on_tty, /* stdout is not a tty */
+ term_too_small, /* terminal dimensions too small */
+ no_forkserver, /* Disable forkserver? */
+ crash_mode, /* Crash mode! Yeah! */
+ in_place_resume, /* Attempt in-place resume? */
+ autoresume, /* Resume if afl->out_dir exists? */
+ auto_changed, /* Auto-generated tokens changed? */
+ no_cpu_meter_red, /* Feng shui on the status screen */
+ no_arith, /* Skip most arithmetic ops */
+ shuffle_queue, /* Shuffle input queue? */
+ bitmap_changed, /* Time to update bitmap? */
+ qemu_mode, /* Running in QEMU mode? */
+ unicorn_mode, /* Running in Unicorn mode? */
+ use_wine, /* Use WINE with QEMU mode */
+ skip_requested, /* Skip request, via SIGUSR1 */
+ run_over10m, /* Run time over 10 minutes? */
+ persistent_mode, /* Running in persistent mode? */
+ deferred_mode, /* Deferred forkserver mode? */
+ fixed_seed, /* do not reseed */
+ fast_cal, /* Try to calibrate faster? */
+ disable_trim; /* Never trim in fuzz_one */
+
+ u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
+ virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */
+ virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */
+
+ u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
+
+ volatile u8 stop_soon, /* Ctrl-C pressed? */
+ clear_screen; /* Window resized? */
+
+ u32 queued_paths, /* Total number of queued testcases */
+ queued_variable, /* Testcases with variable behavior */
+ queued_at_start, /* Total number of initial inputs */
+ queued_discovered, /* Items discovered during this run */
+ queued_imported, /* Items imported via -S */
+ queued_favored, /* Paths deemed favorable */
+ queued_with_cov, /* Paths with new coverage bytes */
+ pending_not_fuzzed, /* Queued but not done yet */
+ pending_favored, /* Pending favored paths */
+ cur_skipped_paths, /* Abandoned inputs in cur cycle */
+ cur_depth, /* Current path depth */
+ max_depth, /* Max path depth */
+ useless_at_start, /* Number of useless starting paths */
+ var_byte_count, /* Bitmap bytes with var behavior */
+ current_entry, /* Current queue entry ID */
+ havoc_div; /* Cycle count divisor for havoc */
+
+ u64 total_crashes, /* Total number of crashes */
+ unique_crashes, /* Crashes with unique signatures */
+ total_tmouts, /* Total number of timeouts */
+ unique_tmouts, /* Timeouts with unique signatures */
+ unique_hangs, /* Hangs with unique signatures */
+ total_execs, /* Total execve() calls */
+ slowest_exec_ms, /* Slowest testcase non hang in ms */
+ start_time, /* Unix start time (ms) */
+ last_path_time, /* Time for most recent path (ms) */
+ last_crash_time, /* Time for most recent crash (ms) */
+ last_hang_time, /* Time for most recent hang (ms) */
+ last_crash_execs, /* Exec counter at last crash */
+ queue_cycle, /* Queue round counter */
+ cycles_wo_finds, /* Cycles without any new paths */
+ trim_execs, /* Execs done to trim input files */
+ bytes_trim_in, /* Bytes coming into the trimmer */
+ bytes_trim_out, /* Bytes coming outa the trimmer */
+ blocks_eff_total, /* Blocks subject to effector maps */
+ blocks_eff_select; /* Blocks selected as fuzzable */
+
+ u32 subseq_tmouts; /* Number of timeouts in a row */
+
+ u8 *stage_name, /* Name of the current fuzz stage */
+ *stage_short, /* Short stage name */
+ *syncing_party; /* Currently syncing with... */
+
+ u8 stage_name_buf64[64]; /* A name buf with len 64 if needed */
+
+ s32 stage_cur, stage_max; /* Stage progression */
+ s32 splicing_with; /* Splicing with which test case? */
+
+ u32 master_id, master_max; /* Master instance job splitting */
+
+ u32 syncing_case; /* Syncing with case #... */
+
+ s32 stage_cur_byte, /* Byte offset of current stage op */
+ stage_cur_val; /* Value used for stage op */
+
+ u8 stage_val_type; /* Value type (STAGE_VAL_*) */
+
+ u64 stage_finds[32], /* Patterns found per fuzz stage */
+ stage_cycles[32]; /* Execs per fuzz stage */
+
+ #ifndef HAVE_ARC4RANDOM
+ u32 rand_cnt; /* Random number counter */
+ #endif
+
+ u32 rand_seed[2];
+ s64 init_seed;
+
+ u64 total_cal_us, /* Total calibration time (us) */
+ total_cal_cycles; /* Total calibration cycles */
+
+ u64 total_bitmap_size, /* Total bit count for all bitmaps */
+ total_bitmap_entries; /* Number of bitmaps counted */
+
+ s32 cpu_core_count; /* CPU core count */
#ifdef HAVE_AFFINITY
+ s32 cpu_aff; /* Selected CPU core */
+#endif /* HAVE_AFFINITY */
-extern s32 cpu_aff; /* Selected CPU core */
+ struct queue_entry *queue, /* Fuzzing queue (linked list) */
+ *queue_cur, /* Current offset within the queue */
+ *queue_top, /* Top of the list */
+ *q_prev100; /* Previous 100 marker */
-#endif /* HAVE_AFFINITY */
+ struct queue_entry*
+ top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
-extern FILE* plot_file; /* Gnuplot output file */
+ struct extra_data* extras; /* Extra tokens to fuzz with */
+ u32 extras_cnt; /* Total number of tokens read */
-extern struct queue_entry *queue, /* Fuzzing queue (linked list) */
- *queue_cur, /* Current offset within the queue */
- *queue_top, /* Top of the list */
- *q_prev100; /* Previous 100 marker */
+ struct extra_data* a_extras; /* Automatically selected extras */
+ u32 a_extras_cnt; /* Total number of tokens available */
-extern struct queue_entry*
- top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
+ u8* (*post_handler)(u8* buf, u32* len);
-extern struct extra_data* extras; /* Extra tokens to fuzz with */
-extern u32 extras_cnt; /* Total number of tokens read */
+ /* CmpLog */
-extern struct extra_data* a_extras; /* Automatically selected extras */
-extern u32 a_extras_cnt; /* Total number of tokens available */
+ u8* cmplog_binary;
+ s32 cmplog_child_pid, cmplog_fsrv_pid;
-u8* (*post_handler)(u8* buf, u32* len);
+ /* Custom mutators */
+ struct custom_mutator* mutator;
-/* CmpLog */
+ /* cmplog forkserver ids */
+ s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
-extern u8* cmplog_binary;
-extern s32 cmplog_child_pid, cmplog_forksrv_pid;
+ u8 describe_op_buf_256[256]; /* describe_op will use this to return a string up to 256 */
-/* Custom mutators */
+#ifdef USE_PYTHON
+ /* Python Mutators */
+ PyObject *py_module;
+ PyObject *py_functions[PY_FUNC_COUNT];
+#endif
+
+#ifdef _AFL_DOCUMENT_MUTATIONS
+ u8 do_document;
+ u32 document_counter;
+#endif
+
+} afl_state_t;
+
+/* A global pointer to all instances is needed (for now) for signals to arrive */
+
+extern list_t afl_states;
struct custom_mutator {
@@ -474,7 +558,7 @@ struct custom_mutator {
*
* @param seed Seed used for the mutation.
*/
- void (*afl_custom_init)(unsigned int seed);
+ void (*afl_custom_init)(afl_state_t *afl, unsigned int seed);
/**
* Perform custom mutations on a given input
@@ -490,7 +574,7 @@ struct custom_mutator {
* not produce data larger than max_size.
* @return Size of the mutated output.
*/
- size_t (*afl_custom_fuzz)(u8** buf, size_t buf_size, u8* add_buf,
+ size_t (*afl_custom_fuzz)(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf,
size_t add_buf_size, size_t max_size);
/**
@@ -507,7 +591,7 @@ struct custom_mutator {
* will release the memory after saving the test case.
* @return Size of the output buffer after processing
*/
- size_t (*afl_custom_pre_save)(u8* buf, size_t buf_size, u8** out_buf);
+ size_t (*afl_custom_pre_save)(afl_state_t *afl, u8* buf, size_t buf_size, u8** out_buf);
/**
* This method is called at the start of each trimming operation and receives
@@ -529,7 +613,7 @@ struct custom_mutator {
* @param buf_size Size of the test case
* @return The amount of possible iteration steps to trim the input
*/
- u32 (*afl_custom_init_trim)(u8* buf, size_t buf_size);
+ u32 (*afl_custom_init_trim)(afl_state_t *afl, u8* buf, size_t buf_size);
/**
* This method is called for each trimming operation. It doesn't have any
@@ -547,7 +631,7 @@ struct custom_mutator {
* the memory after saving the test case.
* @param[out] out_buf_size Pointer to the size of the trimmed test case
*/
- void (*afl_custom_trim)(u8** out_buf, size_t* out_buf_size);
+ void (*afl_custom_trim)(afl_state_t *afl, u8** out_buf, size_t* out_buf_size);
/**
* This method is called after each trim operation to inform you if your
@@ -560,8 +644,8 @@ struct custom_mutator {
* @return The next trim iteration index (from 0 to the maximum amount of
* steps returned in init_trim)
*/
- u32 (*afl_custom_post_trim)(u8 success);
-
+ u32 (*afl_custom_post_trim)(afl_state_t *afl, u8 success);
+
/**
* Perform a single custom mutation on a given input.
* This mutation is stacked with the other muatations in havoc.
@@ -575,9 +659,8 @@ struct custom_mutator {
* not produce data larger than max_size.
* @return Size of the mutated output.
*/
- size_t (*afl_custom_havoc_mutation)(u8** buf, size_t buf_size,
- size_t max_size);
-
+ size_t (*afl_custom_havoc_mutation)(afl_state_t *afl, u8** buf, size_t buf_size, size_t max_size);
+
/**
* Return the probability (in percentage) that afl_custom_havoc_mutation
* is called in havoc. By default it is 6 %.
@@ -586,7 +669,7 @@ struct custom_mutator {
*
* @return The probability (0-100).
*/
- u8 (*afl_custom_havoc_mutation_probability)(void);
+ u8 (*afl_custom_havoc_mutation_probability)(afl_state_t *afl);
/**
* Determine whether the fuzzer should fuzz the current queue entry or not.
@@ -597,7 +680,7 @@ struct custom_mutator {
* @return Return True(1) if the fuzzer will fuzz the queue entry, and
* False(0) otherwise.
*/
- u8 (*afl_custom_queue_get)(const u8* filename);
+ u8 (*afl_custom_queue_get)(afl_state_t *afl, const u8* filename);
/**
* Allow for additional analysis (e.g. calling a different tool that does a
@@ -609,112 +692,57 @@ struct custom_mutator {
* @param filename_orig_queue File name of the original queue entry. This
* argument can be NULL while initializing the fuzzer
*/
- void (*afl_custom_queue_new_entry)(const u8* filename_new_queue,
+ void (*afl_custom_queue_new_entry)(afl_state_t *afl, const u8* filename_new_queue,
const u8* filename_orig_queue);
};
-extern struct custom_mutator* mutator;
-
-/* Interesting values, as per config.h */
-
-extern s8 interesting_8[INTERESTING_8_LEN];
-extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN];
-extern s32
- interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN];
-
-/* Python stuff */
-#ifdef USE_PYTHON
-
-// because Python sets stuff it should not ...
-#ifdef _POSIX_C_SOURCE
-#define _SAVE_POSIX_C_SOURCE _POSIX_C_SOURCE
-#undef _POSIX_C_SOURCE
-#endif
-#ifdef _XOPEN_SOURCE
-#define _SAVE_XOPEN_SOURCE _XOPEN_SOURCE
-#undef _XOPEN_SOURCE
-#endif
-
-#include <Python.h>
-
-#ifdef _SAVE_POSIX_C_SOURCE
-#ifdef _POSIX_C_SOURCE
-#undef _POSIX_C_SOURCE
-#endif
-#define _POSIX_C_SOURCE _SAVE_POSIX_C_SOURCE
-#endif
-#ifdef _SAVE_XOPEN_SOURCE
-#ifdef _XOPEN_SOURCE
-#undef _XOPEN_SOURCE
-#endif
-#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE
-#endif
-
-extern PyObject* py_module;
-enum {
- /* 00 */ PY_FUNC_INIT,
- /* 01 */ PY_FUNC_FUZZ,
- /* 02 */ PY_FUNC_PRE_SAVE,
- /* 03 */ PY_FUNC_INIT_TRIM,
- /* 04 */ PY_FUNC_POST_TRIM,
- /* 05 */ PY_FUNC_TRIM,
- /* 06 */ PY_FUNC_HAVOC_MUTATION,
- /* 07 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY,
- /* 08 */ PY_FUNC_QUEUE_GET,
- /* 09 */ PY_FUNC_QUEUE_NEW_ENTRY,
- PY_FUNC_COUNT
-
-};
-
-extern PyObject* py_functions[PY_FUNC_COUNT];
-
-#endif
+void afl_state_init(afl_state_t *);
+void afl_state_deinit(afl_state_t*);
/**** Prototypes ****/
/* Custom mutators */
-void setup_custom_mutator(void);
-void destroy_custom_mutator(void);
-u8 trim_case_custom(char** argv, struct queue_entry* q, u8* in_buf);
+void setup_custom_mutator(afl_state_t*);
+void destroy_custom_mutator(afl_state_t*);
+u8 trim_case_custom(afl_state_t *, struct queue_entry* q, u8* in_buf);
/* Python */
#ifdef USE_PYTHON
-int init_py_module(u8*);
-void finalize_py_module();
+int init_py_module(afl_state_t*, u8*);
+void finalize_py_module(afl_state_t*);
-void init_py(unsigned int);
-size_t fuzz_py(u8**, size_t, u8*, size_t, size_t);
-size_t pre_save_py(u8*, size_t, u8**);
-u32 init_trim_py(u8*, size_t);
-u32 post_trim_py(u8);
-void trim_py(u8**, size_t*);
-size_t havoc_mutation_py(u8**, size_t, size_t);
-u8 havoc_mutation_probability_py(void);
-u8 queue_get_py(const u8*);
-void queue_new_entry_py(const u8*, const u8*);
+void init_py(afl_state_t*, unsigned int);
+size_t fuzz_py(afl_state_t*, u8**, size_t, u8*, size_t, size_t);
+size_t pre_save_py(afl_state_t*, u8*, size_t, u8**);
+u32 init_trim_py(afl_state_t*, u8*, size_t);
+u32 post_trim_py(afl_state_t*, u8);
+void trim_py(afl_state_t*, u8**, size_t*);
+size_t havoc_mutation_py(afl_state_t *, u8**, size_t, size_t);
+u8 havoc_mutation_probability_py(afl_state_t*);
+u8 queue_get_py(afl_state_t*, const u8*);
+void queue_new_entry_py(afl_state_t*, const u8*, const u8*);
#endif
/* Queue */
-void mark_as_det_done(struct queue_entry*);
-void mark_as_variable(struct queue_entry*);
-void mark_as_redundant(struct queue_entry*, u8);
-void add_to_queue(u8*, u32, u8);
-void destroy_queue(void);
-void update_bitmap_score(struct queue_entry*);
-void cull_queue(void);
-u32 calculate_score(struct queue_entry*);
+void mark_as_det_done(afl_state_t*, struct queue_entry*);
+void mark_as_variable(afl_state_t*, struct queue_entry*);
+void mark_as_redundant(afl_state_t*, struct queue_entry*, u8);
+void add_to_queue(afl_state_t*, u8*, u32, u8);
+void destroy_queue(afl_state_t*);
+void update_bitmap_score(afl_state_t*, struct queue_entry*);
+void cull_queue(afl_state_t*);
+u32 calculate_score(afl_state_t*, struct queue_entry*);
/* Bitmap */
-void write_bitmap(void);
-void read_bitmap(u8*);
-u8 has_new_bits(u8*);
+void read_bitmap(afl_state_t*, u8*);
+void write_bitmap(afl_state_t*);
u32 count_bits(u8*);
u32 count_bytes(u8*);
u32 count_non_255_bytes(u8*);
@@ -728,9 +756,10 @@ void classify_counts(u32*);
void init_count_class16(void);
void minimize_bits(u8*, u8*);
#ifndef SIMPLE_FILES
-u8* describe_op(u8);
+u8* describe_op(afl_state_t*, u8);
#endif
-u8 save_if_interesting(char**, void*, u32, u8);
+u8 save_if_interesting(afl_state_t*, void*, u32, u8);
+u8 has_new_bits(afl_state_t *, u8*);
/* Misc */
@@ -741,75 +770,71 @@ u8* DTD(u64, u64);
/* Extras */
-void load_extras_file(u8*, u32*, u32*, u32);
-void load_extras(u8*);
-void maybe_add_auto(u8*, u32);
-void save_auto(void);
-void load_auto(void);
-void destroy_extras(void);
+void load_extras_file(afl_state_t*, u8*, u32*, u32*, u32);
+void load_extras(afl_state_t*, u8*);
+void maybe_add_auto(afl_state_t*, u8*, u32);
+void save_auto(afl_state_t*);
+void load_auto(afl_state_t*);
+void destroy_extras(afl_state_t*);
/* Stats */
-void write_stats_file(double, double, double);
-void maybe_update_plot_file(double, double);
-void show_stats(void);
-void show_init_stats(void);
+void write_stats_file(afl_state_t*, double, double, double);
+void maybe_update_plot_file(afl_state_t*, double, double);
+void show_stats(afl_state_t*);
+void show_init_stats(afl_state_t*);
/* Run */
-u8 run_target(char**, u32);
-void write_to_testcase(void*, u32);
-void write_with_gap(void*, u32, u32, u32);
-u8 calibrate_case(char**, struct queue_entry*, u8*, u32, u8);
-void sync_fuzzers(char**);
-u8 trim_case(char**, struct queue_entry*, u8*);
-u8 common_fuzz_stuff(char**, u8*, u32);
+u8 run_target(afl_state_t*, u32);
+void write_to_testcase(afl_state_t*, void*, u32);
+u8 calibrate_case(afl_state_t*, struct queue_entry*, u8*, u32, u8);
+void sync_fuzzers(afl_state_t*);
+u8 trim_case(afl_state_t*, struct queue_entry*, u8*);
+u8 common_fuzz_stuff(afl_state_t*, u8*, u32);
/* Fuzz one */
-u8 fuzz_one_original(char**);
-u8 pilot_fuzzing(char**);
-u8 core_fuzzing(char**);
-void pso_updating(void);
-u8 fuzz_one(char**);
+u8 fuzz_one_original(afl_state_t*);
+u8 pilot_fuzzing(afl_state_t*);
+u8 core_fuzzing(afl_state_t*);
+void pso_updating(afl_state_t*);
+u8 fuzz_one(afl_state_t*);
/* Init */
#ifdef HAVE_AFFINITY
-void bind_to_free_cpu(void);
+void bind_to_free_cpu(afl_state_t*);
#endif
-void setup_post(void);
-void read_testcases(void);
-void perform_dry_run(char**);
-void pivot_inputs(void);
-u32 find_start_position(void);
-void find_timeout(void);
+void setup_post(afl_state_t*);
+void read_testcases(afl_state_t*);
+void perform_dry_run(afl_state_t*);
+void pivot_inputs(afl_state_t*);
+u32 find_start_position(afl_state_t*);
+void find_timeout(afl_state_t*);
double get_runnable_processes(void);
-void nuke_resume_dir(void);
-void setup_dirs_fds(void);
-void setup_cmdline_file(char**);
-void setup_stdio_file(void);
+void nuke_resume_dir(afl_state_t*);
+void setup_dirs_fds(afl_state_t*);
+void setup_cmdline_file(afl_state_t*, char**);
+void setup_stdio_file(afl_state_t*);
void check_crash_handling(void);
-void check_cpu_governor(void);
-void get_core_count(void);
-void fix_up_sync(void);
+void check_cpu_governor(afl_state_t*);
+void get_core_count(afl_state_t*);
+void fix_up_sync(afl_state_t*);
void check_asan_opts(void);
-void check_binary(u8*);
-void fix_up_banner(u8*);
-void check_if_tty(void);
+void check_binary(afl_state_t*, u8*);
+void fix_up_banner(afl_state_t*, u8*);
+void check_if_tty(afl_state_t*);
void setup_signal_handlers(void);
-char** get_qemu_argv(u8*, char**, int);
-char** get_wine_argv(u8*, char**, int);
-void save_cmdline(u32, char**);
+void save_cmdline(afl_state_t*, u32, char**);
/* CmpLog */
-void init_cmplog_forkserver(char** argv);
-u8 common_fuzz_cmplog_stuff(char** argv, u8* out_buf, u32 len);
+void init_cmplog_forkserver(afl_state_t *afl);
+u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
/* RedQueen */
-
-u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len,
+u8 input_to_state_stage(afl_state_t *afl, u8* orig_buf, u8* buf, u32 len,
u32 exec_cksum);
/**** Inline routines ****/
@@ -817,20 +842,20 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len,
/* Generate a random number (from 0 to limit - 1). This may
have slight bias. */
-static inline u32 UR(u32 limit) {
+static inline u32 UR(afl_state_t *afl, u32 limit) {
#ifdef HAVE_ARC4RANDOM
- if (fixed_seed) { return random() % limit; }
+ if (afl->fixed_seed) { return random() % limit; }
/* The boundary not being necessarily a power of 2,
we need to ensure the result uniformity. */
return arc4random_uniform(limit);
#else
- if (!fixed_seed && unlikely(!rand_cnt--)) {
+ if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) {
- ck_read(dev_urandom_fd, &rand_seed, sizeof(rand_seed), "/dev/urandom");
- srandom(rand_seed[0]);
- rand_cnt = (RESEED_RNG / 2) + (rand_seed[1] % RESEED_RNG);
+ ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom");
+ srandom(afl->rand_seed[0]);
+ afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
}
@@ -839,10 +864,10 @@ static inline u32 UR(u32 limit) {
}
-static inline u32 get_rand_seed() {
+static inline u32 get_rand_seed(afl_state_t *afl) {
- if (fixed_seed) return (u32)init_seed;
- return rand_seed[0];
+ if (afl->fixed_seed) return (u32)afl->init_seed;
+ return afl->rand_seed[0];
}
@@ -858,10 +883,4 @@ static u64 next_p2(u64 val) {
}
-#ifdef _AFL_DOCUMENT_MUTATIONS
-extern u8 do_document;
-extern u32 document_counter;
-#endif
-
-#endif
-
+#endif \ No newline at end of file
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h
new file mode 100644
index 00000000..712cdec6
--- /dev/null
+++ b/include/afl-prealloc.h
@@ -0,0 +1,101 @@
+/* If we know we'll reuse small elements often, we'll just preallocate a buffer, then fall back to malloc */
+// TODO: Replace free status check with bitmask+CLZ
+
+#ifndef AFL_PREALLOC_H
+#define AFL_PREALLOC_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "debug.h"
+
+typedef enum prealloc_status {
+ PRE_STATUS_UNUSED = 0,/* free in buf */
+ PRE_STATUS_USED, /* used in buf */
+ PRE_STATUS_MALLOC /* system malloc */
+} pre_status_t;
+
+
+/* Adds the entry used for prealloc bookkeeping to this struct */
+
+#define PREALLOCABLE ;pre_status_t pre_status; /* prealloc status of this instance */
+
+
+/* allocate an element of type *el_ptr, to this variable.
+ Uses (and reuses) the given prealloc_buf before hitting libc's malloc.
+ prealloc_buf must be the pointer to an array with type `type`.
+ `type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status member).
+ prealloc_size must be the array size.
+ prealloc_counter must be a variable initialized with 0 (of any name).
+ */
+
+#define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) do { \
+ \
+ if ((prealloc_counter) >= (prealloc_size)) { \
+ \
+ el_ptr = malloc(sizeof(*el_ptr)); \
+ el_ptr->pre_status = PRE_STATUS_MALLOC; \
+ \
+ } else { \
+ \
+ /* Find one of our preallocated elements */ \
+ u32 i; \
+ for (i = 0; i < (prealloc_size); i++) { \
+ \
+ el_ptr = &((prealloc_buf)[i]); \
+ if (el_ptr->pre_status == PRE_STATUS_UNUSED) { \
+ \
+ (prealloc_counter)++; \
+ el_ptr->pre_status = PRE_STATUS_USED; \
+ break; \
+ \
+ } \
+ } \
+ } \
+ \
+ if(!el_ptr) { \
+ FATAL("BUG in list.h -> no element found or allocated!"); \
+ } \
+} while(0);
+
+
+/* Take a chosen (free) element from the prealloc_buf directly */
+
+#define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) do { \
+ if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \
+ FATAL("PRE_ALLOC_FORCE element already allocated"); \
+ } \
+ (el_ptr)->pre_status = PRE_STATUS_USED; \
+ (prealloc_counter)++; \
+} while(0);
+
+
+/* free an preallocated element */
+
+#define PRE_FREE(el_ptr, prealloc_counter) do { \
+ \
+ switch ((el_ptr)->pre_status) { \
+ \
+ case PRE_STATUS_USED: { \
+ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
+ (prealloc_counter)--; \
+ if ((prealloc_counter) < 0) { \
+ FATAL("Inconsistent data in PRE_FREE"); \
+ } \
+ break; \
+ } \
+ case PRE_STATUS_MALLOC: { \
+ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
+ free((el_ptr)); \
+ break; \
+ } \
+ default: { \
+ FATAL("Double Free Detected"); \
+ break; \
+ } \
+ \
+ } \
+} while(0);
+
+#endif
diff --git a/include/common.h b/include/common.h
index 0d7f4f0b..780e083b 100644
--- a/include/common.h
+++ b/include/common.h
@@ -28,16 +28,14 @@
#include <sys/time.h>
#include "types.h"
+#include "stdbool.h"
-extern u8* target_path; /* Path to target binary */
-
-void detect_file_args(char** argv, u8* prog_in);
+void detect_file_args(char** argv, u8* prog_in, u8 use_stdin);
void check_environment_vars(char** env);
-char** get_qemu_argv(u8* own_loc, char** argv, int argc);
-char** get_wine_argv(u8* own_loc, char** argv, int argc);
+char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv);
+char** get_wine_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv);
char* get_afl_env(char* env);
-#endif
/* Get unix time in milliseconds */
@@ -65,3 +63,4 @@ static u64 get_cur_time_us(void) {
}
+#endif
diff --git a/include/forkserver.h b/include/forkserver.h
index 0fdcba48..3587427b 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -27,8 +27,47 @@
#ifndef __AFL_FORKSERVER_H
#define __AFL_FORKSERVER_H
+#include <stdio.h>
+
+typedef struct afl_forkserver {
+
+ /* a program that includes afl-forkserver needs to define these */
+
+ u8 uses_asan; /* Target uses ASAN? */
+ u8* trace_bits; /* SHM with instrumentation bitmap */
+ u8 use_stdin; /* use stdin for sending data */
+
+s32 fsrv_pid, /* PID of the fork server */
+ child_pid, /* PID of the fuzzed program */
+ out_dir_fd; /* FD of the lock file */
+
+s32 out_fd, /* Persistent fd for afl->fsrv.out_file */
+#ifndef HAVE_ARC4RANDOM
+ dev_urandom_fd, /* Persistent fd for /dev/urandom */
+#endif
+ 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) */
+ u64 mem_limit; /* Memory cap for child (MB) */
+
+ u8 *out_file, /* File to fuzz, if any */
+ *target_path; /* Path of the target */
+
+ FILE* plot_file; /* Gnuplot output file */
+
+ u8 child_timed_out; /* Traced process timed out? */
+
+} afl_forkserver_t;
+
+
+
void handle_timeout(int sig);
-void init_forkserver(char **argv);
+void afl_fsrv_init(afl_forkserver_t *fsrv);
+void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv);
+void afl_fsrv_deinit(afl_forkserver_t *fsrv);
+void afl_fsrv_killall();
#ifdef __APPLE__
#define MSG_FORK_ON_APPLE \
diff --git a/include/list.h b/include/list.h
new file mode 100644
index 00000000..7184850f
--- /dev/null
+++ b/include/list.h
@@ -0,0 +1,133 @@
+#ifndef AFL_LIST
+#define AFL_LIST
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "debug.h"
+#include "afl-prealloc.h"
+
+#define LIST_PREALLOC_SIZE (64) /* How many elements to allocate before malloc is needed */
+
+typedef struct list_element {
+ PREALLOCABLE;
+
+ struct list_element *prev;
+ struct list_element *next;
+ void *data;
+
+} element_t;
+
+typedef struct list {
+
+ element_t element_prealloc_buf[LIST_PREALLOC_SIZE];
+ u32 element_prealloc_count;
+
+} list_t;
+
+static inline element_t *get_head(list_t *list) {
+
+ return &list->element_prealloc_buf[0];
+
+}
+
+static void list_free_el(list_t *list, element_t *el) {
+
+ PRE_FREE(el, list->element_prealloc_count);
+
+}
+
+static void list_append(list_t *list, void *el) {
+
+ element_t *head = get_head(list);
+ if (!head->next) {
+
+ /* initialize */
+
+ memset(list, 0, sizeof(list_t));
+ PRE_ALLOC_FORCE(head, list->element_prealloc_count);
+ head->next = head->prev = head;
+
+ }
+
+ element_t *el_box = NULL;
+ PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE, list->element_prealloc_count);
+ if (!el_box) FATAL("failed to allocate list element");
+ el_box->data = el;
+ el_box->next = head;
+ el_box->prev = head->prev;
+ head->prev->next = el_box;
+ head->prev = el_box;
+
+}
+
+/* Simple foreach.
+ Pointer to the current element is in `el`,
+ casted to (a pointer) of the given `type`.
+ A return from this block will return from calling func.
+*/
+
+#define LIST_FOREACH(list, type, block) do { \
+ list_t *li = (list); \
+ element_t *head = get_head((li)); \
+ element_t *el_box = (head)->next; \
+ if (!el_box) \
+ FATAL("foreach over uninitialized list");\
+ while(el_box != head) { \
+ type *el = (type *)((el_box)->data); \
+ /* get next so el_box can be unlinked */ \
+ element_t *next = el_box->next; \
+ {block}; \
+ el_box = next; \
+ } \
+} while(0);
+
+/* In foreach: remove the current el from the list */
+
+#define LIST_REMOVE_CURRENT_EL_IN_FOREACH() do { \
+ el_box->prev->next = next; \
+ el_box->next->prev = el_box->prev; \
+ list_free_el(li, el_box); \
+} while(0);
+
+/* Same as foreach, but will clear list in the process */
+
+#define LIST_FOREACH_CLEAR(list, type, block) do { \
+ LIST_FOREACH((list), type, { \
+ {block}; \
+ LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \
+ }); \
+} while(0);
+
+/* remove an item from the list */
+
+static void list_remove(list_t *list, void *remove_me) {
+
+ LIST_FOREACH(list, void, {
+ if (el == remove_me) {
+ el_box->prev->next = el_box->next;
+ el_box->next->prev = el_box->prev;
+ el_box->data = NULL;
+ list_free_el(list, el_box);
+ return;
+ }
+ });
+
+ FATAL ("List item to be removed not in list");
+
+}
+
+/* Returns true if el is in list */
+
+static bool list_contains(list_t *list, void *contains_me) {
+
+ LIST_FOREACH(list, void, {
+ if (el == contains_me) return true;
+ });
+
+ return false;
+
+}
+
+#endif \ No newline at end of file
diff --git a/include/sharedmem.h b/include/sharedmem.h
index 8c1c2b20..b90f7d87 100644
--- a/include/sharedmem.h
+++ b/include/sharedmem.h
@@ -27,11 +27,32 @@
#ifndef __AFL_SHAREDMEM_H
#define __AFL_SHAREDMEM_H
-void setup_shm(unsigned char dumb_mode);
-void remove_shm(void);
+typedef struct sharedmem {
-extern int cmplog_mode;
-extern struct cmp_map* cmp_map;
+ //extern unsigned char *trace_bits;
+
+ #ifdef USEMMAP
+ /* ================ Proteas ================ */
+ int g_shm_fd;
+ char g_shm_file_path[L_tmpnam];
+ /* ========================================= */
+ #else
+ s32 shm_id; /* ID of the SHM region */
+ s32 cmplog_shm_id;
+ #endif
+
+ u8 *map; /* shared memory region */
+
+ size_t size_alloc; /* actual allocated size */
+ size_t size_used; /* in use by shmem app */
+
+ int cmplog_mode;
+ struct cmp_map *cmp_map;
+
+} sharedmem_t;
+
+u8 *afl_shm_init(sharedmem_t*, size_t, unsigned char dumb_mode);
+void afl_shm_deinit(sharedmem_t*);
#endif