aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-31 19:04:37 +0200
committerGitHub <noreply@github.com>2020-08-31 19:04:37 +0200
commit2dffed1cffcd78db16412d0531d2976bfd3bc0fe (patch)
treedd41be1ffcc9e471591d7c7bd899baf1987aeb97 /src
parent42ef1968a530d5fe598d53e93431dfcff3727b4b (diff)
parente93f78eca53e3b1542d109fd9b4c634831e9fd63 (diff)
downloadafl++-2dffed1cffcd78db16412d0531d2976bfd3bc0fe.tar.gz
Merge pull request #534 from AFLplusplus/dev
push to stable for GSOC
Diffstat (limited to 'src')
-rw-r--r--src/afl-as.c2
-rw-r--r--src/afl-forkserver.c16
-rw-r--r--src/afl-fuzz-extras.c20
-rw-r--r--src/afl-fuzz-init.c22
-rw-r--r--src/afl-fuzz-mutators.c5
-rw-r--r--src/afl-fuzz-one.c149
-rw-r--r--src/afl-fuzz-python.c59
-rw-r--r--src/afl-fuzz-state.c14
-rw-r--r--src/afl-fuzz.c38
-rw-r--r--src/afl-gcc.c2
-rw-r--r--src/afl-performance.c12
-rw-r--r--src/afl-showmap.c15
-rw-r--r--src/afl-tmin.c14
13 files changed, 255 insertions, 113 deletions
diff --git a/src/afl-as.c b/src/afl-as.c
index 0ed47d8c..7d70bfcd 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -152,7 +152,7 @@ static void edit_params(int argc, char **argv) {
/* The Apple case is a bit different... */
- if (!strcmp(argv[i], "-arch") && i + 1 < argc) {
+ if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) {
if (!strcmp(argv[i + 1], "x86_64"))
use_64bit = 1;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 8277116b..93203cb2 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -79,6 +79,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->use_stdin = 1;
fsrv->no_unlink = 0;
fsrv->exec_tmout = EXEC_TIMEOUT;
+ fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
fsrv->mem_limit = MEM_LIMIT;
fsrv->out_file = NULL;
@@ -101,6 +102,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->out_fd = from->out_fd;
fsrv_to->dev_null_fd = from->dev_null_fd;
fsrv_to->exec_tmout = from->exec_tmout;
+ fsrv_to->init_tmout = from->init_tmout;
fsrv_to->mem_limit = from->mem_limit;
fsrv_to->map_size = from->map_size;
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
@@ -115,6 +117,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->out_file = NULL;
fsrv_to->init_child_func = fsrv_exec_child;
+ // Note: do not copy ->add_extra_func
list_append(&fsrv_list, fsrv_to);
@@ -516,15 +519,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
rlen = 0;
if (fsrv->exec_tmout) {
- u32 time_ms =
- read_s32_timed(fsrv->fsrv_st_fd, &status,
- fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
+ u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, fsrv->init_tmout,
+ stop_soon_p);
if (!time_ms) {
kill(fsrv->fsrv_pid, SIGKILL);
- } else if (time_ms > fsrv->exec_tmout * FORK_WAIT_MULT) {
+ } else if (time_ms > fsrv->init_tmout) {
fsrv->last_run_timed_out = 1;
kill(fsrv->fsrv_pid, SIGKILL);
@@ -632,7 +634,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) {
- // this is not afl-fuzz - we deny and return
+ // this is not afl-fuzz - or it is cmplog - we deny and return
if (fsrv->use_shmem_fuzz) {
status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
@@ -939,7 +941,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
s32 fd = fsrv->out_fd;
- if (fsrv->out_file) {
+ if (!fsrv->use_stdin) {
if (fsrv->no_unlink) {
@@ -962,7 +964,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
ck_write(fd, buf, len, fsrv->out_file);
- if (!fsrv->out_file) {
+ if (fsrv->use_stdin) {
if (ftruncate(fd, len)) { PFATAL("ftruncate() failed"); }
lseek(fd, 0, SEEK_SET);
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 1452c55e..d6c368d1 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -248,10 +248,10 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
}
- if (afl->extras_cnt > MAX_DET_EXTRAS) {
+ if (afl->extras_cnt > afl->max_det_extras) {
- WARNF("More than %d tokens - will use them probabilistically.",
- MAX_DET_EXTRAS);
+ OKF("More than %d tokens - will use them probabilistically.",
+ afl->max_det_extras);
}
@@ -319,8 +319,8 @@ void load_extras(afl_state_t *afl, u8 *dir) {
if (st.st_size > MAX_DICT_FILE) {
- FATAL(
- "Extra '%s' is too big (%s, limit is %s)", fn,
+ WARNF(
+ "Extra '%s' is very big (%s, limit is %s)", fn,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
@@ -370,14 +370,14 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
}
-/* Adds a new extra / dict entry. */
+/* Adds a new extra / dict entry. Used for LTO autodict. */
void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
if (len > MAX_DICT_FILE) {
- FATAL("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem,
+ WARNF("Extra '%.*s' is very big (%s, limit is %s)", (int)len, mem,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
@@ -403,10 +403,10 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
/* We only want to print this once */
- if (afl->extras_cnt == MAX_DET_EXTRAS + 1) {
+ if (afl->extras_cnt == afl->max_det_extras + 1) {
- WARNF("More than %d tokens - will use them probabilistically.",
- MAX_DET_EXTRAS);
+ OKF("More than %d tokens - will use them probabilistically.",
+ afl->max_det_extras);
}
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 350a8599..102f04b9 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -256,18 +256,18 @@ void bind_to_free_cpu(afl_state_t *afl) {
}
- for (i = 0; i < proccount; i++) {
+ for (i = 0; i < (s32)proccount; i++) {
#if defined(__FreeBSD__)
if (!strcmp(procs[i].ki_comm, "idle")) continue;
// fix when ki_oncpu = -1
- int oncpu;
+ s32 oncpu;
oncpu = procs[i].ki_oncpu;
if (oncpu == -1) oncpu = procs[i].ki_lastcpu;
- if (oncpu != -1 && oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 60)
+ if (oncpu != -1 && oncpu < (s32)sizeof(cpu_used) && procs[i].ki_pctcpu > 60)
cpu_used[oncpu] = 1;
#elif defined(__DragonFly__)
@@ -1841,24 +1841,26 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
void setup_stdio_file(afl_state_t *afl) {
- u8 *fn;
if (afl->file_extension) {
- fn = 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 {
- fn = alloc_printf("%s/.cur_input", afl->tmp_dir);
+ afl->fsrv.out_file = alloc_printf("%s/.cur_input", afl->tmp_dir);
}
- unlink(fn); /* Ignore errors */
+ unlink(afl->fsrv.out_file); /* Ignore errors */
- afl->fsrv.out_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0600);
+ afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fn); }
+ if (afl->fsrv.out_fd < 0) {
- ck_free(fn);
+ PFATAL("Unable to create '%s'", afl->fsrv.out_file);
+
+ }
}
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 22578df9..d24b7db9 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -166,6 +166,11 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
}
+ /* "afl_custom_fuzz_count", optional */
+ mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count");
+ if (!mutator->afl_custom_fuzz_count)
+ ACTF("optional symbol 'afl_custom_fuzz_count' not found.");
+
/* "afl_custom_deinit", optional for backward compatibility */
mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
if (!mutator->afl_custom_deinit)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 3bf0c195..bf568c38 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1509,13 +1509,13 @@ skip_interest:
for (j = 0; j < afl->extras_cnt; ++j) {
- /* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also
- skip them if there's no room to insert the payload, if the token
+ /* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS.
+ Also skip them if there's no room to insert the payload, if the token
is redundant, or if its entire span has no bytes set in the effector
map. */
- if ((afl->extras_cnt > MAX_DET_EXTRAS &&
- rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
+ if ((afl->extras_cnt > afl->max_det_extras &&
+ rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) ||
afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1,
@@ -1672,7 +1672,7 @@ custom_mutator_stage:
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
- const u32 max_seed_size = MAX_FILE;
+ const u32 max_seed_size = MAX_FILE, saved_max = afl->stage_max;
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
@@ -1680,104 +1680,123 @@ custom_mutator_stage:
if (el->afl_custom_fuzz) {
+ if (el->afl_custom_fuzz_count)
+ afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len);
+ else
+ afl->stage_max = saved_max;
+
has_custom_fuzz = true;
afl->stage_short = el->name_short;
- for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
- ++afl->stage_cur) {
+ if (afl->stage_max) {
- struct queue_entry *target;
- u32 tid;
- u8 * new_buf;
+ for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
+ ++afl->stage_cur) {
- retry_external_pick:
- /* Pick a random other queue entry for passing to external API */
+ struct queue_entry *target;
+ u32 tid;
+ u8 * new_buf;
- do {
+ retry_external_pick:
+ /* Pick a random other queue entry for passing to external API */
- tid = rand_below(afl, afl->queued_paths);
+ do {
- } while (tid == afl->current_entry && afl->queued_paths > 1);
+ tid = rand_below(afl, afl->queued_paths);
- target = afl->queue;
+ } while (tid == afl->current_entry && afl->queued_paths > 1);
- while (tid >= 100) {
+ target = afl->queue;
- target = target->next_100;
- tid -= 100;
+ while (tid >= 100) {
- }
+ target = target->next_100;
+ tid -= 100;
- while (tid--) {
-
- target = target->next;
+ }
- }
+ while (tid--) {
- /* Make sure that the target has a reasonable length. */
+ target = target->next;
- while (target && (target->len < 2 || target == afl->queue_cur) &&
- afl->queued_paths > 3) {
+ }
- target = target->next;
- ++afl->splicing_with;
+ /* Make sure that the target has a reasonable length. */
- }
+ while (target && (target->len < 2 || target == afl->queue_cur) &&
+ afl->queued_paths > 3) {
- if (!target) { goto retry_external_pick; }
+ target = target->next;
+ ++afl->splicing_with;
- /* Read the additional testcase into a new buffer. */
- fd = open(target->fname, O_RDONLY);
- if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); }
+ }
- new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len);
- if (unlikely(!new_buf)) { PFATAL("alloc"); }
- ck_read(fd, new_buf, target->len, target->fname);
- close(fd);
+ if (!target) { goto retry_external_pick; }
- u8 *mutated_buf = NULL;
+ /* Read the additional testcase into a new buffer. */
+ fd = open(target->fname, O_RDONLY);
+ if (unlikely(fd < 0)) {
- size_t mutated_size =
- el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
- target->len, max_seed_size);
+ PFATAL("Unable to open '%s'", target->fname);
- if (unlikely(!mutated_buf)) {
+ }
- FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
+ new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len);
+ if (unlikely(!new_buf)) { PFATAL("alloc"); }
+ ck_read(fd, new_buf, target->len, target->fname);
+ close(fd);
- }
+ u8 *mutated_buf = NULL;
- if (mutated_size > 0) {
+ size_t mutated_size =
+ el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
+ target->len, max_seed_size);
- if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
+ if (unlikely(!mutated_buf)) {
- goto abandon_entry;
+ FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
}
- /* If we're finding new stuff, let's run for a bit longer, limits
- permitting. */
+ if (mutated_size > 0) {
- if (afl->queued_paths != havoc_queued) {
+ if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
- if (perf_score <= afl->havoc_max_mult * 100) {
-
- afl->stage_max *= 2;
- perf_score *= 2;
+ goto abandon_entry;
}
- havoc_queued = afl->queued_paths;
+ if (!el->afl_custom_fuzz_count) {
+
+ /* If we're finding new stuff, let's run for a bit longer, limits
+ permitting. */
+
+ if (afl->queued_paths != havoc_queued) {
+
+ if (perf_score <= afl->havoc_max_mult * 100) {
+
+ afl->stage_max *= 2;
+ perf_score *= 2;
+
+ }
+
+ havoc_queued = afl->queued_paths;
+
+ }
+
+ }
}
- }
+ /* `(afl->)out_buf` may have been changed by the call to custom_fuzz
+ */
+ /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs
+ * Memcpy.
+ */
+ memcpy(out_buf, in_buf, len);
- /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */
- /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy.
- */
- memcpy(out_buf, in_buf, len);
+ }
}
@@ -3722,13 +3741,13 @@ skip_interest:
for (j = 0; j < afl->extras_cnt; ++j) {
- /* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also
- skip them if there's no room to insert the payload, if the token
+ /* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS.
+ Also skip them if there's no room to insert the payload, if the token
is redundant, or if its entire span has no bytes set in the effector
map. */
- if ((afl->extras_cnt > MAX_DET_EXTRAS &&
- rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
+ if ((afl->extras_cnt > afl->max_det_extras &&
+ rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) ||
afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1,
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index e540f548..adb92649 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -144,6 +144,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
if (!py_functions[PY_FUNC_FUZZ])
py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate");
+ py_functions[PY_FUNC_FUZZ_COUNT] =
+ PyObject_GetAttrString(py_module, "fuzz_count");
if (!py_functions[PY_FUNC_FUZZ])
WARNF("fuzz function not found in python module");
py_functions[PY_FUNC_POST_PROCESS] =
@@ -169,27 +171,20 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) {
- if (py_idx == PY_FUNC_POST_PROCESS) {
-
- // Implenting the post_process API is optional for now
- if (PyErr_Occurred()) { PyErr_Print(); }
-
- } else if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
+ if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
// Implementing the trim API is optional for now
if (PyErr_Occurred()) { PyErr_Print(); }
py_notrim = 1;
- } else if ((py_idx >= PY_FUNC_HAVOC_MUTATION) &&
+ } else if (py_idx >= PY_OPTIONAL) {
- (py_idx <= PY_FUNC_QUEUE_NEW_ENTRY)) {
+ // Only _init and _deinit are not optional currently
- // Implenting the havoc and queue API is optional for now
if (PyErr_Occurred()) { PyErr_Print(); }
} else {
- if (PyErr_Occurred()) { PyErr_Print(); }
fprintf(stderr,
"Cannot find/call function with index %d in external "
"Python module.\n",
@@ -347,6 +342,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
}
+ if (py_functions[PY_FUNC_FUZZ_COUNT]) {
+
+ mutator->afl_custom_fuzz_count = fuzz_count_py;
+
+ }
+
if (py_functions[PY_FUNC_POST_TRIM]) {
mutator->afl_custom_post_trim = post_trim_py;
@@ -477,6 +478,44 @@ s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
}
+u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) {
+
+ PyObject *py_args, *py_value;
+
+ py_args = PyTuple_New(1);
+ py_value = PyByteArray_FromStringAndSize(buf, buf_size);
+ if (!py_value) {
+
+ Py_DECREF(py_args);
+ FATAL("Failed to convert arguments");
+
+ }
+
+ PyTuple_SetItem(py_args, 0, py_value);
+
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args);
+ Py_DECREF(py_args);
+
+ if (py_value != NULL) {
+
+ #if PY_MAJOR_VERSION >= 3
+ u32 retcnt = (u32)PyLong_AsLong(py_value);
+ #else
+ u32 retcnt = PyInt_AsLong(py_value);
+ #endif
+ Py_DECREF(py_value);
+ return retcnt;
+
+ } else {
+
+ PyErr_Print();
+ FATAL("Call failed");
+
+ }
+
+}
+
s32 post_trim_py(void *py_mutator, u8 success) {
PyObject *py_args, *py_value;
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index dd0e316c..577fc34f 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -349,6 +349,20 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_preload =
(u8 *)get_afl_env(afl_environment_variables[i]);
+ } else if (!strncmp(env, "AFL_MAX_DET_EXTRAS",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_max_det_extras =
+ (u8 *)get_afl_env(afl_environment_variables[i]);
+
+ } else if (!strncmp(env, "AFL_FORKSRV_INIT_TMOUT",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_forksrv_init_tmout =
+ (u8 *)get_afl_env(afl_environment_variables[i]);
+
}
} else {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 5dd092f2..0df6c15c 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -173,10 +173,14 @@ static void usage(u8 *argv0, int more_help) {
"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"
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
+ "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
" the target was compiled for\n"
+ "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
+ " then they are randomly selected instead all of them being\n"
+ " used. Defaults to 200.\n"
"AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
"AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
"AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
@@ -188,7 +192,7 @@ static void usage(u8 *argv0, int more_help) {
"AFL_QUIET: suppress forkserver status messages\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
- "AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n"
+ "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n"
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
@@ -949,8 +953,36 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->afl_env.afl_hang_tmout) {
- afl->hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
- if (!afl->hang_tmout) { FATAL("Invalid value of AFL_HANG_TMOUT"); }
+ s32 hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
+ if (hang_tmout < 1) { FATAL("Invalid value for AFL_HANG_TMOUT"); }
+ afl->hang_tmout = (u32)hang_tmout;
+
+ }
+
+ if (afl->afl_env.afl_max_det_extras) {
+
+ s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
+ if (max_det_extras < 1) { FATAL("Invalid value for AFL_MAX_DET_EXTRAS"); }
+ afl->max_det_extras = (u32)max_det_extras;
+
+ } else {
+
+ afl->max_det_extras = MAX_DET_EXTRAS;
+
+ }
+
+ if (afl->afl_env.afl_forksrv_init_tmout) {
+
+ afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout);
+ if (!afl->fsrv.init_tmout) {
+
+ FATAL("Invalid value of AFL_FORKSRV_INIT_TMOUT");
+
+ }
+
+ } else {
+
+ afl->fsrv.init_tmout = afl->fsrv.exec_tmout * FORK_WAIT_MULT;
}
diff --git a/src/afl-gcc.c b/src/afl-gcc.c
index 22e6be8e..97564aea 100644
--- a/src/afl-gcc.c
+++ b/src/afl-gcc.c
@@ -415,7 +415,7 @@ int main(int argc, char **argv) {
"AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
"AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n";
- if (argc == 2 && strcmp(argv[1], "-h") == 0) {
+ if (argc == 2 && strncmp(argv[1], "-h", 2) == 0) {
printf("afl-cc" VERSION " by Michal Zalewski\n\n");
printf("%s \n\n", argv[0]);
diff --git a/src/afl-performance.c b/src/afl-performance.c
index 0c1697a8..a9d7cefa 100644
--- a/src/afl-performance.c
+++ b/src/afl-performance.c
@@ -72,12 +72,12 @@ void jump(afl_state_t *afl) {
static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c,
0xa9582618e03fc9aa, 0x39abdc4529b1661c};
- int i, b;
+ size_t i, b;
uint64_t s0 = 0;
uint64_t s1 = 0;
uint64_t s2 = 0;
uint64_t s3 = 0;
- for (i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
+ for (i = 0; i < (sizeof(JUMP) / sizeof(*JUMP)); i++)
for (b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
@@ -110,12 +110,12 @@ void long_jump(afl_state_t *afl) {
static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3,
0x77710069854ee241, 0x39109bb02acbe635};
- int i, b;
+ size_t i, b;
uint64_t s0 = 0;
uint64_t s1 = 0;
uint64_t s2 = 0;
uint64_t s3 = 0;
- for (i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
+ for (i = 0; i < (sizeof(LONG_JUMP) / sizeof(*LONG_JUMP)); i++)
for (b = 0; b < 64; b++) {
if (LONG_JUMP[i] & UINT64_C(1) << b) {
@@ -145,7 +145,7 @@ void long_jump(afl_state_t *afl) {
u32 hash32(u8 *key, u32 len, u32 seed) {
#else
-u32 inline hash32(u8 *key, u32 len, u32 seed) {
+inline u32 hash32(u8 *key, u32 len, u32 seed) {
#endif
@@ -157,7 +157,7 @@ u32 inline hash32(u8 *key, u32 len, u32 seed) {
u64 hash64(u8 *key, u32 len, u64 seed) {
#else
-u64 inline hash64(u8 *key, u32 len, u64 seed) {
+inline u64 hash64(u8 *key, u32 len, u64 seed) {
#endif
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 47c615d8..f4a7c336 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -636,6 +636,8 @@ static void usage(u8 *argv0) {
"size\n"
" the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+ "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
+ "startup (in milliseconds)\n"
"AFL_QUIET: do not print extra informational output\n",
argv0, MEM_LIMIT, doc_path);
@@ -1036,6 +1038,19 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
+
+ s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
+ if (forksrv_init_tmout < 1) {
+
+ FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
+
+ }
+
+ fsrv->init_tmout = (u32)forksrv_init_tmout;
+
+ }
+
afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
map_size = fsrv->map_size;
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index b50d8597..e1d08054 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -846,6 +846,7 @@ static void usage(u8 *argv0) {
" the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
+ "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@@ -1104,6 +1105,19 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF("\n");
+ if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
+
+ s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
+ if (forksrv_init_tmout < 1) {
+
+ FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
+
+ }
+
+ fsrv->init_tmout = (u32)forksrv_init_tmout;
+
+ }
+
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */