code-format

This commit is contained in:
van Hauser
2020-03-09 12:21:54 +01:00
parent 188a6f5ec5
commit 988a32ced5
25 changed files with 1014 additions and 802 deletions

View File

@ -109,8 +109,8 @@
extern s8 interesting_8[INTERESTING_8_LEN]; extern s8 interesting_8[INTERESTING_8_LEN];
extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN]; extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN];
extern s32 interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN]; extern s32
interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN];
struct queue_entry { struct queue_entry {
@ -233,7 +233,7 @@ enum {
}; };
extern u8 *doc_path; /* gath to documentation dir */ extern u8* doc_path; /* gath to documentation dir */
/* Python stuff */ /* Python stuff */
#ifdef USE_PYTHON #ifdef USE_PYTHON
@ -263,7 +263,6 @@ extern u8 *doc_path; /* gath to documentation dir */
#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE #define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE
#endif #endif
enum { enum {
/* 00 */ PY_FUNC_INIT, /* 00 */ PY_FUNC_INIT,
@ -284,18 +283,18 @@ enum {
typedef struct MOpt_globals { typedef struct MOpt_globals {
u64* finds; u64* finds;
u64* finds_v2; u64* finds_v2;
u64* cycles; u64* cycles;
u64* cycles_v2; u64* cycles_v2;
u64* cycles_v3; u64* cycles_v3;
u32 is_pilot_mode; u32 is_pilot_mode;
u64* pTime; u64* pTime;
u64 period; u64 period;
char* havoc_stagename; char* havoc_stagename;
char* splice_stageformat; char* splice_stageformat;
char* havoc_stagenameshort; char* havoc_stagenameshort;
char* splice_stagenameshort; char* splice_stagenameshort;
} MOpt_globals_t; } MOpt_globals_t;
@ -307,9 +306,9 @@ typedef struct afl_state {
u32 _id; u32 _id;
afl_forkserver_t fsrv; afl_forkserver_t fsrv;
sharedmem_t shm; sharedmem_t shm;
char** argv; /* argv if needed */ char** argv; /* argv if needed */
/* MOpt: /* MOpt:
Lots of globals, but mostly for the status UI and other things where it Lots of globals, but mostly for the status UI and other things where it
@ -346,171 +345,170 @@ typedef struct afl_state {
core_operator_finds_puppet_v2[operator_num], core_operator_finds_puppet_v2[operator_num],
core_operator_cycles_puppet[operator_num], core_operator_cycles_puppet[operator_num],
core_operator_cycles_puppet_v2[operator_num], core_operator_cycles_puppet_v2[operator_num],
core_operator_cycles_puppet_v3[operator_num]; /* Execs per fuzz stage */ core_operator_cycles_puppet_v3[operator_num]; /* Execs per fuzz stage */
double period_pilot_tmp; double period_pilot_tmp;
s32 key_lv; s32 key_lv;
u8 *in_dir, /* Input directory with test cases */ u8 *in_dir, /* Input directory with test cases */
*out_dir, /* Working & output directory */ *out_dir, /* Working & output directory */
*tmp_dir, /* Temporary directory for input */ *tmp_dir, /* Temporary directory for input */
*sync_dir, /* Synchronization directory */ *sync_dir, /* Synchronization directory */
*sync_id, /* Fuzzer ID */ *sync_id, /* Fuzzer ID */
*power_name, /* Power schedule name */ *power_name, /* Power schedule name */
*use_banner, /* Display banner */ *use_banner, /* Display banner */
*in_bitmap, /* Input bitmap */ *in_bitmap, /* Input bitmap */
*file_extension, /* File extension */ *file_extension, /* File extension */
*orig_cmdline, /* Original command line */ *orig_cmdline, /* Original command line */
*infoexec; /* Command to execute on a new crash */ *infoexec; /* Command to execute on a new crash */
u32 hang_tmout; /* Timeout used for hang det (ms) */ u32 hang_tmout; /* Timeout used for hang det (ms) */
u8 cal_cycles, /* Calibration cycles defaults */ u8 cal_cycles, /* Calibration cycles defaults */
cal_cycles_long, /* Calibration cycles defaults */ cal_cycles_long, /* Calibration cycles defaults */
no_unlink, /* do not unlink cur_input */ no_unlink, /* do not unlink cur_input */
debug, /* Debug mode */ debug, /* Debug mode */
custom_only, /* Custom mutator only mode */ custom_only, /* Custom mutator only mode */
python_only; /* Python-only mode */ python_only; /* Python-only mode */
u32 stats_update_freq; /* Stats update frequency (execs) */ u32 stats_update_freq; /* Stats update frequency (execs) */
u8 schedule; /* Power schedule (default: EXPLORE)*/ u8 schedule; /* Power schedule (default: EXPLORE)*/
u8 havoc_max_mult; u8 havoc_max_mult;
u8 use_radamsa; u8 use_radamsa;
size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32); size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32);
u8 skip_deterministic, /* Skip deterministic stages? */ u8 skip_deterministic, /* Skip deterministic stages? */
force_deterministic, /* Force deterministic stages? */ force_deterministic, /* Force deterministic stages? */
use_splicing, /* Recombine input files? */ use_splicing, /* Recombine input files? */
dumb_mode, /* Run in non-instrumented mode? */ dumb_mode, /* Run in non-instrumented mode? */
score_changed, /* Scoring for favorites changed? */ score_changed, /* Scoring for favorites changed? */
kill_signal, /* Signal that killed the child */ kill_signal, /* Signal that killed the child */
resuming_fuzz, /* Resuming an older fuzzing job? */ resuming_fuzz, /* Resuming an older fuzzing job? */
timeout_given, /* Specific timeout given? */ timeout_given, /* Specific timeout given? */
not_on_tty, /* stdout is not a tty */ not_on_tty, /* stdout is not a tty */
term_too_small, /* terminal dimensions too small */ term_too_small, /* terminal dimensions too small */
no_forkserver, /* Disable forkserver? */ no_forkserver, /* Disable forkserver? */
crash_mode, /* Crash mode! Yeah! */ crash_mode, /* Crash mode! Yeah! */
in_place_resume, /* Attempt in-place resume? */ in_place_resume, /* Attempt in-place resume? */
autoresume, /* Resume if afl->out_dir exists? */ autoresume, /* Resume if afl->out_dir exists? */
auto_changed, /* Auto-generated tokens changed? */ auto_changed, /* Auto-generated tokens changed? */
no_cpu_meter_red, /* Feng shui on the status screen */ no_cpu_meter_red, /* Feng shui on the status screen */
no_arith, /* Skip most arithmetic ops */ no_arith, /* Skip most arithmetic ops */
shuffle_queue, /* Shuffle input queue? */ shuffle_queue, /* Shuffle input queue? */
bitmap_changed, /* Time to update bitmap? */ bitmap_changed, /* Time to update bitmap? */
qemu_mode, /* Running in QEMU mode? */ qemu_mode, /* Running in QEMU mode? */
unicorn_mode, /* Running in Unicorn mode? */ unicorn_mode, /* Running in Unicorn mode? */
use_wine, /* Use WINE with QEMU mode */ use_wine, /* Use WINE with QEMU mode */
skip_requested, /* Skip request, via SIGUSR1 */ skip_requested, /* Skip request, via SIGUSR1 */
run_over10m, /* Run time over 10 minutes? */ run_over10m, /* Run time over 10 minutes? */
persistent_mode, /* Running in persistent mode? */ persistent_mode, /* Running in persistent mode? */
deferred_mode, /* Deferred forkserver mode? */ deferred_mode, /* Deferred forkserver mode? */
fixed_seed, /* do not reseed */ fixed_seed, /* do not reseed */
fast_cal, /* Try to calibrate faster? */ fast_cal, /* Try to calibrate faster? */
disable_trim; /* Never trim in fuzz_one */ disable_trim; /* Never trim in fuzz_one */
u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */ u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */ virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */
virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */ virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */
u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */ u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
volatile u8 stop_soon, /* Ctrl-C pressed? */ volatile u8 stop_soon, /* Ctrl-C pressed? */
clear_screen; /* Window resized? */ clear_screen; /* Window resized? */
u32 queued_paths, /* Total number of queued testcases */ u32 queued_paths, /* Total number of queued testcases */
queued_variable, /* Testcases with variable behavior */ queued_variable, /* Testcases with variable behavior */
queued_at_start, /* Total number of initial inputs */ queued_at_start, /* Total number of initial inputs */
queued_discovered, /* Items discovered during this run */ queued_discovered, /* Items discovered during this run */
queued_imported, /* Items imported via -S */ queued_imported, /* Items imported via -S */
queued_favored, /* Paths deemed favorable */ queued_favored, /* Paths deemed favorable */
queued_with_cov, /* Paths with new coverage bytes */ queued_with_cov, /* Paths with new coverage bytes */
pending_not_fuzzed, /* Queued but not done yet */ pending_not_fuzzed, /* Queued but not done yet */
pending_favored, /* Pending favored paths */ pending_favored, /* Pending favored paths */
cur_skipped_paths, /* Abandoned inputs in cur cycle */ cur_skipped_paths, /* Abandoned inputs in cur cycle */
cur_depth, /* Current path depth */ cur_depth, /* Current path depth */
max_depth, /* Max path depth */ max_depth, /* Max path depth */
useless_at_start, /* Number of useless starting paths */ useless_at_start, /* Number of useless starting paths */
var_byte_count, /* Bitmap bytes with var behavior */ var_byte_count, /* Bitmap bytes with var behavior */
current_entry, /* Current queue entry ID */ current_entry, /* Current queue entry ID */
havoc_div; /* Cycle count divisor for havoc */ havoc_div; /* Cycle count divisor for havoc */
u64 total_crashes, /* Total number of crashes */ u64 total_crashes, /* Total number of crashes */
unique_crashes, /* Crashes with unique signatures */ unique_crashes, /* Crashes with unique signatures */
total_tmouts, /* Total number of timeouts */ total_tmouts, /* Total number of timeouts */
unique_tmouts, /* Timeouts with unique signatures */ unique_tmouts, /* Timeouts with unique signatures */
unique_hangs, /* Hangs with unique signatures */ unique_hangs, /* Hangs with unique signatures */
total_execs, /* Total execve() calls */ total_execs, /* Total execve() calls */
slowest_exec_ms, /* Slowest testcase non hang in ms */ slowest_exec_ms, /* Slowest testcase non hang in ms */
start_time, /* Unix start time (ms) */ start_time, /* Unix start time (ms) */
last_path_time, /* Time for most recent path (ms) */ last_path_time, /* Time for most recent path (ms) */
last_crash_time, /* Time for most recent crash (ms) */ last_crash_time, /* Time for most recent crash (ms) */
last_hang_time, /* Time for most recent hang (ms) */ last_hang_time, /* Time for most recent hang (ms) */
last_crash_execs, /* Exec counter at last crash */ last_crash_execs, /* Exec counter at last crash */
queue_cycle, /* Queue round counter */ queue_cycle, /* Queue round counter */
cycles_wo_finds, /* Cycles without any new paths */ cycles_wo_finds, /* Cycles without any new paths */
trim_execs, /* Execs done to trim input files */ trim_execs, /* Execs done to trim input files */
bytes_trim_in, /* Bytes coming into the trimmer */ bytes_trim_in, /* Bytes coming into the trimmer */
bytes_trim_out, /* Bytes coming outa the trimmer */ bytes_trim_out, /* Bytes coming outa the trimmer */
blocks_eff_total, /* Blocks subject to effector maps */ blocks_eff_total, /* Blocks subject to effector maps */
blocks_eff_select; /* Blocks selected as fuzzable */ blocks_eff_select; /* Blocks selected as fuzzable */
u32 subseq_tmouts; /* Number of timeouts in a row */ u32 subseq_tmouts; /* Number of timeouts in a row */
u8 *stage_name, /* Name of the current fuzz stage */ u8 *stage_name, /* Name of the current fuzz stage */
*stage_short, /* Short stage name */ *stage_short, /* Short stage name */
*syncing_party; /* Currently syncing with... */ *syncing_party; /* Currently syncing with... */
u8 stage_name_buf64[64]; /* A name buf with len 64 if needed */ u8 stage_name_buf64[64]; /* A name buf with len 64 if needed */
s32 stage_cur, stage_max; /* Stage progression */ s32 stage_cur, stage_max; /* Stage progression */
s32 splicing_with; /* Splicing with which test case? */ s32 splicing_with; /* Splicing with which test case? */
u32 master_id, master_max; /* Master instance job splitting */ u32 master_id, master_max; /* Master instance job splitting */
u32 syncing_case; /* Syncing with case #... */ u32 syncing_case; /* Syncing with case #... */
s32 stage_cur_byte, /* Byte offset of current stage op */ s32 stage_cur_byte, /* Byte offset of current stage op */
stage_cur_val; /* Value used for stage op */ stage_cur_val; /* Value used for stage op */
u8 stage_val_type; /* Value type (STAGE_VAL_*) */ u8 stage_val_type; /* Value type (STAGE_VAL_*) */
u64 stage_finds[32], /* Patterns found per fuzz stage */ u64 stage_finds[32], /* Patterns found per fuzz stage */
stage_cycles[32]; /* Execs per fuzz stage */ stage_cycles[32]; /* Execs per fuzz stage */
#ifndef HAVE_ARC4RANDOM #ifndef HAVE_ARC4RANDOM
u32 rand_cnt; /* Random number counter */ u32 rand_cnt; /* Random number counter */
#endif #endif
u32 rand_seed[2]; u32 rand_seed[2];
s64 init_seed; s64 init_seed;
u64 total_cal_us, /* Total calibration time (us) */ u64 total_cal_us, /* Total calibration time (us) */
total_cal_cycles; /* Total calibration cycles */ total_cal_cycles; /* Total calibration cycles */
u64 total_bitmap_size, /* Total bit count for all bitmaps */ u64 total_bitmap_size, /* Total bit count for all bitmaps */
total_bitmap_entries; /* Number of bitmaps counted */ total_bitmap_entries; /* Number of bitmaps counted */
s32 cpu_core_count; /* CPU core count */ s32 cpu_core_count; /* CPU core count */
#ifdef HAVE_AFFINITY #ifdef HAVE_AFFINITY
s32 cpu_aff; /* Selected CPU core */ s32 cpu_aff; /* Selected CPU core */
#endif /* HAVE_AFFINITY */ #endif /* HAVE_AFFINITY */
struct queue_entry *queue, /* Fuzzing queue (linked list) */ struct queue_entry *queue, /* Fuzzing queue (linked list) */
*queue_cur, /* Current offset within the queue */ *queue_cur, /* Current offset within the queue */
*queue_top, /* Top of the list */ *queue_top, /* Top of the list */
*q_prev100; /* Previous 100 marker */ *q_prev100; /* Previous 100 marker */
struct queue_entry* struct queue_entry* top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
struct extra_data* extras; /* Extra tokens to fuzz with */ struct extra_data* extras; /* Extra tokens to fuzz with */
u32 extras_cnt; /* Total number of tokens read */ u32 extras_cnt; /* Total number of tokens read */
struct extra_data* a_extras; /* Automatically selected extras */ struct extra_data* a_extras; /* Automatically selected extras */
u32 a_extras_cnt; /* Total number of tokens available */ u32 a_extras_cnt; /* Total number of tokens available */
u8* (*post_handler)(u8* buf, u32* len); u8* (*post_handler)(u8* buf, u32* len);
@ -525,12 +523,13 @@ typedef struct afl_state {
/* cmplog forkserver ids */ /* cmplog forkserver ids */
s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
u8 describe_op_buf_256[256]; /* describe_op will use this to return a string up to 256 */ u8 describe_op_buf_256[256]; /* describe_op will use this to return a string
up to 256 */
#ifdef USE_PYTHON #ifdef USE_PYTHON
/* Python Mutators */ /* Python Mutators */
PyObject *py_module; PyObject* py_module;
PyObject *py_functions[PY_FUNC_COUNT]; PyObject* py_functions[PY_FUNC_COUNT];
#endif #endif
#ifdef _AFL_DOCUMENT_MUTATIONS #ifdef _AFL_DOCUMENT_MUTATIONS
@ -540,7 +539,8 @@ typedef struct afl_state {
} afl_state_t; } afl_state_t;
/* A global pointer to all instances is needed (for now) for signals to arrive */ /* A global pointer to all instances is needed (for now) for signals to arrive
*/
extern list_t afl_states; extern list_t afl_states;
@ -558,7 +558,7 @@ struct custom_mutator {
* *
* @param seed Seed used for the mutation. * @param seed Seed used for the mutation.
*/ */
void (*afl_custom_init)(afl_state_t *afl, unsigned int seed); void (*afl_custom_init)(afl_state_t* afl, unsigned int seed);
/** /**
* Perform custom mutations on a given input * Perform custom mutations on a given input
@ -574,8 +574,8 @@ struct custom_mutator {
* not produce data larger than max_size. * not produce data larger than max_size.
* @return Size of the mutated output. * @return Size of the mutated output.
*/ */
size_t (*afl_custom_fuzz)(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf, size_t (*afl_custom_fuzz)(afl_state_t* afl, u8** buf, size_t buf_size,
size_t add_buf_size, size_t max_size); u8* add_buf, size_t add_buf_size, size_t max_size);
/** /**
* A post-processing function to use right before AFL writes the test case to * A post-processing function to use right before AFL writes the test case to
@ -591,7 +591,8 @@ struct custom_mutator {
* will release the memory after saving the test case. * will release the memory after saving the test case.
* @return Size of the output buffer after processing * @return Size of the output buffer after processing
*/ */
size_t (*afl_custom_pre_save)(afl_state_t *afl, 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 * This method is called at the start of each trimming operation and receives
@ -613,7 +614,7 @@ struct custom_mutator {
* @param buf_size Size of the test case * @param buf_size Size of the test case
* @return The amount of possible iteration steps to trim the input * @return The amount of possible iteration steps to trim the input
*/ */
u32 (*afl_custom_init_trim)(afl_state_t *afl, 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 * This method is called for each trimming operation. It doesn't have any
@ -631,7 +632,7 @@ struct custom_mutator {
* the memory after saving the test case. * the memory after saving the test case.
* @param[out] out_buf_size Pointer to the size of the trimmed test case * @param[out] out_buf_size Pointer to the size of the trimmed test case
*/ */
void (*afl_custom_trim)(afl_state_t *afl, 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 * This method is called after each trim operation to inform you if your
@ -644,7 +645,7 @@ struct custom_mutator {
* @return The next trim iteration index (from 0 to the maximum amount of * @return The next trim iteration index (from 0 to the maximum amount of
* steps returned in init_trim) * steps returned in init_trim)
*/ */
u32 (*afl_custom_post_trim)(afl_state_t *afl, u8 success); u32 (*afl_custom_post_trim)(afl_state_t* afl, u8 success);
/** /**
* Perform a single custom mutation on a given input. * Perform a single custom mutation on a given input.
@ -659,7 +660,8 @@ struct custom_mutator {
* not produce data larger than max_size. * not produce data larger than max_size.
* @return Size of the mutated output. * @return Size of the mutated output.
*/ */
size_t (*afl_custom_havoc_mutation)(afl_state_t *afl, 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 * Return the probability (in percentage) that afl_custom_havoc_mutation
@ -669,7 +671,7 @@ struct custom_mutator {
* *
* @return The probability (0-100). * @return The probability (0-100).
*/ */
u8 (*afl_custom_havoc_mutation_probability)(afl_state_t *afl); u8 (*afl_custom_havoc_mutation_probability)(afl_state_t* afl);
/** /**
* Determine whether the fuzzer should fuzz the current queue entry or not. * Determine whether the fuzzer should fuzz the current queue entry or not.
@ -680,7 +682,7 @@ struct custom_mutator {
* @return Return True(1) if the fuzzer will fuzz the queue entry, and * @return Return True(1) if the fuzzer will fuzz the queue entry, and
* False(0) otherwise. * False(0) otherwise.
*/ */
u8 (*afl_custom_queue_get)(afl_state_t *afl, 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 * Allow for additional analysis (e.g. calling a different tool that does a
@ -692,14 +694,13 @@ struct custom_mutator {
* @param filename_orig_queue File name of the original queue entry. This * @param filename_orig_queue File name of the original queue entry. This
* argument can be NULL while initializing the fuzzer * argument can be NULL while initializing the fuzzer
*/ */
void (*afl_custom_queue_new_entry)(afl_state_t *afl, const u8* filename_new_queue, void (*afl_custom_queue_new_entry)(afl_state_t* afl,
const u8* filename_orig_queue); const u8* filename_new_queue,
const u8* filename_orig_queue);
}; };
void afl_state_init(afl_state_t*);
void afl_state_init(afl_state_t *);
void afl_state_deinit(afl_state_t*); void afl_state_deinit(afl_state_t*);
/**** Prototypes ****/ /**** Prototypes ****/
@ -707,13 +708,13 @@ void afl_state_deinit(afl_state_t*);
/* Custom mutators */ /* Custom mutators */
void setup_custom_mutator(afl_state_t*); void setup_custom_mutator(afl_state_t*);
void destroy_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); u8 trim_case_custom(afl_state_t*, struct queue_entry* q, u8* in_buf);
/* Python */ /* Python */
#ifdef USE_PYTHON #ifdef USE_PYTHON
int init_py_module(afl_state_t*, u8*); int init_py_module(afl_state_t*, u8*);
void finalize_py_module(afl_state_t*); void finalize_py_module(afl_state_t*);
void init_py(afl_state_t*, unsigned int); 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 fuzz_py(afl_state_t*, u8**, size_t, u8*, size_t, size_t);
@ -721,7 +722,7 @@ size_t pre_save_py(afl_state_t*, u8*, size_t, u8**);
u32 init_trim_py(afl_state_t*, u8*, size_t); u32 init_trim_py(afl_state_t*, u8*, size_t);
u32 post_trim_py(afl_state_t*, u8); u32 post_trim_py(afl_state_t*, u8);
void trim_py(afl_state_t*, u8**, size_t*); void trim_py(afl_state_t*, u8**, size_t*);
size_t havoc_mutation_py(afl_state_t *, u8**, size_t, size_t); size_t havoc_mutation_py(afl_state_t*, u8**, size_t, size_t);
u8 havoc_mutation_probability_py(afl_state_t*); u8 havoc_mutation_probability_py(afl_state_t*);
u8 queue_get_py(afl_state_t*, const u8*); u8 queue_get_py(afl_state_t*, const u8*);
void queue_new_entry_py(afl_state_t*, const u8*, const u8*); void queue_new_entry_py(afl_state_t*, const u8*, const u8*);
@ -759,7 +760,7 @@ void minimize_bits(u8*, u8*);
u8* describe_op(afl_state_t*, u8); u8* describe_op(afl_state_t*, u8);
#endif #endif
u8 save_if_interesting(afl_state_t*, void*, u32, u8); u8 save_if_interesting(afl_state_t*, void*, u32, u8);
u8 has_new_bits(afl_state_t *, u8*); u8 has_new_bits(afl_state_t*, u8*);
/* Misc */ /* Misc */
@ -830,11 +831,11 @@ void save_cmdline(afl_state_t*, u32, char**);
/* CmpLog */ /* CmpLog */
void init_cmplog_forkserver(afl_state_t *afl); void init_cmplog_forkserver(afl_state_t* afl);
u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len); u8 common_fuzz_cmplog_stuff(afl_state_t* afl, u8* out_buf, u32 len);
/* RedQueen */ /* RedQueen */
u8 input_to_state_stage(afl_state_t *afl, 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); u32 exec_cksum);
/**** Inline routines ****/ /**** Inline routines ****/
@ -842,7 +843,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8* orig_buf, u8* buf, u32 len,
/* Generate a random number (from 0 to limit - 1). This may /* Generate a random number (from 0 to limit - 1). This may
have slight bias. */ have slight bias. */
static inline u32 UR(afl_state_t *afl, u32 limit) { static inline u32 UR(afl_state_t* afl, u32 limit) {
#ifdef HAVE_ARC4RANDOM #ifdef HAVE_ARC4RANDOM
if (afl->fixed_seed) { return random() % limit; } if (afl->fixed_seed) { return random() % limit; }
@ -853,7 +854,8 @@ static inline u32 UR(afl_state_t *afl, u32 limit) {
#else #else
if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) { if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) {
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom"); ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
"/dev/urandom");
srandom(afl->rand_seed[0]); srandom(afl->rand_seed[0]);
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG); afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
@ -864,7 +866,7 @@ static inline u32 UR(afl_state_t *afl, u32 limit) {
} }
static inline u32 get_rand_seed(afl_state_t *afl) { static inline u32 get_rand_seed(afl_state_t* afl) {
if (afl->fixed_seed) return (u32)afl->init_seed; if (afl->fixed_seed) return (u32)afl->init_seed;
return afl->rand_seed[0]; return afl->rand_seed[0];

View File

@ -1,4 +1,5 @@
/* If we know we'll reuse small elements often, we'll just preallocate a buffer, then fall back to malloc */ /* 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 // TODO: Replace free status check with bitmask+CLZ
#ifndef AFL_PREALLOC_H #ifndef AFL_PREALLOC_H
@ -11,91 +12,109 @@
#include "debug.h" #include "debug.h"
typedef enum prealloc_status { 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;
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 */ /* Adds the entry used for prealloc bookkeeping to this struct */
#define PREALLOCABLE ;pre_status_t pre_status; /* prealloc status of this instance */ #define PREALLOCABLE \
; \
pre_status_t pre_status; /* prealloc status of this instance */
/* allocate an element of type *el_ptr, to this variable. /* allocate an element of type *el_ptr, to this variable.
Uses (and reuses) the given prealloc_buf before hitting libc's malloc. Uses (and reuses) the given prealloc_buf before hitting libc's malloc.
prealloc_buf must be the pointer to an array with type `type`. 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). `type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status
prealloc_size must be the array size. member). prealloc_size must be the array size. prealloc_counter must be a
prealloc_counter must be a variable initialized with 0 (of any name). variable initialized with 0 (of any name).
*/ */
#define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) do { \ #define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) \
\ do { \
if ((prealloc_counter) >= (prealloc_size)) { \ \
\ if ((prealloc_counter) >= (prealloc_size)) { \
el_ptr = malloc(sizeof(*el_ptr)); \ \
el_ptr->pre_status = PRE_STATUS_MALLOC; \ el_ptr = malloc(sizeof(*el_ptr)); \
\ el_ptr->pre_status = PRE_STATUS_MALLOC; \
} else { \ \
\ } else { \
/* Find one of our preallocated elements */ \ \
u32 i; \ /* Find one of our preallocated elements */ \
for (i = 0; i < (prealloc_size); i++) { \ u32 i; \
\ for (i = 0; i < (prealloc_size); i++) { \
el_ptr = &((prealloc_buf)[i]); \ \
if (el_ptr->pre_status == PRE_STATUS_UNUSED) { \ el_ptr = &((prealloc_buf)[i]); \
\ if (el_ptr->pre_status == PRE_STATUS_UNUSED) { \
(prealloc_counter)++; \ \
el_ptr->pre_status = PRE_STATUS_USED; \ (prealloc_counter)++; \
break; \ el_ptr->pre_status = PRE_STATUS_USED; \
\ break; \
} \ \
} \ } \
} \ \
\ } \
if(!el_ptr) { \ \
FATAL("BUG in list.h -> no element found or allocated!"); \ } \
} \ \
} while(0); 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 */ /* Take a chosen (free) element from the prealloc_buf directly */
#define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) do { \ #define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) \
if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \ do { \
FATAL("PRE_ALLOC_FORCE element already allocated"); \ \
} \ if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \
(el_ptr)->pre_status = PRE_STATUS_USED; \ \
(prealloc_counter)++; \ FATAL("PRE_ALLOC_FORCE element already allocated"); \
} while(0); \
} \
(el_ptr)->pre_status = PRE_STATUS_USED; \
(prealloc_counter)++; \
\
} while (0);
/* free an preallocated element */ /* free an preallocated element */
#define PRE_FREE(el_ptr, prealloc_counter) do { \ #define PRE_FREE(el_ptr, prealloc_counter) \
\ do { \
switch ((el_ptr)->pre_status) { \ \
\ switch ((el_ptr)->pre_status) { \
case PRE_STATUS_USED: { \ \
(el_ptr)->pre_status = PRE_STATUS_UNUSED; \ case PRE_STATUS_USED: { \
(prealloc_counter)--; \ \
if ((prealloc_counter) < 0) { \ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
FATAL("Inconsistent data in PRE_FREE"); \ (prealloc_counter)--; \
} \ if ((prealloc_counter) < 0) { \
break; \ \
} \ FATAL("Inconsistent data in PRE_FREE"); \
case PRE_STATUS_MALLOC: { \ \
(el_ptr)->pre_status = PRE_STATUS_UNUSED; \ } \
free((el_ptr)); \ break; \
break; \ \
} \ } \
default: { \ case PRE_STATUS_MALLOC: { \
FATAL("Double Free Detected"); \ \
break; \ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
} \ free((el_ptr)); \
\ break; \
} \ \
} while(0); } \
default: { \
\
FATAL("Double Free Detected"); \
break; \
\
} \
\
} \
\
} while (0);
#endif #endif

View File

@ -33,8 +33,8 @@
void detect_file_args(char** argv, u8* prog_in, u8 use_stdin); void detect_file_args(char** argv, u8* prog_in, u8 use_stdin);
void check_environment_vars(char** env); void check_environment_vars(char** env);
char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv); 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_wine_argv(u8* own_loc, u8** target_path_p, int argc, char** argv);
char* get_afl_env(char* env); char* get_afl_env(char* env);
/* Get unix time in milliseconds */ /* Get unix time in milliseconds */
@ -64,3 +64,4 @@ static u64 get_cur_time_us(void) {
} }
#endif #endif

View File

@ -33,36 +33,34 @@ typedef struct afl_forkserver {
/* a program that includes afl-forkserver needs to define these */ /* a program that includes afl-forkserver needs to define these */
u8 uses_asan; /* Target uses ASAN? */ u8 uses_asan; /* Target uses ASAN? */
u8* trace_bits; /* SHM with instrumentation bitmap */ u8 *trace_bits; /* SHM with instrumentation bitmap */
u8 use_stdin; /* use stdin for sending data */ u8 use_stdin; /* use stdin for sending data */
s32 fsrv_pid, /* PID of the fork server */ s32 fsrv_pid, /* PID of the fork server */
child_pid, /* PID of the fuzzed program */ child_pid, /* PID of the fuzzed program */
out_dir_fd; /* FD of the lock file */ out_dir_fd; /* FD of the lock file */
s32 out_fd, /* Persistent fd for afl->fsrv.out_file */ s32 out_fd, /* Persistent fd for afl->fsrv.out_file */
#ifndef HAVE_ARC4RANDOM #ifndef HAVE_ARC4RANDOM
dev_urandom_fd, /* Persistent fd for /dev/urandom */ dev_urandom_fd, /* Persistent fd for /dev/urandom */
#endif #endif
dev_null_fd, /* Persistent fd for /dev/null */ dev_null_fd, /* Persistent fd for /dev/null */
fsrv_ctl_fd, /* Fork server control pipe (write) */ fsrv_ctl_fd, /* Fork server control pipe (write) */
fsrv_st_fd; /* Fork server status pipe (read) */ fsrv_st_fd; /* Fork server status pipe (read) */
u32 exec_tmout; /* Configurable exec timeout (ms) */ u32 exec_tmout; /* Configurable exec timeout (ms) */
u64 mem_limit; /* Memory cap for child (MB) */ u64 mem_limit; /* Memory cap for child (MB) */
u8 *out_file, /* File to fuzz, if any */ u8 *out_file, /* File to fuzz, if any */
*target_path; /* Path of the target */ *target_path; /* Path of the target */
FILE* plot_file; /* Gnuplot output file */ FILE *plot_file; /* Gnuplot output file */
u8 child_timed_out; /* Traced process timed out? */ u8 child_timed_out; /* Traced process timed out? */
} afl_forkserver_t; } afl_forkserver_t;
void handle_timeout(int sig); void handle_timeout(int sig);
void afl_fsrv_init(afl_forkserver_t *fsrv); void afl_fsrv_init(afl_forkserver_t *fsrv);
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv); void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv);

View File

@ -8,21 +8,23 @@
#include "debug.h" #include "debug.h"
#include "afl-prealloc.h" #include "afl-prealloc.h"
#define LIST_PREALLOC_SIZE (64) /* How many elements to allocate before malloc is needed */ #define LIST_PREALLOC_SIZE \
(64) /* How many elements to allocate before malloc is needed */
typedef struct list_element { typedef struct list_element {
PREALLOCABLE; PREALLOCABLE;
struct list_element *prev; struct list_element *prev;
struct list_element *next; struct list_element *next;
void *data; void * data;
} element_t; } element_t;
typedef struct list { typedef struct list {
element_t element_prealloc_buf[LIST_PREALLOC_SIZE]; element_t element_prealloc_buf[LIST_PREALLOC_SIZE];
u32 element_prealloc_count; u32 element_prealloc_count;
} list_t; } list_t;
@ -52,7 +54,8 @@ static void list_append(list_t *list, void *el) {
} }
element_t *el_box = NULL; element_t *el_box = NULL;
PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE, list->element_prealloc_count); PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE,
list->element_prealloc_count);
if (!el_box) FATAL("failed to allocate list element"); if (!el_box) FATAL("failed to allocate list element");
el_box->data = el; el_box->data = el;
el_box->next = head; el_box->next = head;
@ -68,53 +71,69 @@ static void list_append(list_t *list, void *el) {
A return from this block will return from calling func. A return from this block will return from calling func.
*/ */
#define LIST_FOREACH(list, type, block) do { \ #define LIST_FOREACH(list, type, block) \
list_t *li = (list); \ do { \
element_t *head = get_head((li)); \ \
element_t *el_box = (head)->next; \ list_t * li = (list); \
if (!el_box) \ element_t *head = get_head((li)); \
FATAL("foreach over uninitialized list");\ element_t *el_box = (head)->next; \
while(el_box != head) { \ if (!el_box) FATAL("foreach over uninitialized list"); \
type *el = (type *)((el_box)->data); \ while (el_box != head) { \
/* get next so el_box can be unlinked */ \ \
element_t *next = el_box->next; \ type *el = (type *)((el_box)->data); \
{block}; \ /* get next so el_box can be unlinked */ \
el_box = next; \ element_t *next = el_box->next; \
} \ {block}; \
} while(0); el_box = next; \
\
} \
\
} while (0);
/* In foreach: remove the current el from the list */ /* In foreach: remove the current el from the list */
#define LIST_REMOVE_CURRENT_EL_IN_FOREACH() do { \ #define LIST_REMOVE_CURRENT_EL_IN_FOREACH() \
el_box->prev->next = next; \ do { \
el_box->next->prev = el_box->prev; \ \
list_free_el(li, el_box); \ el_box->prev->next = next; \
} while(0); 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 */ /* Same as foreach, but will clear list in the process */
#define LIST_FOREACH_CLEAR(list, type, block) do { \ #define LIST_FOREACH_CLEAR(list, type, block) \
LIST_FOREACH((list), type, { \ do { \
{block}; \ \
LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \ LIST_FOREACH((list), type, { \
}); \ \
} while(0); {block}; \
LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \
\
}); \
\
} while (0);
/* remove an item from the list */ /* remove an item from the list */
static void list_remove(list_t *list, void *remove_me) { static void list_remove(list_t *list, void *remove_me) {
LIST_FOREACH(list, void, { LIST_FOREACH(list, void, {
if (el == remove_me) { if (el == remove_me) {
el_box->prev->next = el_box->next; el_box->prev->next = el_box->next;
el_box->next->prev = el_box->prev; el_box->next->prev = el_box->prev;
el_box->data = NULL; el_box->data = NULL;
list_free_el(list, el_box); list_free_el(list, el_box);
return; return;
} }
}); });
FATAL ("List item to be removed not in list"); FATAL("List item to be removed not in list");
} }
@ -123,7 +142,9 @@ static void list_remove(list_t *list, void *remove_me) {
static bool list_contains(list_t *list, void *contains_me) { static bool list_contains(list_t *list, void *contains_me) {
LIST_FOREACH(list, void, { LIST_FOREACH(list, void, {
if (el == contains_me) return true; if (el == contains_me) return true;
}); });
return false; return false;

View File

@ -29,30 +29,30 @@
typedef struct sharedmem { typedef struct sharedmem {
//extern unsigned char *trace_bits; // extern unsigned char *trace_bits;
#ifdef USEMMAP #ifdef USEMMAP
/* ================ Proteas ================ */ /* ================ Proteas ================ */
int g_shm_fd; int g_shm_fd;
char g_shm_file_path[L_tmpnam]; char g_shm_file_path[L_tmpnam];
/* ========================================= */ /* ========================================= */
#else #else
s32 shm_id; /* ID of the SHM region */ s32 shm_id; /* ID of the SHM region */
s32 cmplog_shm_id; s32 cmplog_shm_id;
#endif #endif
u8 *map; /* shared memory region */ u8 *map; /* shared memory region */
size_t size_alloc; /* actual allocated size */ size_t size_alloc; /* actual allocated size */
size_t size_used; /* in use by shmem app */ size_t size_used; /* in use by shmem app */
int cmplog_mode; int cmplog_mode;
struct cmp_map *cmp_map; struct cmp_map *cmp_map;
} sharedmem_t; } sharedmem_t;
u8 *afl_shm_init(sharedmem_t*, size_t, unsigned char dumb_mode); u8 * afl_shm_init(sharedmem_t *, size_t, unsigned char dumb_mode);
void afl_shm_deinit(sharedmem_t*); void afl_shm_deinit(sharedmem_t *);
#endif #endif

View File

@ -84,7 +84,7 @@ static volatile u8 stop_soon, /* Ctrl-C pressed? */
static u8 qemu_mode; static u8 qemu_mode;
static u8 *target_path; static u8* target_path;
/* Constants used for describing byte behavior. */ /* Constants used for describing byte behavior. */
@ -1014,9 +1014,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &target_path, argc - optind, argv + optind); use_argv =
get_wine_argv(argv[0], &target_path, argc - optind, argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind); use_argv =
get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind);
} else } else

