diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index f7d564b6cb3b9378a7349d01a04a10d7f76d6bac..f48754b659c7ca79f25807526a09319d23912c27 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -184,7 +184,8 @@ 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 */ + stats_mutated, /* stats: # of mutations performed */ + first_fuzz; /* Time of first fuzzing */ u8 *trace_mini; /* Trace bytes, if kept */ u32 tc_ref; /* Trace bytes ref count */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index d600fff2cb069b3adc70f57c9b62cb4978839eb5..d435042029c548b9af7deab66cb0766982210e7b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -902,6 +902,8 @@ 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: @@ -928,6 +930,7 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; + q->first_fuzz = runtime; mark_as_fuzzed(afl, q); } @@ -1061,6 +1064,7 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; + q->first_fuzz = runtime; mark_as_fuzzed(afl, q); } @@ -1182,6 +1186,7 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; + p->first_fuzz = runtime; mark_as_fuzzed(afl, p); } @@ -1197,6 +1202,7 @@ void perform_dry_run(afl_state_t *afl) { --afl->pending_not_fuzzed; --afl->active_items; + q->first_fuzz = runtime; mark_as_fuzzed(afl, q); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9496a0520a24e94272d7f4f4da2c4056ca8bc7be..53f6e447977399ce1c652c9dcc2e0140880b4fac 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -3091,6 +3091,8 @@ 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); } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b57fe0e9d245215bef3d403c1a9c3f65e9e595af..e5282517efdf491e015d282878a2a8f9e7a73af5 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -302,6 +302,9 @@ void mark_as_fuzzed(afl_state_t *afl, struct queue_entry *q) { 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); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index eef580a5dbe4393c64868e449736b489ef2713a5..7dc669b54e696d12b247acb6245f8506814fc00f 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -780,9 +780,9 @@ void sync_fuzzers(afl_state_t *afl) { for (o = m; o < n; o++) { - s32 fd; + s32 fd, wf_fd; struct stat st; - struct stat wf_st; + u64 ftime; u8 skip; snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name); @@ -793,16 +793,20 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->afl_env.afl_delay_sync) { - u64 cycle_time = (get_cur_time() - - (!afl->last_sync_time ? afl->start_time : afl->last_sync_time)) / 1000; + u64 cycle_time = get_cur_time() - + (!afl->last_sync_time ? afl->start_time : afl->last_sync_time); + + u64 runtime = afl->prev_run_time + get_cur_time() - afl->start_time; snprintf(wf_path, sizeof(wf_path), "%s/.state/was_fuzzed/%s", qd_path, namelist[o]->d_name); - if (lstat(wf_path, &wf_st) || - ((u64)wf_st.st_mtime > - get_cur_time() / 1000 - SYNC_DELAY_CYCLES * cycle_time)) { - + wf_fd = open(wf_path, O_RDONLY); + + if (wf_fd < 0 || + read(wf_fd, &ftime, sizeof(u64)) != sizeof(u64) || + ftime > runtime - SYNC_DELAY_CYCLES * cycle_time) { + skip = 1; /* All entries beyond this one would need to be retried at the next @@ -813,6 +817,8 @@ 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;