aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-09-25 11:39:25 +0200
committerGitHub <noreply@github.com>2020-09-25 11:39:25 +0200
commit3334eeb4ebd1d933f3b663a6eabc17835c6850c5 (patch)
tree8b292e6c58086d785fa692f5344eedc5974e32ef
parente38ca0e7508752c8a8d1e87d4bb215d90126babf (diff)
parenta75e7594f78454a11e3d93b3cb4878a21e4e943f (diff)
downloadafl++-3334eeb4ebd1d933f3b663a6eabc17835c6850c5.tar.gz
Merge pull request #564 from wakolzin/dev
Fix potential endless loop in custom_mutator_stage
-rw-r--r--include/afl-fuzz.h3
-rw-r--r--src/afl-fuzz-one.c67
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-state.c2
4 files changed, 49 insertions, 25 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 9404c417..0efd48ec 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -657,6 +657,9 @@ typedef struct afl_state {
* they do not call another function */
u8 *map_tmp_buf;
+ /* queue entries ready for splicing count (len > 1) */
+ u32 ready_for_splicing_count;
+
} afl_state_t;
struct custom_mutator {
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 5737c1f5..8c1aa179 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1696,50 +1696,61 @@ custom_mutator_stage:
struct queue_entry *target;
u32 tid;
- u8 * new_buf;
+ u8 * new_buf = NULL;
+ u32 target_len = 0;
- retry_external_pick:
- /* Pick a random other queue entry for passing to external API */
+ /* check if splicing is possible (if the only entry has len > 1
+ * check it is not current entry)
+ */
+ if (afl->ready_for_splicing_count > 1 ||
+ (afl->ready_for_splicing_count == 1 &&
+ afl->queue_cur->len == 1)) {
- 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);
- afl->splicing_with = tid;
- target = afl->queue_buf[tid];
+ } while (tid == afl->current_entry && afl->queued_paths > 1);
- /* Make sure that the target has a reasonable length. */
+ afl->splicing_with = tid;
+ target = afl->queue_buf[tid];
- while (target && (target->len < 2 || target == afl->queue_cur) &&
- afl->queued_paths > 3) {
+ /* Make sure that the target has a reasonable length. */
- target = target->next;
- ++afl->splicing_with;
+ while (target && (target->len < 2 || target == afl->queue_cur) &&
+ afl->queued_paths > 2) {
- }
+ target = target->next;
+ ++afl->splicing_with;
- if (!target) { goto retry_external_pick; }
+ }
- /* Read the additional testcase into a new buffer. */
- fd = open(target->fname, O_RDONLY);
- if (unlikely(fd < 0)) {
+ if (!target) { goto retry_external_pick; }
- PFATAL("Unable to open '%s'", target->fname);
+ /* 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);
+ 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);
+ target_len = target->len;
+
+ }
u8 *mutated_buf = NULL;
size_t mutated_size =
el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
- target->len, max_seed_size);
+ target_len, max_seed_size);
if (unlikely(!mutated_buf)) {
@@ -2738,6 +2749,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) {
+ u32 old_len = afl->queue_cur->len;
+
u8 res = trim_case(afl, afl->queue_cur, in_buf);
if (res == FSRV_RUN_ERROR) {
@@ -2759,6 +2772,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
len = afl->queue_cur->len;
+ /* maybe current entry is not ready for splicing anymore */
+ if (old_len > 1 && afl->queue_cur->len == 1)
+ afl->ready_for_splicing_count--;
+
}
memcpy(out_buf, in_buf, len);
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index ddd08f1c..14aa34fc 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -234,6 +234,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
}
+ if (q->len > 1) afl->ready_for_splicing_count++;
+
++afl->queued_paths;
++afl->pending_not_fuzzed;
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index ae45d571..9f68bb51 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -155,6 +155,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->stats_last_execs = 0;
afl->stats_avg_exec = -1;
+ afl->ready_for_splicing_count = 0;
+
init_mopt_globals(afl);
list_append(&afl_states, afl);