diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index f48754b659c7ca79f25807526a09319d23912c27..f87e21df2cb498c48a2f1714b7f98852f07652c5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -184,8 +184,7 @@ struct queue_entry { handicap, /* Number of queue cycles behind */ depth, /* Path depth */ exec_cksum, /* Checksum of the execution trace */ - stats_mutated, /* stats: # of mutations performed */ - first_fuzz; /* Time of first fuzzing */ + stats_mutated; /* stats: # of mutations performed */ u8 *trace_mini; /* Trace bytes, if kept */ u32 tc_ref; /* Trace bytes ref count */ @@ -400,7 +399,7 @@ typedef struct afl_env_vars { afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts, - afl_no_startup_calibration, afl_no_warn_instability, afl_delay_sync; + afl_no_startup_calibration, afl_no_warn_instability; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, @@ -596,7 +595,8 @@ typedef struct afl_state { last_hang_time, /* Time for most recent hang (ms) */ longest_find_time, /* Longest time taken for a find */ exit_on_time, /* Delay to exit if no new paths */ - sync_time; /* Sync time (ms) */ + sync_time, /* Sync time (ms) */ + sync_delay; /* Sync delay (ms) */ u32 slowest_exec_ms, /* Slowest testcase non hang in ms */ subseq_tmouts; /* Number of timeouts in a row */ @@ -1089,7 +1089,6 @@ void deinit_py(void *); /* Queue */ void mark_as_det_done(afl_state_t *, struct queue_entry *); -void mark_as_fuzzed(afl_state_t *, struct queue_entry *); void mark_as_variable(afl_state_t *, struct queue_entry *); void mark_as_redundant(afl_state_t *, struct queue_entry *, u8); void add_to_queue(afl_state_t *, u8 *, u32, u8); diff --git a/include/config.h b/include/config.h index 1360ba256b016fb1df1bc4ca111de11fa34dce8b..b6249a0fc7e963f1e8913d7f71bfe94fb7e3e725 100644 --- a/include/config.h +++ b/include/config.h @@ -309,11 +309,6 @@ #define SYNC_TIME (30 * 60 * 1000) -/* Approximate number of queue cycles to delay syncing of new discoveries - when AFL_DELAY_SYNC is in effect. */ - -#define SYNC_DELAY_CYCLES 3 - /* Output directory reuse grace period (minutes): */ #define OUTPUT_GRACE 25 diff --git a/include/envs.h b/include/envs.h index 6f5576f4a9018c67e443268edcfd8e6ad283c711..942aab669c1d1196fd5ab0d4c7c908c8c637936c 100644 --- a/include/envs.h +++ b/include/envs.h @@ -221,7 +221,7 @@ static char *afl_environment_variables[] = { "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_SYNC_TIME", - "AFL_DELAY_SYNC", + "AFL_SYNC_DELAY", "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT", diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 7531149cd54bcb92698c64dfd4fc709168a0a228..01d1e82ecef53ea80921a45326196aa757baab29 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -801,24 +801,6 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } - /* Carry over saved time of first fuzzing from resumed run, if present */ - - u8 wf_fn[PATH_MAX]; - s32 wf_fd; - u64 first_fuzz; - snprintf(wf_fn, PATH_MAX, "%s/.state/was_fuzzed/%s", afl->in_dir, - nl[i]->d_name); - wf_fd = open(wf_fn, O_RDONLY); - - if (wf_fd != -1 && - read(wf_fd, &first_fuzz, sizeof(u64)) == sizeof(u64)) { - afl->queue_top->was_fuzzed = 1; - afl->queue_top->first_fuzz = first_fuzz; - afl->pending_not_fuzzed--; - } - - close(wf_fd); - /* if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { @@ -920,8 +902,6 @@ void perform_dry_run(afl_state_t *afl) { } - u64 runtime = afl->prev_run_time + get_cur_time() - afl->start_time; - switch (res) { case FSRV_RUN_OK: @@ -948,9 +928,6 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; - q->first_fuzz = runtime; - mark_as_fuzzed(afl, q); - } break; @@ -1082,9 +1059,6 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; - q->first_fuzz = runtime; - mark_as_fuzzed(afl, q); - } q->disabled = 1; @@ -1195,8 +1169,6 @@ void perform_dry_run(afl_state_t *afl) { duplicates = 1; - u64 runtime = afl->prev_run_time + get_cur_time() - afl->start_time; - // we keep the shorter file if (p->len >= q->len) { @@ -1206,9 +1178,6 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; - p->first_fuzz = runtime; - mark_as_fuzzed(afl, p); - } p->disabled = 1; @@ -1222,9 +1191,6 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; - q->first_fuzz = runtime; - mark_as_fuzzed(afl, q); - } q->disabled = 1; @@ -1393,10 +1359,6 @@ void pivot_inputs(afl_state_t *afl) { if (q->passed_det) { mark_as_det_done(afl, q); } - /* ...and the time of first fuzzing. */ - - if (q->was_fuzzed) { mark_as_fuzzed(afl, q); } - if (afl->custom_mutators_count) { run_afl_custom_queue_new_entry(afl, q, q->fname, NULL); @@ -1594,10 +1556,6 @@ void nuke_resume_dir(afl_state_t *afl) { if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); - fn = alloc_printf("%s/_resume/.state/was_fuzzed", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } - ck_free(fn); - fn = alloc_printf("%s/_resume/.state/auto_extras", afl->out_dir); if (delete_files(fn, "auto_")) { goto dir_cleanup_failed; } ck_free(fn); @@ -1758,10 +1716,6 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); - fn = alloc_printf("%s/queue/.state/was_fuzzed", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } - ck_free(fn); - fn = alloc_printf("%s/queue/.state/auto_extras", afl->out_dir); if (delete_files(fn, "auto_")) { goto dir_cleanup_failed; } ck_free(fn); @@ -2053,12 +2007,6 @@ void setup_dirs_fds(afl_state_t *afl) { if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); - /* Directory for flagging queue entries that have been fuzzed */ - - tmp = alloc_printf("%s/queue/.state/was_fuzzed/", afl->out_dir); - if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } - ck_free(tmp); - /* Directory with the auto-selected dictionary entries. */ tmp = alloc_printf("%s/queue/.state/auto_extras/", afl->out_dir); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 53f6e447977399ce1c652c9dcc2e0140880b4fac..ee562f960ac2cc74202c5de96b03d1f00b0377d6 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -3091,10 +3091,6 @@ abandon_entry: afl->reinit_table = 1; if (afl->queue_cur->favored) { --afl->pending_favored; } - afl->queue_cur->first_fuzz = - afl->prev_run_time + get_cur_time() - afl->start_time; - mark_as_fuzzed(afl, afl->queue_cur); - } ++afl->queue_cur->fuzz_level; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index e5282517efdf491e015d282878a2a8f9e7a73af5..8ad7cd976260eb9c0197b07e8b8c6c325967f47f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -292,23 +292,6 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { } -void mark_as_fuzzed(afl_state_t *afl, struct queue_entry *q) { - - char fn[PATH_MAX]; - s32 fd; - - snprintf(fn, PATH_MAX, "%s/queue/.state/was_fuzzed/%s", afl->out_dir, - strrchr((char *)q->fname, '/') + 1); - - fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (fd < 0) { PFATAL("Unable to create '%s'", fn); } - - ck_write(fd, &q->first_fuzz, sizeof(u64), fn); - - close(fd); - -} - /* Mark as variable. Create symlinks if possible to make it easier to examine the files. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 99519757355cba196b24a42f46ef075675a0d1c8..04222817174710807a68fdbc53f92657656d3b5c 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -648,7 +648,6 @@ void sync_fuzzers(afl_state_t *afl) { struct dirent *sd_ent; u32 sync_cnt = 0, synced = 0, entries = 0; u8 path[PATH_MAX + 1 + NAME_MAX]; - u8 wf_path[PATH_MAX + 1 + NAME_MAX]; sd = opendir(afl->sync_dir); if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); } @@ -704,7 +703,6 @@ void sync_fuzzers(afl_state_t *afl) { /* document the attempt to sync to this instance */ sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name); - id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, DEFAULT_PERMISSION); if (id_fd >= 0) close(id_fd); @@ -748,12 +746,6 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_cur = 0; afl->stage_max = 0; - if(afl->afl_env.afl_delay_sync && !afl->last_sync_time) { - - goto close_sync; - - } - /* For every file queued by this fuzzer, parse ID and see if we have looked at it before; exec a test case if not. */ @@ -777,37 +769,46 @@ void sync_fuzzers(afl_state_t *afl) { if (m >= n) { goto close_sync; } // nothing new u8 retry_remaining = 0; - + for (o = m; o < n; o++) { - s32 fd, wf_fd; + s32 fd; struct stat st; - u64 ftime; u8 skip; snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name); - /* Skip syncing of recent discoveries if AFL_DELAY_SYNC is set. */ + /* Skip syncing of recent discoveries if AFL_SYNC_DELAY is set. */ skip = 0; - if (afl->afl_env.afl_delay_sync) { + if (afl->sync_delay) { + + u8 *timep = NULL; + u8 *timep_tmp = namelist[o]->d_name; + u64 discovery_time = 0; + + /* Parse time field in file name. Scan in reverse order to capture + original discovery time in case of a resumed session. */ + + while ( (timep_tmp = strstr(timep_tmp, "time:")) ) { - u64 cycle_time = get_cur_time() - afl->last_sync_time; + timep_tmp += 5; + timep = timep_tmp; - u64 runtime = afl->prev_run_time + get_cur_time() - afl->start_time; + } + + if (timep) { + + sscanf(timep, "%llu", &discovery_time); - snprintf(wf_path, sizeof(wf_path), "%s/.state/was_fuzzed/%s", - qd_path, namelist[o]->d_name); + } - wf_fd = open(wf_path, O_RDONLY); + if (afl->prev_run_time + get_cur_time() - afl->start_time < + afl->sync_delay + discovery_time) { - if (wf_fd < 0 || - read(wf_fd, &ftime, sizeof(u64)) != sizeof(u64) || - ftime + SYNC_DELAY_CYCLES * cycle_time > runtime) { - skip = 1; - + /* All entries beyond this one would need to be retried at the next sync. (Pretty wasteful, would be better to document each synced test case individually, e.g. in the .synced dir.) */ @@ -816,8 +817,7 @@ void sync_fuzzers(afl_state_t *afl) { ck_write(id_fd, &next_min_accept, sizeof(u32), qd_synced_path); } - close(wf_fd); - + } afl->syncing_case = next_min_accept; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index b6bb0fdfb100e9373c46d05c3d7ef3630d73f5cf..60206b4a7e66b385bb7654a56c1fc78fe974b63b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -567,12 +567,22 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } - } else if (!strncmp(env, "AFL_DELAY_SYNC", + } else if (!strncmp(env, "AFL_SYNC_DELAY", afl_environment_variable_len)) { - afl->afl_env.afl_delay_sync = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; + int delay = atoi((u8 *)get_afl_env(afl_environment_variables[i])); + if (delay > 0) { + + afl->sync_delay = delay * (60 * 1000LL); + + } else { + + WARNF( + "incorrect value for AFL_SYNC_DELAY environment variable, " + "used default value 0 instead."); + + } } else if (!strncmp(env, "AFL_FUZZER_STATS_UPDATE_INTERVAL", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9866642b1975d8b3d5b922877de3a8df6a9176f1..b93b04efc83442538e4ad2bd483a0f75e0f33d00 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1339,6 +1339,13 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->sync_delay) { + + OKF("AFL_SYNC_DELAY set. Delaying sync by %llu minutes.", + afl->sync_delay / (60 * 1000LL)); + + } + #ifdef __linux__ if (afl->fsrv.nyx_mode) { @@ -2578,8 +2585,7 @@ int main(int argc, char **argv_orig, char **envp) { } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon); - if (likely(!afl->stop_soon && afl->sync_id && - !afl->afl_env.afl_delay_sync)) { + if (likely(!afl->stop_soon && afl->sync_id)) { if (likely(afl->skip_deterministic)) {