View File

@ -38,7 +38,7 @@
extern u8 be_quiet; extern u8 be_quiet;
void detect_file_args(char **argv, u8 *prog_in, u8 use_stdin) { void detect_file_args(char** argv, u8* prog_in, u8 use_stdin) {
u32 i = 0; u32 i = 0;
#ifdef __GLIBC__ #ifdef __GLIBC__
@ -110,7 +110,7 @@ void detect_file_args(char **argv, u8 *prog_in, u8 use_stdin) {
/* Rewrite argv for QEMU. */ /* Rewrite argv for QEMU. */
char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) { char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv) {
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4)); char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
u8 * tmp, *cp = NULL, *rsl, *own_copy; u8 * tmp, *cp = NULL, *rsl, *own_copy;
@ -168,7 +168,8 @@ char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the 'afl-qemu-trace' binary. The binary must be " "Oops, unable to find the 'afl-qemu-trace' binary. The binary must be "
"built\n" "built\n"
" separately by following the instructions in afl->qemu_mode/README.md. " " separately by following the instructions in "
"afl->qemu_mode/README.md. "
"If you\n" "If you\n"
" already have the binary installed, you may need to specify " " already have the binary installed, you may need to specify "
"AFL_PATH in the\n" "AFL_PATH in the\n"
@ -187,7 +188,7 @@ char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) {
/* Rewrite argv for Wine+QEMU. */ /* Rewrite argv for Wine+QEMU. */
char** get_wine_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** new_argv = ck_alloc(sizeof(char*) * (argc + 3)); char** new_argv = ck_alloc(sizeof(char*) * (argc + 3));
u8 * tmp, *cp = NULL, *rsl, *own_copy; u8 * tmp, *cp = NULL, *rsl, *own_copy;
@ -264,7 +265,8 @@ char** get_wine_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the '%s' binary. The binary must be " "Oops, unable to find the '%s' binary. The binary must be "
"built\n" "built\n"
" separately by following the instructions in afl->qemu_mode/README.md. " " separately by following the instructions in "
"afl->qemu_mode/README.md. "
"If you\n" "If you\n"
" already have the binary installed, you may need to specify " " already have the binary installed, you may need to specify "
"AFL_PATH in the\n" "AFL_PATH in the\n"
@ -329,3 +331,4 @@ char* get_afl_env(char* env) {
return val; return val;
} }

View File

