aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-forkserver.c2
-rw-r--r--src/afl-fuzz-extras.c4
-rw-r--r--src/afl-fuzz-mutators.c5
-rw-r--r--src/afl-fuzz-one.c129
-rw-r--r--src/afl-fuzz-python.c44
5 files changed, 124 insertions, 60 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c496975f..72f3dc3b 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -634,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);
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 8cc2425f..d6c368d1 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -251,7 +251,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
if (afl->extras_cnt > afl->max_det_extras) {
OKF("More than %d tokens - will use them probabilistically.",
- afl->max_det_extras);
+ afl->max_det_extras);
}
@@ -406,7 +406,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
if (afl->extras_cnt == afl->max_det_extras + 1) {
OKF("More than %d tokens - will use them probabilistically.",
- afl->max_det_extras);
+ afl->max_det_extras);
}
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 c0c036db..03c0d3a1 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -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,119 @@ 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) {
- }
-
- while (tid--) {
+ target = target->next_100;
+ tid -= 100;
- 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 (afl->queued_paths != havoc_queued) {
+ if (mutated_size > 0) {
- if (perf_score <= afl->havoc_max_mult * 100) {
+ if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
- afl->stage_max *= 2;
- perf_score *= 2;
+ goto abandon_entry;
}
- havoc_queued = afl->queued_paths;
+ /* 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);
+ }
}
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index e540f548..68540dd7 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -347,6 +347,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 +483,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;