Fix potential endless loop in custom_mutator_stage

Co-authored-by: Ivan Gulakov <gulakov@ispras.ru>
This commit is contained in:
Vitalii Akolzin
2020-09-24 18:25:32 +03:00
parent 60ef1f7305
commit 888d63748a
4 changed files with 50 additions and 29 deletions

View File

@ -657,6 +657,9 @@ typedef struct afl_state {
* they do not call another function */ * they do not call another function */
u8 *map_tmp_buf; u8 *map_tmp_buf;
/* queue entries ready for splicing count (len > 1) */
u32 ready_for_splicing_count;
} afl_state_t; } afl_state_t;
struct custom_mutator { struct custom_mutator {

View File

@ -1696,50 +1696,58 @@ custom_mutator_stage:
struct queue_entry *target; struct queue_entry *target;
u32 tid; u32 tid;
u8 * new_buf; u8 * new_buf = NULL;
u32 target_len = 0;
retry_external_pick: if (afl->ready_for_splicing_count > 1 ||
/* Pick a random other queue entry for passing to external API */ (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; } while (tid == afl->current_entry && afl->queued_paths > 1);
target = afl->queue_buf[tid];
/* 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) && /* Make sure that the target has a reasonable length. */
afl->queued_paths > 3) {
target = target->next; while (target && (target->len < 2 || target == afl->queue_cur) &&
++afl->splicing_with; 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)) {
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);
target_len = target->len;
} }
if (!target) { goto retry_external_pick; }
/* 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);
u8 *mutated_buf = NULL; u8 *mutated_buf = NULL;
size_t mutated_size = size_t mutated_size =
el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, 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)) { if (unlikely(!mutated_buf)) {
@ -2738,6 +2746,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) { 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); u8 res = trim_case(afl, afl->queue_cur, in_buf);
if (res == FSRV_RUN_ERROR) { if (res == FSRV_RUN_ERROR) {
@ -2759,6 +2769,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
len = afl->queue_cur->len; len = afl->queue_cur->len;
/* maybe current entry stop being ready for splicing */
if (old_len > 1 && afl->queue_cur->len == 1)
afl->ready_for_splicing_count--;
} }
memcpy(out_buf, in_buf, len); memcpy(out_buf, in_buf, len);

View File

@ -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->queued_paths;
++afl->pending_not_fuzzed; ++afl->pending_not_fuzzed;

View File

@ -155,6 +155,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->stats_last_execs = 0; afl->stats_last_execs = 0;
afl->stats_avg_exec = -1; afl->stats_avg_exec = -1;
afl->ready_for_splicing_count = 0;
init_mopt_globals(afl); init_mopt_globals(afl);
list_append(&afl_states, afl); list_append(&afl_states, afl);