@ -114,7 +114,7 @@ void handle_timeout(int sig) {
LIST_FOREACH(&fsrv_list, afl_forkserver_t, { LIST_FOREACH(&fsrv_list, afl_forkserver_t, {
//TODO: We need a proper timer to handle multiple timeouts // TODO: We need a proper timer to handle multiple timeouts
if (el->child_pid > 0) { if (el->child_pid > 0) {
el->child_timed_out = 1; el->child_timed_out = 1;
@ -465,8 +465,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
void afl_fsrv_killall() { void afl_fsrv_killall() {
LIST_FOREACH(&fsrv_list, afl_forkserver_t, { LIST_FOREACH(&fsrv_list, afl_forkserver_t, {
if (el->child_pid > 0) kill(el->child_pid, SIGKILL); if (el->child_pid > 0) kill(el->child_pid, SIGKILL);
}); });
} }
void afl_fsrv_deinit(afl_forkserver_t *fsrv) { void afl_fsrv_deinit(afl_forkserver_t *fsrv) {
@ -474,3 +477,4 @@ void afl_fsrv_deinit(afl_forkserver_t *fsrv) {
list_remove(&fsrv_list, fsrv); list_remove(&fsrv_list, fsrv);
} }

View File

@ -29,7 +29,7 @@
-B option, to focus a separate fuzzing session on a particular -B option, to focus a separate fuzzing session on a particular
interesting input without rediscovering all the others. */ interesting input without rediscovering all the others. */
void write_bitmap(afl_state_t *afl) { void write_bitmap(afl_state_t* afl) {
u8* fname; u8* fname;
s32 fd; s32 fd;
@ -51,7 +51,7 @@ void write_bitmap(afl_state_t *afl) {
/* Read bitmap from file. This is for the -B option again. */ /* Read bitmap from file. This is for the -B option again. */
void read_bitmap(afl_state_t *afl, u8* fname) { void read_bitmap(afl_state_t* afl, u8* fname) {
s32 fd = open(fname, O_RDONLY); s32 fd = open(fname, O_RDONLY);
@ -71,7 +71,7 @@ void read_bitmap(afl_state_t *afl, u8* fname) {
This function is called after every exec() on a fairly large buffer, so This function is called after every exec() on a fairly large buffer, so
it needs to be fast. We do this in 32-bit and 64-bit flavors. */ it needs to be fast. We do this in 32-bit and 64-bit flavors. */
u8 has_new_bits(afl_state_t *afl, u8* virgin_map) { u8 has_new_bits(afl_state_t* afl, u8* virgin_map) {
#ifdef WORD_SIZE_64 #ifdef WORD_SIZE_64
@ -415,9 +415,9 @@ void minimize_bits(u8* dst, u8* src) {
/* Construct a file name for a new test case, capturing the operation /* Construct a file name for a new test case, capturing the operation
that led to its discovery. Uses a static buffer. */ that led to its discovery. Uses a static buffer. */
u8* describe_op(afl_state_t *afl, u8 hnb) { u8* describe_op(afl_state_t* afl, u8 hnb) {
u8 *ret = afl->describe_op_buf_256; u8* ret = afl->describe_op_buf_256;
if (afl->syncing_party) { if (afl->syncing_party) {
@ -429,7 +429,8 @@ u8* describe_op(afl_state_t *afl, u8 hnb) {
sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
if (afl->splicing_with >= 0) sprintf(ret + strlen(ret), "+%06d", afl->splicing_with); if (afl->splicing_with >= 0)
sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
sprintf(ret + strlen(ret), ",op:%s", afl->stage_short); sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
@ -439,7 +440,8 @@ u8* describe_op(afl_state_t *afl, u8 hnb) {
if (afl->stage_val_type != STAGE_VAL_NONE) if (afl->stage_val_type != STAGE_VAL_NONE)
sprintf(ret + strlen(ret), ",val:%s%+d", sprintf(ret + strlen(ret), ",val:%s%+d",
(afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "", afl->stage_cur_val); (afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "",
afl->stage_cur_val);
} else } else
@ -457,7 +459,7 @@ u8* describe_op(afl_state_t *afl, u8 hnb) {
/* Write a message accompanying the crash directory :-) */ /* Write a message accompanying the crash directory :-) */
static void write_crash_readme(afl_state_t *afl) { static void write_crash_readme(afl_state_t* afl) {
u8* fn = alloc_printf("%s/crashes/README.txt", afl->out_dir); u8* fn = alloc_printf("%s/crashes/README.txt", afl->out_dir);
s32 fd; s32 fd;
@ -499,7 +501,7 @@ static void write_crash_readme(afl_state_t *afl) {
" https://github.com/vanhauser-thc/AFLplusplus\n\n", " https://github.com/vanhauser-thc/AFLplusplus\n\n",
afl->orig_cmdline, DMS(afl->fsrv.mem_limit << 20)); /* ignore errors */ afl->orig_cmdline, DMS(afl->fsrv.mem_limit << 20)); /* ignore errors */
fclose(f); fclose(f);
@ -509,7 +511,7 @@ static void write_crash_readme(afl_state_t *afl) {
save or queue the input test case for further analysis if so. Returns 1 if save or queue the input test case for further analysis if so. Returns 1 if
entry is saved, 0 otherwise. */ entry is saved, 0 otherwise. */
u8 save_if_interesting(afl_state_t *afl, void* mem, u32 len, u8 fault) { u8 save_if_interesting(afl_state_t* afl, void* mem, u32 len, u8 fault) {
if (len == 0) return 0; if (len == 0) return 0;
@ -634,8 +636,8 @@ u8 save_if_interesting(afl_state_t *afl, void* mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES #ifndef SIMPLE_FILES
fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir, afl->unique_hangs, fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir,
describe_op(afl, 0)); afl->unique_hangs, describe_op(afl, 0));
#else #else
@ -678,19 +680,21 @@ u8 save_if_interesting(afl_state_t *afl, void* mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES #ifndef SIMPLE_FILES
fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); afl->unique_crashes, afl->kill_signal,
describe_op(afl, 0));
#else #else
fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir, afl->unique_crashes, fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir,
afl->kill_signal); afl->unique_crashes, afl->kill_signal);
#endif /* ^!SIMPLE_FILES */ #endif /* ^!SIMPLE_FILES */
++afl->unique_crashes; ++afl->unique_crashes;
if (afl->infoexec) { // if the user wants to be informed on new crashes - do if (afl->infoexec) { // if the user wants to be informed on new crashes -
// do
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
// that // that
if (system(afl->infoexec) == -1) if (system(afl->infoexec) == -1)
hnb += 0; // we dont care if system errors, but we dont want a hnb += 0; // we dont care if system errors, but we dont want a
// compiler warning either // compiler warning either

View File

@ -81,8 +81,9 @@ void init_cmplog_forkserver(afl_state_t *afl) {
// r.rlim_max = r.rlim_cur = 0; // r.rlim_max = r.rlim_cur = 0;
// setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ // setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -156,7 +157,7 @@ void init_cmplog_forkserver(afl_state_t *afl) {
/* Use a distinctive bitmap signature to tell the parent about execv() /* Use a distinctive bitmap signature to tell the parent about execv()
falling through. */ falling through. */
*(u32*)afl->fsrv.trace_bits = EXEC_FAIL_SIG; *(u32 *)afl->fsrv.trace_bits = EXEC_FAIL_SIG;
exit(0); exit(0);
} }
@ -176,7 +177,8 @@ void init_cmplog_forkserver(afl_state_t *afl) {
if (afl->fsrv.exec_tmout) { if (afl->fsrv.exec_tmout) {
it.it_value.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000); it.it_value.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000);
it.it_value.tv_usec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000; it.it_value.tv_usec =
((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;
} }
@ -204,11 +206,13 @@ void init_cmplog_forkserver(afl_state_t *afl) {
"Timeout while initializing cmplog fork server (adjusting -t may " "Timeout while initializing cmplog fork server (adjusting -t may "
"help)"); "help)");
if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
if (WIFSIGNALED(status)) { if (WIFSIGNALED(status)) {
if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 && afl->fsrv.uses_asan) { if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 &&
afl->fsrv.uses_asan) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, " "Whoops, the target binary crashed suddenly, "
@ -281,7 +285,7 @@ void init_cmplog_forkserver(afl_state_t *afl) {
} }
if (*(u32*)afl->fsrv.trace_bits == EXEC_FAIL_SIG) if (*(u32 *)afl->fsrv.trace_bits == EXEC_FAIL_SIG)
FATAL("Unable to execute target application ('%s')", afl->argv[0]); FATAL("Unable to execute target application ('%s')", afl->argv[0]);
if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 && afl->fsrv.uses_asan) { if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 && afl->fsrv.uses_asan) {
@ -400,8 +404,9 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -449,7 +454,7 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
/* Use a distinctive bitmap value to tell the parent about execv() /* Use a distinctive bitmap value to tell the parent about execv()
falling through. */ falling through. */
*(u32*)afl->fsrv.trace_bits = EXEC_FAIL_SIG; *(u32 *)afl->fsrv.trace_bits = EXEC_FAIL_SIG;
exit(0); exit(0);
} }
@ -495,7 +500,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
if (afl->dumb_mode == 1 || afl->no_forkserver) { if (afl->dumb_mode == 1 || afl->no_forkserver) {
if (waitpid(afl->cmplog_child_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->cmplog_child_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
} else { } else {
@ -540,17 +546,17 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
++afl->total_execs; ++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
compiler below this point. Past this location, afl->fsrv.trace_bits[] behave compiler below this point. Past this location, afl->fsrv.trace_bits[]
very normally and do not have to be treated as volatile. */ behave very normally and do not have to be treated as volatile. */
MEM_BARRIER(); MEM_BARRIER();
tb4 = *(u32*)afl->fsrv.trace_bits; tb4 = *(u32 *)afl->fsrv.trace_bits;
#ifdef WORD_SIZE_64 #ifdef WORD_SIZE_64
classify_counts((u64*)afl->fsrv.trace_bits); classify_counts((u64 *)afl->fsrv.trace_bits);
#else #else
classify_counts((u32*)afl->fsrv.trace_bits); classify_counts((u32 *)afl->fsrv.trace_bits);
#endif /* ^WORD_SIZE_64 */ #endif /* ^WORD_SIZE_64 */
prev_timed_out = afl->fsrv.child_timed_out; prev_timed_out = afl->fsrv.child_timed_out;
@ -561,7 +567,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
afl->kill_signal = WTERMSIG(status); afl->kill_signal = WTERMSIG(status);
if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL) return FAULT_TMOUT; if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL)
return FAULT_TMOUT;
return FAULT_CRASH; return FAULT_CRASH;
@ -584,7 +591,7 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
} }
u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8* out_buf, u32 len) { u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault; u8 fault;
@ -627,10 +634,11 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8* out_buf, u32 len) {
/* This handles FAULT_ERROR for us: */ /* This handles FAULT_ERROR for us: */
/* afl->queued_discovered += save_if_interesting(afl, argv, out_buf, len, fault); /* afl->queued_discovered += save_if_interesting(afl, argv, out_buf, len,
fault);
if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 == afl->stage_max) if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 ==
show_stats(afl); */ afl->stage_max) show_stats(afl); */
return 0; return 0;

View File

@ -45,7 +45,8 @@ static int compare_extras_use_d(const void* p1, const void* p2) {
/* Read extras from a file, sort by size. */ /* Read extras from a file, sort by size. */
void load_extras_file(afl_state_t *afl, u8* fname, u32* min_len, u32* max_len, u32 dict_level) { void load_extras_file(afl_state_t* afl, u8* fname, u32* min_len, u32* max_len,
u32 dict_level) {
FILE* f; FILE* f;
u8 buf[MAX_LINE]; u8 buf[MAX_LINE];
@ -120,8 +121,8 @@ void load_extras_file(afl_state_t *afl, u8* fname, u32* min_len, u32* max_len, u
/* Okay, let's allocate memory and copy data between "...", handling /* Okay, let's allocate memory and copy data between "...", handling
\xNN escaping, \\, and \". */ \xNN escaping, \\, and \". */
afl->extras = afl->extras = ck_realloc_block(
ck_realloc_block(afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr); wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
@ -183,7 +184,7 @@ void load_extras_file(afl_state_t *afl, u8* fname, u32* min_len, u32* max_len, u
/* Read extras from the extras directory and sort them by size. */ /* Read extras from the extras directory and sort them by size. */
void load_extras(afl_state_t *afl, u8* dir) { void load_extras(afl_state_t* afl, u8* dir) {
DIR* d; DIR* d;
struct dirent* de; struct dirent* de;
@ -241,8 +242,8 @@ void load_extras(afl_state_t *afl, u8* dir) {
if (min_len > st.st_size) min_len = st.st_size; if (min_len > st.st_size) min_len = st.st_size;
if (max_len < st.st_size) max_len = st.st_size; if (max_len < st.st_size) max_len = st.st_size;
afl->extras = afl->extras = ck_realloc_block(
ck_realloc_block(afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size); afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size);
afl->extras[afl->extras_cnt].len = st.st_size; afl->extras[afl->extras_cnt].len = st.st_size;
@ -266,10 +267,11 @@ check_and_sort:
if (!afl->extras_cnt) FATAL("No usable files in '%s'", dir); if (!afl->extras_cnt) FATAL("No usable files in '%s'", dir);
qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
compare_extras_len);
OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, DMS(min_len), OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt,
DMS(max_len)); DMS(min_len), DMS(max_len));
if (max_len > 32) if (max_len > 32)
WARNF("Some tokens are relatively large (%s) - consider trimming.", WARNF("Some tokens are relatively large (%s) - consider trimming.",
@ -293,7 +295,7 @@ static inline u8 memcmp_nocase(u8* m1, u8* m2, u32 len) {
/* Maybe add automatic extra. */ /* Maybe add automatic extra. */
void maybe_add_auto(afl_state_t *afl, u8* mem, u32 len) { void maybe_add_auto(afl_state_t* afl, u8* mem, u32 len) {
u32 i; u32 i;
@ -349,7 +351,8 @@ void maybe_add_auto(afl_state_t *afl, u8* mem, u32 len) {
for (i = 0; i < afl->a_extras_cnt; ++i) { for (i = 0; i < afl->a_extras_cnt; ++i) {
if (afl->a_extras[i].len == len && !memcmp_nocase(afl->a_extras[i].data, mem, len)) { if (afl->a_extras[i].len == len &&
!memcmp_nocase(afl->a_extras[i].data, mem, len)) {
afl->a_extras[i].hit_cnt++; afl->a_extras[i].hit_cnt++;
goto sort_a_extras; goto sort_a_extras;
@ -364,8 +367,8 @@ void maybe_add_auto(afl_state_t *afl, u8* mem, u32 len) {
if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) { if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) {
afl->a_extras = ck_realloc_block(afl->a_extras, afl->a_extras = ck_realloc_block(
(afl->a_extras_cnt + 1) * sizeof(struct extra_data)); afl->a_extras, (afl->a_extras_cnt + 1) * sizeof(struct extra_data));
afl->a_extras[afl->a_extras_cnt].data = ck_memdup(mem, len); afl->a_extras[afl->a_extras_cnt].data = ck_memdup(mem, len);
afl->a_extras[afl->a_extras_cnt].len = len; afl->a_extras[afl->a_extras_cnt].len = len;
@ -392,14 +395,14 @@ sort_a_extras:
/* Then, sort the top USE_AUTO_EXTRAS entries by size. */ /* Then, sort the top USE_AUTO_EXTRAS entries by size. */
qsort(afl->a_extras, MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt), sizeof(struct extra_data), qsort(afl->a_extras, MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt),
compare_extras_len); sizeof(struct extra_data), compare_extras_len);
} }
/* Save automatically generated extras. */ /* Save automatically generated extras. */
void save_auto(afl_state_t *afl) { void save_auto(afl_state_t* afl) {
u32 i; u32 i;
@ -408,7 +411,8 @@ void save_auto(afl_state_t *afl) {
for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) { for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
u8* fn = alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i); u8* fn =
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
s32 fd; s32 fd;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
@ -426,7 +430,7 @@ void save_auto(afl_state_t *afl) {
/* Load automatically generated extras. */ /* Load automatically generated extras. */
void load_auto(afl_state_t *afl) { void load_auto(afl_state_t* afl) {
u32 i; u32 i;
@ -470,7 +474,7 @@ void load_auto(afl_state_t *afl) {
/* Destroy extras. */ /* Destroy extras. */
void destroy_extras(afl_state_t *afl) { void destroy_extras(afl_state_t* afl) {
u32 i; u32 i;

View File

@ -32,11 +32,11 @@ s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
char *power_names[POWER_SCHEDULES_NUM] = {"explore", "fast", "coe", char *power_names[POWER_SCHEDULES_NUM] = {"explore", "fast", "coe",
"lin", "quad", "exploit"}; "lin", "quad", "exploit"};
u8 *doc_path = NULL; /* gath to documentation dir */ u8 *doc_path = NULL; /* gath to documentation dir */
/* Initialize MOpt "globals" for this afl state */ /* Initialize MOpt "globals" for this afl state */
static void init_mopt_globals(afl_state_t *afl){ static void init_mopt_globals(afl_state_t *afl) {
MOpt_globals_t *core = &afl->mopt_globals_pilot; MOpt_globals_t *core = &afl->mopt_globals_pilot;
core->finds = afl->core_operator_finds_puppet; core->finds = afl->core_operator_finds_puppet;
@ -68,7 +68,8 @@ static void init_mopt_globals(afl_state_t *afl){
} }
/* A global pointer to all instances is needed (for now) for signals to arrive */ /* A global pointer to all instances is needed (for now) for signals to arrive
*/
list_t afl_states = {0}; list_t afl_states = {0};
@ -76,45 +77,45 @@ list_t afl_states = {0};
void afl_state_init(afl_state_t *afl) { void afl_state_init(afl_state_t *afl) {
afl->w_init = 0.9; afl->w_init = 0.9;
afl->w_end = 0.3; afl->w_end = 0.3;
afl->g_max = 5000; afl->g_max = 5000;
afl->period_pilot_tmp = 5000.0; afl->period_pilot_tmp = 5000.0;
afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/
afl->havoc_max_mult = HAVOC_MAX_MULT; afl->havoc_max_mult = HAVOC_MAX_MULT;
afl->clear_screen = 1; /* Window resized? */ afl->clear_screen = 1; /* Window resized? */
afl->havoc_div = 1; /* Cycle count divisor for havoc */ afl->havoc_div = 1; /* Cycle count divisor for havoc */
afl->stage_name = "init"; /* Name of the current fuzz stage */ afl->stage_name = "init"; /* Name of the current fuzz stage */
afl->splicing_with = -1; /* Splicing with which test case? */ afl->splicing_with = -1; /* Splicing with which test case? */
#ifdef HAVE_AFFINITY #ifdef HAVE_AFFINITY
afl->cpu_aff = -1; /* Selected CPU core */ afl->cpu_aff = -1; /* Selected CPU core */
#endif /* HAVE_AFFINITY */ #endif /* HAVE_AFFINITY */
afl->fsrv.use_stdin = 1; afl->fsrv.use_stdin = 1;
afl->cal_cycles = CAL_CYCLES; afl->cal_cycles = CAL_CYCLES;
afl->cal_cycles_long = CAL_CYCLES_LONG; afl->cal_cycles_long = CAL_CYCLES_LONG;
afl->fsrv.exec_tmout = EXEC_TIMEOUT; afl->fsrv.exec_tmout = EXEC_TIMEOUT;
afl->hang_tmout = EXEC_TIMEOUT; afl->hang_tmout = EXEC_TIMEOUT;
afl->fsrv.mem_limit = MEM_LIMIT; afl->fsrv.mem_limit = MEM_LIMIT;
afl->stats_update_freq = 1; afl->stats_update_freq = 1;
#ifndef HAVE_ARC4RANDOM #ifndef HAVE_ARC4RANDOM
afl->fsrv.dev_urandom_fd = -1; afl->fsrv.dev_urandom_fd = -1;
#endif #endif
afl->fsrv.dev_null_fd = -1; afl->fsrv.dev_null_fd = -1;
afl->fsrv.child_pid = -1; afl->fsrv.child_pid = -1;
afl->fsrv.out_dir_fd = -1; afl->fsrv.out_dir_fd = -1;
init_mopt_globals(afl); init_mopt_globals(afl);
list_append(&afl_states, afl); list_append(&afl_states, afl);
} }
@ -122,6 +123,6 @@ void afl_state_init(afl_state_t *afl) {
void afl_state_deinit(afl_state_t *afl) { void afl_state_deinit(afl_state_t *afl) {
list_remove(&afl_states, afl); list_remove(&afl_states, afl);
} }

View File

@ -30,7 +30,7 @@
/* Build a list of processes bound to specific cores. Returns -1 if nothing /* Build a list of processes bound to specific cores. Returns -1 if nothing
can be found. Assumes an upper bound of 4k CPUs. */ can be found. Assumes an upper bound of 4k CPUs. */
void bind_to_free_cpu(afl_state_t *afl) { void bind_to_free_cpu(afl_state_t* afl) {
#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
cpu_set_t c; cpu_set_t c;
@ -272,7 +272,7 @@ cpuset_destroy(c);
/* Load postprocessor, if available. */ /* Load postprocessor, if available. */
void setup_post(afl_state_t *afl) { void setup_post(afl_state_t* afl) {
void* dh; void* dh;
u8* fn = get_afl_env("AFL_POST_LIBRARY"); u8* fn = get_afl_env("AFL_POST_LIBRARY");
@ -298,7 +298,7 @@ void setup_post(afl_state_t *afl) {
/* Shuffle an array of pointers. Might be slightly biased. */ /* Shuffle an array of pointers. Might be slightly biased. */
static void shuffle_ptrs(afl_state_t *afl, void** ptrs, u32 cnt) { static void shuffle_ptrs(afl_state_t* afl, void** ptrs, u32 cnt) {
u32 i; u32 i;
@ -316,7 +316,7 @@ static void shuffle_ptrs(afl_state_t *afl, void** ptrs, u32 cnt) {
/* Read all testcases from the input directory, then queue them for testing. /* Read all testcases from the input directory, then queue them for testing.
Called at startup. */ Called at startup. */
void read_testcases(afl_state_t *afl) { void read_testcases(afl_state_t* afl) {
struct dirent** nl; struct dirent** nl;
s32 nl_cnt; s32 nl_cnt;
@ -368,8 +368,8 @@ void read_testcases(afl_state_t *afl) {
struct stat st; struct stat st;
u8* fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); u8* fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name);
u8* dfn = u8* dfn = alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir,
alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); nl[i]->d_name);
u8 passed_det = 0; u8 passed_det = 0;
@ -428,7 +428,7 @@ void read_testcases(afl_state_t *afl) {
/* Examine map coverage. Called once, for first test case. */ /* Examine map coverage. Called once, for first test case. */
static void check_map_coverage(afl_state_t *afl) { static void check_map_coverage(afl_state_t* afl) {
u32 i; u32 i;
@ -444,7 +444,7 @@ static void check_map_coverage(afl_state_t *afl) {
/* Perform dry run of all test cases to confirm that the app is working as /* Perform dry run of all test cases to confirm that the app is working as
expected. This is done only for the initial inputs, and only once. */ expected. This is done only for the initial inputs, and only once. */
void perform_dry_run(afl_state_t *afl) { void perform_dry_run(afl_state_t* afl) {
struct queue_entry* q = afl->queue; struct queue_entry* q = afl->queue;
u32 cal_failures = 0; u32 cal_failures = 0;
@ -493,9 +493,9 @@ void perform_dry_run(afl_state_t *afl) {
if (afl->timeout_given) { if (afl->timeout_given) {
/* The -t nn+ syntax in the command line sets afl->timeout_given to '2' and /* The -t nn+ syntax in the command line sets afl->timeout_given to
instructs afl-fuzz to tolerate but skip queue entries that time '2' and instructs afl-fuzz to tolerate but skip queue entries that
out. */ time out. */
if (afl->timeout_given > 1) { if (afl->timeout_given > 1) {
@ -593,7 +593,8 @@ void perform_dry_run(afl_state_t *afl) {
"other options\n" "other options\n"
" fail, poke <afl-users@googlegroups.com> for " " fail, poke <afl-users@googlegroups.com> for "
"troubleshooting tips.\n", "troubleshooting tips.\n",
DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1, doc_path); DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1,
doc_path);
} else { } else {
@ -702,7 +703,7 @@ static void link_or_copy(u8* old_path, u8* new_path) {
/* Create hard links for input test cases in the output directory, choosing /* Create hard links for input test cases in the output directory, choosing
good names and pivoting accordingly. */ good names and pivoting accordingly. */
void pivot_inputs(afl_state_t *afl) { void pivot_inputs(afl_state_t* afl) {
struct queue_entry* q = afl->queue; struct queue_entry* q = afl->queue;
u32 id = 0; u32 id = 0;
@ -794,7 +795,7 @@ void pivot_inputs(afl_state_t *afl) {
/* When resuming, try to find the queue position to start from. This makes sense /* When resuming, try to find the queue position to start from. This makes sense
only when resuming, and when we can find the original fuzzer_stats. */ only when resuming, and when we can find the original fuzzer_stats. */
u32 find_start_position(afl_state_t *afl) { u32 find_start_position(afl_state_t* afl) {
static u8 tmp[4096]; /* Ought to be enough for anybody. */ static u8 tmp[4096]; /* Ought to be enough for anybody. */
@ -831,7 +832,7 @@ u32 find_start_position(afl_state_t *afl) {
-t given, we don't want to keep auto-scaling the timeout over and over -t given, we don't want to keep auto-scaling the timeout over and over
again to prevent it from growing due to random flukes. */ again to prevent it from growing due to random flukes. */
void find_timeout(afl_state_t *afl) { void find_timeout(afl_state_t* afl) {
static u8 tmp[4096]; /* Ought to be enough for anybody. */ static u8 tmp[4096]; /* Ought to be enough for anybody. */
@ -953,7 +954,7 @@ double get_runnable_processes(void) {
/* Delete the temporary directory used for in-place session resume. */ /* Delete the temporary directory used for in-place session resume. */
void nuke_resume_dir(afl_state_t *afl) { void nuke_resume_dir(afl_state_t* afl) {
u8* fn; u8* fn;
@ -993,7 +994,7 @@ dir_cleanup_failed:
is not currently running, and if the last run time isn't too great. is not currently running, and if the last run time isn't too great.
Resume fuzzing if `-` is set as in_dir or if AFL_AUTORESUME is set */ Resume fuzzing if `-` is set as in_dir or if AFL_AUTORESUME is set */
static void handle_existing_out_dir(afl_state_t *afl) { static void handle_existing_out_dir(afl_state_t* afl) {
FILE* f; FILE* f;
u8* fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); u8* fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
@ -1048,7 +1049,8 @@ static void handle_existing_out_dir(afl_state_t *afl) {
/* Let's see how much work is at stake. */ /* Let's see how much work is at stake. */
if (!afl->in_place_resume && last_update - start_time2 > OUTPUT_GRACE * 60) { if (!afl->in_place_resume &&
last_update - start_time2 > OUTPUT_GRACE * 60) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"The job output directory already exists and contains the results " "The job output directory already exists and contains the results "
@ -1086,7 +1088,7 @@ static void handle_existing_out_dir(afl_state_t *afl) {
afl->in_dir = alloc_printf("%s/_resume", afl->out_dir); afl->in_dir = alloc_printf("%s/_resume", afl->out_dir);
rename(orig_q, afl->in_dir); /* Ignore errors */ rename(orig_q, afl->in_dir); /* Ignore errors */
OKF("Output directory exists, will attempt session resume."); OKF("Output directory exists, will attempt session resume.");
@ -1140,7 +1142,8 @@ static void handle_existing_out_dir(afl_state_t *afl) {
if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;
ck_free(fn); ck_free(fn);
/* All right, let's do <afl->out_dir>/crashes/id:* and <afl->out_dir>/hangs/id:*. */ /* All right, let's do <afl->out_dir>/crashes/id:* and
* <afl->out_dir>/hangs/id:*. */
if (!afl->in_place_resume) { if (!afl->in_place_resume) {
@ -1275,7 +1278,7 @@ dir_cleanup_failed:
/* Prepare output directories and fds. */ /* Prepare output directories and fds. */
void setup_dirs_fds(afl_state_t *afl) { void setup_dirs_fds(afl_state_t* afl) {
u8* tmp; u8* tmp;
s32 fd; s32 fd;
@ -1300,7 +1303,8 @@ void setup_dirs_fds(afl_state_t *afl) {
#ifndef __sun #ifndef __sun
if (afl->fsrv.out_dir_fd < 0 || flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB)) if (afl->fsrv.out_dir_fd < 0 ||
flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB))
PFATAL("Unable to flock() output directory."); PFATAL("Unable to flock() output directory.");
#endif /* !__sun */ #endif /* !__sun */
@ -1398,7 +1402,7 @@ void setup_dirs_fds(afl_state_t *afl) {
} }
void setup_cmdline_file(afl_state_t *afl, char **argv) { void setup_cmdline_file(afl_state_t* afl, char** argv) {
u8* tmp; u8* tmp;
s32 fd; s32 fd;
@ -1428,7 +1432,7 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
/* Setup the output file for fuzzed data, if not using -f. */ /* Setup the output file for fuzzed data, if not using -f. */
void setup_stdio_file(afl_state_t *afl) { void setup_stdio_file(afl_state_t* afl) {
u8* fn; u8* fn;
if (afl->file_extension) { if (afl->file_extension) {
@ -1527,7 +1531,7 @@ void check_crash_handling(void) {
/* Check CPU governor. */ /* Check CPU governor. */
void check_cpu_governor(afl_state_t *afl) { void check_cpu_governor(afl_state_t* afl) {
#ifdef __linux__ #ifdef __linux__
FILE* f; FILE* f;
@ -1537,8 +1541,8 @@ void check_cpu_governor(afl_state_t *afl) {
if (get_afl_env("AFL_SKIP_CPUFREQ")) return; if (get_afl_env("AFL_SKIP_CPUFREQ")) return;
if (afl->cpu_aff > 0) if (afl->cpu_aff > 0)
snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpu", afl->cpu_aff, snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpu",
"/cpufreq/scaling_governor"); afl->cpu_aff, "/cpufreq/scaling_governor");
else else
snprintf(tmp, sizeof(tmp), "%s", snprintf(tmp, sizeof(tmp), "%s",
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
@ -1650,7 +1654,7 @@ void check_cpu_governor(afl_state_t *afl) {
/* Count the number of logical CPU cores. */ /* Count the number of logical CPU cores. */
void get_core_count(afl_state_t *afl) { void get_core_count(afl_state_t* afl) {
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__DragonFly__) defined(__DragonFly__)
@ -1661,7 +1665,8 @@ void get_core_count(afl_state_t *afl) {
#ifdef __APPLE__ #ifdef __APPLE__
if (sysctlbyname("hw.logicalcpu", &afl->cpu_core_count, &s, NULL, 0) < 0) return; if (sysctlbyname("hw.logicalcpu", &afl->cpu_core_count, &s, NULL, 0) < 0)
return;
#else #else
@ -1737,7 +1742,7 @@ void get_core_count(afl_state_t *afl) {
/* Validate and fix up afl->out_dir and sync_dir when using -S. */ /* Validate and fix up afl->out_dir and sync_dir when using -S. */
void fix_up_sync(afl_state_t *afl) { void fix_up_sync(afl_state_t* afl) {
u8* x = afl->sync_id; u8* x = afl->sync_id;
@ -1844,7 +1849,7 @@ static void handle_skipreq(int sig) {
isn't a shell script - a common and painful mistake. We also check for isn't a shell script - a common and painful mistake. We also check for
a valid ELF header and for evidence of AFL instrumentation. */ a valid ELF header and for evidence of AFL instrumentation. */
void check_binary(afl_state_t *afl, u8* fname) { void check_binary(afl_state_t* afl, u8* fname) {
u8* env_path = 0; u8* env_path = 0;
struct stat st; struct stat st;
@ -1896,7 +1901,8 @@ void check_binary(afl_state_t *afl, u8* fname) {
} }
if (!afl->fsrv.target_path) FATAL("Program '%s' not found or not executable", fname); if (!afl->fsrv.target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -1904,8 +1910,10 @@ void check_binary(afl_state_t *afl, u8* fname) {
/* Check for blatant user errors. */ /* Check for blatant user errors. */
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) && !strchr(afl->fsrv.target_path + 5, '/')) || if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) && !strchr(afl->fsrv.target_path + 9, '/'))) !strchr(afl->fsrv.target_path + 5, '/')) ||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
!strchr(afl->fsrv.target_path + 9, '/')))
FATAL("Please don't keep binaries in /tmp or /var/tmp"); FATAL("Please don't keep binaries in /tmp or /var/tmp");
fd = open(afl->fsrv.target_path, O_RDONLY); fd = open(afl->fsrv.target_path, O_RDONLY);
@ -1914,7 +1922,8 @@ void check_binary(afl_state_t *afl, u8* fname) {
f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0); f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
if (f_data == MAP_FAILED) PFATAL("Unable to mmap file '%s'", afl->fsrv.target_path); if (f_data == MAP_FAILED)
PFATAL("Unable to mmap file '%s'", afl->fsrv.target_path);
close(fd); close(fd);
@ -2033,7 +2042,7 @@ void check_binary(afl_state_t *afl, u8* fname) {
/* Trim and possibly create a banner for the run. */ /* Trim and possibly create a banner for the run. */
void fix_up_banner(afl_state_t *afl, u8* name) { void fix_up_banner(afl_state_t* afl, u8* name) {
if (!afl->use_banner) { if (!afl->use_banner) {
@ -2065,7 +2074,7 @@ void fix_up_banner(afl_state_t *afl, u8* name) {
/* Check if we're on TTY. */ /* Check if we're on TTY. */
void check_if_tty(afl_state_t *afl) { void check_if_tty(afl_state_t* afl) {
struct winsize ws; struct winsize ws;
@ -2139,7 +2148,7 @@ void setup_signal_handlers(void) {
/* Make a copy of the current command line. */ /* Make a copy of the current command line. */
void save_cmdline(afl_state_t *afl, u32 argc, char **argv) { void save_cmdline(afl_state_t* afl, u32 argc, char** argv) {
u32 len = 1, i; u32 len = 1, i;
u8* buf; u8* buf;

View File

@ -30,12 +30,13 @@ void load_custom_mutator(afl_state_t*, const char*);
void load_custom_mutator_py(afl_state_t*, const char*); void load_custom_mutator_py(afl_state_t*, const char*);
#endif #endif
void setup_custom_mutator(afl_state_t *afl) { void setup_custom_mutator(afl_state_t* afl) {
/* Try mutator library first */ /* Try mutator library first */
u8* fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); u8* fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
if (fn) { if (fn) {
if (afl->limit_time_sig) if (afl->limit_time_sig)
FATAL( FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull " "MOpt and custom mutator are mutually exclusive. We accept pull "
@ -74,7 +75,7 @@ void setup_custom_mutator(afl_state_t *afl) {
} }
void destroy_custom_mutator(afl_state_t *afl) { void destroy_custom_mutator(afl_state_t* afl) {
if (afl->mutator) { if (afl->mutator) {
@ -90,11 +91,12 @@ void destroy_custom_mutator(afl_state_t *afl) {
} }
ck_free(afl->mutator); ck_free(afl->mutator);
} }
} }
void load_custom_mutator(afl_state_t *afl, const char *fn) { void load_custom_mutator(afl_state_t* afl, const char* fn) {
void* dh; void* dh;
afl->mutator = ck_alloc(sizeof(struct custom_mutator)); afl->mutator = ck_alloc(sizeof(struct custom_mutator));
@ -109,7 +111,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Mutator */ /* Mutator */
/* "afl_custom_init", optional for backward compatibility */ /* "afl_custom_init", optional for backward compatibility */
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
if (!afl->mutator->afl_custom_init) WARNF("Symbol 'afl_custom_init' not found."); if (!afl->mutator->afl_custom_init)
WARNF("Symbol 'afl_custom_init' not found.");
/* "afl_custom_fuzz" or "afl_custom_mutator", required */ /* "afl_custom_fuzz" or "afl_custom_mutator", required */
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
@ -137,7 +140,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* "afl_custom_trim", optional */ /* "afl_custom_trim", optional */
afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
if (!afl->mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found."); if (!afl->mutator->afl_custom_trim)
WARNF("Symbol 'afl_custom_trim' not found.");
/* "afl_custom_post_trim", optional */ /* "afl_custom_post_trim", optional */
afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
@ -156,7 +160,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
} }
/* "afl_custom_havoc_mutation", optional */ /* "afl_custom_havoc_mutation", optional */
afl->mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); afl->mutator->afl_custom_havoc_mutation =
dlsym(dh, "afl_custom_havoc_mutation");
if (!afl->mutator->afl_custom_havoc_mutation) if (!afl->mutator->afl_custom_havoc_mutation)
WARNF("Symbol 'afl_custom_havoc_mutation' not found."); WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
@ -172,7 +177,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
WARNF("Symbol 'afl_custom_queue_get' not found."); WARNF("Symbol 'afl_custom_queue_get' not found.");
/* "afl_custom_queue_new_entry", optional */ /* "afl_custom_queue_new_entry", optional */
afl->mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); afl->mutator->afl_custom_queue_new_entry =
dlsym(dh, "afl_custom_queue_new_entry");
if (!afl->mutator->afl_custom_queue_new_entry) if (!afl->mutator->afl_custom_queue_new_entry)
WARNF("Symbol 'afl_custom_queue_new_entry' not found"); WARNF("Symbol 'afl_custom_queue_new_entry' not found");
@ -184,7 +190,7 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
} }
u8 trim_case_custom(afl_state_t *afl, struct queue_entry* q, u8* in_buf) { u8 trim_case_custom(afl_state_t* afl, struct queue_entry* q, u8* in_buf) {
static u8 tmp[64]; static u8 tmp[64];
static u8 clean_trace[MAP_SIZE]; static u8 clean_trace[MAP_SIZE];
@ -306,17 +312,16 @@ abort_trimming:
} }
#ifdef USE_PYTHON #ifdef USE_PYTHON
void load_custom_mutator_py(afl_state_t *afl, const char* module_name) { void load_custom_mutator_py(afl_state_t* afl, const char* module_name) {
PyObject **py_functions = afl->py_functions; PyObject** py_functions = afl->py_functions;
afl->mutator = ck_alloc(sizeof(struct custom_mutator)); afl->mutator = ck_alloc(sizeof(struct custom_mutator));
afl->mutator->name = module_name; afl->mutator->name = module_name;
ACTF("Loading Python mutator library from '%s'...", module_name); ACTF("Loading Python mutator library from '%s'...", module_name);
if (py_functions[PY_FUNC_INIT]) if (py_functions[PY_FUNC_INIT]) afl->mutator->afl_custom_init = init_py;
afl->mutator->afl_custom_init = init_py;
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
is quite different from the custom mutator. */ is quite different from the custom mutator. */
@ -331,15 +336,14 @@ void load_custom_mutator_py(afl_state_t *afl, const char* module_name) {
if (py_functions[PY_FUNC_POST_TRIM]) if (py_functions[PY_FUNC_POST_TRIM])
afl->mutator->afl_custom_post_trim = post_trim_py; afl->mutator->afl_custom_post_trim = post_trim_py;
if (py_functions[PY_FUNC_TRIM]) if (py_functions[PY_FUNC_TRIM]) afl->mutator->afl_custom_trim = trim_py;
afl->mutator->afl_custom_trim = trim_py;
if (py_functions[PY_FUNC_HAVOC_MUTATION]) if (py_functions[PY_FUNC_HAVOC_MUTATION])
afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py; afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY])
afl->mutator->afl_custom_havoc_mutation_probability = afl->mutator->afl_custom_havoc_mutation_probability =
havoc_mutation_probability_py; havoc_mutation_probability_py;
if (py_functions[PY_FUNC_QUEUE_GET]) if (py_functions[PY_FUNC_QUEUE_GET])
afl->mutator->afl_custom_queue_get = queue_get_py; afl->mutator->afl_custom_queue_get = queue_get_py;

View File

@ -27,7 +27,7 @@
/* MOpt */ /* MOpt */
int select_algorithm(afl_state_t *afl) { int select_algorithm(afl_state_t* afl) {
int i_puppet, j_puppet; int i_puppet, j_puppet;
@ -52,7 +52,8 @@ int select_algorithm(afl_state_t *afl) {
} }
if (j_puppet == 1 && sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) if (j_puppet == 1 &&
sele < afl->probability_now[afl->swarm_now][i_puppet - 1])
FATAL("error select_algorithm"); FATAL("error select_algorithm");
return i_puppet; return i_puppet;
@ -61,7 +62,7 @@ int select_algorithm(afl_state_t *afl) {
/* Helper to choose random block len for block operations in fuzz_one(). /* Helper to choose random block len for block operations in fuzz_one().
Doesn't return zero, provided that max_len is > 0. */ Doesn't return zero, provided that max_len is > 0. */
static u32 choose_block_len(afl_state_t *afl, u32 limit) { static u32 choose_block_len(afl_state_t* afl, u32 limit) {
u32 min_value, max_value; u32 min_value, max_value;
u32 rlim = MIN(afl->queue_cycle, 3); u32 rlim = MIN(afl->queue_cycle, 3);
@ -334,7 +335,7 @@ static void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) {
function is a tad too long... returns 0 if fuzzed successfully, 1 if function is a tad too long... returns 0 if fuzzed successfully, 1 if
skipped or bailed out. */ skipped or bailed out. */
u8 fuzz_one_original(afl_state_t *afl) { u8 fuzz_one_original(afl_state_t* afl) {
s32 len, fd, temp_len, i, j; s32 len, fd, temp_len, i, j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
@ -375,7 +376,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
UR(afl, 100) < SKIP_TO_NEW_PROB) UR(afl, 100) < SKIP_TO_NEW_PROB)
return 1; return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored && afl->queued_paths > 10) { } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
/* Otherwise, still possibly skip non-favored cases, albeit less often. /* Otherwise, still possibly skip non-favored cases, albeit less often.
The odds of skipping stuff are higher for already-fuzzed inputs and The odds of skipping stuff are higher for already-fuzzed inputs and
@ -439,7 +442,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
if (res == FAULT_ERROR) FATAL("Unable to execute target application"); if (res == FAULT_ERROR) FATAL("Unable to execute target application");
@ -493,7 +497,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->shm.cmplog_mode) { if (afl->shm.cmplog_mode) {
if (input_to_state_stage(afl, in_buf, out_buf, len, afl->queue_cur->exec_cksum)) if (input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum))
goto abandon_entry; goto abandon_entry;
} }
@ -517,7 +522,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* Skip deterministic fuzzing if exec path checksum puts this out of scope /* Skip deterministic fuzzing if exec path checksum puts this out of scope
for this master instance. */ for this master instance. */
if (afl->master_max && (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) { if (afl->master_max &&
(afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
goto custom_mutator_stage; goto custom_mutator_stage;
@ -596,7 +602,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* If at end of file and we are still collecting a string, grab the /* If at end of file and we are still collecting a string, grab the
final character and force output. */ final character and force output. */
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)
@ -620,7 +627,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (cksum != afl->queue_cur->exec_cksum) { if (cksum != afl->queue_cur->exec_cksum) {
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
} }
@ -1392,10 +1400,12 @@ skip_interest:
is redundant, or if its entire span has no bytes set in the effector is redundant, or if its entire span has no bytes set in the effector
map. */ map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS && UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || if ((afl->extras_cnt > MAX_DET_EXTRAS &&
UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i || afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->extras[j].len))) { !memchr(eff_map + EFF_APOS(i), 1,
EFF_SPAN_ALEN(i, afl->extras[j].len))) {
--afl->stage_max; --afl->stage_max;
continue; continue;
@ -1598,9 +1608,8 @@ custom_mutator_stage:
ck_read(fd, new_buf, target->len, target->fname); ck_read(fd, new_buf, target->len, target->fname);
close(fd); close(fd);
size_t mutated_size = afl->mutator->afl_custom_fuzz(afl, &out_buf, len, size_t mutated_size = afl->mutator->afl_custom_fuzz(
new_buf, target->len, afl, &out_buf, len, new_buf, target->len, max_seed_size);
max_seed_size);
ck_free(new_buf); ck_free(new_buf);
@ -1663,8 +1672,8 @@ havoc_stage:
afl->stage_name = "havoc"; afl->stage_name = "havoc";
afl->stage_short = "havoc"; afl->stage_short = "havoc";
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * perf_score / afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
afl->havoc_div / 100; perf_score / afl->havoc_div / 100;
} else { } else {
@ -1686,11 +1695,12 @@ havoc_stage:
havoc_queued = afl->queued_paths; havoc_queued = afl->queued_paths;
u8 stacked_custom = (afl->mutator && afl->mutator->afl_custom_havoc_mutation); u8 stacked_custom = (afl->mutator && afl->mutator->afl_custom_havoc_mutation);
u8 stacked_custom_prob = 6; // like one of the default mutations in havoc u8 stacked_custom_prob = 6; // like one of the default mutations in havoc
if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) { if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) {
stacked_custom_prob = afl->mutator->afl_custom_havoc_mutation_probability(afl); stacked_custom_prob =
afl->mutator->afl_custom_havoc_mutation_probability(afl);
if (stacked_custom_prob > 100) if (stacked_custom_prob > 100)
FATAL( FATAL(
"The probability returned by afl_custom_havoc_mutation_propability " "The probability returned by afl_custom_havoc_mutation_propability "
@ -1711,8 +1721,8 @@ havoc_stage:
if (stacked_custom && UR(afl, 100) < stacked_custom_prob) { if (stacked_custom && UR(afl, 100) < stacked_custom_prob) {
temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf, temp_len, temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf,
MAX_FILE); temp_len, MAX_FILE);
} }
@ -1729,7 +1739,8 @@ havoc_stage:
/* Set byte to interesting value. */ /* Set byte to interesting value. */
out_buf[UR(afl, temp_len)] = interesting_8[UR(afl, sizeof(interesting_8))]; out_buf[UR(afl, temp_len)] =
interesting_8[UR(afl, sizeof(interesting_8))];
break; break;
case 2: case 2:
@ -1952,7 +1963,8 @@ havoc_stage:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else else
memset(new_buf + clone_to, memset(new_buf + clone_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], clone_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
clone_len);
/* Tail */ /* Tail */
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@ -1987,7 +1999,8 @@ havoc_stage:
} else } else
memset(out_buf + copy_to, UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], memset(out_buf + copy_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
copy_len); copy_len);
break; break;
@ -2013,20 +2026,21 @@ havoc_stage:
if (extra_len > temp_len) break; if (extra_len > temp_len) break;
insert_at = UR(afl, temp_len - extra_len + 1); insert_at = UR(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
} else { } else {
/* No auto extras or odds in our favor. Use the dictionary. */ /* No auto extras or odds in our favor. Use the dictionary. */
u32 use_extra = UR(afl, afl->extras_cnt); u32 use_extra = UR(afl, afl->extras_cnt);
u32 extra_len =afl->extras[use_extra].len; u32 extra_len = afl->extras[use_extra].len;
u32 insert_at; u32 insert_at;
if (extra_len > temp_len) break; if (extra_len > temp_len) break;
insert_at = UR(afl, temp_len - extra_len + 1); insert_at = UR(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at,afl->extras[use_extra].data, extra_len); memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len);
} }
@ -2055,12 +2069,13 @@ havoc_stage:
memcpy(new_buf, out_buf, insert_at); memcpy(new_buf, out_buf, insert_at);
/* Inserted part */ /* Inserted part */
memcpy(new_buf + insert_at, afl->a_extras[use_extra].data, extra_len); memcpy(new_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
} else { } else {
use_extra = UR(afl, afl->extras_cnt); use_extra = UR(afl, afl->extras_cnt);
extra_len =afl->extras[use_extra].len; extra_len = afl->extras[use_extra].len;
if (temp_len + extra_len >= MAX_FILE) break; if (temp_len + extra_len >= MAX_FILE) break;
@ -2070,7 +2085,7 @@ havoc_stage:
memcpy(new_buf, out_buf, insert_at); memcpy(new_buf, out_buf, insert_at);
/* Inserted part */ /* Inserted part */
memcpy(new_buf + insert_at,afl->extras[use_extra].data, extra_len); memcpy(new_buf + insert_at, afl->extras[use_extra].data, extra_len);
} }
@ -2144,8 +2159,8 @@ havoc_stage:
retry_splicing: retry_splicing:
if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && afl->queued_paths > 1 && if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES &&
afl->queue_cur->len > 1) { afl->queued_paths > 1 && afl->queue_cur->len > 1) {
struct queue_entry* target; struct queue_entry* target;
u32 tid, split_at; u32 tid, split_at;
@ -2252,7 +2267,8 @@ radamsa_stage:
afl->stage_name = "radamsa"; afl->stage_name = "radamsa";
afl->stage_short = "radamsa"; afl->stage_short = "radamsa";
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100) << afl->use_radamsa; afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100)
<< afl->use_radamsa;
if (afl->stage_max < HAVOC_MIN) afl->stage_max = HAVOC_MIN; if (afl->stage_max < HAVOC_MIN) afl->stage_max = HAVOC_MIN;
@ -2268,8 +2284,8 @@ radamsa_stage:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 new_len = u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len, get_rand_seed(afl)); get_rand_seed(afl));
if (new_len) { if (new_len) {
@ -2336,7 +2352,7 @@ abandon_entry:
} }
/* MOpt mode */ /* MOpt mode */
u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { u8 mopt_common_fuzzing(afl_state_t* afl, MOpt_globals_t MOpt_globals) {
if (!MOpt_globals.is_pilot_mode) { if (!MOpt_globals.is_pilot_mode) {
@ -2378,7 +2394,9 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
UR(afl, 100) < SKIP_TO_NEW_PROB) UR(afl, 100) < SKIP_TO_NEW_PROB)
return 1; return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored && afl->queued_paths > 10) { } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
/* Otherwise, still possibly skip non-favored cases, albeit less often. /* Otherwise, still possibly skip non-favored cases, albeit less often.
The odds of skipping stuff are higher for already-fuzzed inputs and The odds of skipping stuff are higher for already-fuzzed inputs and
@ -2416,7 +2434,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (orig_in == MAP_FAILED) PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); if (orig_in == MAP_FAILED)
PFATAL("Unable to mmap '%s'", afl->queue_cur->fname);
close(fd); close(fd);
@ -2440,7 +2459,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
if (res == FAULT_ERROR) FATAL("Unable to execute target application"); if (res == FAULT_ERROR) FATAL("Unable to execute target application");
@ -2492,20 +2512,23 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
this entry ourselves (was_fuzzed), or if it has gone through deterministic this entry ourselves (was_fuzzed), or if it has gone through deterministic
testing in earlier, resumed runs (passed_det). */ testing in earlier, resumed runs (passed_det). */
if (afl->skip_deterministic || afl->queue_cur->was_fuzzed || afl->queue_cur->passed_det) if (afl->skip_deterministic || afl->queue_cur->was_fuzzed ||
afl->queue_cur->passed_det)
goto havoc_stage; goto havoc_stage;
/* Skip deterministic fuzzing if exec path checksum puts this out of scope /* Skip deterministic fuzzing if exec path checksum puts this out of scope
for this master instance. */ for this master instance. */
if (afl->master_max && (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) if (afl->master_max &&
(afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1)
goto havoc_stage; goto havoc_stage;
cur_ms_lv = get_cur_time(); cur_ms_lv = get_cur_time();
if (!(afl->key_puppet == 0 && ((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) || if (!(afl->key_puppet == 0 &&
(afl->last_crash_time != 0 && ((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) ||
cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) || (afl->last_crash_time != 0 &&
afl->last_path_time == 0))) { cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) ||
afl->last_path_time == 0))) {
afl->key_puppet = 1; afl->key_puppet = 1;
goto pacemaker_fuzzing; goto pacemaker_fuzzing;
@ -2585,7 +2608,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
/* If at end of file and we are still collecting a string, grab the /* If at end of file and we are still collecting a string, grab the
final character and force output. */ final character and force output. */
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)
@ -2609,14 +2633,15 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (cksum != afl->queue_cur->exec_cksum) { if (cksum != afl->queue_cur->exec_cksum) {
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
} }
} /* if (afl->stage_cur & 7) == 7 */ } /* if (afl->stage_cur & 7) == 7 */
} /* for afl->stage_cur */ } /* for afl->stage_cur */
new_hit_cnt = afl->queued_paths + afl->unique_crashes; new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -2643,7 +2668,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
FLIP_BIT(out_buf, afl->stage_cur); FLIP_BIT(out_buf, afl->stage_cur);
FLIP_BIT(out_buf, afl->stage_cur + 1); FLIP_BIT(out_buf, afl->stage_cur + 1);
} /* for afl->stage_cur */ } /* for afl->stage_cur */
new_hit_cnt = afl->queued_paths + afl->unique_crashes; new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -2674,7 +2699,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
FLIP_BIT(out_buf, afl->stage_cur + 2); FLIP_BIT(out_buf, afl->stage_cur + 2);
FLIP_BIT(out_buf, afl->stage_cur + 3); FLIP_BIT(out_buf, afl->stage_cur + 3);
} /* for afl->stage_cur */ } /* for afl->stage_cur */
new_hit_cnt = afl->queued_paths + afl->unique_crashes; new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -2751,7 +2776,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
out_buf[afl->stage_cur] ^= 0xFF; out_buf[afl->stage_cur] ^= 0xFF;
} /* for afl->stage_cur */ } /* for afl->stage_cur */
/* If the effector map is more than EFF_MAX_PERC dense, just flag the /* If the effector map is more than EFF_MAX_PERC dense, just flag the
whole thing as worth fuzzing, since we wouldn't be saving much time whole thing as worth fuzzing, since we wouldn't be saving much time
@ -3381,10 +3406,12 @@ skip_interest:
is redundant, or if its entire span has no bytes set in the effector is redundant, or if its entire span has no bytes set in the effector
map. */ map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS && UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || if ((afl->extras_cnt > MAX_DET_EXTRAS &&
UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i || afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->extras[j].len))) { !memchr(eff_map + EFF_APOS(i), 1,
EFF_SPAN_ALEN(i, afl->extras[j].len))) {
--afl->stage_max; --afl->stage_max;
continue; continue;
@ -3440,7 +3467,7 @@ skip_interest:
/* Copy tail */ /* Copy tail */
memcpy(ex_tmp + i + afl->extras[j].len, out_buf + i, len - i); memcpy(ex_tmp + i + afl->extras[j].len, out_buf + i, len - i);
if (common_fuzz_stuff(afl, ex_tmp, len +afl->extras[j].len)) { if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) {
ck_free(ex_tmp); ck_free(ex_tmp);
goto abandon_entry; goto abandon_entry;
@ -3539,14 +3566,15 @@ pacemaker_fuzzing:
afl->stage_name = MOpt_globals.havoc_stagename; afl->stage_name = MOpt_globals.havoc_stagename;
afl->stage_short = MOpt_globals.havoc_stagenameshort; afl->stage_short = MOpt_globals.havoc_stagenameshort;
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * perf_score / afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
afl->havoc_div / 100; perf_score / afl->havoc_div / 100;
} else { } else {
perf_score = orig_perf; perf_score = orig_perf;
snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat, splice_cycle); snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
splice_cycle);
afl->stage_name = afl->stage_name_buf64; afl->stage_name = afl->stage_name_buf64;
afl->stage_short = MOpt_globals.splice_stagenameshort; afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@ -3571,7 +3599,7 @@ pacemaker_fuzzing:
} }
} /* if afl->key_puppet == 1 */ } /* if afl->key_puppet == 1 */
{ {
@ -3590,12 +3618,13 @@ pacemaker_fuzzing:
afl->stage_name = MOpt_globals.havoc_stagename; afl->stage_name = MOpt_globals.havoc_stagename;
afl->stage_short = MOpt_globals.havoc_stagenameshort; afl->stage_short = MOpt_globals.havoc_stagenameshort;
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
perf_score / afl->havoc_div / 100; perf_score / afl->havoc_div / 100;
} else { } else {
perf_score = orig_perf; perf_score = orig_perf;
snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat, splice_cycle); snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
splice_cycle);
afl->stage_name = afl->stage_name_buf64; afl->stage_name = afl->stage_name_buf64;
afl->stage_short = MOpt_globals.splice_stagenameshort; afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@ -3610,7 +3639,8 @@ pacemaker_fuzzing:
havoc_queued = afl->queued_paths; havoc_queued = afl->queued_paths;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
++afl->stage_cur) {
u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2)); u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2));
@ -3748,7 +3778,8 @@ pacemaker_fuzzing:
case 9: case 9:
/* Set byte to interesting value. */ /* Set byte to interesting value. */
if (temp_len < 4) break; if (temp_len < 4) break;
out_buf[UR(afl, temp_len)] = interesting_8[UR(afl, sizeof(interesting_8))]; out_buf[UR(afl, temp_len)] =
interesting_8[UR(afl, sizeof(interesting_8))];
MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1; MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1;
break; break;
@ -3762,8 +3793,8 @@ pacemaker_fuzzing:
} else { } else {
*(u16*)(out_buf + UR(afl, temp_len - 1)) = *(u16*)(out_buf + UR(afl, temp_len - 1)) = SWAP16(
SWAP16(interesting_16[UR(afl, sizeof(interesting_16) >> 1)]); interesting_16[UR(afl, sizeof(interesting_16) >> 1)]);
} }
@ -3782,8 +3813,8 @@ pacemaker_fuzzing:
} else { } else {
*(u32*)(out_buf + UR(afl, temp_len - 3)) = *(u32*)(out_buf + UR(afl, temp_len - 3)) = SWAP32(
SWAP32(interesting_32[UR(afl, sizeof(interesting_32) >> 2)]); interesting_32[UR(afl, sizeof(interesting_32) >> 2)]);
} }
@ -3862,7 +3893,8 @@ pacemaker_fuzzing:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else else
memset(new_buf + clone_to, memset(new_buf + clone_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], clone_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
clone_len);
/* Tail */ /* Tail */
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@ -3899,7 +3931,8 @@ pacemaker_fuzzing:
} else } else
memset(out_buf + copy_to, memset(out_buf + copy_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], copy_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
copy_len);
MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1; MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1;
break; break;
@ -3939,7 +3972,8 @@ pacemaker_fuzzing:
} }
if (unlikely(afl->queued_paths + afl->unique_crashes > temp_total_found)) { if (unlikely(afl->queued_paths + afl->unique_crashes >
temp_total_found)) {
u64 temp_temp_puppet = u64 temp_temp_puppet =
afl->queued_paths + afl->unique_crashes - temp_total_found; afl->queued_paths + afl->unique_crashes - temp_total_found;
@ -3953,7 +3987,9 @@ pacemaker_fuzzing:
} /* if */ } /* if */
} /* for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { */ } /* for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
++afl->stage_cur) { */
new_hit_cnt = afl->queued_paths + afl->unique_crashes; new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -4089,10 +4125,11 @@ pacemaker_fuzzing:
afl->splicing_with = -1; afl->splicing_with = -1;
/* Update afl->pending_not_fuzzed count if we made it through the calibration /* Update afl->pending_not_fuzzed count if we made it through the
cycle and have not seen this entry before. */ calibration cycle and have not seen this entry before. */
// if (!afl->stop_soon && !afl->queue_cur->cal_failed && !afl->queue_cur->was_fuzzed) { // if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
// !afl->queue_cur->was_fuzzed) {
// afl->queue_cur->was_fuzzed = 1; // afl->queue_cur->was_fuzzed = 1;
// --afl->pending_not_fuzzed; // --afl->pending_not_fuzzed;
@ -4107,9 +4144,10 @@ pacemaker_fuzzing:
if (afl->key_puppet == 1) { if (afl->key_puppet == 1) {
if (unlikely(afl->queued_paths + afl->unique_crashes > if (unlikely(
((afl->queued_paths + afl->unique_crashes) * limit_time_bound + afl->queued_paths + afl->unique_crashes >
afl->orig_hit_cnt_puppet))) { ((afl->queued_paths + afl->unique_crashes) * limit_time_bound +
afl->orig_hit_cnt_puppet))) {
afl->key_puppet = 0; afl->key_puppet = 0;
cur_ms_lv = get_cur_time(); cur_ms_lv = get_cur_time();
@ -4175,7 +4213,8 @@ pacemaker_fuzzing:
afl->core_operator_cycles_puppet[i]; afl->core_operator_cycles_puppet[i];
afl->core_operator_cycles_puppet_v3[i] = afl->core_operator_cycles_puppet_v3[i] =
afl->core_operator_cycles_puppet[i]; afl->core_operator_cycles_puppet[i];
afl->core_operator_finds_puppet_v2[i] = afl->core_operator_finds_puppet[i]; afl->core_operator_finds_puppet_v2[i] =
afl->core_operator_finds_puppet[i];
} }
@ -4195,14 +4234,19 @@ pacemaker_fuzzing:
if (afl->swarm_now < 0 || afl->swarm_now > swarm_num - 1) if (afl->swarm_now < 0 || afl->swarm_now > swarm_num - 1)
PFATAL("swarm_now error number %d", afl->swarm_now); PFATAL("swarm_now error number %d", afl->swarm_now);
} /* if afl->swarm_now == swarm_num */ } /* if afl->swarm_now == swarm_num */
/* adjust pointers dependent on 'afl->swarm_now' */ /* adjust pointers dependent on 'afl->swarm_now' */
afl->mopt_globals_pilot.finds = afl->stage_finds_puppet[afl->swarm_now]; afl->mopt_globals_pilot.finds =
afl->mopt_globals_pilot.finds_v2 = afl->stage_finds_puppet_v2[afl->swarm_now]; afl->stage_finds_puppet[afl->swarm_now];
afl->mopt_globals_pilot.cycles = afl->stage_cycles_puppet[afl->swarm_now]; afl->mopt_globals_pilot.finds_v2 =
afl->mopt_globals_pilot.cycles_v2 = afl->stage_cycles_puppet_v2[afl->swarm_now]; afl->stage_finds_puppet_v2[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v3 = afl->stage_cycles_puppet_v3[afl->swarm_now]; afl->mopt_globals_pilot.cycles =
afl->stage_cycles_puppet[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v2 =
afl->stage_cycles_puppet_v2[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v3 =
afl->stage_cycles_puppet_v3[afl->swarm_now];
} else { } else {
@ -4224,19 +4268,25 @@ pacemaker_fuzzing:
#undef FLIP_BIT #undef FLIP_BIT
u8 core_fuzzing(afl_state_t *afl) { u8 core_fuzzing(afl_state_t* afl) {
return mopt_common_fuzzing(afl, afl->mopt_globals_core); return mopt_common_fuzzing(afl, afl->mopt_globals_core);
} }
u8 pilot_fuzzing(afl_state_t *afl) { u8 pilot_fuzzing(afl_state_t* afl) {
return mopt_common_fuzzing(afl, afl->mopt_globals_pilot); return mopt_common_fuzzing(afl, afl->mopt_globals_pilot);
} }
void pso_updating(afl_state_t *afl) { void pso_updating(afl_state_t* afl) {
afl->g_now += 1; afl->g_now += 1;
if (afl->g_now > afl->g_max) afl->g_now = 0; if (afl->g_now > afl->g_max) afl->g_now = 0;
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) + afl->w_end; afl->w_now =
(afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) +
afl->w_end;
int tmp_swarm, i, j; int tmp_swarm, i, j;
u64 temp_operator_finds_puppet = 0; u64 temp_operator_finds_puppet = 0;
for (i = 0; i < operator_num; ++i) { for (i = 0; i < operator_num; ++i) {
@ -4259,7 +4309,7 @@ void pso_updating(afl_state_t *afl) {
if (afl->operator_finds_puppet[i]) if (afl->operator_finds_puppet[i])
afl->G_best[i] = (double)((double)(afl->operator_finds_puppet[i]) / afl->G_best[i] = (double)((double)(afl->operator_finds_puppet[i]) /
(double)(temp_operator_finds_puppet)); (double)(temp_operator_finds_puppet));
} }
@ -4308,7 +4358,7 @@ void pso_updating(afl_state_t *afl) {
to fuzz_one_original. All documentation references to fuzz_one therefore to fuzz_one_original. All documentation references to fuzz_one therefore
mean fuzz_one_original */ mean fuzz_one_original */
u8 fuzz_one(afl_state_t *afl) { u8 fuzz_one(afl_state_t* afl) {
int key_val_lv = 0; int key_val_lv = 0;
@ -4353,3 +4403,4 @@ u8 fuzz_one(afl_state_t *afl) {
return key_val_lv; return key_val_lv;
} }

View File

@ -28,22 +28,22 @@
/* Python stuff */ /* Python stuff */
#ifdef USE_PYTHON #ifdef USE_PYTHON
int init_py_module(afl_state_t *afl, u8* module_name) { int init_py_module(afl_state_t *afl, u8 *module_name) {
if (!module_name) return 1; if (!module_name) return 1;
Py_Initialize(); Py_Initialize();
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
PyObject* py_name = PyUnicode_FromString(module_name); PyObject *py_name = PyUnicode_FromString(module_name);
#else #else
PyObject* py_name = PyString_FromString(module_name); PyObject *py_name = PyString_FromString(module_name);
#endif #endif
afl->py_module = PyImport_Import(py_name); afl->py_module = PyImport_Import(py_name);
Py_DECREF(py_name); Py_DECREF(py_name);
PyObject *py_module = afl->py_module; PyObject * py_module = afl->py_module;
PyObject **py_functions = afl->py_functions; PyObject **py_functions = afl->py_functions;
if (afl->py_module != NULL) { if (afl->py_module != NULL) {
@ -144,6 +144,7 @@ void finalize_py_module(afl_state_t *afl) {
} }
void init_py(afl_state_t *afl, unsigned int seed) { void init_py(afl_state_t *afl, unsigned int seed) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
/* Provide the init function a seed for the Python RNG */ /* Provide the init function a seed for the Python RNG */
@ -178,7 +179,7 @@ void init_py(afl_state_t *afl, unsigned int seed) {
} }
size_t fuzz_py(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf, size_t fuzz_py(afl_state_t *afl, u8 **buf, size_t buf_size, u8 *add_buf,
size_t add_buf_size, size_t max_size) { size_t add_buf_size, size_t max_size) {
size_t mutated_size; size_t mutated_size;
@ -244,7 +245,7 @@ size_t fuzz_py(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf,
} }
size_t pre_save_py(afl_state_t *afl, u8* buf, size_t buf_size, u8** out_buf) { size_t pre_save_py(afl_state_t *afl, u8 *buf, size_t buf_size, u8 **out_buf) {
size_t out_buf_size; size_t out_buf_size;
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -280,7 +281,7 @@ size_t pre_save_py(afl_state_t *afl, u8* buf, size_t buf_size, u8** out_buf) {
} }
u32 init_trim_py(afl_state_t *afl, u8* buf, size_t buf_size) { u32 init_trim_py(afl_state_t *afl, u8 *buf, size_t buf_size) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -355,7 +356,7 @@ u32 post_trim_py(afl_state_t *afl, u8 success) {
} }
void trim_py(afl_state_t *afl, u8** out_buf, size_t* out_buf_size) { void trim_py(afl_state_t *afl, u8 **out_buf, size_t *out_buf_size) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -379,7 +380,8 @@ void trim_py(afl_state_t *afl, u8** out_buf, size_t* out_buf_size) {
} }
size_t havoc_mutation_py(afl_state_t *afl, u8** buf, size_t buf_size, size_t max_size) { size_t havoc_mutation_py(afl_state_t *afl, u8 **buf, size_t buf_size,
size_t max_size) {
size_t mutated_size; size_t mutated_size;
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -411,7 +413,8 @@ size_t havoc_mutation_py(afl_state_t *afl, u8** buf, size_t buf_size, size_t max
PyTuple_SetItem(py_args, 1, py_value); PyTuple_SetItem(py_args, 1, py_value);
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION], py_args); py_value =
PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
@ -439,8 +442,8 @@ u8 havoc_mutation_probability_py(afl_state_t *afl) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
py_args = PyTuple_New(0); py_args = PyTuple_New(0);
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_value = PyObject_CallObject(
py_args); afl->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
if (py_value != NULL) { if (py_value != NULL) {
@ -458,7 +461,7 @@ u8 havoc_mutation_probability_py(afl_state_t *afl) {
} }
u8 queue_get_py(afl_state_t *afl, const u8* filename) { u8 queue_get_py(afl_state_t *afl, const u8 *filename) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -506,8 +509,8 @@ u8 queue_get_py(afl_state_t *afl, const u8* filename) {
} }
void queue_new_entry_py(afl_state_t *afl, const u8* filename_new_queue, void queue_new_entry_py(afl_state_t *afl, const u8 *filename_new_queue,
const u8* filename_orig_queue) { const u8 *filename_orig_queue) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -549,8 +552,8 @@ void queue_new_entry_py(afl_state_t *afl, const u8* filename_new_queue,
PyTuple_SetItem(py_args, 1, py_value); PyTuple_SetItem(py_args, 1, py_value);
// Call // Call
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_value =
py_args); PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
if (py_value == NULL) { if (py_value == NULL) {

View File

@ -28,12 +28,13 @@
.state file to avoid repeating deterministic fuzzing when resuming aborted .state file to avoid repeating deterministic fuzzing when resuming aborted
scans. */ scans. */
void mark_as_det_done(afl_state_t *afl, struct queue_entry* q) { void mark_as_det_done(afl_state_t* afl, struct queue_entry* q) {
u8* fn = strrchr(q->fname, '/'); u8* fn = strrchr(q->fname, '/');
s32 fd; s32 fd;
fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir, fn + 1); fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir,
fn + 1);
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0) PFATAL("Unable to create '%s'", fn); if (fd < 0) PFATAL("Unable to create '%s'", fn);
@ -48,7 +49,7 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry* q) {
/* Mark as variable. Create symlinks if possible to make it easier to examine /* Mark as variable. Create symlinks if possible to make it easier to examine
the files. */ the files. */
void mark_as_variable(afl_state_t *afl, struct queue_entry* q) { void mark_as_variable(afl_state_t* afl, struct queue_entry* q) {
u8 *fn = strrchr(q->fname, '/') + 1, *ldest; u8 *fn = strrchr(q->fname, '/') + 1, *ldest;
@ -73,7 +74,7 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry* q) {
/* Mark / unmark as redundant (edge-only). This is not used for restoring state, /* Mark / unmark as redundant (edge-only). This is not used for restoring state,
but may be useful for post-processing datasets. */ but may be useful for post-processing datasets. */
void mark_as_redundant(afl_state_t *afl, struct queue_entry* q, u8 state) { void mark_as_redundant(afl_state_t* afl, struct queue_entry* q, u8 state) {
u8* fn; u8* fn;
@ -104,7 +105,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry* q, u8 state) {
/* Append new test case to the queue. */ /* Append new test case to the queue. */
void add_to_queue(afl_state_t *afl, u8* fname, u32 len, u8 passed_det) { void add_to_queue(afl_state_t* afl, u8* fname, u32 len, u8 passed_det) {
struct queue_entry* q = ck_alloc(sizeof(struct queue_entry)); struct queue_entry* q = ck_alloc(sizeof(struct queue_entry));
@ -154,7 +155,7 @@ void add_to_queue(afl_state_t *afl, u8* fname, u32 len, u8 passed_det) {
/* Destroy the entire queue. */ /* Destroy the entire queue. */
void destroy_queue(afl_state_t *afl) { void destroy_queue(afl_state_t* afl) {
struct queue_entry *q = afl->queue, *n; struct queue_entry *q = afl->queue, *n;
@ -176,18 +177,19 @@ void destroy_queue(afl_state_t *afl) {
seen in the bitmap so far, and focus on fuzzing them at the expense of seen in the bitmap so far, and focus on fuzzing them at the expense of
the rest. the rest.
The first step of the process is to maintain a list of afl->top_rated[] entries The first step of the process is to maintain a list of afl->top_rated[]
for every byte in the bitmap. We win that slot if there is no previous entries for every byte in the bitmap. We win that slot if there is no
contender, or if the contender has a more favorable speed x size factor. */ previous contender, or if the contender has a more favorable speed x size
factor. */
void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) { void update_bitmap_score(afl_state_t* afl, struct queue_entry* q) {
u32 i; u32 i;
u64 fav_factor = q->exec_us * q->len; u64 fav_factor = q->exec_us * q->len;
u64 fuzz_p2 = next_p2(q->n_fuzz); u64 fuzz_p2 = next_p2(q->n_fuzz);
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous winner, /* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
and how it compares to us. */ winner, and how it compares to us. */
for (i = 0; i < MAP_SIZE; ++i) for (i = 0; i < MAP_SIZE; ++i)
@ -197,7 +199,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
/* Faster-executing or smaller test cases are favored. */ /* Faster-executing or smaller test cases are favored. */
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz); u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
u64 top_rated_fav_factor = afl->top_rated[i]->exec_us * afl->top_rated[i]->len; u64 top_rated_fav_factor =
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
if (fuzz_p2 > top_rated_fuzz_p2) { if (fuzz_p2 > top_rated_fuzz_p2) {
@ -209,7 +212,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
} }
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) continue; if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
continue;
/* Looks like we're going to win. Decrease ref count for the /* Looks like we're going to win. Decrease ref count for the
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */ previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
@ -247,7 +251,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
until the next run. The favored entries are given more air time during until the next run. The favored entries are given more air time during
all fuzzing steps. */ all fuzzing steps. */
void cull_queue(afl_state_t *afl) { void cull_queue(afl_state_t* afl) {
struct queue_entry* q; struct queue_entry* q;
static u8 temp_v[MAP_SIZE >> 3]; static u8 temp_v[MAP_SIZE >> 3];
@ -308,7 +312,7 @@ void cull_queue(afl_state_t *afl) {
A helper function for fuzz_one(). Maybe some of these constants should A helper function for fuzz_one(). Maybe some of these constants should
go into config.h. */ go into config.h. */
u32 calculate_score(afl_state_t *afl, struct queue_entry* q) { u32 calculate_score(afl_state_t* afl, struct queue_entry* q) {
u32 avg_exec_us = afl->total_cal_us / afl->total_cal_cycles; u32 avg_exec_us = afl->total_cal_us / afl->total_cal_cycles;
u32 avg_bitmap_size = afl->total_bitmap_size / afl->total_bitmap_entries; u32 avg_bitmap_size = afl->total_bitmap_size / afl->total_bitmap_entries;
@ -459,7 +463,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry* q) {
/* Make sure that we don't go over limit. */ /* Make sure that we don't go over limit. */
if (perf_score > afl->havoc_max_mult * 100) perf_score = afl->havoc_max_mult * 100; if (perf_score > afl->havoc_max_mult * 100)
perf_score = afl->havoc_max_mult * 100;
return perf_score; return perf_score;

View File

@ -84,7 +84,7 @@ struct range* pop_biggest_range(struct range** ranges) {
} }
static u8 get_exec_checksum(afl_state_t *afl, u8* buf, u32 len, u32* cksum) { static u8 get_exec_checksum(afl_state_t* afl, u8* buf, u32 len, u32* cksum) {
if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1; if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1;
@ -93,7 +93,7 @@ static u8 get_exec_checksum(afl_state_t *afl, u8* buf, u32 len, u32* cksum) {
} }
static void rand_replace(afl_state_t *afl, u8* buf, u32 len) { static void rand_replace(afl_state_t* afl, u8* buf, u32 len) {
u32 i; u32 i;
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
@ -101,7 +101,7 @@ static void rand_replace(afl_state_t *afl, u8* buf, u32 len) {
} }
static u8 colorization(afl_state_t *afl, u8* buf, u32 len, u32 exec_cksum) { static u8 colorization(afl_state_t* afl, u8* buf, u32 len, u32 exec_cksum) {
struct range* ranges = add_range(NULL, 0, len); struct range* ranges = add_range(NULL, 0, len);
u8* backup = ck_alloc_nozero(len); u8* backup = ck_alloc_nozero(len);
@ -117,7 +117,8 @@ static u8 colorization(afl_state_t *afl, u8* buf, u32 len, u32 exec_cksum) {
struct range* rng; struct range* rng;
afl->stage_cur = 0; afl->stage_cur = 0;
while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { while ((rng = pop_biggest_range(&ranges)) != NULL &&
afl->stage_cur < afl->stage_max) {
u32 s = rng->end - rng->start; u32 s = rng->end - rng->start;
if (s == 0) goto empty_range; if (s == 0) goto empty_range;
@ -171,7 +172,7 @@ static u8 colorization(afl_state_t *afl, u8* buf, u32 len, u32 exec_cksum) {
} else { } else {
unlink(afl->queue_cur->fname); /* ignore errors */ unlink(afl->queue_cur->fname); /* ignore errors */
fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
} }
@ -204,7 +205,7 @@ checksum_fail:
///// Input to State replacement ///// Input to State replacement
static u8 its_fuzz(afl_state_t *afl, u8* buf, u32 len, u8* status) { static u8 its_fuzz(afl_state_t* afl, u8* buf, u32 len, u8* status) {
u64 orig_hit_cnt, new_hit_cnt; u64 orig_hit_cnt, new_hit_cnt;
@ -223,9 +224,9 @@ static u8 its_fuzz(afl_state_t *afl, u8* buf, u32 len, u8* status) {
} }
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 pattern, u64 repl, u32 idx, static u8 cmp_extend_encoding(afl_state_t* afl, struct cmp_header* h,
u8* orig_buf, u8* buf, u32 len, u8 do_reverse, u64 pattern, u64 repl, u32 idx, u8* orig_buf,
u8* status) { u8* buf, u32 len, u8 do_reverse, u8* status) {
u64* buf_64 = (u64*)&buf[idx]; u64* buf_64 = (u64*)&buf[idx];
u32* buf_32 = (u32*)&buf[idx]; u32* buf_32 = (u32*)&buf[idx];
@ -251,8 +252,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -270,8 +271,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -289,8 +290,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -312,7 +313,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
} }
static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { static void try_to_add_to_dict(afl_state_t* afl, u64 v, u8 shape) {
u8* b = (u8*)&v; u8* b = (u8*)&v;
@ -354,7 +355,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
} }
static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) { static u8 cmp_fuzz(afl_state_t* afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
struct cmp_header* h = &afl->shm.cmp_map->headers[key]; struct cmp_header* h = &afl->shm.cmp_map->headers[key];
u32 i, j, idx; u32 i, j, idx;
@ -372,21 +373,22 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
// opt not in the paper // opt not in the paper
for (j = 0; j < i; ++j) for (j = 0; j < i; ++j)
if (afl->shm.cmp_map->log[key][j].v0 == o->v0 && afl->shm.cmp_map->log[key][i].v1 == o->v1) if (afl->shm.cmp_map->log[key][j].v0 == o->v0 &&
afl->shm.cmp_map->log[key][i].v1 == o->v1)
goto cmp_fuzz_next_iter; goto cmp_fuzz_next_iter;
for (idx = 0; idx < len && fails < 8; ++idx) { for (idx = 0; idx < len && fails < 8; ++idx) {
if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf,
1, &status))) len, 1, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
else if (status == 1) else if (status == 1)
break; break;
if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf,
1, &status))) len, 1, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
@ -412,8 +414,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
} }
static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header* h, u8* pattern, u8* repl, u32 idx, static u8 rtn_extend_encoding(afl_state_t* afl, struct cmp_header* h,
u8* orig_buf, u8* buf, u32 len, u8* status) { u8* pattern, u8* repl, u32 idx, u8* orig_buf,
u8* buf, u32 len, u8* status) {
u32 i; u32 i;
u32 its_len = MIN(32, len - idx); u32 its_len = MIN(32, len - idx);
@ -437,7 +440,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header* h, u8* patter
} }
static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) { static u8 rtn_fuzz(afl_state_t* afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
struct cmp_header* h = &afl->shm.cmp_map->headers[key]; struct cmp_header* h = &afl->shm.cmp_map->headers[key];
u32 i, j, idx; u32 i, j, idx;
@ -451,7 +454,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
for (i = 0; i < loggeds; ++i) { for (i = 0; i < loggeds; ++i) {
struct cmpfn_operands* o = &((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[i]; struct cmpfn_operands* o =
&((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[i];
// opt not in the paper // opt not in the paper
for (j = 0; j < i; ++j) for (j = 0; j < i; ++j)
@ -461,16 +465,16 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
for (idx = 0; idx < len && fails < 8; ++idx) { for (idx = 0; idx < len && fails < 8; ++idx) {
if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf,
&status))) len, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
else if (status == 1) else if (status == 1)
break; break;
if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf,
&status))) len, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
@ -499,7 +503,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
///// Input to State stage ///// Input to State stage
// afl->queue_cur->exec_cksum // afl->queue_cur->exec_cksum
u8 input_to_state_stage(afl_state_t *afl, 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) { u32 exec_cksum) {
u8 r = 1; u8 r = 1;

View File

@ -28,7 +28,7 @@
/* Execute target application, monitoring for timeouts. Return status /* Execute target application, monitoring for timeouts. Return status
information. The called program will update afl->fsrv.trace_bits[]. */ information. The called program will update afl->fsrv.trace_bits[]. */
u8 run_target(afl_state_t *afl, u32 timeout) { u8 run_target(afl_state_t* afl, u32 timeout) {
static struct itimerval it; static struct itimerval it;
static u32 prev_timed_out = 0; static u32 prev_timed_out = 0;
@ -81,8 +81,9 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -165,11 +166,13 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_REAL, &it, NULL);
/* The SIGALRM handler simply kills the afl->fsrv.child_pid and sets afl->fsrv.child_timed_out. */ /* The SIGALRM handler simply kills the afl->fsrv.child_pid and sets
* afl->fsrv.child_timed_out. */
if (afl->dumb_mode == 1 || afl->no_forkserver) { if (afl->dumb_mode == 1 || afl->no_forkserver) {
if (waitpid(afl->fsrv.child_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->fsrv.child_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
} else { } else {
@ -218,8 +221,8 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
++afl->total_execs; ++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
compiler below this point. Past this location, afl->fsrv.trace_bits[] behave compiler below this point. Past this location, afl->fsrv.trace_bits[]
very normally and do not have to be treated as volatile. */ behave very normally and do not have to be treated as volatile. */
MEM_BARRIER(); MEM_BARRIER();
@ -239,7 +242,8 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
afl->kill_signal = WTERMSIG(status); afl->kill_signal = WTERMSIG(status);
if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL) return FAULT_TMOUT; if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL)
return FAULT_TMOUT;
return FAULT_CRASH; return FAULT_CRASH;
@ -262,18 +266,18 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
} }
/* Write modified data to file for testing. If afl->fsrv.out_file is set, the old file /* Write modified data to file for testing. If afl->fsrv.out_file is set, the
is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is rewound and old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is
truncated. */ rewound and truncated. */
void write_to_testcase(afl_state_t *afl, void* mem, u32 len) { void write_to_testcase(afl_state_t* afl, void* mem, u32 len) {
s32 fd = afl->fsrv.out_fd; s32 fd = afl->fsrv.out_fd;
#ifdef _AFL_DOCUMENT_MUTATIONS #ifdef _AFL_DOCUMENT_MUTATIONS
s32 doc_fd; s32 doc_fd;
char* fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir, afl->document_counter++, char* fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir,
describe_op(0)); afl->document_counter++, describe_op(0));
if (fn != NULL) { if (fn != NULL) {
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
@ -298,7 +302,7 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
} else { } else {
unlink(afl->fsrv.out_file); /* Ignore errors. */ unlink(afl->fsrv.out_file); /* Ignore errors. */
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
} }
@ -312,7 +316,8 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
if (afl->mutator && afl->mutator->afl_custom_pre_save) { if (afl->mutator && afl->mutator->afl_custom_pre_save) {
u8* new_data; u8* new_data;
size_t new_size = afl->mutator->afl_custom_pre_save(afl, mem, len, &new_data); size_t new_size =
afl->mutator->afl_custom_pre_save(afl, mem, len, &new_data);
ck_write(fd, new_data, new_size, afl->fsrv.out_file); ck_write(fd, new_data, new_size, afl->fsrv.out_file);
ck_free(new_data); ck_free(new_data);
@ -335,7 +340,8 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
/* The same, but with an adjustable gap. Used for trimming. */ /* The same, but with an adjustable gap. Used for trimming. */
static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u32 skip_len) { static void write_with_gap(afl_state_t* afl, void* mem, u32 len, u32 skip_at,
u32 skip_len) {
s32 fd = afl->fsrv.out_fd; s32 fd = afl->fsrv.out_fd;
u32 tail_len = len - skip_at - skip_len; u32 tail_len = len - skip_at - skip_len;
@ -348,7 +354,7 @@ static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u3
} else { } else {
unlink(afl->fsrv.out_file); /* Ignore errors. */ unlink(afl->fsrv.out_file); /* Ignore errors. */
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
} }
@ -362,7 +368,8 @@ static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u3
if (skip_at) ck_write(fd, mem, skip_at, afl->fsrv.out_file); if (skip_at) ck_write(fd, mem, skip_at, afl->fsrv.out_file);
u8* memu8 = mem; u8* memu8 = mem;
if (tail_len) ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file); if (tail_len)
ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file);
if (!afl->fsrv.out_file) { if (!afl->fsrv.out_file) {
@ -379,8 +386,8 @@ static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u3
to warn about flaky or otherwise problematic test cases early on; and when to warn about flaky or otherwise problematic test cases early on; and when
new paths are discovered to detect variable behavior and so on. */ new paths are discovered to detect variable behavior and so on. */
u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 handicap, u8 calibrate_case(afl_state_t* afl, struct queue_entry* q, u8* use_mem,
u8 from_queue) { u32 handicap, u8 from_queue) {
static u8 first_trace[MAP_SIZE]; static u8 first_trace[MAP_SIZE];
@ -398,8 +405,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
to intermittent latency. */ to intermittent latency. */
if (!from_queue || afl->resuming_fuzz) if (!from_queue || afl->resuming_fuzz)
use_tmout = use_tmout = MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD,
MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD, afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100); afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100);
++q->cal_failed; ++q->cal_failed;
@ -409,8 +416,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
/* Make sure the forkserver is up before we do anything, and let's not /* Make sure the forkserver is up before we do anything, and let's not
count its spin-up time toward binary calibration. */ count its spin-up time toward binary calibration. */
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->fsrv.fsrv_pid) afl_fsrv_start(&afl->fsrv, afl->argv); if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->fsrv.fsrv_pid)
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid && afl->shm.cmplog_mode) afl_fsrv_start(&afl->fsrv, afl->argv);
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid &&
afl->shm.cmplog_mode)
init_cmplog_forkserver(afl); init_cmplog_forkserver(afl);
if (q->exec_cksum) memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE); if (q->exec_cksum) memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE);
@ -421,7 +430,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
u32 cksum; u32 cksum;
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) show_stats(afl); if (!first_run && !(afl->stage_cur % afl->stats_update_freq))
show_stats(afl);
write_to_testcase(afl, use_mem, q->len); write_to_testcase(afl, use_mem, q->len);
@ -432,7 +442,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
if (afl->stop_soon || fault != afl->crash_mode) goto abort_calibration; if (afl->stop_soon || fault != afl->crash_mode) goto abort_calibration;
if (!afl->dumb_mode && !afl->stage_cur && !count_bytes(afl->fsrv.trace_bits)) { if (!afl->dumb_mode && !afl->stage_cur &&
!count_bytes(afl->fsrv.trace_bits)) {
fault = FAULT_NOINST; fault = FAULT_NOINST;
goto abort_calibration; goto abort_calibration;
@ -534,7 +545,7 @@ abort_calibration:
/* Grab interesting test cases from other fuzzers. */ /* Grab interesting test cases from other fuzzers. */
void sync_fuzzers(afl_state_t *afl) { void sync_fuzzers(afl_state_t* afl) {
DIR* sd; DIR* sd;
struct dirent* sd_ent; struct dirent* sd_ent;
@ -562,7 +573,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* Skip dot files and our own output directory. */ /* Skip dot files and our own output directory. */
if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name)) continue; if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name))
continue;
/* Skip anything that doesn't have a queue/ subdirectory. */ /* Skip anything that doesn't have a queue/ subdirectory. */
@ -577,7 +589,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* Retrieve the ID of the last seen test case. */ /* Retrieve the ID of the last seen test case. */
qd_synced_path = alloc_printf("%s/.synced/%s", afl->out_dir, sd_ent->d_name); qd_synced_path =
alloc_printf("%s/.synced/%s", afl->out_dir, sd_ent->d_name);
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600); id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
@ -610,7 +623,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* OK, sounds like a new one. Let's give it a try. */ /* OK, sounds like a new one. Let's give it a try. */
if (afl->syncing_case >= next_min_accept) next_min_accept = afl->syncing_case + 1; if (afl->syncing_case >= next_min_accept)
next_min_accept = afl->syncing_case + 1;
path = alloc_printf("%s/%s", qd_path, qd_ent->d_name); path = alloc_printf("%s/%s", qd_path, qd_ent->d_name);
@ -646,7 +660,8 @@ void sync_fuzzers(afl_state_t *afl) {
if (afl->stop_soon) goto close_sync; if (afl->stop_soon) goto close_sync;
afl->syncing_party = sd_ent->d_name; afl->syncing_party = sd_ent->d_name;
afl->queued_imported += save_if_interesting(afl, mem, st.st_size, fault); afl->queued_imported +=
save_if_interesting(afl, mem, st.st_size, fault);
afl->syncing_party = 0; afl->syncing_party = 0;
munmap(mem, st.st_size); munmap(mem, st.st_size);
@ -678,7 +693,7 @@ void sync_fuzzers(afl_state_t *afl) {
trimmer uses power-of-two increments somewhere between 1/16 and 1/1024 of trimmer uses power-of-two increments somewhere between 1/16 and 1/1024 of
file size, to keep the stage short and sweet. */ file size, to keep the stage short and sweet. */
u8 trim_case(afl_state_t *afl, struct queue_entry* q, u8* in_buf) { u8 trim_case(afl_state_t* afl, struct queue_entry* q, u8* in_buf) {
/* Custom mutator trimmer */ /* Custom mutator trimmer */
if (afl->mutator && afl->mutator->afl_custom_trim) if (afl->mutator && afl->mutator->afl_custom_trim)
@ -814,7 +829,7 @@ abort_trimming:
error conditions, returning 1 if it's time to bail out. This is error conditions, returning 1 if it's time to bail out. This is
a helper function for fuzz_one(). */ a helper function for fuzz_one(). */
u8 common_fuzz_stuff(afl_state_t *afl, u8* out_buf, u32 len) { u8 common_fuzz_stuff(afl_state_t* afl, u8* out_buf, u32 len) {
u8 fault; u8 fault;
@ -859,7 +874,8 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8* out_buf, u32 len) {
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault); afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault);
if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 == afl->stage_max) if (!(afl->stage_cur % afl->stats_update_freq) ||
afl->stage_cur + 1 == afl->stage_max)
show_stats(afl); show_stats(afl);
return 0; return 0;

View File

@ -27,14 +27,15 @@
/* Update stats file for unattended monitoring. */ /* Update stats file for unattended monitoring. */
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, double eps) { void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
double eps) {
static double last_bcvg, last_stab, last_eps; static double last_bcvg, last_stab, last_eps;
static struct rusage rus; static struct rusage rus;
u8* fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
s32 fd; s32 fd;
FILE* f; FILE *f;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
@ -101,23 +102,28 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, dou
"command_line : %s\n", "command_line : %s\n",
afl->start_time / 1000, get_cur_time() / 1000, getpid(), afl->start_time / 1000, get_cur_time() / 1000, getpid(),
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs, afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
/*eps,*/ afl->total_execs / ((double)(get_cur_time() - afl->start_time) / 1000), /*eps,*/ afl->total_execs /
afl->queued_paths, afl->queued_favored, afl->queued_discovered, afl->queued_imported, ((double)(get_cur_time() - afl->start_time) / 1000),
afl->max_depth, afl->current_entry, afl->pending_favored, afl->pending_not_fuzzed, afl->queued_paths, afl->queued_favored, afl->queued_discovered,
afl->queued_variable, stability, bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->queued_imported, afl->max_depth, afl->current_entry,
afl->last_path_time / 1000, afl->last_crash_time / 1000, afl->last_hang_time / 1000, afl->pending_favored, afl->pending_not_fuzzed, afl->queued_variable,
afl->total_execs - afl->last_crash_execs, afl->fsrv.exec_tmout, afl->slowest_exec_ms, stability, bitmap_cvg, afl->unique_crashes, afl->unique_hangs,
afl->last_path_time / 1000, afl->last_crash_time / 1000,
afl->last_hang_time / 1000, afl->total_execs - afl->last_crash_execs,
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
#ifdef __APPLE__ #ifdef __APPLE__
(unsigned long int)(rus.ru_maxrss >> 20), (unsigned long int)(rus.ru_maxrss >> 20),
#else #else
(unsigned long int)(rus.ru_maxrss >> 10), (unsigned long int)(rus.ru_maxrss >> 10),
#endif #endif
afl->use_banner, afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "", afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "", afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "",
afl->crash_mode ? "crash " : "", afl->persistent_mode ? "persistent " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
afl->persistent_mode ? "persistent " : "",
afl->deferred_mode ? "deferred " : "", afl->deferred_mode ? "deferred " : "",
(afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode || afl->no_forkserver || afl->crash_mode || (afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode ||
afl->persistent_mode || afl->deferred_mode) afl->no_forkserver || afl->crash_mode || afl->persistent_mode ||
afl->deferred_mode)
? "" ? ""
: "default", : "default",
afl->orig_cmdline); afl->orig_cmdline);
@ -157,9 +163,10 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
fprintf(afl->fsrv.plot_file, fprintf(afl->fsrv.plot_file,
"%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\n", "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\n",
get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, afl->queued_paths, get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg, afl->unique_crashes, afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
afl->unique_hangs, afl->max_depth, eps); /* ignore errors */ bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth,
eps); /* ignore errors */
fflush(afl->fsrv.plot_file); fflush(afl->fsrv.plot_file);
@ -266,11 +273,12 @@ void show_stats(afl_state_t *afl) {
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */ /* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
if (!afl->dumb_mode && afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed && if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
get_afl_env("AFL_EXIT_WHEN_DONE")) !afl->pending_not_fuzzed && get_afl_env("AFL_EXIT_WHEN_DONE"))
afl->stop_soon = 2; afl->stop_soon = 2;
if (afl->total_crashes && get_afl_env("AFL_BENCH_UNTIL_CRASH")) afl->stop_soon = 2; if (afl->total_crashes && get_afl_env("AFL_BENCH_UNTIL_CRASH"))
afl->stop_soon = 2;
/* If we're not on TTY, bail out. */ /* If we're not on TTY, bail out. */
@ -305,20 +313,22 @@ void show_stats(afl_state_t *afl) {
/* Let's start by drawing a centered banner. */ /* Let's start by drawing a centered banner. */
banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) + strlen(afl->use_banner) + banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) +
strlen(afl->power_name) + 3 + 5; strlen(afl->use_banner) + strlen(afl->power_name) + 3 + 5;
banner_pad = (79 - banner_len) / 2; banner_pad = (79 - banner_len) / 2;
memset(tmp, ' ', banner_pad); memset(tmp, ' ', banner_pad);
#ifdef HAVE_AFFINITY #ifdef HAVE_AFFINITY
sprintf(tmp + banner_pad, sprintf(
"%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}", tmp + banner_pad,
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop", "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}",
afl->use_banner, afl->power_name, afl->cpu_aff); afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name, afl->cpu_aff);
#else #else
sprintf(tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]", sprintf(
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop", tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]",
afl->use_banner, afl->power_name); afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name);
#endif /* HAVE_AFFINITY */ #endif /* HAVE_AFFINITY */
SAYF("\n%s\n", tmp); SAYF("\n%s\n", tmp);
@ -360,7 +370,8 @@ void show_stats(afl_state_t *afl) {
else else
/* No finds for a long time and no test cases to try. */ /* No finds for a long time and no test cases to try. */
if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed && min_wo_finds > 120) if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
min_wo_finds > 120)
strcpy(tmp, cLGN); strcpy(tmp, cLGN);
/* Default: cautiously OK to stop? */ /* Default: cautiously OK to stop? */
@ -376,8 +387,9 @@ void show_stats(afl_state_t *afl) {
/* We want to warn people about not seeing new paths after a full cycle, /* We want to warn people about not seeing new paths after a full cycle,
except when resuming fuzzing or running in non-instrumented mode. */ except when resuming fuzzing or running in non-instrumented mode. */
if (!afl->dumb_mode && (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 || if (!afl->dumb_mode &&
afl->in_bitmap || afl->crash_mode)) { (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
afl->in_bitmap || afl->crash_mode)) {
SAYF(bV bSTOP " last new path : " cRST "%-33s ", SAYF(bV bSTOP " last new path : " cRST "%-33s ",
DTD(cur_ms, afl->last_path_time)); DTD(cur_ms, afl->last_path_time));
@ -407,7 +419,8 @@ void show_stats(afl_state_t *afl) {
SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP
" uniq crashes : %s%-6s" bSTG bV "\n", " uniq crashes : %s%-6s" bSTG bV "\n",
DTD(cur_ms, afl->last_crash_time), afl->unique_crashes ? cLRD : cRST, tmp); DTD(cur_ms, afl->last_crash_time), afl->unique_crashes ? cLRD : cRST,
tmp);
sprintf(tmp, "%s%s", DI(afl->unique_hangs), sprintf(tmp, "%s%s", DI(afl->unique_hangs),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
@ -434,7 +447,8 @@ void show_stats(afl_state_t *afl) {
((double)afl->queue_cur->bitmap_size) * 100 / MAP_SIZE, t_byte_ratio); ((double)afl->queue_cur->bitmap_size) * 100 / MAP_SIZE, t_byte_ratio);
SAYF(" map density : %s%-21s" bSTG bV "\n", SAYF(" map density : %s%-21s" bSTG bV "\n",
t_byte_ratio > 70 ? cLRD : ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST), t_byte_ratio > 70 ? cLRD
: ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST),
tmp); tmp);
sprintf(tmp, "%s (%0.02f%%)", DI(afl->cur_skipped_paths), sprintf(tmp, "%s (%0.02f%%)", DI(afl->cur_skipped_paths),
@ -477,7 +491,8 @@ void show_stats(afl_state_t *afl) {
SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp); SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp);
sprintf(tmp, "%s (%s%s unique)", DI(afl->total_crashes), DI(afl->unique_crashes), sprintf(tmp, "%s (%s%s unique)", DI(afl->total_crashes),
DI(afl->unique_crashes),
(afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : ""); (afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
if (afl->crash_mode) { if (afl->crash_mode) {
@ -510,7 +525,8 @@ void show_stats(afl_state_t *afl) {
} }
sprintf(tmp, "%s (%s%s unique)", DI(afl->total_tmouts), DI(afl->unique_tmouts), sprintf(tmp, "%s (%s%s unique)", DI(afl->total_tmouts),
DI(afl->unique_tmouts),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp); SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
@ -527,10 +543,11 @@ void show_stats(afl_state_t *afl) {
} else { } else {
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP1]), sprintf(
DI(afl->stage_cycles[STAGE_FLIP1]), DI(afl->stage_finds[STAGE_FLIP2]), tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP1]),
DI(afl->stage_cycles[STAGE_FLIP2]), DI(afl->stage_finds[STAGE_FLIP4]), DI(afl->stage_cycles[STAGE_FLIP1]), DI(afl->stage_finds[STAGE_FLIP2]),
DI(afl->stage_cycles[STAGE_FLIP4])); DI(afl->stage_cycles[STAGE_FLIP2]), DI(afl->stage_finds[STAGE_FLIP4]),
DI(afl->stage_cycles[STAGE_FLIP4]));
} }
@ -539,10 +556,11 @@ void show_stats(afl_state_t *afl) {
tmp, DI(afl->max_depth)); tmp, DI(afl->max_depth));
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP8]), sprintf(
DI(afl->stage_cycles[STAGE_FLIP8]), DI(afl->stage_finds[STAGE_FLIP16]), tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP8]),
DI(afl->stage_cycles[STAGE_FLIP16]), DI(afl->stage_finds[STAGE_FLIP32]), DI(afl->stage_cycles[STAGE_FLIP8]), DI(afl->stage_finds[STAGE_FLIP16]),
DI(afl->stage_cycles[STAGE_FLIP32])); DI(afl->stage_cycles[STAGE_FLIP16]), DI(afl->stage_finds[STAGE_FLIP32]),
DI(afl->stage_cycles[STAGE_FLIP32]));
SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP
" pending : " cRST "%-10s" bSTG bV "\n", " pending : " cRST "%-10s" bSTG bV "\n",
@ -550,8 +568,10 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_ARITH8]), sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_ARITH8]),
DI(afl->stage_cycles[STAGE_ARITH8]), DI(afl->stage_finds[STAGE_ARITH16]), DI(afl->stage_cycles[STAGE_ARITH8]),
DI(afl->stage_cycles[STAGE_ARITH16]), DI(afl->stage_finds[STAGE_ARITH32]), DI(afl->stage_finds[STAGE_ARITH16]),
DI(afl->stage_cycles[STAGE_ARITH16]),
DI(afl->stage_finds[STAGE_ARITH32]),
DI(afl->stage_cycles[STAGE_ARITH32])); DI(afl->stage_cycles[STAGE_ARITH32]));
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
@ -559,11 +579,12 @@ void show_stats(afl_state_t *afl) {
tmp, DI(afl->pending_favored)); tmp, DI(afl->pending_favored));
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf( sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_INTEREST8]),
tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_INTEREST8]), DI(afl->stage_cycles[STAGE_INTEREST8]),
DI(afl->stage_cycles[STAGE_INTEREST8]), DI(afl->stage_finds[STAGE_INTEREST16]), DI(afl->stage_finds[STAGE_INTEREST16]),
DI(afl->stage_cycles[STAGE_INTEREST16]), DI(afl->stage_finds[STAGE_INTEREST32]), DI(afl->stage_cycles[STAGE_INTEREST16]),
DI(afl->stage_cycles[STAGE_INTEREST32])); DI(afl->stage_finds[STAGE_INTEREST32]),
DI(afl->stage_cycles[STAGE_INTEREST32]));
SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP
" own finds : " cRST "%-10s" bSTG bV "\n", " own finds : " cRST "%-10s" bSTG bV "\n",
@ -571,18 +592,21 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_EXTRAS_UO]), sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_EXTRAS_UO]),
DI(afl->stage_cycles[STAGE_EXTRAS_UO]), DI(afl->stage_finds[STAGE_EXTRAS_UI]), DI(afl->stage_cycles[STAGE_EXTRAS_UO]),
DI(afl->stage_cycles[STAGE_EXTRAS_UI]), DI(afl->stage_finds[STAGE_EXTRAS_AO]), DI(afl->stage_finds[STAGE_EXTRAS_UI]),
DI(afl->stage_cycles[STAGE_EXTRAS_UI]),
DI(afl->stage_finds[STAGE_EXTRAS_AO]),
DI(afl->stage_cycles[STAGE_EXTRAS_AO])); DI(afl->stage_cycles[STAGE_EXTRAS_AO]));
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
" imported : " cRST "%-10s" bSTG bV "\n", " imported : " cRST "%-10s" bSTG bV "\n",
tmp, afl->sync_id ? DI(afl->queued_imported) : (u8*)"n/a"); tmp, afl->sync_id ? DI(afl->queued_imported) : (u8 *)"n/a");
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_HAVOC]), sprintf(
DI(afl->stage_cycles[STAGE_HAVOC]), DI(afl->stage_finds[STAGE_SPLICE]), tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_HAVOC]),
DI(afl->stage_cycles[STAGE_SPLICE]), DI(afl->stage_finds[STAGE_RADAMSA]), DI(afl->stage_cycles[STAGE_HAVOC]), DI(afl->stage_finds[STAGE_SPLICE]),
DI(afl->stage_cycles[STAGE_RADAMSA])); DI(afl->stage_cycles[STAGE_SPLICE]), DI(afl->stage_finds[STAGE_RADAMSA]),
DI(afl->stage_cycles[STAGE_RADAMSA]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp); SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
@ -594,20 +618,22 @@ void show_stats(afl_state_t *afl) {
SAYF(" stability : %s%-10s" bSTG bV "\n", SAYF(" stability : %s%-10s" bSTG bV "\n",
(stab_ratio < 85 && afl->var_byte_count > 40) (stab_ratio < 85 && afl->var_byte_count > 40)
? cLRD ? cLRD
: ((afl->queued_variable && (!afl->persistent_mode || afl->var_byte_count > 20)) : ((afl->queued_variable &&
(!afl->persistent_mode || afl->var_byte_count > 20))
? cMGN ? cMGN
: cRST), : cRST),
tmp); tmp);
if (afl->shm.cmplog_mode) { if (afl->shm.cmplog_mode) {
sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_PYTHON]), sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
DI(afl->stage_finds[STAGE_PYTHON]),
DI(afl->stage_cycles[STAGE_PYTHON]), DI(afl->stage_cycles[STAGE_PYTHON]),
DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]), DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
DI(afl->stage_finds[STAGE_COLORIZATION]), DI(afl->stage_finds[STAGE_COLORIZATION]),
DI(afl->stage_cycles[STAGE_COLORIZATION]), DI(afl->stage_finds[STAGE_ITS]), DI(afl->stage_cycles[STAGE_COLORIZATION]),
DI(afl->stage_cycles[STAGE_ITS])); DI(afl->stage_finds[STAGE_ITS]), DI(afl->stage_cycles[STAGE_ITS]));
SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp); tmp);
@ -631,7 +657,8 @@ void show_stats(afl_state_t *afl) {
} else { } else {
sprintf(tmp, "%0.02f%%/%s, ", sprintf(tmp, "%0.02f%%/%s, ",
((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 / afl->bytes_trim_in, ((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 /
afl->bytes_trim_in,
DI(afl->trim_execs)); DI(afl->trim_execs));
} }
@ -674,7 +701,7 @@ void show_stats(afl_state_t *afl) {
double cur_runnable = get_runnable_processes(); double cur_runnable = get_runnable_processes();
u32 cur_utilization = cur_runnable * 100 / afl->cpu_core_count; u32 cur_utilization = cur_runnable * 100 / afl->cpu_core_count;
u8* cpu_color = cCYA; u8 *cpu_color = cCYA;
/* If we could still run one or more processes, use green. */ /* If we could still run one or more processes, use green. */
@ -725,7 +752,7 @@ void show_stats(afl_state_t *afl) {
void show_init_stats(afl_state_t *afl) { void show_init_stats(afl_state_t *afl) {
struct queue_entry* q = afl->queue; struct queue_entry *q = afl->queue;
u32 min_bits = 0, max_bits = 0; u32 min_bits = 0, max_bits = 0;
u64 min_us = 0, max_us = 0; u64 min_us = 0, max_us = 0;
u64 avg_us = 0; u64 avg_us = 0;
@ -756,11 +783,11 @@ void show_init_stats(afl_state_t *afl) {
/* Let's keep things moving with slow binaries. */ /* Let's keep things moving with slow binaries. */
if (avg_us > 50000) if (avg_us > 50000)
afl->havoc_div = 10; /* 0-19 execs/sec */ afl->havoc_div = 10; /* 0-19 execs/sec */
else if (avg_us > 20000) else if (avg_us > 20000)
afl->havoc_div = 5; /* 20-49 execs/sec */ afl->havoc_div = 5; /* 20-49 execs/sec */
else if (avg_us > 10000) else if (avg_us > 10000)
afl->havoc_div = 2; /* 50-100 execs/sec */ afl->havoc_div = 2; /* 50-100 execs/sec */
if (!afl->resuming_fuzz) { if (!afl->resuming_fuzz) {
@ -789,7 +816,8 @@ void show_init_stats(afl_state_t *afl) {
"%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST "%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST
"%u to %u bits (average: %0.02f bits)\n" cGRA "%u to %u bits (average: %0.02f bits)\n" cGRA
" Exec timing : " cRST "%s to %s us (average: %s us)\n", " Exec timing : " cRST "%s to %s us (average: %s us)\n",
afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits, max_bits, afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits,
max_bits,
((double)afl->total_bitmap_size) / ((double)afl->total_bitmap_size) /
(afl->total_bitmap_entries ? afl->total_bitmap_entries : 1), (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1),
DI(min_us), DI(max_us), DI(avg_us)); DI(min_us), DI(max_us), DI(avg_us));
@ -811,9 +839,11 @@ void show_init_stats(afl_state_t *afl) {
afl->fsrv.exec_tmout = avg_us * 5 / 1000; afl->fsrv.exec_tmout = avg_us * 5 / 1000;
afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000); afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000);
afl->fsrv.exec_tmout = (afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND; afl->fsrv.exec_tmout =
(afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;
if (afl->fsrv.exec_tmout > EXEC_TIMEOUT) afl->fsrv.exec_tmout = EXEC_TIMEOUT; if (afl->fsrv.exec_tmout > EXEC_TIMEOUT)
afl->fsrv.exec_tmout = EXEC_TIMEOUT;
ACTF("No -t option specified, so I'll use exec timeout of %u ms.", ACTF("No -t option specified, so I'll use exec timeout of %u ms.",
afl->fsrv.exec_tmout); afl->fsrv.exec_tmout);
@ -822,7 +852,8 @@ void show_init_stats(afl_state_t *afl) {
} else if (afl->timeout_given == 3) { } else if (afl->timeout_given == 3) {
ACTF("Applying timeout settings from resumed session (%u ms).", afl->fsrv.exec_tmout); ACTF("Applying timeout settings from resumed session (%u ms).",
afl->fsrv.exec_tmout);
} }

View File

@ -84,7 +84,7 @@ static u8* get_libradamsa_path(u8* own_loc) {
/* Display usage hints. */ /* Display usage hints. */
static void usage(afl_state_t *afl, u8* argv0, int more_help) { static void usage(afl_state_t* afl, u8* argv0, int more_help) {
SAYF( SAYF(
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n" "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
@ -222,7 +222,6 @@ static int stricmp(char const* a, char const* b) {
} }
/* Main entry point */ /* Main entry point */
int main(int argc, char** argv, char** envp) { int main(int argc, char** argv, char** envp) {
@ -238,10 +237,8 @@ int main(int argc, char** argv, char** envp) {
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
afl_state_t *afl = calloc(1, sizeof(afl_state_t)); afl_state_t* afl = calloc(1, sizeof(afl_state_t));
if (!afl) { if (!afl) { FATAL("Could not create afl state"); }
FATAL("Could not create afl state");
}
afl_state_init(afl); afl_state_init(afl);
afl_fsrv_init(&afl->fsrv); afl_fsrv_init(&afl->fsrv);
@ -249,7 +246,7 @@ int main(int argc, char** argv, char** envp) {
SAYF(cCYA "afl-fuzz" VERSION cRST SAYF(cCYA "afl-fuzz" VERSION cRST
" based on afl by Michal Zalewski and a big online community\n"); " based on afl by Michal Zalewski and a big online community\n");
doc_path = access(DOC_PATH, F_OK) ? (u8 *)"docs" : doc_path; doc_path = access(DOC_PATH, F_OK) ? (u8*)"docs" : doc_path;
gettimeofday(&tv, &tz); gettimeofday(&tv, &tz);
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@ -348,8 +345,8 @@ int main(int argc, char** argv, char** envp) {
*c = 0; *c = 0;
if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 || if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
!afl->master_id || !afl->master_max || afl->master_id > afl->master_max || !afl->master_id || !afl->master_max ||
afl->master_max > 1000000) afl->master_id > afl->master_max || afl->master_max > 1000000)
FATAL("Bogus master ID passed to -M"); FATAL("Bogus master ID passed to -M");
} }
@ -543,7 +540,8 @@ int main(int argc, char** argv, char** envp) {
afl->limit_time_sig = 1; afl->limit_time_sig = 1;
afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT; afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
if (sscanf(optarg, "%llu", &afl->limit_time_puppet) < 1 || optarg[0] == '-') if (sscanf(optarg, "%llu", &afl->limit_time_puppet) < 1 ||
optarg[0] == '-')
FATAL("Bad syntax used for -L"); FATAL("Bad syntax used for -L");
u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000; u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000;
@ -561,7 +559,9 @@ int main(int argc, char** argv, char** envp) {
int tmp_swarm = 0; int tmp_swarm = 0;
if (afl->g_now > afl->g_max) afl->g_now = 0; if (afl->g_now > afl->g_max) afl->g_now = 0;
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) + afl->w_end; afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) /
(afl->g_max) +
afl->w_end;
for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) { for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) {
@ -572,7 +572,8 @@ int main(int argc, char** argv, char** envp) {
afl->stage_finds_puppet[tmp_swarm][i] = 0; afl->stage_finds_puppet[tmp_swarm][i] = 0;
afl->probability_now[tmp_swarm][i] = 0.0; afl->probability_now[tmp_swarm][i] = 0.0;
afl->x_now[tmp_swarm][i] = ((double)(random() % 7000) * 0.0001 + 0.1); afl->x_now[tmp_swarm][i] =
((double)(random() % 7000) * 0.0001 + 0.1);
total_puppet_temp += afl->x_now[tmp_swarm][i]; total_puppet_temp += afl->x_now[tmp_swarm][i];
afl->v_now[tmp_swarm][i] = 0.1; afl->v_now[tmp_swarm][i] = 0.1;
afl->L_best[tmp_swarm][i] = 0.5; afl->L_best[tmp_swarm][i] = 0.5;
@ -587,7 +588,8 @@ int main(int argc, char** argv, char** envp) {
afl->stage_cycles_puppet[tmp_swarm][i]; afl->stage_cycles_puppet[tmp_swarm][i];
afl->stage_finds_puppet_v2[tmp_swarm][i] = afl->stage_finds_puppet_v2[tmp_swarm][i] =
afl->stage_finds_puppet[tmp_swarm][i]; afl->stage_finds_puppet[tmp_swarm][i];
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / total_puppet_temp; afl->x_now[tmp_swarm][i] =
afl->x_now[tmp_swarm][i] / total_puppet_temp;
} }
@ -598,7 +600,8 @@ int main(int argc, char** argv, char** envp) {
afl->probability_now[tmp_swarm][i] = 0.0; afl->probability_now[tmp_swarm][i] = 0.0;
afl->v_now[tmp_swarm][i] = afl->v_now[tmp_swarm][i] =
afl->w_now * afl->v_now[tmp_swarm][i] + afl->w_now * afl->v_now[tmp_swarm][i] +
RAND_C * (afl->L_best[tmp_swarm][i] - afl->x_now[tmp_swarm][i]) + RAND_C *
(afl->L_best[tmp_swarm][i] - afl->x_now[tmp_swarm][i]) +
RAND_C * (afl->G_best[i] - afl->x_now[tmp_swarm][i]); RAND_C * (afl->G_best[i] - afl->x_now[tmp_swarm][i]);
afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i]; afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i];
@ -617,7 +620,8 @@ int main(int argc, char** argv, char** envp) {
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp; afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp;
if (likely(i != 0)) if (likely(i != 0))
afl->probability_now[tmp_swarm][i] = afl->probability_now[tmp_swarm][i] =
afl->probability_now[tmp_swarm][i - 1] + afl->x_now[tmp_swarm][i]; afl->probability_now[tmp_swarm][i - 1] +
afl->x_now[tmp_swarm][i];
else else
afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i]; afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i];
@ -669,7 +673,8 @@ int main(int argc, char** argv, char** envp) {
OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL");
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
if (afl->sync_id && afl->force_deterministic && getenv("AFL_CUSTOM_MUTATOR_ONLY")) if (afl->sync_id && afl->force_deterministic &&
getenv("AFL_CUSTOM_MUTATOR_ONLY"))
WARNF( WARNF(
"Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will " "Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
"result in no deterministic mutations being done!"); "result in no deterministic mutations being done!");
@ -764,8 +769,7 @@ int main(int argc, char** argv, char** envp) {
if (get_afl_env("AFL_AUTORESUME")) { if (get_afl_env("AFL_AUTORESUME")) {
afl->autoresume = 1; afl->autoresume = 1;
if (afl->in_place_resume) if (afl->in_place_resume) SAYF("AFL_AUTORESUME has no effect for '-i -'");
SAYF("AFL_AUTORESUME has no effect for '-i -'");
} }
@ -886,11 +890,12 @@ int main(int argc, char** argv, char** envp) {
if (!afl->timeout_given) find_timeout(afl); if (!afl->timeout_given) find_timeout(afl);
if ((afl->tmp_dir = get_afl_env("AFL_TMPDIR")) != NULL && !afl->in_place_resume) { if ((afl->tmp_dir = get_afl_env("AFL_TMPDIR")) != NULL &&
!afl->in_place_resume) {
char tmpfile[afl->file_extension char tmpfile[afl->file_extension ? strlen(afl->tmp_dir) + 1 + 10 + 1 +
? strlen(afl->tmp_dir) + 1 + 10 + 1 + strlen(afl->file_extension) + 1 strlen(afl->file_extension) + 1
: strlen(afl->tmp_dir) + 1 + 10 + 1]; : strlen(afl->tmp_dir) + 1 + 10 + 1];
if (afl->file_extension) { if (afl->file_extension) {
sprintf(tmpfile, "%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); sprintf(tmpfile, "%s/.cur_input.%s", afl->tmp_dir, afl->file_extension);
@ -927,7 +932,8 @@ int main(int argc, char** argv, char** envp) {
if (afl->file_extension) { if (afl->file_extension) {
afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir,
afl->file_extension);
} else { } else {
@ -935,7 +941,8 @@ int main(int argc, char** argv, char** envp) {
} }
detect_file_args(argv + optind + 1, afl->fsrv.out_file, afl->fsrv.use_stdin); detect_file_args(argv + optind + 1, afl->fsrv.out_file,
afl->fsrv.use_stdin);
break; break;
} }
@ -969,9 +976,11 @@ int main(int argc, char** argv, char** envp) {
if (afl->qemu_mode) { if (afl->qemu_mode) {
if (afl->use_wine) if (afl->use_wine)
use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind,
argv + optind);
} else { } else {
@ -1053,7 +1062,8 @@ int main(int argc, char** argv, char** envp) {
prev_queued = afl->queued_paths; prev_queued = afl->queued_paths;
if (afl->sync_id && afl->queue_cycle == 1 && get_afl_env("AFL_IMPORT_FIRST")) if (afl->sync_id && afl->queue_cycle == 1 &&
get_afl_env("AFL_IMPORT_FIRST"))
sync_fuzzers(afl); sync_fuzzers(afl);
} }
@ -1134,13 +1144,15 @@ stop_fuzzing:
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST, SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
afl->stop_soon == 2 ? "programmatically" : "by user"); afl->stop_soon == 2 ? "programmatically" : "by user");
if (afl->most_time_key == 2) SAYF(cYEL "[!] " cRST "Time limit was reached\n"); if (afl->most_time_key == 2)
SAYF(cYEL "[!] " cRST "Time limit was reached\n");
if (afl->most_execs_key == 2) if (afl->most_execs_key == 2)
SAYF(cYEL "[!] " cRST "Execution limit was reached\n"); SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
/* Running for more than 30 minutes but still doing first cycle? */ /* Running for more than 30 minutes but still doing first cycle? */
if (afl->queue_cycle == 1 && get_cur_time() - afl->start_time > 30 * 60 * 1000) { if (afl->queue_cycle == 1 &&
get_cur_time() - afl->start_time > 30 * 60 * 1000) {
SAYF("\n" cYEL "[!] " cRST SAYF("\n" cYEL "[!] " cRST
"Stopped during the first cycle, results may be incomplete.\n" "Stopped during the first cycle, results may be incomplete.\n"

View File

@ -124,7 +124,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random()); snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
/* create the shared memory segment as if it was a file */ /* create the shared memory segment as if it was a file */
shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600); shm->g_shm_fd =
shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); } if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */ /* configure the size of the shared memory segment */
@ -135,8 +136,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
} }
/* map the shared memory segment to the address space of the process */ /* map the shared memory segment to the address space of the process */
shm->map = shm->map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, map_size->g_shm_fd, 0); map_size->g_shm_fd, 0);
if (map_size->map == MAP_FAILED) { if (map_size->map == MAP_FAILED) {
close(map_size->g_shm_fd); close(map_size->g_shm_fd);
@ -164,7 +165,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
if (shm->cmplog_mode) { if (shm->cmplog_mode) {
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map), shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
IPC_CREAT | IPC_EXCL | 0600); IPC_CREAT | IPC_EXCL | 0600);
if (shm->cmplog_shm_id < 0) PFATAL("shmget() failed"); if (shm->cmplog_shm_id < 0) PFATAL("shmget() failed");
@ -203,7 +204,6 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
} }
#endif #endif
list_append(&shm_list, shm); list_append(&shm_list, shm);
@ -212,3 +212,4 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
return shm->map; return shm->map;
} }

View File

@ -59,12 +59,12 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/resource.h> #include <sys/resource.h>
u8 be_quiet; u8 be_quiet;
u8 *stdin_file, /* stdin file */ u8 *stdin_file, /* stdin file */
*in_dir, /* input folder */ *in_dir, /* input folder */
*doc_path, /* Path to docs */ *doc_path, /* Path to docs */
*at_file = NULL; /* Substitution string for @@ */ *at_file = NULL; /* Substitution string for @@ */
static u8* in_data; /* Input data */ static u8* in_data; /* Input data */
@ -146,7 +146,7 @@ static void at_exit_handler(void) {
/* Write results. */ /* Write results. */
static u32 write_results_to_file(afl_forkserver_t *fsrv) { static u32 write_results_to_file(afl_forkserver_t* fsrv) {
s32 fd; s32 fd;
u32 i, ret = 0; u32 i, ret = 0;
@ -166,7 +166,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv) {
} else { } else {
unlink(fsrv->out_file); /* Ignore errors */ unlink(fsrv->out_file); /* Ignore errors */
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file); if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
@ -217,7 +217,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv) {
/* Write results. */ /* Write results. */
static u32 write_results(afl_forkserver_t *fsrv) { static u32 write_results(afl_forkserver_t* fsrv) {
return write_results_to_file(fsrv); return write_results_to_file(fsrv);
@ -247,7 +247,7 @@ static s32 write_to_file(u8* path, u8* mem, u32 len) {
is unlinked and a new one is created. Otherwise, out_fd is rewound and is unlinked and a new one is created. Otherwise, out_fd is rewound and
truncated. */ truncated. */
static void write_to_testcase(afl_forkserver_t *fsrv, void* mem, u32 len) { static void write_to_testcase(afl_forkserver_t* fsrv, void* mem, u32 len) {
lseek(fsrv->out_fd, 0, SEEK_SET); lseek(fsrv->out_fd, 0, SEEK_SET);
ck_write(fsrv->out_fd, mem, len, fsrv->out_file); ck_write(fsrv->out_fd, mem, len, fsrv->out_file);
@ -259,7 +259,8 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void* mem, u32 len) {
/* Execute target application. Returns 0 if the changes are a dud, or /* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */ 1 if they should be kept. */
static u8 run_target_forkserver(afl_forkserver_t *fsrv, char** argv, u8* mem, u32 len) { static u8 run_target_forkserver(afl_forkserver_t* fsrv, char** argv, u8* mem,
u32 len) {
static struct itimerval it; static struct itimerval it;
static u32 prev_timed_out = 0; static u32 prev_timed_out = 0;
@ -379,7 +380,7 @@ u32 read_file(u8* in_file) {
/* Execute target application. */ /* Execute target application. */
static void run_target(afl_forkserver_t *fsrv, char** argv) { static void run_target(afl_forkserver_t* fsrv, char** argv) {
static struct itimerval it; static struct itimerval it;
int status = 0; int status = 0;
@ -476,7 +477,8 @@ static void run_target(afl_forkserver_t *fsrv, char** argv) {
if (!quiet_mode) SAYF(cRST "-- Program output ends --\n"); if (!quiet_mode) SAYF(cRST "-- Program output ends --\n");
if (!fsrv->child_timed_out && !stop_soon && WIFSIGNALED(status)) child_crashed = 1; if (!fsrv->child_timed_out && !stop_soon && WIFSIGNALED(status))
child_crashed = 1;
if (!quiet_mode) { if (!quiet_mode) {
@ -492,7 +494,7 @@ static void run_target(afl_forkserver_t *fsrv, char** argv) {
} }
extern afl_forkserver_t *fsrv_glob; extern afl_forkserver_t* fsrv_glob;
/* Handle Ctrl-C and the like. */ /* Handle Ctrl-C and the like. */
@ -646,7 +648,7 @@ static void usage(u8* argv0) {
/* Find binary. */ /* Find binary. */
static void find_binary(afl_forkserver_t *fsrv, u8* fname) { static void find_binary(afl_forkserver_t* fsrv, u8* fname) {
u8* env_path = 0; u8* env_path = 0;
struct stat st; struct stat st;
@ -693,7 +695,8 @@ static void find_binary(afl_forkserver_t *fsrv, u8* fname) {
} }
if (!fsrv->target_path) FATAL("Program '%s' not found or not executable", fname); if (!fsrv->target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -703,14 +706,14 @@ static void find_binary(afl_forkserver_t *fsrv, u8* fname) {
int main(int argc, char** argv, char** envp) { int main(int argc, char** argv, char** envp) {
//TODO: u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */ // TODO: u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
s32 opt, i; s32 opt, i;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
u32 tcnt = 0; u32 tcnt = 0;
char** use_argv; char** use_argv;
afl_forkserver_t *fsrv = calloc(1, sizeof(afl_forkserver_t)); afl_forkserver_t* fsrv = calloc(1, sizeof(afl_forkserver_t));
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
@ -912,9 +915,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
} else } else
@ -985,7 +990,8 @@ int main(int argc, char** argv, char** envp) {
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue; if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
#endif #endif
snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file, dir_ent->d_name); snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file,
dir_ent->d_name);
if (read_file(infile)) { if (read_file(infile)) {

View File

@ -159,7 +159,7 @@ static void apply_mask(u32* mem, u32* mask) {
/* See if any bytes are set in the bitmap. */ /* See if any bytes are set in the bitmap. */
static inline u8 anything_set(afl_forkserver_t *fsrv) { static inline u8 anything_set(afl_forkserver_t* fsrv) {
u32* ptr = (u32*)fsrv->trace_bits; u32* ptr = (u32*)fsrv->trace_bits;
u32 i = (MAP_SIZE >> 2); u32 i = (MAP_SIZE >> 2);
@ -226,13 +226,13 @@ static s32 write_to_file(u8* path, u8* mem, u32 len) {
is unlinked and a new one is created. Otherwise, out_fd is rewound and is unlinked and a new one is created. Otherwise, out_fd is rewound and
truncated. */ truncated. */
static void write_to_testcase(afl_forkserver_t *fsrv, void* mem, u32 len) { static void write_to_testcase(afl_forkserver_t* fsrv, void* mem, u32 len) {
s32 fd = fsrv->out_fd; s32 fd = fsrv->out_fd;
if (!fsrv->use_stdin) { if (!fsrv->use_stdin) {
unlink(fsrv->out_file); /* Ignore errors. */ unlink(fsrv->out_file); /* Ignore errors. */
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
@ -403,7 +403,8 @@ static void init_forkserver(char **argv) {
/* Execute target application. Returns 0 if the changes are a dud, or /* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */ 1 if they should be kept. */
static u8 run_target(afl_forkserver_t *fsrv, char** argv, u8* mem, u32 len, u8 first_run) { static u8 run_target(afl_forkserver_t* fsrv, char** argv, u8* mem, u32 len,
u8 first_run) {
static struct itimerval it; static struct itimerval it;
static u32 prev_timed_out = 0; static u32 prev_timed_out = 0;
@ -572,7 +573,7 @@ static u32 next_p2(u32 val) {
/* Actually minimize! */ /* Actually minimize! */
static void minimize(afl_forkserver_t *fsrv, char** argv) { static void minimize(afl_forkserver_t* fsrv, char** argv) {
static u32 alpha_map[256]; static u32 alpha_map[256];
@ -840,7 +841,7 @@ static void handle_stop_sig(int sig) {
/* Do basic preparations - persistent fds, filenames, etc. */ /* Do basic preparations - persistent fds, filenames, etc. */
static void set_up_environment(afl_forkserver_t *fsrv) { static void set_up_environment(afl_forkserver_t* fsrv) {
u8* x; u8* x;
@ -1023,7 +1024,7 @@ static void usage(u8* argv0) {
/* Find binary. */ /* Find binary. */
static void find_binary(afl_forkserver_t *fsrv, u8* fname) { static void find_binary(afl_forkserver_t* fsrv, u8* fname) {
u8* env_path = 0; u8* env_path = 0;
struct stat st; struct stat st;
@ -1070,7 +1071,8 @@ static void find_binary(afl_forkserver_t *fsrv, u8* fname) {
} }
if (!fsrv->target_path) FATAL("Program '%s' not found or not executable", fname); if (!fsrv->target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -1098,7 +1100,7 @@ int main(int argc, char** argv, char** envp) {
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
char** use_argv; char** use_argv;
afl_forkserver_t *fsrv = calloc(1, sizeof(afl_forkserver_t)); afl_forkserver_t* fsrv = calloc(1, sizeof(afl_forkserver_t));
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
@ -1275,9 +1277,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
} else } else
@ -1344,7 +1348,6 @@ int main(int argc, char** argv, char** envp) {
OKF("We're done here. Have a nice day!\n"); OKF("We're done here. Have a nice day!\n");
afl_shm_deinit(&shm); afl_shm_deinit(&shm);
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
free(fsrv); free(fsrv);