aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-cc.c4
-rw-r--r--src/afl-forkserver.c5
-rw-r--r--src/afl-fuzz-bitmap.c2
-rw-r--r--src/afl-fuzz-cmplog.c2
-rw-r--r--src/afl-fuzz-init.c10
-rw-r--r--src/afl-fuzz-mutators.c54
-rw-r--r--src/afl-fuzz-one.c4
-rw-r--r--src/afl-fuzz-run.c10
-rw-r--r--src/afl-fuzz-state.c8
-rw-r--r--src/afl-fuzz-stats.c16
-rw-r--r--src/afl-fuzz.c38
-rw-r--r--src/afl-ld-lto.c11
12 files changed, 118 insertions, 46 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 1f89bac5..09009334 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -560,12 +560,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (lto_mode && !have_c) {
u8 *ld_path = strdup(AFL_REAL_LD);
- if (!*ld_path) ld_path = "ld.lld";
+ if (!ld_path || !*ld_path) { ld_path = strdup("ld.lld"); }
+ if (!ld_path) { PFATAL("Could not allocate mem for ld_path"); }
#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12
cc_params[cc_par_cnt++] = alloc_printf("--ld-path=%s", ld_path);
#else
cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", ld_path);
#endif
+ free(ld_path);
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 727e7f8d..a07e78b4 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -416,7 +416,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
struct rlimit r;
- if (!fsrv->cmplog_binary && fsrv->qemu_mode == false) {
+ if (!fsrv->cmplog_binary && fsrv->qemu_mode == false &&
+ fsrv->frida_mode == false) {
unsetenv(CMPLOG_SHM_ENV_VAR); // we do not want that in non-cmplog fsrv
@@ -1089,7 +1090,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
#endif
- if (likely(fsrv->use_shmem_fuzz && fsrv->shmem_fuzz)) {
+ if (likely(fsrv->use_shmem_fuzz)) {
if (unlikely(len > MAX_FILE)) len = MAX_FILE;
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 3d0228db..97f10e6f 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -397,7 +397,7 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) {
/* Write a message accompanying the crash directory :-) */
-static void write_crash_readme(afl_state_t *afl) {
+void write_crash_readme(afl_state_t *afl) {
u8 fn[PATH_MAX];
s32 fd;
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 27c6c413..c2e9c80f 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -35,7 +35,7 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); }
- if (!fsrv->qemu_mode && argv[0] != fsrv->cmplog_binary) {
+ if (!fsrv->qemu_mode && !fsrv->frida_mode && argv[0] != fsrv->cmplog_binary) {
argv[0] = fsrv->cmplog_binary;
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index b6bfbc29..cb586111 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -2031,7 +2031,7 @@ void setup_dirs_fds(afl_state_t *afl) {
fprintf(
afl->fsrv.plot_file,
- "# unix_time, cycles_done, cur_path, paths_total, "
+ "# relative_time, cycles_done, cur_path, paths_total, "
"pending_total, pending_favs, map_size, unique_crashes, "
"unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n");
@@ -2774,6 +2774,14 @@ void check_binary(afl_state_t *afl, u8 *fname) {
WARNF("AFL_PERSISTENT is no longer supported and may misbehave!");
+ } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) {
+
+ OKF("FRIDA Persistent mode configuration options detected.");
+ setenv(PERSIST_ENV_VAR, "1", 1);
+ afl->persistent_mode = 1;
+
+ afl->shmem_testcase_mode = 1;
+
}
if (afl->fsrv.frida_mode ||
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index c99d9a4d..e27d6fae 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -308,9 +308,11 @@ struct custom_mutator *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,
struct custom_mutator *mutator) {
- u8 needs_write = 0, fault = 0;
+ u8 fault = 0;
u32 trim_exec = 0;
u32 orig_len = q->len;
+ u32 out_len = 0;
+ u8 *out_buf = NULL;
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
@@ -397,33 +399,33 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
if (likely(retlen && cksum == q->exec_cksum)) {
- if (afl_realloc((void **)&in_buf, retlen) == NULL) {
-
- FATAL("can not allocate memory for trim");
-
- }
-
- memcpy(in_buf, retbuf, retlen);
- q->len = retlen;
-
/* Let's save a clean trace, which will be needed by
- update_bitmap_score once we're done with the trimming stuff. */
+ update_bitmap_score once we're done with the trimming stuff.
+ Use out_buf NULL check to make this only happen once per trim. */
- if (!needs_write) {
+ if (!out_buf) {
- needs_write = 1;
memcpy(afl->clean_trace_custom, afl->fsrv.trace_bits,
afl->fsrv.map_size);
}
+ if (afl_realloc((void **)&out_buf, retlen) == NULL) {
+
+ FATAL("can not allocate memory for trim");
+
+ }
+
+ out_len = retlen;
+ memcpy(out_buf, retbuf, retlen);
+
/* Tell the custom mutator that the trimming was successful */
afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 1);
if (afl->not_on_tty && afl->debug) {
SAYF("[Custom Trimming] SUCCESS: %u/%u iterations (now at %u bytes)",
- afl->stage_cur, afl->stage_max, q->len);
+ afl->stage_cur, afl->stage_max, out_len);
}
@@ -456,16 +458,10 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
}
- if (afl->not_on_tty && afl->debug) {
-
- SAYF("[Custom Trimming] DONE: %u bytes -> %u bytes", orig_len, q->len);
-
- }
-
- /* If we have made changes to in_buf, we also need to update the on-disk
+ /* If we have made changes, we also need to update the on-disk
version of the test case. */
- if (needs_write) {
+ if (out_buf) {
s32 fd;
@@ -475,16 +471,28 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
- ck_write(fd, in_buf, q->len, q->fname);
+ ck_write(fd, out_buf, out_len, q->fname);
close(fd);
+ /* Update the queue's knowledge of length as soon as we write the file.
+ We do this here so that exit/error cases that *don't* update the file
+ also don't update q->len. */
+ q->len = out_len;
+
memcpy(afl->fsrv.trace_bits, afl->clean_trace_custom, afl->fsrv.map_size);
update_bitmap_score(afl, q);
}
+ if (afl->not_on_tty && afl->debug) {
+
+ SAYF("[Custom Trimming] DONE: %u bytes -> %u bytes", orig_len, q->len);
+
+ }
+
abort_trimming:
+ if (out_buf) afl_free(out_buf);
afl->bytes_trim_out += q->len;
return fault;
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index d72d4145..4eeb93de 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -3010,13 +3010,13 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
u8 res = trim_case(afl, afl->queue_cur, in_buf);
orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur);
- if (res == FSRV_RUN_ERROR) {
+ if (unlikely(res == FSRV_RUN_ERROR)) {
FATAL("Unable to execute target application");
}
- if (afl->stop_soon) {
+ if (unlikely(afl->stop_soon)) {
++afl->cur_skipped_paths;
goto abandon_entry;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 832f17bb..6e5210b8 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -203,7 +203,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
}
- if (afl->fsrv.shmem_fuzz) {
+ if (likely(afl->fsrv.use_shmem_fuzz)) {
if (!post_process_skipped) {
@@ -211,9 +211,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
memcpy(afl->fsrv.shmem_fuzz, new_mem, new_size);
- }
-
- else {
+ } else {
memcpy(afl->fsrv.shmem_fuzz, mem, skip_at);
@@ -244,7 +242,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
return;
- } else if (afl->fsrv.out_file) {
+ } else if (unlikely(!afl->fsrv.use_stdin)) {
if (unlikely(afl->no_unlink)) {
@@ -279,7 +277,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
}
- if (!afl->fsrv.out_file) {
+ if (afl->fsrv.use_stdin) {
if (ftruncate(fd, new_size)) { PFATAL("ftruncate() failed"); }
lseek(fd, 0, SEEK_SET);
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 28d3339a..c886cb28 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -99,6 +99,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->cal_cycles = CAL_CYCLES;
afl->cal_cycles_long = CAL_CYCLES_LONG;
afl->hang_tmout = EXEC_TIMEOUT;
+ afl->exit_on_time = 0;
afl->stats_update_freq = 1;
afl->stats_avg_exec = 0;
afl->skip_deterministic = 1;
@@ -187,6 +188,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_exit_when_done =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+ } else if (!strncmp(env, "AFL_EXIT_ON_TIME",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_exit_on_time =
+ (u8 *)get_afl_env(afl_environment_variables[i]);
+
} else if (!strncmp(env, "AFL_NO_AFFINITY",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 22c0cbd2..313263f9 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -179,6 +179,8 @@ void load_stats_file(afl_state_t *afl) {
}
+ if (afl->unique_crashes) { write_crash_readme(afl); }
+
return;
}
@@ -384,7 +386,7 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
/* Fields in the file:
- unix_time, afl->cycles_done, cur_path, paths_total, paths_not_fuzzed,
+ relative_time, afl->cycles_done, cur_path, paths_total, paths_not_fuzzed,
favored_not_fuzzed, unique_crashes, unique_hangs, max_depth,
execs_per_sec, edges_found */
@@ -544,7 +546,7 @@ void show_stats(afl_state_t *afl) {
if (unlikely(afl->afl_env.afl_statsd)) {
- if (unlikely(afl->force_ui_update && cur_ms - afl->statsd_last_send_ms >
+ if (unlikely(afl->force_ui_update || cur_ms - afl->statsd_last_send_ms >
STATSD_UPDATE_SEC * 1000)) {
/* reset counter, even if send failed. */
@@ -574,6 +576,16 @@ void show_stats(afl_state_t *afl) {
}
+ /* AFL_EXIT_ON_TIME. */
+
+ if (unlikely(afl->last_path_time && !afl->non_instrumented_mode &&
+ afl->afl_env.afl_exit_on_time &&
+ (cur_ms - afl->last_path_time) > afl->exit_on_time)) {
+
+ afl->stop_soon = 2;
+
+ }
+
if (unlikely(afl->total_crashes && afl->afl_env.afl_bench_until_crash)) {
afl->stop_soon = 2;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 3606533d..8de3ed6b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -204,6 +204,7 @@ static void usage(u8 *argv0, int more_help) {
"AFL_DISABLE_TRIM: disable the trimming of test cases\n"
"AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
"AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
+ "AFL_EXIT_ON_TIME: exit when no new paths are found within the specified time period\n"
"AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n"
"AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
"AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
@@ -1246,6 +1247,13 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ if (afl->afl_env.afl_exit_on_time) {
+
+ u64 exit_on_time = atoi(afl->afl_env.afl_exit_on_time);
+ afl->exit_on_time = (u64)exit_on_time * 1000;
+
+ }
+
if (afl->afl_env.afl_max_det_extras) {
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
@@ -1358,6 +1366,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl_preload = getenv("AFL_PRELOAD");
u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
+ OKF("Injecting %s ...", frida_binary);
if (afl_preload) {
frida_afl_preload = alloc_printf("%s:%s", afl_preload, frida_binary);
@@ -1383,6 +1392,7 @@ int main(int argc, char **argv_orig, char **envp) {
} else if (afl->fsrv.frida_mode) {
u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
+ OKF("Injecting %s ...", frida_binary);
setenv("LD_PRELOAD", frida_binary, 1);
setenv("DYLD_INSERT_LIBRARIES", frida_binary, 1);
ck_free(frida_binary);
@@ -1697,13 +1707,14 @@ int main(int argc, char **argv_orig, char **envp) {
// TODO: this is semi-nice
afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
+ afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
if ((map_size <= DEFAULT_SHMEM_SIZE ||
afl->cmplog_fsrv.map_size < map_size) &&
!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
- !afl->unicorn_mode) {
+ !afl->fsrv.frida_mode && !afl->unicorn_mode) {
afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
char vbuf[16];
@@ -2209,6 +2220,31 @@ stop_fuzzing:
}
afl_fsrv_deinit(&afl->fsrv);
+
+ /* remove tmpfile */
+ if (afl->tmp_dir != NULL && !afl->in_place_resume) {
+
+ char tmpfile[PATH_MAX];
+
+ if (afl->file_extension) {
+
+ snprintf(tmpfile, PATH_MAX, "%s/.cur_input.%s", afl->tmp_dir,
+ afl->file_extension);
+
+ } else {
+
+ snprintf(tmpfile, PATH_MAX, "%s/.cur_input", afl->tmp_dir);
+
+ }
+
+ if (unlink(tmpfile) != 0) {
+
+ FATAL("Could not unlink current input file: %s.", tmpfile);
+
+ }
+
+ }
+
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
ck_free(afl->fsrv.target_path);
ck_free(afl->fsrv.out_file);
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index d0113af9..1ce97649 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -298,13 +298,12 @@ int main(int argc, char **argv) {
SAYF(
"\n"
- "This is a helper application for afl-clang-lto. It is a wrapper "
- "around GNU "
- "llvm's 'lld',\n"
- "executed by the toolchain whenever using "
- "afl-clang-lto/afl-clang-lto++.\n"
+ "This is a helper application for afl-clang-lto.\n"
+ "It is a wrapper around llvm's 'lld' in case afl-clang-lto cannot be "
+ "used.\n"
+ "Note that the target still has to be compiled with -flto=full!\n"
"You probably don't want to run this program directly but rather pass "
- "it as LD parameter to configure scripts\n\n"
+ "it as LD\nparameter to e.g. configure scripts.\n\n"
"Environment variables:\n"
" AFL_LD_PASSTHROUGH do not link+optimize == no instrumentation\n"