From 4b99ebbf22fa7a9d4fe43056c641e71af04133be Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Jun 2020 18:48:17 +0200 Subject: Revert "Merge branch 'text_inputs' into dev" This reverts commit 6d9b29daca46c8912aa9ddf6c053bc8554e9e9f7, reversing changes made to 07648f75ea5ef8f03a92db0c7566da8c229dc27b. --- src/afl-fuzz-one.c | 584 +++++------------------------------------------------ 1 file changed, 55 insertions(+), 529 deletions(-) (limited to 'src/afl-fuzz-one.c') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9e54815c..72383727 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -24,11 +24,6 @@ */ #include "afl-fuzz.h" -#include - -static u8 *strnstr(const u8 *s, const u8 *find, size_t slen); -static u32 string_replace(u8 **out_buf, s32 *temp_len, u32 pos, u8 *from, - u8 *to); /* MOpt */ @@ -367,463 +362,6 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { #endif /* !IGNORE_FINDS */ -/* Not pretty, but saves a lot of writing */ -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - -static u8 *strnstr(const u8 *s, const u8 *find, size_t slen) { - - char c, sc; - size_t len; - - if ((c = *find++) != '\0') { - - len = strlen(find); - do { - - do { - - if (slen-- < 1 || (sc = *s++) == '\0') return (NULL); - - } while (sc != c); - - if (len > slen) return (NULL); - - } while (strncmp(s, find, len) != 0); - - s--; - - } - - return ((u8 *)s); - -} - -/* replace between deliminators, if rep == NULL, then we will duplicate the - * target */ - -static u32 delim_replace(u8 **out_buf, s32 *temp_len, size_t pos, - const u8 *ldelim, const u8 *rdelim, u8 *rep) { - - u8 *end_buf = *out_buf + *temp_len; - u8 *ldelim_start = strnstr(*out_buf + pos, ldelim, *temp_len - pos); - - if (ldelim_start != NULL) { - - u32 max = (end_buf - ldelim_start - 1 > AFL_TXT_STRING_MAX_LEN - ? AFL_TXT_STRING_MAX_LEN - : end_buf - ldelim_start - 1); - - if (max > 0) { - - u8 *rdelim_end = strnstr(ldelim_start + 1, rdelim, max); - - if (rdelim_end != NULL) { - - u32 rep_len, delim_space_len = rdelim_end - ldelim_start - 1, xtra = 0; - - if (rep != NULL) { - - rep_len = (u32)strlen(rep); - - } else { // NULL? then we copy the value in between the delimiters - - rep_len = delim_space_len; - delim_space_len = 0; - rep = ldelim_start + 1; - xtra = rep_len; - - } - - if (rep_len != delim_space_len) { - - memmove(ldelim_start + rep_len + xtra + 1, rdelim_end, - *temp_len - (rdelim_end - *out_buf)); - - } - - memcpy(ldelim_start + 1, rep, rep_len); - *temp_len = (*temp_len - delim_space_len + rep_len); - - return 1; - - } - - } - - } - - return 0; - -} - -static u32 delim_swap(u8 **out_buf, s32 *temp_len, size_t pos, const u8 *ldelim, - const u8 *mdelim, const u8 *rdelim) { - - u8 *out_buf_end = *out_buf + *temp_len; - u32 max = (*temp_len - pos > AFL_TXT_STRING_MAX_LEN ? AFL_TXT_STRING_MAX_LEN - : *temp_len - pos); - u8 *ldelim_start = strnstr(*out_buf + pos, ldelim, max); - - if (ldelim_start != NULL) { - - max = (out_buf_end - ldelim_start - 1 > AFL_TXT_STRING_MAX_LEN - ? AFL_TXT_STRING_MAX_LEN - : out_buf_end - ldelim_start - 1); - if (max > 1) { - - u8 *mdelim_pos = strnstr(ldelim_start + 1, mdelim, max); - - if (mdelim_pos != NULL) { - - max = (out_buf_end - mdelim_pos - 1 > AFL_TXT_STRING_MAX_LEN - ? AFL_TXT_STRING_MAX_LEN - : out_buf_end - mdelim_pos - 1); - if (max > 0) { - - u8 *rdelim_end = strnstr(mdelim + 1, rdelim, max); - - if (rdelim_end != NULL) { - - u32 first_len = mdelim_pos - ldelim_start - 1; - u32 second_len = rdelim_end - mdelim_pos - 1; - u8 scratch[AFL_TXT_STRING_MAX_LEN]; - - memcpy(scratch, ldelim_start + 1, first_len); - - if (first_len != second_len) { - - memmove(ldelim_start + second_len + 1, mdelim_pos, - out_buf_end - mdelim_pos); - - } - - memcpy(ldelim_start + 1, mdelim_pos + 1, second_len); - - if (first_len != second_len) { - - memmove(mdelim_pos + first_len + 1, rdelim_end, - out_buf_end - rdelim_end); - - } - - memcpy(mdelim_pos + 1, scratch, first_len); - - return 1; - - } - - } - - } - - } - - } - - return 0; - -} - -static u32 string_replace(u8 **out_buf, s32 *temp_len, u32 pos, u8 *from, - u8 *to) { - - u8 *start = strnstr(*out_buf + pos, from, *temp_len - pos); - - if (start) { - - u32 from_len = strlen(from); - u32 to_len = strlen(to); - - if (from_len != to_len) { - - memmove(start + to_len, start + from_len, - *temp_len - from_len - (start - *out_buf)); - - } - - memcpy(start, to, to_len); - *temp_len = (*temp_len - from_len + to_len); - - return 1; - - } - - return 0; - -} - -/* Returns 1 if a mutant was generated and placed in out_buf, 0 if none - * generated. */ - -static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) { - - s32 temp_len; - u32 pos, yes = 0, - mutations = rand_below(afl, AFL_TXT_STRING_MAX_MUTATIONS) + 1; - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - *orig_temp_len + AFL_TXT_STRING_MAX_MUTATIONS); - temp_len = *orig_temp_len; - memcpy(new_buf, *out_buf, temp_len); - - for (u32 i = 0; i < mutations; i++) { - - if (temp_len < AFL_TXT_MIN_LEN) { - - if (yes) - return 1; - else - return 0; - - } - - pos = rand_below(afl, temp_len - 1); - int choice = rand_below(afl, 76); - switch (choice) { - - case 0: - yes += string_replace(out_buf, &temp_len, pos, "*", " "); - break; - case 1: - yes += string_replace(out_buf, &temp_len, pos, "(", "(!"); - break; - case 2: - yes += string_replace(out_buf, &temp_len, pos, "==", "!="); - break; - case 3: - yes += string_replace(out_buf, &temp_len, pos, "!=", "=="); - break; - case 4: - yes += string_replace(out_buf, &temp_len, pos, "==", "<"); - break; - case 5: - yes += string_replace(out_buf, &temp_len, pos, "<", "=="); - break; - case 6: - yes += string_replace(out_buf, &temp_len, pos, "==", ">"); - break; - case 7: - yes += string_replace(out_buf, &temp_len, pos, ">", "=="); - break; - case 8: - yes += string_replace(out_buf, &temp_len, pos, "=", "<"); - break; - case 9: - yes += string_replace(out_buf, &temp_len, pos, "=", ">"); - break; - case 10: - yes += string_replace(out_buf, &temp_len, pos, "<", ">"); - break; - case 11: - yes += string_replace(out_buf, &temp_len, pos, ">", "<"); - break; - case 12: - yes += string_replace(out_buf, &temp_len, pos, "++", "--"); - break; - case 13: - yes += string_replace(out_buf, &temp_len, pos, "--", "++"); - break; - case 14: - yes += string_replace(out_buf, &temp_len, pos, "+", "-"); - break; - case 15: - yes += string_replace(out_buf, &temp_len, pos, "+", "*"); - break; - case 16: - yes += string_replace(out_buf, &temp_len, pos, "+", "/"); - break; - case 17: - yes += string_replace(out_buf, &temp_len, pos, "+", "%"); - break; - case 18: - yes += string_replace(out_buf, &temp_len, pos, "*", "-"); - break; - case 19: - yes += string_replace(out_buf, &temp_len, pos, "*", "+"); - break; - case 20: - yes += string_replace(out_buf, &temp_len, pos, "*", "/"); - break; - case 21: - yes += string_replace(out_buf, &temp_len, pos, "*", "%"); - break; - case 22: - yes += string_replace(out_buf, &temp_len, pos, "-", "+"); - break; - case 23: - yes += string_replace(out_buf, &temp_len, pos, "-", "*"); - break; - case 24: - yes += string_replace(out_buf, &temp_len, pos, "-", "/"); - break; - case 25: - yes += string_replace(out_buf, &temp_len, pos, "-", "%"); - break; - case 26: - yes += string_replace(out_buf, &temp_len, pos, "/", "-"); - break; - case 27: - yes += string_replace(out_buf, &temp_len, pos, "/", "*"); - break; - case 28: - yes += string_replace(out_buf, &temp_len, pos, "/", "+"); - break; - case 29: - yes += string_replace(out_buf, &temp_len, pos, "/", "%"); - break; - case 30: - yes += string_replace(out_buf, &temp_len, pos, "%", "-"); - break; - case 31: - yes += string_replace(out_buf, &temp_len, pos, "%", "*"); - break; - case 32: - yes += string_replace(out_buf, &temp_len, pos, "%", "/"); - break; - case 33: - yes += string_replace(out_buf, &temp_len, pos, "%", "+"); - break; - case 34: - yes += string_replace(out_buf, &temp_len, pos, "->", "."); - break; - case 35: - yes += string_replace(out_buf, &temp_len, pos, ".", "->"); - break; - case 36: - yes += string_replace(out_buf, &temp_len, pos, "0", "1"); - break; - case 37: - yes += string_replace(out_buf, &temp_len, pos, "1", "0"); - break; - case 38: - yes += string_replace(out_buf, &temp_len, pos, "if", "while"); - break; - case 39: - yes += string_replace(out_buf, &temp_len, pos, "while", "if"); - break; - case 40: - yes += string_replace(out_buf, &temp_len, pos, "!", " "); - break; - case 41: - yes += string_replace(out_buf, &temp_len, pos, "&&", "||"); - break; - case 42: - yes += string_replace(out_buf, &temp_len, pos, "||", "&&"); - break; - case 43: - yes += string_replace(out_buf, &temp_len, pos, "!", ""); - break; - case 44: - yes += string_replace(out_buf, &temp_len, pos, "==", "="); - break; - case 45: - yes += string_replace(out_buf, &temp_len, pos, "--", ""); - break; - case 46: - yes += string_replace(out_buf, &temp_len, pos, "<<", "<"); - break; - case 47: - yes += string_replace(out_buf, &temp_len, pos, ">>", ">"); - break; - case 48: - yes += string_replace(out_buf, &temp_len, pos, "<", "<<"); - break; - case 49: - yes += string_replace(out_buf, &temp_len, pos, ">", ">>"); - break; - case 50: - yes += string_replace(out_buf, &temp_len, pos, "\"", "'"); - break; - case 51: - yes += string_replace(out_buf, &temp_len, pos, "'", "\""); - break; - case 52: - yes += string_replace(out_buf, &temp_len, pos, "(", "\""); - break; - case 53: - yes += string_replace(out_buf, &temp_len, pos, "\n", " "); - break; - case 54: - yes += string_replace(out_buf, &temp_len, pos, "\n", ";"); - break; - case 55: - yes += string_replace(out_buf, &temp_len, pos, "\n", "<"); - break; - case 56: /* Remove a semicolon delimited statement after a semicolon */ - yes += delim_replace(out_buf, &temp_len, pos, ";", ";", ";"); - break; - case 57: /* Remove a semicolon delimited statement after a left curly - brace */ - yes += delim_replace(out_buf, &temp_len, pos, "}", ";", "}"); - break; - case 58: /* Remove a curly brace construct */ - yes += delim_replace(out_buf, &temp_len, pos, "{", "}", ""); - break; - case 59: /* Replace a curly brace construct with an empty one */ - yes += delim_replace(out_buf, &temp_len, pos, "{", "}", "{}"); - break; - case 60: - yes += delim_swap(out_buf, &temp_len, pos, ";", ";", ";"); - break; - case 61: - yes += delim_swap(out_buf, &temp_len, pos, "}", ";", ";"); - break; - case 62: /* Swap comma delimited things case 1 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ")"); - break; - case 63: /* Swap comma delimited things case 2 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ","); - break; - case 64: /* Swap comma delimited things case 3 */ - yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ","); - break; - case 65: /* Swap comma delimited things case 4 */ - yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ")"); - break; - case 66: /* Just delete a line */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", ""); - break; - case 67: /* Delete something like "const" case 1 */ - yes += delim_replace(out_buf, &temp_len, pos, " ", " ", ""); - break; - case 68: /* Delete something like "const" case 2 */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", " ", ""); - break; - case 69: /* Delete something like "const" case 3 */ - yes += delim_replace(out_buf, &temp_len, pos, "(", " ", ""); - break; - case 70: /* Swap space delimited things case 1 */ - yes += delim_swap(out_buf, &temp_len, pos, " ", " ", " "); - break; - case 71: /* Swap space delimited things case 2 */ - yes += delim_swap(out_buf, &temp_len, pos, " ", " ", ")"); - break; - case 72: /* Swap space delimited things case 3 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", " ", " "); - break; - case 73: /* Swap space delimited things case 4 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", " ", ")"); - break; - case 74: /* Duplicate a single line of code */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", NULL); - break; - case 75: /* Duplicate a construct (most often, a non-nested for loop */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", "}", NULL); - break; - - } - - } - - if (yes == 0 || temp_len <= 0) { return 0; } - - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); - *out_buf = new_buf; - *orig_temp_len = temp_len; - - return 1; - -} - /* Take the current entry from the queue, fuzz it for a while. This function is a tad too long... returns 0 if fuzzed successfully, 1 if skipped or bailed out. */ @@ -840,6 +378,9 @@ u8 fuzz_one_original(afl_state_t *afl) { u8 a_collect[MAX_AUTO_EXTRA]; u32 a_len = 0; +/* Not pretty, but saves a lot of writing */ +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + #ifdef IGNORE_FINDS /* In IGNORE_FINDS mode, skip any entries that weren't in the @@ -2313,12 +1854,9 @@ havoc_stage: /* We essentially just do several thousand runs (depending on perf_score) where we take the input file and make random stacked tweaks. */ - u32 r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0) + - (afl->queue_cur->is_ascii ? AFL_TXT_BIAS : 0); - for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 r, use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); + u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); afl->stage_cur_val = use_stacking; @@ -2358,9 +1896,8 @@ havoc_stage: } - retry_havoc: - - switch ((r = rand_below(afl, r_max))) { + switch (rand_below( + afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) { case 0: @@ -2655,96 +2192,85 @@ havoc_stage: } - // TODO: add splicing mutation here. - // 15: - // break; - - default: - if (r == 15 && (afl->extras_cnt || afl->a_extras_cnt)) { + /* Values 15 and 16 can be selected only if there are any extras + present in the dictionaries. */ - /* Values 15 and 16 can be selected only if there are any extras - present in the dictionaries. */ + case 15: { - /* Overwrite bytes with an extra. */ + /* Overwrite bytes with an extra. */ - if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) { + if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) { - /* No user-specified extras or odds in our favor. Let's use an - auto-detected one. */ + /* No user-specified extras or odds in our favor. Let's use an + auto-detected one. */ - u32 use_extra = rand_below(afl, afl->a_extras_cnt); - u32 extra_len = afl->a_extras[use_extra].len; - u32 insert_at; + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; + u32 insert_at; - if (extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); - memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, - extra_len); + insert_at = rand_below(afl, temp_len - extra_len + 1); + memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, + extra_len); - } else { + } else { - /* No auto extras or odds in our favor. Use the dictionary. */ + /* No auto extras or odds in our favor. Use the dictionary. */ - u32 use_extra = rand_below(afl, afl->extras_cnt); - u32 extra_len = afl->extras[use_extra].len; - u32 insert_at; + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; + u32 insert_at; - if (extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); - memcpy(out_buf + insert_at, afl->extras[use_extra].data, - extra_len); + insert_at = rand_below(afl, temp_len - extra_len + 1); + memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); - } + } - } else if (r == 16 && (afl->extras_cnt || afl->a_extras_cnt)) { + break; - u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1); - u8 *ptr; + } - /* Insert an extra. Do the same dice-rolling stuff as for the - previous case. */ + case 16: { - if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) { + u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1); + u8 *ptr; - use_extra = rand_below(afl, afl->a_extras_cnt); - extra_len = afl->a_extras[use_extra].len; - ptr = afl->a_extras[use_extra].data; + /* Insert an extra. Do the same dice-rolling stuff as for the + previous case. */ - } else { + if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) { - use_extra = rand_below(afl, afl->extras_cnt); - extra_len = afl->extras[use_extra].len; - ptr = afl->extras[use_extra].data; + use_extra = rand_below(afl, afl->a_extras_cnt); + extra_len = afl->a_extras[use_extra].len; + ptr = afl->a_extras[use_extra].data; - } + } else { - if (temp_len + extra_len >= MAX_FILE) { break; } + use_extra = rand_below(afl, afl->extras_cnt); + extra_len = afl->extras[use_extra].len; + ptr = afl->extras[use_extra].data; - out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + } - /* Tail */ - memmove(out_buf + insert_at + extra_len, out_buf + insert_at, - temp_len - insert_at); + if (temp_len + extra_len >= MAX_FILE) { break; } - /* Inserted part */ - memcpy(out_buf + insert_at, ptr, extra_len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); - temp_len += extra_len; + /* Tail */ + memmove(out_buf + insert_at + extra_len, out_buf + insert_at, + temp_len - insert_at); - } else { + /* Inserted part */ + memcpy(out_buf + insert_at, ptr, extra_len); - // ascii mutations - if (text_mutation(afl, &out_buf, &temp_len) == 0) goto retry_havoc; + temp_len += extra_len; - //#ifdef _AFL_DOCUMENT_MUTATIONS - // fprintf(stderr, "MUTATED: %s/mutations/%09u:*\n", - // afl->out_dir, - // afl->document_counter); - //#endif + break; - } + } } -- cgit 1.4.1 From c2b04bdf6c596f5d220f27caead20d09452ed42d Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 16 Jul 2020 14:32:41 +0200 Subject: queue buffer and new splice havoc mutation --- include/afl-fuzz.h | 4 ++ src/afl-fuzz-one.c | 111 +++++++++++++++++++++++++++++++++++++++++++-------- src/afl-fuzz-queue.c | 5 +++ src/afl-fuzz-state.c | 1 + 4 files changed, 104 insertions(+), 17 deletions(-) (limited to 'src/afl-fuzz-one.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index c9f84c61..adab8155 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -546,6 +546,10 @@ typedef struct afl_state { *queue_top, /* Top of the list */ *q_prev100; /* Previous 100 marker */ + // growing buf + struct queue_entry **queue_buf; + size_t queue_size; + struct queue_entry **top_rated; /* Top entries for bitmap bytes */ struct extra_data *extras; /* Extra tokens to fuzz with */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 72383727..399bfcab 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1897,7 +1897,7 @@ havoc_stage: } switch (rand_below( - afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) { + afl, 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) { case 0: @@ -2190,12 +2190,102 @@ havoc_stage: break; + } + + case 15: { + + /* Overwrite bytes with a randomly selected chunk from another + testcase or insert that chunk. */ + + if (afl->queued_paths < 2) break; + + /* Pick a random queue entry and seek to it. */ + + u32 tid; + do + tid = rand_below(afl, afl->queued_paths); + while (tid == afl->current_entry); + + struct queue_entry* target = afl->queue_buf[tid]; + + /* Make sure that the target has a reasonable length. */ + + while (target && (target->len < 2 || target == afl->queue_cur)) + target = target->next; + + if (!target) break; + + /* Read the testcase into a new buffer. */ + + fd = open(target->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + + u32 new_len = target->len; + u8 * new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); + + ck_read(fd, new_buf, new_len, target->fname); + + close(fd); + + u8 overwrite = 0; + if (temp_len >= 2 && rand_below(afl, 2)) + overwrite = 1; + else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + if (temp_len >= 2) overwrite = 1; + else break; + } + + if (overwrite) { + + u32 copy_from, copy_to, copy_len; + + copy_len = choose_block_len(afl, new_len - 1); + if (copy_len > temp_len) copy_len = temp_len; + + copy_from = rand_below(afl, new_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + + memmove(out_buf + copy_to, new_buf + copy_from, copy_len); + + } else { + + u32 clone_from, clone_to, clone_len; + + clone_len = choose_block_len(afl, new_len); + clone_from = rand_below(afl, new_len - clone_len + 1); + + clone_to = rand_below(afl, temp_len); + + u8 * temp_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + + /* Head */ + + memcpy(temp_buf, out_buf, clone_to); + + /* Inserted part */ + + memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); + + /* Tail */ + memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + out_buf = temp_buf; + temp_len += clone_len; + + } + + break; + } /* Values 15 and 16 can be selected only if there are any extras present in the dictionaries. */ - case 15: { + case 16: { /* Overwrite bytes with an extra. */ @@ -2233,7 +2323,7 @@ havoc_stage: } - case 16: { + case 17: { u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1); u8 *ptr; @@ -2357,20 +2447,7 @@ retry_splicing: } while (tid == afl->current_entry); afl->splicing_with = tid; - target = afl->queue; - - while (tid >= 100) { - - target = target->next_100; - tid -= 100; - - } - - while (tid--) { - - target = target->next; - - } + target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 7afdd9f1..a96995e5 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -25,6 +25,8 @@ #include "afl-fuzz.h" #include +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted scans. */ @@ -137,6 +139,9 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { afl->q_prev100 = q; } + + struct queue_entry** queue_buf = ck_maybe_grow(BUF_PARAMS(queue), afl->queued_paths * sizeof(struct queue_entry*)); + queue_buf[afl->queued_paths -1] = q; afl->last_path_time = get_cur_time(); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e0e43f54..e56d122a 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -405,6 +405,7 @@ void afl_state_deinit(afl_state_t *afl) { if (afl->pass_stats) { ck_free(afl->pass_stats); } if (afl->orig_cmp_map) { ck_free(afl->orig_cmp_map); } + if (afl->queue_buf) { free(afl->queue_buf); } if (afl->out_buf) { free(afl->out_buf); } if (afl->out_scratch_buf) { free(afl->out_scratch_buf); } if (afl->eff_buf) { free(afl->eff_buf); } -- cgit 1.4.1