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. --- include/afl-fuzz.h | 7 +- include/config.h | 26 +-- src/afl-fuzz-one.c | 584 +++++--------------------------------------------- src/afl-fuzz-queue.c | 116 ---------- src/afl-performance.c | 10 +- 5 files changed, 63 insertions(+), 680 deletions(-) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index ca785e47..c9f84c61 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -139,8 +139,7 @@ struct queue_entry { var_behavior, /* Variable behavior? */ favored, /* Currently favored? */ fs_redundant, /* Marked as redundant in the fs? */ - fully_colorized, /* Do not run redqueen stage again */ - is_ascii; /* Is the input just ascii text? */ + fully_colorized; /* Do not run redqueen stage again */ u32 bitmap_size, /* Number of bits set in bitmap */ fuzz_level; /* Number of fuzzing iterations */ @@ -948,7 +947,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, u64 exec_cksum); /* xoshiro256** */ -uint32_t rand_next(afl_state_t *afl); +uint64_t rand_next(afl_state_t *afl); /**** Inline routines ****/ @@ -968,7 +967,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) { } - return (rand_next(afl) % limit); + return rand_next(afl) % limit; } diff --git a/include/config.h b/include/config.h index 09405a22..087e0a76 100644 --- a/include/config.h +++ b/include/config.h @@ -293,7 +293,7 @@ /* Call count interval between reseeding the libc PRNG from /dev/urandom: */ -#define RESEED_RNG 256000 +#define RESEED_RNG 100000 /* Maximum line length passed from GCC to 'as' and used for parsing configuration files: */ @@ -397,29 +397,5 @@ // #define IGNORE_FINDS -/* Text mutations */ - -/* What is the minimum length of a queue input to be evaluated for "is_ascii"? - */ - -#define AFL_TXT_MIN_LEN 12 - -/* What is the minimum percentage of ascii characters present to be classifed - as "is_ascii"? */ - -#define AFL_TXT_MIN_PERCENT 95 - -/* How often to perform ASCII mutations 0 = disable, 1-8 are good values */ - -#define AFL_TXT_BIAS 8 - -/* Maximum length of a string to tamper with */ - -#define AFL_TXT_STRING_MAX_LEN 1024 - -/* Maximum mutations on a string */ - -#define AFL_TXT_STRING_MAX_MUTATIONS 6 - #endif /* ! _HAVE_CONFIG_H */ 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; - } + } } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index da6b1eee..7afdd9f1 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -24,7 +24,6 @@ #include "afl-fuzz.h" #include -#include /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted @@ -101,119 +100,6 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } -/* check if ascii or UTF-8 */ - -static u8 check_if_text(struct queue_entry *q) { - - if (q->len < AFL_TXT_MIN_LEN) return 0; - - u8 buf[MAX_FILE], bom[3] = {0xef, 0xbb, 0xbf}; - s32 fd, len = q->len, offset = 0, ascii = 0, utf8 = 0, comp; - - if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; - if ((comp = read(fd, buf, len)) != len) return 0; - close(fd); - - while (offset < len) { - - // ASCII: <= 0x7F to allow ASCII control characters - if ((buf[offset + 0] == 0x09 || buf[offset + 0] == 0x0A || - buf[offset + 0] == 0x0D || - (0x20 <= buf[offset + 0] && buf[offset + 0] <= 0x7E))) { - - offset++; - utf8++; - ascii++; - continue; - - } - - if (isascii((int)buf[offset]) || isprint((int)buf[offset])) { - - ascii++; - // we continue though as it can also be a valid utf8 - - } - - // non-overlong 2-byte - if (((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { - - offset += 2; - utf8++; - comp--; - continue; - - } - - // excluding overlongs - if ((buf[offset + 0] == 0xE0 && - (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // straight 3-byte - (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) || - buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // excluding surrogates - (buf[offset + 0] == 0xED && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF))) { - - offset += 3; - utf8++; - comp -= 2; - continue; - - } - - // planes 1-3 - if ((buf[offset + 0] == 0xF0 && - (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && - buf[offset + 3] <= 0xBF)) || // planes 4-15 - ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16 - (buf[offset + 0] == 0xF4 && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF))) { - - offset += 4; - utf8++; - comp -= 3; - continue; - - } - - // handle utf8 bom - if (buf[offset + 0] == bom[0] && buf[offset + 1] == bom[1] && - buf[offset + 2] == bom[2]) { - - offset += 3; - utf8++; - comp -= 2; - continue; - - } - - offset++; - - } - - u32 percent_utf8 = (utf8 * 100) / comp; - u32 percent_ascii = (ascii * 100) / len; - - if (percent_utf8 >= percent_ascii && percent_utf8 >= AFL_TXT_MIN_PERCENT) - return 2; - if (percent_ascii >= AFL_TXT_MIN_PERCENT) return 1; - return 0; - -} - /* Append new test case to the queue. */ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { @@ -273,8 +159,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - q->is_ascii = check_if_text(q); - } /* Destroy the entire queue. */ diff --git a/src/afl-performance.c b/src/afl-performance.c index 6631f148..0c1697a8 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -44,12 +44,10 @@ void rand_set_seed(afl_state_t *afl, s64 init_seed) { } -uint32_t rand_next(afl_state_t *afl) { +uint64_t rand_next(afl_state_t *afl) { - const uint32_t result = - (uint32_t)rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + - afl->rand_seed[0]; - // const uint32_t result = (uint32_t) rotl(afl->rand_seed[1] * 5, 7) * 9; + const uint64_t result = + rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + afl->rand_seed[0]; const uint64_t t = afl->rand_seed[1] << 17; @@ -62,7 +60,7 @@ uint32_t rand_next(afl_state_t *afl) { afl->rand_seed[3] = rotl(afl->rand_seed[3], 45); - return (uint32_t)result; + return result; } -- cgit 1.4.1 From 878b27af762b9d79d46c3de59ced749bb0e93d35 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 16:52:48 +0200 Subject: blacklist -> ignore renaming --- llvm_mode/afl-llvm-common.cc | 14 +++++++------- llvm_mode/afl-llvm-common.h | 2 +- llvm_mode/afl-llvm-lto-instrim.so.cc | 2 +- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 2 +- llvm_mode/afl-llvm-lto-whitelist.so.cc | 2 +- src/afl-fuzz-redqueen.c | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc index 6c7222cd..5a75c4dd 100644 --- a/llvm_mode/afl-llvm-common.cc +++ b/llvm_mode/afl-llvm-common.cc @@ -44,13 +44,13 @@ char *getBBName(const llvm::BasicBlock *BB) { } /* Function that we never instrument or analyze */ -/* Note: this blacklist check is also called in isInWhitelist() */ -bool isBlacklisted(const llvm::Function *F) { +/* Note: this ignore check is also called in isInWhitelist() */ +bool isIgnoreFunction(const llvm::Function *F) { // Starting from "LLVMFuzzer" these are functions used in libfuzzer based // fuzzing campaign installations, e.g. oss-fuzz - static const char *Blacklist[] = { + static const char *ignoreList[] = { "asan.", "llvm.", @@ -73,9 +73,9 @@ bool isBlacklisted(const llvm::Function *F) { }; - for (auto const &BlacklistFunc : Blacklist) { + for (auto const &ignoreListFunc : ignoreList) { - if (F->getName().startswith(BlacklistFunc)) { return true; } + if (F->getName().startswith(ignoreListFunc)) { return true; } } @@ -107,8 +107,8 @@ void initWhitelist() { bool isInWhitelist(llvm::Function *F) { // is this a function with code? If it is external we dont instrument it - // anyway and cant be in the whitelist. Or if it is blacklisted. - if (!F->size() || isBlacklisted(F)) return false; + // anyway and cant be in the whitelist. Or if it is ignored. + if (!F->size() || isIgnoreFunction(F)) return false; // if we do not have a whitelist return true if (myWhitelist.empty()) return true; diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h index 50ad3abc..db009f8f 100644 --- a/llvm_mode/afl-llvm-common.h +++ b/llvm_mode/afl-llvm-common.h @@ -33,7 +33,7 @@ typedef long double max_align_t; #endif char * getBBName(const llvm::BasicBlock *BB); -bool isBlacklisted(const llvm::Function *F); +bool isIgnoreFunction(const llvm::Function *F); void initWhitelist(); bool isInWhitelist(llvm::Function *F); unsigned long long int calculateCollisions(uint32_t edges); diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc index 4b89c9d0..b62912a6 100644 --- a/llvm_mode/afl-llvm-lto-instrim.so.cc +++ b/llvm_mode/afl-llvm-lto-instrim.so.cc @@ -562,7 +562,7 @@ struct InsTrimLTO : public ModulePass { // if the function below our minimum size skip it (1 or 2) if (F.size() < function_minimum_size) continue; - if (isBlacklisted(&F)) continue; + if (isIgnoreFunction(&F)) continue; functions++; diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 0d3015d7..82af890c 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -196,7 +196,7 @@ bool AFLLTOPass::runOnModule(Module &M) { // fprintf(stderr, "DEBUG: Function %s\n", F.getName().str().c_str()); if (F.size() < function_minimum_size) continue; - if (isBlacklisted(&F)) continue; + if (isIgnoreFunction(&F)) continue; // whitelist check AttributeList Attrs = F.getAttributes(); diff --git a/llvm_mode/afl-llvm-lto-whitelist.so.cc b/llvm_mode/afl-llvm-lto-whitelist.so.cc index b1f791f4..52c7cf0d 100644 --- a/llvm_mode/afl-llvm-lto-whitelist.so.cc +++ b/llvm_mode/afl-llvm-lto-whitelist.so.cc @@ -126,7 +126,7 @@ bool AFLwhitelist::runOnModule(Module &M) { if (F.size() < 1) continue; // fprintf(stderr, "F:%s\n", F.getName().str().c_str()); - if (isBlacklisted(&F)) continue; + if (isIgnoreFunction(&F)) continue; BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt(); IRBuilder<> IRB(&(*IP)); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 43850eb5..44953a52 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -435,7 +435,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u32 fails; u8 found_one = 0; - /* loop cmps are useless, detect and blacklist them */ + /* loop cmps are useless, detect and ignores them */ u64 s_v0, s_v1; u8 s_v0_fixed = 1, s_v1_fixed = 1; u8 s_v0_inc = 1, s_v1_inc = 1; @@ -743,7 +743,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, afl->pass_stats[k].faileds || afl->pass_stats[k].total == 0xff)) { - afl->shm.cmp_map->headers[k].hits = 0; // blacklist this cmp + afl->shm.cmp_map->headers[k].hits = 0; // ignores this cmp } -- cgit 1.4.1 From 06264df16891070a09a31cd981a9dcaaf01de7c7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 17:28:21 +0200 Subject: rename whitelist -> instrumentlist --- README.md | 8 +- docs/Changelog.md | 14 +- docs/PATCHES.md | 2 +- docs/env_variables.md | 12 +- docs/perf_tips.md | 4 +- gcc_plugin/GNUmakefile | 2 +- gcc_plugin/Makefile | 2 +- gcc_plugin/README.instrument_file.md | 73 ++++++++ gcc_plugin/README.whitelist.md | 73 -------- gcc_plugin/afl-gcc-fast.c | 95 +++++----- gcc_plugin/afl-gcc-pass.so.cc | 37 ++-- llvm_mode/GNUmakefile | 6 +- llvm_mode/LLVMInsTrim.so.cc | 4 +- llvm_mode/README.instrument_file.md | 79 +++++++++ llvm_mode/README.lto.md | 4 +- llvm_mode/README.md | 4 +- llvm_mode/README.whitelist.md | 79 --------- llvm_mode/TODO | 10 -- llvm_mode/afl-clang-fast.c | 17 +- llvm_mode/afl-llvm-common.cc | 37 ++-- llvm_mode/afl-llvm-common.h | 4 +- llvm_mode/afl-llvm-lto-instrim.so.cc | 5 +- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 5 +- llvm_mode/afl-llvm-lto-instrumentlist.so.cc | 253 +++++++++++++++++++++++++++ llvm_mode/afl-llvm-lto-whitelist.so.cc | 244 -------------------------- llvm_mode/afl-llvm-pass.so.cc | 4 +- llvm_mode/cmplog-instructions-pass.cc | 4 +- llvm_mode/cmplog-routines-pass.cc | 4 +- llvm_mode/compare-transform-pass.so.cc | 4 +- llvm_mode/split-compares-pass.so.cc | 4 +- llvm_mode/split-switches-pass.so.cc | 4 +- src/afl-common.c | 4 +- src/afl-fuzz.c | 4 +- test/test-performance.sh | 4 +- test/test.sh | 40 ++--- 35 files changed, 586 insertions(+), 563 deletions(-) create mode 100644 gcc_plugin/README.instrument_file.md delete mode 100644 gcc_plugin/README.whitelist.md create mode 100644 llvm_mode/README.instrument_file.md delete mode 100644 llvm_mode/README.whitelist.md delete mode 100644 llvm_mode/TODO create mode 100644 llvm_mode/afl-llvm-lto-instrumentlist.so.cc delete mode 100644 llvm_mode/afl-llvm-lto-whitelist.so.cc diff --git a/README.md b/README.md index 104f56ea..dd32e28e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ AFL++ Logo - ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=master) + ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) Release Version: [2.65c](https://github.com/AFLplusplus/AFLplusplus/releases) @@ -40,7 +40,7 @@ * InsTrim, a very effective CFG llvm_mode instrumentation implementation for large targets: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim) - * C. Holler's afl-fuzz Python mutator module and llvm_mode whitelist support: [https://github.com/choller/afl](https://github.com/choller/afl) + * C. Holler's afl-fuzz Python mutator module and llvm_mode instrument file support: [https://github.com/choller/afl](https://github.com/choller/afl) * Custom mutator by a library (instead of Python) by kyakdan @@ -70,7 +70,7 @@ | Persistent mode | | x | x | x86[_64]/arm[64] | x | | LAF-Intel / CompCov | | x | | x86[_64]/arm[64] | x86[_64]/arm | | CmpLog | | x | | x86[_64]/arm[64] | | - | Whitelist | | x | x | (x)(3) | | + | Instrument file list | | x | x | (x)(3) | | | Non-colliding coverage | | x(4) | | (x)(5) | | | InsTrim | | x | | | | | Ngram prev_loc coverage | | x(6) | | | | @@ -297,7 +297,7 @@ Using the LAF Intel performance enhancements are also recommended, see [llvm_mode/README.laf-intel.md](llvm_mode/README.laf-intel.md) Using partial instrumentation is also recommended, see -[llvm_mode/README.whitelist.md](llvm_mode/README.whitelist.md) +[llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md) When testing libraries, you need to find or write a simple program that reads data from stdin or from a file and passes it to the tested library. In such a diff --git a/docs/Changelog.md b/docs/Changelog.md index 1ecea274..6718ecde 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,10 @@ sending a mail to . ### Version ++2.65d (dev) + - renamed the main branch on Github to "stable" + - renamed master/slave to main/secondary + - renamed blacklist/whitelist to ignorelist/instrumentlist -> + AFL_LLVM_INSTRUMENT_FILE and AFL_GCC_INSTRUMENT_FILE - afl-fuzz: - -S secondary nodes now only sync from the main node to increase performance, the -M main node still syncs from everyone. Added checks @@ -40,8 +44,8 @@ sending a mail to . - WHITELIST feature now supports wildcards (thanks to sirmc) - small change to cmplog to make it work with current llvm 11-dev - added AFL_LLVM_LAF_ALL, sets all laf-intel settings - - LTO whitelist functionality rewritten, now main, _init etc functions - need not to be whitelisted anymore + - LTO instrument_files functionality rewritten, now main, _init etc functions + need not to be instrument_filesed anymore - fixed crash in compare-transform-pass when strcasecmp/strncasecmp was tried to be instrumented with LTO - fixed crash in cmplog with LTO @@ -249,7 +253,7 @@ sending a mail to . the original script is still present as afl-cmin.bash - afl-showmap: -i dir option now allows processing multiple inputs using the forkserver. This is for enhanced speed in afl-cmin. - - added blacklist and whitelisting function check in all modules of llvm_mode + - added blacklist and instrument_filesing function check in all modules of llvm_mode - added fix from Debian project to compile libdislocator and libtokencap - libdislocator: AFL_ALIGNED_ALLOC to force size alignment to max_align_t @@ -304,7 +308,7 @@ sending a mail to . performance loss of ~10% - added test/test-performance.sh script - (re)added gcc_plugin, fast inline instrumentation is not yet finished, - however it includes the whitelisting and persistance feature! by hexcoder- + however it includes the instrument_filesing and persistance feature! by hexcoder- - gcc_plugin tests added to testing framework @@ -392,7 +396,7 @@ sending a mail to . - more cpu power for afl-system-config - added forkserver patch to afl-tmin, makes it much faster (originally from github.com/nccgroup/TriforceAFL) - - added whitelist support for llvm_mode via AFL_LLVM_WHITELIST to allow + - added instrument_files support for llvm_mode via AFL_LLVM_WHITELIST to allow only to instrument what is actually interesting. Gives more speed and less map pollution (originally by choller@mozilla) - added Python Module mutator support, python2.7-dev is autodetected. diff --git a/docs/PATCHES.md b/docs/PATCHES.md index a6783523..b2cff43a 100644 --- a/docs/PATCHES.md +++ b/docs/PATCHES.md @@ -28,7 +28,7 @@ afl-qemu-optimize-map.diff by mh(at)mh-sec(dot)de + AFLfast additions (github.com/mboehme/aflfast) were incorporated. + Qemu 3.1 upgrade with enhancement patches (github.com/andreafioraldi/afl) + Python mutator modules support (github.com/choller/afl) -+ Whitelisting in LLVM mode (github.com/choller/afl) ++ Instrument file list in LLVM mode (github.com/choller/afl) + forkserver patch for afl-tmin (github.com/nccgroup/TriforceAFL) diff --git a/docs/env_variables.md b/docs/env_variables.md index 867e937e..87344331 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -204,14 +204,14 @@ Then there are a few specific features that are only available in llvm_mode: See llvm_mode/README.laf-intel.md for more information. -### WHITELIST +### INSTRUMENT_FILE This feature allows selectively instrumentation of the source - - Setting AFL_LLVM_WHITELIST with a filename will only instrument those + - Setting AFL_LLVM_INSTRUMENT_FILE with a filename will only instrument those files that match the names listed in this file. - See llvm_mode/README.whitelist.md for more information. + See llvm_mode/README.instrument_file.md for more information. ### NOT_ZERO @@ -236,14 +236,14 @@ Then there are a few specific features that are only available in llvm_mode: Then there are a few specific features that are only available in the gcc_plugin: -### WHITELIST +### INSTRUMENT_FILE This feature allows selective instrumentation of the source - - Setting AFL_GCC_WHITELIST with a filename will only instrument those + - Setting AFL_GCC_INSTRUMENT_FILE with a filename will only instrument those files that match the names listed in this file (one filename per line). - See gcc_plugin/README.whitelist.md for more information. + See gcc_plugin/README.instrument_file.md for more information. ## 3) Settings for afl-fuzz diff --git a/docs/perf_tips.md b/docs/perf_tips.md index fcd03db7..7a690b77 100644 --- a/docs/perf_tips.md +++ b/docs/perf_tips.md @@ -66,8 +66,8 @@ then using laf-intel (see llvm_mode/README.laf-intel.md) will help `afl-fuzz` a to get to the important parts in the code. If you are only interested in specific parts of the code being fuzzed, you can -whitelist the files that are actually relevant. This improves the speed and -accuracy of afl. See llvm_mode/README.whitelist.md +instrument_files the files that are actually relevant. This improves the speed and +accuracy of afl. See llvm_mode/README.instrument_file.md Also use the InsTrim mode on larger binaries, this improves performance and coverage a lot. diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile index 60f04bb7..bf5c53e0 100644 --- a/gcc_plugin/GNUmakefile +++ b/gcc_plugin/GNUmakefile @@ -156,7 +156,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 7eff326a..f720112f 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -152,7 +152,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/README.instrument_file.md b/gcc_plugin/README.instrument_file.md new file mode 100644 index 00000000..d0eaf6ff --- /dev/null +++ b/gcc_plugin/README.instrument_file.md @@ -0,0 +1,73 @@ +======================================== +Using afl++ with partial instrumentation +======================================== + + This file describes how you can selectively instrument only the source files + that are interesting to you using the gcc instrumentation provided by + afl++. + + Plugin by hexcoder-. + + +## 1) Description and purpose + +When building and testing complex programs where only a part of the program is +the fuzzing target, it often helps to only instrument the necessary parts of +the program, leaving the rest uninstrumented. This helps to focus the fuzzer +on the important parts of the program, avoiding undesired noise and +disturbance by uninteresting code being exercised. + +For this purpose, I have added a "partial instrumentation" support to the gcc +plugin of AFLFuzz that allows you to specify on a source file level which files +should be compiled with or without instrumentation. + + +## 2) Building the gcc plugin + +The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ +subdirectory. There is nothing specifically to do :) + + +## 3) How to use the partial instrumentation mode + +In order to build with partial instrumentation, you need to build with +afl-gcc-fast and afl-g++-fast respectively. The only required change is +that you need to set the environment variable AFL_GCC_INSTRUMENT_FILE when calling +the compiler. + +The environment variable must point to a file containing all the filenames +that should be instrumented. For matching, the filename that is being compiled +must end in the filename entry contained in this instrument list (to avoid breaking +the matching when absolute paths are used during compilation). + +For example if your source tree looks like this: + +``` +project/ +project/feature_a/a1.cpp +project/feature_a/a2.cpp +project/feature_b/b1.cpp +project/feature_b/b2.cpp +``` + +and you only want to test feature_a, then create a instrument list file containing: + +``` +feature_a/a1.cpp +feature_a/a2.cpp +``` + +However if the instrument list file contains only this, it works as well: + +``` +a1.cpp +a2.cpp +``` + +but it might lead to files being unwantedly instrumented if the same filename +exists somewhere else in the project directories. + +The created instrument list file is then set to AFL_GCC_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the instrument list, the compiler will +issue a warning at the end stating that no blocks were instrumented. If you +didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/README.whitelist.md b/gcc_plugin/README.whitelist.md deleted file mode 100644 index 8ad2068d..00000000 --- a/gcc_plugin/README.whitelist.md +++ /dev/null @@ -1,73 +0,0 @@ -======================================== -Using afl++ with partial instrumentation -======================================== - - This file describes how you can selectively instrument only the source files - that are interesting to you using the gcc instrumentation provided by - afl++. - - Plugin by hexcoder-. - - -## 1) Description and purpose - -When building and testing complex programs where only a part of the program is -the fuzzing target, it often helps to only instrument the necessary parts of -the program, leaving the rest uninstrumented. This helps to focus the fuzzer -on the important parts of the program, avoiding undesired noise and -disturbance by uninteresting code being exercised. - -For this purpose, I have added a "partial instrumentation" support to the gcc -plugin of AFLFuzz that allows you to specify on a source file level which files -should be compiled with or without instrumentation. - - -## 2) Building the gcc plugin - -The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ -subdirectory. There is nothing specifically to do :) - - -## 3) How to use the partial instrumentation mode - -In order to build with partial instrumentation, you need to build with -afl-gcc-fast and afl-g++-fast respectively. The only required change is -that you need to set the environment variable AFL_GCC_WHITELIST when calling -the compiler. - -The environment variable must point to a file containing all the filenames -that should be instrumented. For matching, the filename that is being compiled -must end in the filename entry contained in this whitelist (to avoid breaking -the matching when absolute paths are used during compilation). - -For example if your source tree looks like this: - -``` -project/ -project/feature_a/a1.cpp -project/feature_a/a2.cpp -project/feature_b/b1.cpp -project/feature_b/b2.cpp -``` - -and you only want to test feature_a, then create a whitelist file containing: - -``` -feature_a/a1.cpp -feature_a/a2.cpp -``` - -However if the whitelist file contains only this, it works as well: - -``` -a1.cpp -a2.cpp -``` - -but it might lead to files being unwantedly instrumented if the same filename -exists somewhere else in the project directories. - -The created whitelist file is then set to AFL_GCC_WHITELIST when you compile -your program. For each file that didn't match the whitelist, the compiler will -issue a warning at the end stating that no blocks were instrumented. If you -didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index bd780b40..af0beca7 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -306,47 +306,47 @@ int main(int argc, char **argv, char **envp) { if (argc < 2 || strcmp(argv[1], "-h") == 0) { - printf( - cCYA - "afl-gcc-fast" VERSION cRST - " initially by , maintainer: hexcoder-\n" - "\n" - "afl-gcc-fast [options]\n" - "\n" - "This is a helper application for afl-fuzz. It serves as a drop-in " - "replacement\n" - "for gcc, letting you recompile third-party code with the required " - "runtime\n" - "instrumentation. A common use pattern would be one of the " - "following:\n\n" - - " CC=%s/afl-gcc-fast ./configure\n" - " CXX=%s/afl-g++-fast ./configure\n\n" - - "In contrast to the traditional afl-gcc tool, this version is " - "implemented as\n" - "a GCC plugin and tends to offer improved performance with slow " - "programs\n" - "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" - - "Environment variables used:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_DEBUG: enable developer debugging output\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - "AFL_GCC_WHITELIST: enable whitelisting (selective instrumentation)\n" - - "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " - "\"%s\".\n\n", - BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); + printf(cCYA + "afl-gcc-fast" VERSION cRST + " initially by , maintainer: hexcoder-\n" + "\n" + "afl-gcc-fast [options]\n" + "\n" + "This is a helper application for afl-fuzz. It serves as a drop-in " + "replacement\n" + "for gcc, letting you recompile third-party code with the required " + "runtime\n" + "instrumentation. A common use pattern would be one of the " + "following:\n\n" + + " CC=%s/afl-gcc-fast ./configure\n" + " CXX=%s/afl-g++-fast ./configure\n\n" + + "In contrast to the traditional afl-gcc tool, this version is " + "implemented as\n" + "a GCC plugin and tends to offer improved performance with slow " + "programs\n" + "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" + + "Environment variables used:\n" + "AFL_CC: path to the C compiler to use\n" + "AFL_CXX: path to the C++ compiler to use\n" + "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_DEBUG: enable developer debugging output\n" + "AFL_HARDEN: adds code hardening to catch memory bugs\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + "AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " + "filename\n" + + "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " + "\"%s\".\n\n", + BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); exit(1); @@ -357,12 +357,15 @@ int main(int argc, char **argv, char **envp) { SAYF(cCYA "afl-gcc-fast" VERSION cRST " initially by , maintainer: hexcoder-\n"); - if (getenv("AFL_GCC_WHITELIST") == NULL) { + if (getenv("AFL_GCC_INSTRUMENT_FILE") == NULL && + getenv("AFL_GCC_WHITELIST") == NULL) { - SAYF(cYEL "Warning:" cRST - " using afl-gcc-fast without using AFL_GCC_WHITELIST currently " - "produces worse results than afl-gcc. Even better, use " - "llvm_mode for now.\n"); + SAYF( + cYEL + "Warning:" cRST + " using afl-gcc-fast without using AFL_GCC_INSTRUMENT_FILE currently " + "produces worse results than afl-gcc. Even better, use " + "llvm_mode for now.\n"); } diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc index 08f7d748..c5614aca 100644 --- a/gcc_plugin/afl-gcc-pass.so.cc +++ b/gcc_plugin/afl-gcc-pass.so.cc @@ -2,7 +2,7 @@ // There are some TODOs in this file: // - fix instrumentation via external call // - fix inline instrumentation -// - implement whitelist feature +// - implement instrument list feature // - dont instrument blocks that are uninteresting // - implement neverZero // @@ -95,7 +95,7 @@ static int be_quiet = 0; static unsigned int inst_ratio = 100; static bool inst_ext = true; -static std::list myWhitelist; +static std::list myInstrumentList; static unsigned int ext_call_instrument(function *fun) { @@ -414,7 +414,7 @@ class afl_pass : public gimple_opt_pass { unsigned int execute(function *fun) override { - if (!myWhitelist.empty()) { + if (!myInstrumentList.empty()) { bool instrumentBlock = false; std::string instFilename; @@ -436,8 +436,8 @@ class afl_pass : public gimple_opt_pass { /* Continue only if we know where we actually are */ if (!instFilename.empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -462,13 +462,14 @@ class afl_pass : public gimple_opt_pass { } /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. */ + * not in the instrument list, so we skip instrumentation. */ if (!instrumentBlock) { if (!be_quiet) { if (!instFilename.empty()) - SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n", + SAYF(cYEL "[!] " cBRI + "Not in instrument list, skipping %s line %u...\n", instFilename.c_str(), instLine); else SAYF(cYEL "[!] " cBRI "No filename information found, skipping it"); @@ -562,26 +563,32 @@ int plugin_init(struct plugin_name_args * plugin_info, } - char *instWhiteListFilename = getenv("AFL_GCC_WHITELIST"); - if (instWhiteListFilename) { + char *instInstrumentListFilename = getenv("AFL_GCC_INSTRUMENT_FILE"); + if (!instInstrumentListFilename) + instInstrumentListFilename = getenv("AFL_GCC_WHITELIST"); + if (instInstrumentListFilename) { std::string line; std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) PFATAL("Unable to open AFL_GCC_WHITELIST"); + fileStream.open(instInstrumentListFilename); + if (!fileStream) PFATAL("Unable to open AFL_GCC_INSTRUMENT_FILE"); getline(fileStream, line); while (fileStream) { - myWhitelist.push_back(line); + myInstrumentList.push_back(line); getline(fileStream, line); } - } else if (!be_quiet && getenv("AFL_LLVM_WHITELIST")) + } else if (!be_quiet && (getenv("AFL_LLVM_WHITELIST") || + + getenv("AFL_LLVM_INSTRUMENT_FILE"))) { SAYF(cYEL "[-] " cRST - "AFL_LLVM_WHITELIST environment variable detected - did you mean " - "AFL_GCC_WHITELIST?\n"); + "AFL_LLVM_INSTRUMENT_FILE environment variable detected - did " + "you mean AFL_GCC_INSTRUMENT_FILE?\n"); + + } /* Go go gadget */ register_callback(plugin_info->base_name, PLUGIN_INFO, NULL, diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile index 4cc55d92..b5d026ef 100644 --- a/llvm_mode/GNUmakefile +++ b/llvm_mode/GNUmakefile @@ -253,7 +253,7 @@ ifeq "$(TEST_MMAP)" "1" LDFLAGS += -Wno-deprecated-declarations endif - PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../afl-ld-lto ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so + PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../afl-ld-lto ../afl-llvm-lto-instrumentlist.so ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so # If prerequisites are not given, warn, do not build anything, and exit with code 0 ifeq "$(LLVMVER)" "" @@ -332,7 +332,7 @@ ifeq "$(LLVM_MIN_4_0_1)" "0" endif $(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o -../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o +../afl-llvm-lto-instrumentlist.so: afl-llvm-lto-instrumentlist.so.cc afl-llvm-common.o ifeq "$(LLVM_LTO)" "1" $(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o endif @@ -403,7 +403,7 @@ all_done: test_build install: all install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../afl-clang-lto ]; then set -e; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../afl-llvm-rt-lto*.o ../afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../afl-clang-lto ]; then set -e; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../afl-llvm-rt-lto*.o ../afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi if [ -f ../afl-ld-lto ]; then set -e; install -m 755 ../afl-ld-lto $${DESTDIR}$(BIN_PATH); fi if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index 991127a7..75548266 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -74,7 +74,7 @@ struct InsTrim : public ModulePass { InsTrim() : ModulePass(ID), generator(0) { - initWhitelist(); + initInstrumentList(); } @@ -271,7 +271,7 @@ struct InsTrim : public ModulePass { } - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; // if the function below our minimum size skip it (1 or 2) if (F.size() < function_minimum_size) { continue; } diff --git a/llvm_mode/README.instrument_file.md b/llvm_mode/README.instrument_file.md new file mode 100644 index 00000000..347bd3c6 --- /dev/null +++ b/llvm_mode/README.instrument_file.md @@ -0,0 +1,79 @@ +# Using afl++ with partial instrumentation + + This file describes how you can selectively instrument only the source files + that are interesting to you using the LLVM instrumentation provided by + afl++ + + Originally developed by Christian Holler (:decoder) . + +## 1) Description and purpose + +When building and testing complex programs where only a part of the program is +the fuzzing target, it often helps to only instrument the necessary parts of +the program, leaving the rest uninstrumented. This helps to focus the fuzzer +on the important parts of the program, avoiding undesired noise and +disturbance by uninteresting code being exercised. + +For this purpose, I have added a "partial instrumentation" support to the LLVM +mode of AFLFuzz that allows you to specify on a source file level which files +should be compiled with or without instrumentation. + + +## 2) Building the LLVM module + +The new code is part of the existing afl++ LLVM module in the llvm_mode/ +subdirectory. There is nothing specifically to do :) + + +## 3) How to use the partial instrumentation mode + +In order to build with partial instrumentation, you need to build with +afl-clang-fast and afl-clang-fast++ respectively. The only required change is +that you need to set the environment variable AFL_LLVM_INSTRUMENT_FILE when calling +the compiler. + +The environment variable must point to a file containing all the filenames +that should be instrumented. For matching, the filename that is being compiled +must end in the filename entry contained in this the instrument file list (to avoid breaking +the matching when absolute paths are used during compilation). + +For example if your source tree looks like this: + +``` +project/ +project/feature_a/a1.cpp +project/feature_a/a2.cpp +project/feature_b/b1.cpp +project/feature_b/b2.cpp +``` + +and you only want to test feature_a, then create a the instrument file list file containing: + +``` +feature_a/a1.cpp +feature_a/a2.cpp +``` + +However if the the instrument file list file contains only this, it works as well: + +``` +a1.cpp +a2.cpp +``` + +but it might lead to files being unwantedly instrumented if the same filename +exists somewhere else in the project directories. + +The created the instrument file list file is then set to AFL_LLVM_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the the instrument file list, the compiler will +issue a warning at the end stating that no blocks were instrumented. If you +didn't intend to instrument that file, then you can safely ignore that warning. + +For old LLVM versions this feature might require to be compiled with debug +information (-g), however at least from llvm version 6.0 onwards this is not +required anymore (and might hurt performance and crash detection, so better not +use -g). + +## 4) UNIX-style filename pattern matching +You can add UNIX-style pattern matching in the the instrument file list entries. See `man +fnmatch` for the syntax. We do not set any of the `fnmatch` flags. diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md index 517cb62a..4641fa89 100644 --- a/llvm_mode/README.lto.md +++ b/llvm_mode/README.lto.md @@ -7,7 +7,7 @@ This version requires a current llvm 11 compiled from the github master. 1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better coverage than anything else that is out there in the AFL world -2. You can use it together with llvm_mode: laf-intel and whitelisting +2. You can use it together with llvm_mode: laf-intel and the instrument file listing features and can be combined with cmplog/Redqueen 3. It only works with llvm 11 (current github master state) @@ -108,7 +108,7 @@ make install Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc. -Also whitelisting (AFL_LLVM_WHITELIST -> [README.whitelist.md](README.whitelist.md)) and +Also the instrument file listing (AFL_LLVM_INSTRUMENT_FILE -> [README.instrument_file.md](README.instrument_file.md)) and laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work. InsTrim (control flow graph instrumentation) is supported and recommended! (set `AFL_LLVM_INSTRUMENT=CFG`) diff --git a/llvm_mode/README.md b/llvm_mode/README.md index c24aef49..e2e22751 100644 --- a/llvm_mode/README.md +++ b/llvm_mode/README.md @@ -108,8 +108,8 @@ directory. Several options are present to make llvm_mode faster or help it rearrange the code to make afl-fuzz path discovery easier. -If you need just to instrument specific parts of the code, you can whitelist -which C/C++ files to actually instrument. See [README.whitelist](README.whitelist.md) +If you need just to instrument specific parts of the code, you can the instrument file list +which C/C++ files to actually instrument. See [README.instrument_file](README.instrument_file.md) For splitting memcmp, strncmp, etc. please see [README.laf-intel](README.laf-intel.md) diff --git a/llvm_mode/README.whitelist.md b/llvm_mode/README.whitelist.md deleted file mode 100644 index 6393fae8..00000000 --- a/llvm_mode/README.whitelist.md +++ /dev/null @@ -1,79 +0,0 @@ -# Using afl++ with partial instrumentation - - This file describes how you can selectively instrument only the source files - that are interesting to you using the LLVM instrumentation provided by - afl++ - - Originally developed by Christian Holler (:decoder) . - -## 1) Description and purpose - -When building and testing complex programs where only a part of the program is -the fuzzing target, it often helps to only instrument the necessary parts of -the program, leaving the rest uninstrumented. This helps to focus the fuzzer -on the important parts of the program, avoiding undesired noise and -disturbance by uninteresting code being exercised. - -For this purpose, I have added a "partial instrumentation" support to the LLVM -mode of AFLFuzz that allows you to specify on a source file level which files -should be compiled with or without instrumentation. - - -## 2) Building the LLVM module - -The new code is part of the existing afl++ LLVM module in the llvm_mode/ -subdirectory. There is nothing specifically to do :) - - -## 3) How to use the partial instrumentation mode - -In order to build with partial instrumentation, you need to build with -afl-clang-fast and afl-clang-fast++ respectively. The only required change is -that you need to set the environment variable AFL_LLVM_WHITELIST when calling -the compiler. - -The environment variable must point to a file containing all the filenames -that should be instrumented. For matching, the filename that is being compiled -must end in the filename entry contained in this whitelist (to avoid breaking -the matching when absolute paths are used during compilation). - -For example if your source tree looks like this: - -``` -project/ -project/feature_a/a1.cpp -project/feature_a/a2.cpp -project/feature_b/b1.cpp -project/feature_b/b2.cpp -``` - -and you only want to test feature_a, then create a whitelist file containing: - -``` -feature_a/a1.cpp -feature_a/a2.cpp -``` - -However if the whitelist file contains only this, it works as well: - -``` -a1.cpp -a2.cpp -``` - -but it might lead to files being unwantedly instrumented if the same filename -exists somewhere else in the project directories. - -The created whitelist file is then set to AFL_LLVM_WHITELIST when you compile -your program. For each file that didn't match the whitelist, the compiler will -issue a warning at the end stating that no blocks were instrumented. If you -didn't intend to instrument that file, then you can safely ignore that warning. - -For old LLVM versions this feature might require to be compiled with debug -information (-g), however at least from llvm version 6.0 onwards this is not -required anymore (and might hurt performance and crash detection, so better not -use -g). - -## 4) UNIX-style filename pattern matching -You can add UNIX-style pattern matching in the whitelist entries. See `man -fnmatch` for the syntax. We do not set any of the `fnmatch` flags. diff --git a/llvm_mode/TODO b/llvm_mode/TODO deleted file mode 100644 index 2729d688..00000000 --- a/llvm_mode/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO for afl-ld: -* handle libfoo.a object archives - -TODO for afl-llvm-lto-instrumentation: -* better algo for putting stuff in the map? -* try to predict how long the instrumentation process will take - -TODO for afl-llvm-lto-whitelist -* different solution then renaming? - diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 3b0225c2..f1b03682 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -227,13 +227,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode) { - if (getenv("AFL_LLVM_WHITELIST") != NULL) { + if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST")) { cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-lto-whitelist.so", obj_path); + alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); } @@ -762,7 +763,7 @@ int main(int argc, char **argv, char **envp) { #if LLVM_VERSION_MAJOR <= 6 instrument_mode = INSTRUMENT_AFL; #else - if (getenv("AFL_LLVM_WHITELIST")) + if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) instrument_mode = INSTRUMENT_AFL; else instrument_mode = INSTRUMENT_PCGUARD; @@ -810,8 +811,11 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " "together"); - if (instrument_mode == INSTRUMENT_PCGUARD && getenv("AFL_LLVM_WHITELIST")) - WARNF("Instrumentation type PCGUARD does not support AFL_LLVM_WHITELIST!"); + if (instrument_mode == INSTRUMENT_PCGUARD && + (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST"))) + WARNF( + "Instrumentation type PCGUARD does not support " + "AFL_LLVM_INSTRUMENT_FILE!"); if (argc < 2 || strcmp(argv[1], "-h") == 0) { @@ -861,7 +865,8 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " "function calls\n" "AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" - "AFL_LLVM_WHITELIST: enable whitelisting (selective " + "AFL_LLVM_INSTRUMENT_FILE: enable the instrument file listing " + "(selective " "instrumentation)\n" "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" "AFL_PATH: path to instrumenting pass and runtime " diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc index 5a75c4dd..47b49358 100644 --- a/llvm_mode/afl-llvm-common.cc +++ b/llvm_mode/afl-llvm-common.cc @@ -18,7 +18,7 @@ using namespace llvm; -static std::list myWhitelist; +static std::list myInstrumentList; char *getBBName(const llvm::BasicBlock *BB) { @@ -44,7 +44,7 @@ char *getBBName(const llvm::BasicBlock *BB) { } /* Function that we never instrument or analyze */ -/* Note: this ignore check is also called in isInWhitelist() */ +/* Note: this ignore check is also called in isInInstrumentList() */ bool isIgnoreFunction(const llvm::Function *F) { // Starting from "LLVMFuzzer" these are functions used in libfuzzer based @@ -83,19 +83,22 @@ bool isIgnoreFunction(const llvm::Function *F) { } -void initWhitelist() { +void initInstrumentList() { - char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); - if (instWhiteListFilename) { + char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE"); + if (!instrumentListFilename) + instrumentListFilename = getenv("AFL_LLVM_WHITELIST"); + if (instrumentListFilename) { std::string line; std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); + fileStream.open(instrumentListFilename); + if (!fileStream) + report_fatal_error("Unable to open AFL_LLVM_INSTRUMENT_FILE"); getline(fileStream, line); while (fileStream) { - myWhitelist.push_back(line); + myInstrumentList.push_back(line); getline(fileStream, line); } @@ -104,14 +107,14 @@ void initWhitelist() { } -bool isInWhitelist(llvm::Function *F) { +bool isInInstrumentList(llvm::Function *F) { // is this a function with code? If it is external we dont instrument it - // anyway and cant be in the whitelist. Or if it is ignored. + // anyway and cant be in the the instrument file list. Or if it is ignored. if (!F->size() || isIgnoreFunction(F)) return false; - // if we do not have a whitelist return true - if (myWhitelist.empty()) return true; + // if we do not have a the instrument file list return true + if (myInstrumentList.empty()) return true; // let's try to get the filename for the function auto bb = &F->getEntryBlock(); @@ -147,8 +150,8 @@ bool isInWhitelist(llvm::Function *F) { /* Continue only if we know where we actually are */ if (!instFilename.str().empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -185,8 +188,8 @@ bool isInWhitelist(llvm::Function *F) { /* Continue only if we know where we actually are */ if (!instFilename.str().empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -215,7 +218,7 @@ bool isInWhitelist(llvm::Function *F) { else { // we could not find out the location. in this case we say it is not - // in the whitelist + // in the the instrument file list return false; diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h index db009f8f..38e0c830 100644 --- a/llvm_mode/afl-llvm-common.h +++ b/llvm_mode/afl-llvm-common.h @@ -34,8 +34,8 @@ typedef long double max_align_t; char * getBBName(const llvm::BasicBlock *BB); bool isIgnoreFunction(const llvm::Function *F); -void initWhitelist(); -bool isInWhitelist(llvm::Function *F); +void initInstrumentList(); +bool isInInstrumentList(llvm::Function *F); unsigned long long int calculateCollisions(uint32_t edges); #endif diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc index b62912a6..ca2b5886 100644 --- a/llvm_mode/afl-llvm-lto-instrim.so.cc +++ b/llvm_mode/afl-llvm-lto-instrim.so.cc @@ -566,12 +566,13 @@ struct InsTrimLTO : public ModulePass { functions++; - // whitelist check + // the instrument file list check AttributeList Attrs = F.getAttributes(); if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { if (debug) - fprintf(stderr, "DEBUG: Function %s is not whitelisted\n", + fprintf(stderr, + "DEBUG: Function %s is not the instrument file listed\n", F.getName().str().c_str()); continue; diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 82af890c..af2db3ff 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -198,12 +198,13 @@ bool AFLLTOPass::runOnModule(Module &M) { if (F.size() < function_minimum_size) continue; if (isIgnoreFunction(&F)) continue; - // whitelist check + // the instrument file list check AttributeList Attrs = F.getAttributes(); if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { if (debug) - fprintf(stderr, "DEBUG: Function %s is not whitelisted\n", + fprintf(stderr, + "DEBUG: Function %s is not the instrument file listed\n", F.getName().str().c_str()); continue; diff --git a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc new file mode 100644 index 00000000..6e6199e9 --- /dev/null +++ b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc @@ -0,0 +1,253 @@ +/* + american fuzzy lop++ - LLVM-mode instrumentation pass + --------------------------------------------------- + + Written by Laszlo Szekeres and + Michal Zalewski + + LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted + from afl-as.c are Michal's fault. + + Copyright 2015, 2016 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This library is plugged into LLVM when invoking clang through afl-clang-fast. + It tells the compiler to add code roughly equivalent to the bits discussed + in ../afl-as.h. + + */ + +#define AFL_LLVM_PASS + +#include "config.h" +#include "debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/IR/CFG.h" + +#include "afl-llvm-common.h" + +using namespace llvm; + +namespace { + +class AFLcheckIfInstrument : public ModulePass { + + public: + static char ID; + AFLcheckIfInstrument() : ModulePass(ID) { + + int entries = 0; + + if (getenv("AFL_DEBUG")) debug = 1; + + char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE"); + if (!instrumentListFilename) + instrumentListFilename = getenv("AFL_LLVM_WHITELIST"); + if (instrumentListFilename) { + + std::string line; + std::ifstream fileStream; + fileStream.open(instrumentListFilename); + if (!fileStream) + report_fatal_error("Unable to open AFL_LLVM_INSTRUMENT_FILE"); + getline(fileStream, line); + while (fileStream) { + + myInstrumentList.push_back(line); + getline(fileStream, line); + entries++; + + } + + } else + + PFATAL( + "afl-llvm-lto-instrumentlist.so loaded without " + "AFL_LLVM_INSTRUMENT_FILE?!"); + + if (debug) + SAYF(cMGN "[D] " cRST + "loaded the instrument file list %s with %d entries\n", + instrumentListFilename, entries); + + } + + bool runOnModule(Module &M) override; + + // StringRef getPassName() const override { + + // return "American Fuzzy Lop Instrumentation"; + // } + + protected: + std::list myInstrumentList; + int debug = 0; + +}; + +} // namespace + +char AFLcheckIfInstrument::ID = 0; + +bool AFLcheckIfInstrument::runOnModule(Module &M) { + + /* Show a banner */ + + char be_quiet = 0; + setvbuf(stdout, NULL, _IONBF, 0); + + if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { + + SAYF(cCYA "afl-llvm-lto-instrumentlist" VERSION cRST + " by Marc \"vanHauser\" Heuse \n"); + + } else if (getenv("AFL_QUIET")) + + be_quiet = 1; + + for (auto &F : M) { + + if (F.size() < 1) continue; + // fprintf(stderr, "F:%s\n", F.getName().str().c_str()); + if (isIgnoreFunction(&F)) continue; + + BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); + + if (!myInstrumentList.empty()) { + + bool instrumentFunction = false; + + /* Get the current location using debug information. + * For now, just instrument the block if we are not able + * to determine our location. */ + DebugLoc Loc = IP->getDebugLoc(); + if (Loc) { + + DILocation *cDILoc = dyn_cast(Loc.getAsMDNode()); + + unsigned int instLine = cDILoc->getLine(); + StringRef instFilename = cDILoc->getFilename(); + + if (instFilename.str().empty()) { + + /* If the original location is empty, try using the inlined location + */ + DILocation *oDILoc = cDILoc->getInlinedAt(); + if (oDILoc) { + + instFilename = oDILoc->getFilename(); + instLine = oDILoc->getLine(); + + } + + } + + (void)instLine; + + if (debug) + SAYF(cMGN "[D] " cRST "function %s is in file %s\n", + F.getName().str().c_str(), instFilename.str().c_str()); + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) == + 0) { + + instrumentFunction = true; + break; + + } + + } + + } + + } + + } + + /* Either we couldn't figure out our location or the location is + * not the instrument file listed, so we skip instrumentation. + * We do this by renaming the function. */ + if (instrumentFunction == true) { + + if (debug) + SAYF(cMGN "[D] " cRST "function %s is in the instrument file list\n", + F.getName().str().c_str()); + + } else { + + if (debug) + SAYF(cMGN "[D] " cRST + "function %s is NOT in the instrument file list\n", + F.getName().str().c_str()); + + auto & Ctx = F.getContext(); + AttributeList Attrs = F.getAttributes(); + AttrBuilder NewAttrs; + NewAttrs.addAttribute("skipinstrument"); + F.setAttributes( + Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); + + } + + } else { + + PFATAL("InstrumentList is empty"); + + } + + } + + return true; + +} + +static void registerAFLcheckIfInstrumentpass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { + + PM.add(new AFLcheckIfInstrument()); + +} + +static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass( + PassManagerBuilder::EP_ModuleOptimizerEarly, + registerAFLcheckIfInstrumentpass); + +static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass0( + PassManagerBuilder::EP_EnabledOnOptLevel0, + registerAFLcheckIfInstrumentpass); + diff --git a/llvm_mode/afl-llvm-lto-whitelist.so.cc b/llvm_mode/afl-llvm-lto-whitelist.so.cc deleted file mode 100644 index 52c7cf0d..00000000 --- a/llvm_mode/afl-llvm-lto-whitelist.so.cc +++ /dev/null @@ -1,244 +0,0 @@ -/* - american fuzzy lop++ - LLVM-mode instrumentation pass - --------------------------------------------------- - - Written by Laszlo Szekeres and - Michal Zalewski - - LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted - from afl-as.c are Michal's fault. - - Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This library is plugged into LLVM when invoking clang through afl-clang-fast. - It tells the compiler to add code roughly equivalent to the bits discussed - in ../afl-as.h. - - */ - -#define AFL_LLVM_PASS - -#include "config.h" -#include "debug.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/Debug.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/IR/CFG.h" - -#include "afl-llvm-common.h" - -using namespace llvm; - -namespace { - -class AFLwhitelist : public ModulePass { - - public: - static char ID; - AFLwhitelist() : ModulePass(ID) { - - int entries = 0; - - if (getenv("AFL_DEBUG")) debug = 1; - - char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); - if (instWhiteListFilename) { - - std::string line; - std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); - getline(fileStream, line); - while (fileStream) { - - myWhitelist.push_back(line); - getline(fileStream, line); - entries++; - - } - - } else - - PFATAL("afl-llvm-lto-whitelist.so loaded without AFL_LLVM_WHITELIST?!"); - - if (debug) - SAYF(cMGN "[D] " cRST "loaded whitelist %s with %d entries\n", - instWhiteListFilename, entries); - - } - - bool runOnModule(Module &M) override; - - // StringRef getPassName() const override { - - // return "American Fuzzy Lop Instrumentation"; - // } - - protected: - std::list myWhitelist; - int debug = 0; - -}; - -} // namespace - -char AFLwhitelist::ID = 0; - -bool AFLwhitelist::runOnModule(Module &M) { - - /* Show a banner */ - - char be_quiet = 0; - setvbuf(stdout, NULL, _IONBF, 0); - - if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { - - SAYF(cCYA "afl-llvm-lto-whitelist" VERSION cRST - " by Marc \"vanHauser\" Heuse \n"); - - } else if (getenv("AFL_QUIET")) - - be_quiet = 1; - - for (auto &F : M) { - - if (F.size() < 1) continue; - // fprintf(stderr, "F:%s\n", F.getName().str().c_str()); - if (isIgnoreFunction(&F)) continue; - - BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt(); - IRBuilder<> IRB(&(*IP)); - - if (!myWhitelist.empty()) { - - bool instrumentFunction = false; - - /* Get the current location using debug information. - * For now, just instrument the block if we are not able - * to determine our location. */ - DebugLoc Loc = IP->getDebugLoc(); - if (Loc) { - - DILocation *cDILoc = dyn_cast(Loc.getAsMDNode()); - - unsigned int instLine = cDILoc->getLine(); - StringRef instFilename = cDILoc->getFilename(); - - if (instFilename.str().empty()) { - - /* If the original location is empty, try using the inlined location - */ - DILocation *oDILoc = cDILoc->getInlinedAt(); - if (oDILoc) { - - instFilename = oDILoc->getFilename(); - instLine = oDILoc->getLine(); - - } - - } - - (void)instLine; - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is in file %s\n", - F.getName().str().c_str(), instFilename.str().c_str()); - /* Continue only if we know where we actually are */ - if (!instFilename.str().empty()) { - - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { - - /* We don't check for filename equality here because - * filenames might actually be full paths. Instead we - * check that the actual filename ends in the filename - * specified in the list. */ - if (instFilename.str().length() >= it->length()) { - - if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) == - 0) { - - instrumentFunction = true; - break; - - } - - } - - } - - } - - } - - /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. - * We do this by renaming the function. */ - if (instrumentFunction == true) { - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is in whitelist\n", - F.getName().str().c_str()); - - } else { - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is NOT in whitelist\n", - F.getName().str().c_str()); - - auto & Ctx = F.getContext(); - AttributeList Attrs = F.getAttributes(); - AttrBuilder NewAttrs; - NewAttrs.addAttribute("skipinstrument"); - F.setAttributes( - Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); - - } - - } else { - - PFATAL("Whitelist is empty"); - - } - - } - - return true; - -} - -static void registerAFLwhitelistpass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { - - PM.add(new AFLwhitelist()); - -} - -static RegisterStandardPasses RegisterAFLwhitelistpass( - PassManagerBuilder::EP_ModuleOptimizerEarly, registerAFLwhitelistpass); - -static RegisterStandardPasses RegisterAFLwhitelistpass0( - PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLwhitelistpass); - diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 7997df51..90cf3eb4 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -74,7 +74,7 @@ class AFLCoverage : public ModulePass { static char ID; AFLCoverage() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -307,7 +307,7 @@ bool AFLCoverage::runOnModule(Module &M) { fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(), F.size()); - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; if (F.size() < function_minimum_size) continue; diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc index c5a6ff8b..f929361a 100644 --- a/llvm_mode/cmplog-instructions-pass.cc +++ b/llvm_mode/cmplog-instructions-pass.cc @@ -59,7 +59,7 @@ class CmpLogInstructions : public ModulePass { static char ID; CmpLogInstructions() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -170,7 +170,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { /* iterate over all functions, bbs and instruction and add suitable calls */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/cmplog-routines-pass.cc b/llvm_mode/cmplog-routines-pass.cc index 792a45b9..318193a4 100644 --- a/llvm_mode/cmplog-routines-pass.cc +++ b/llvm_mode/cmplog-routines-pass.cc @@ -59,7 +59,7 @@ class CmpLogRoutines : public ModulePass { static char ID; CmpLogRoutines() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -118,7 +118,7 @@ bool CmpLogRoutines::hookRtns(Module &M) { /* iterate over all functions, bbs and instruction and add suitable calls */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 96abeebb..2d1ab1cc 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -58,7 +58,7 @@ class CompareTransform : public ModulePass { static char ID; CompareTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -124,7 +124,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, * strcmp/memcmp/strncmp/strcasecmp/strncasecmp */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 2c4ed71c..651fa5b4 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -55,7 +55,7 @@ class SplitComparesTransform : public ModulePass { static char ID; SplitComparesTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -102,7 +102,7 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { * all integer comparisons with >= and <= predicates to the icomps vector */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc index 4a6ca3d9..44075c94 100644 --- a/llvm_mode/split-switches-pass.so.cc +++ b/llvm_mode/split-switches-pass.so.cc @@ -60,7 +60,7 @@ class SplitSwitchesTransform : public ModulePass { static char ID; SplitSwitchesTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -312,7 +312,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { * all switches to switches vector for later processing */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/src/afl-common.c b/src/afl-common.c index 79d419cd..8995b57e 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -58,7 +58,7 @@ char *afl_environment_variables[] = { //"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally "AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI", - "AFL_GCC_WHITELIST", "AFL_GCJ", "AFL_HANG_TMOUT", "AFL_HARDEN", + "AFL_GCC_INSTRUMENT_FILE", "AFL_GCJ", "AFL_HANG_TMOUT", "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IMPORT_FIRST", "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", @@ -71,7 +71,7 @@ char *afl_environment_variables[] = { "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_ALL", "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR", "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", - "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_LLVM_SKIP_NEVERZERO", + "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f25f8bb6..7580caad 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -790,8 +790,8 @@ int main(int argc, char **argv_orig, char **envp) { OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator and llvm_mode whitelisting from github.com/choller/afl"); - OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); + OKF("Python Mutator and llvm_mode instrument file list from " + "github.com/choller/afl"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && diff --git a/test/test-performance.sh b/test/test-performance.sh index 87eea665..cee46060 100755 --- a/test/test-performance.sh +++ b/test/test-performance.sh @@ -21,8 +21,8 @@ unset AFL_USE_ASAN unset AFL_USE_MSAN unset AFL_CC unset AFL_PRELOAD -unset AFL_GCC_WHITELIST -unset AFL_LLVM_WHITELIST +unset AFL_GCC_INSTRUMENT_FILE +unset AFL_LLVM_INSTRUMENT_FILE unset AFL_LLVM_INSTRIM unset AFL_LLVM_LAF_SPLIT_SWITCHES unset AFL_LLVM_LAF_TRANSFORM_COMPARES diff --git a/test/test.sh b/test/test.sh index a7d9fc49..90920215 100755 --- a/test/test.sh +++ b/test/test.sh @@ -62,8 +62,8 @@ unset AFL_USE_UBSAN unset AFL_TMPDIR unset AFL_CC unset AFL_PRELOAD -unset AFL_GCC_WHITELIST -unset AFL_LLVM_WHITELIST +unset AFL_GCC_INSTRUMENT_FILE +unset AFL_LLVM_INSTRUMENT_FILE unset AFL_LLVM_INSTRIM unset AFL_LLVM_LAF_SPLIT_SWITCHES unset AFL_LLVM_LAF_TRANSFORM_COMPARES @@ -386,20 +386,20 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } rm -f test-compcov.compcov test.out - echo foobar.c > whitelist.txt - AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 + echo foobar.c > instrumentlist.txt + AFL_DEBUG=1 AFL_LLVM_INSTRUMENT_FILE=instrumentlist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && test_compcov_binary_functionality ./test-compcov && { grep -q "No instrumentation targets found" test.out && { - $ECHO "$GREEN[+] llvm_mode whitelist feature works correctly" + $ECHO "$GREEN[+] llvm_mode instrumentlist feature works correctly" } || { - $ECHO "$RED[!] llvm_mode whitelist feature failed" + $ECHO "$RED[!] llvm_mode instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] llvm_mode whitelist feature compilation failed" + $ECHO "$RED[!] llvm_mode instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { @@ -459,20 +459,20 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && { } rm -f test-instr.plain - echo foobar.c > whitelist.txt - AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 + echo foobar.c > instrumentlist.txt + AFL_DEBUG=1 AFL_LLVM_INSTRUMENT_FILE=instrumentlist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && { grep -q "No instrumentation targets found" test.out && { - $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly" + $ECHO "$GREEN[+] llvm_mode LTO instrumentlist feature works correctly" } || { - $ECHO "$RED[!] llvm_mode LTO whitelist feature failed" + $ECHO "$RED[!] llvm_mode LTO instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed" + $ECHO "$RED[!] llvm_mode LTO instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m none -o /dev/null -q -r ./test-persistent && { @@ -569,20 +569,20 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { rm -f test-instr.plain.gccpi # now for the special gcc_plugin things - echo foobar.c > whitelist.txt - AFL_GCC_WHITELIST=whitelist.txt ../afl-gcc-fast -o test-compcov test-compcov.c > /dev/null 2>&1 + echo foobar.c > instrumentlist.txt + AFL_GCC_INSTRUMENT_FILE=instrumentlist.txt ../afl-gcc-fast -o test-compcov test-compcov.c > /dev/null 2>&1 test -e test-compcov && test_compcov_binary_functionality ./test-compcov && { echo 1 | ../afl-showmap -m ${MEM_LIMIT} -o - -r -- ./test-compcov 2>&1 | grep -q "Captured 1 tuples" && { - $ECHO "$GREEN[+] gcc_plugin whitelist feature works correctly" + $ECHO "$GREEN[+] gcc_plugin instrumentlist feature works correctly" } || { - $ECHO "$RED[!] gcc_plugin whitelist feature failed" + $ECHO "$RED[!] gcc_plugin instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" + $ECHO "$RED[!] gcc_plugin instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-gcc-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { -- cgit 1.4.1 From 7527c76c7446f8197b9f7acb8ca0ccd44fe7bd39 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 17:33:47 +0200 Subject: reduce the time interval in which the secondaries sync --- include/config.h | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/config.h b/include/config.h index 087e0a76..5ee93389 100644 --- a/include/config.h +++ b/include/config.h @@ -234,7 +234,7 @@ /* Sync interval (every n havoc cycles): */ -#define SYNC_INTERVAL 5 +#define SYNC_INTERVAL 8 /* Output directory reuse grace period (minutes): */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7580caad..e4e2669c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1280,7 +1280,7 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->is_main_node)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); } + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } } else { -- cgit 1.4.1 From 9d5007b18e41f17c395fcfc5fc0a8c8c87f4f75d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 23:34:26 +0200 Subject: Big renaming (#429) * first commit, looks good * fix ascii percentage calc * fix ascii percentage calc * modify txt configs for test * further refinement * Revert "Merge branch 'text_inputs' into dev" This reverts commit 6d9b29daca46c8912aa9ddf6c053bc8554e9e9f7, reversing changes made to 07648f75ea5ef8f03a92db0c7566da8c229dc27b. * blacklist -> ignore renaming * rename whitelist -> instrumentlist * reduce the time interval in which the secondaries sync Co-authored-by: root --- README.md | 8 +- docs/Changelog.md | 14 +- docs/PATCHES.md | 2 +- docs/env_variables.md | 12 +- docs/perf_tips.md | 4 +- gcc_plugin/GNUmakefile | 2 +- gcc_plugin/Makefile | 2 +- gcc_plugin/README.instrument_file.md | 73 ++++++++ gcc_plugin/README.whitelist.md | 73 -------- gcc_plugin/afl-gcc-fast.c | 95 +++++----- gcc_plugin/afl-gcc-pass.so.cc | 37 ++-- include/config.h | 2 +- llvm_mode/GNUmakefile | 6 +- llvm_mode/LLVMInsTrim.so.cc | 4 +- llvm_mode/README.instrument_file.md | 79 +++++++++ llvm_mode/README.lto.md | 4 +- llvm_mode/README.md | 4 +- llvm_mode/README.whitelist.md | 79 --------- llvm_mode/TODO | 10 -- llvm_mode/afl-clang-fast.c | 17 +- llvm_mode/afl-llvm-common.cc | 47 ++--- llvm_mode/afl-llvm-common.h | 6 +- llvm_mode/afl-llvm-lto-instrim.so.cc | 7 +- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 7 +- llvm_mode/afl-llvm-lto-instrumentlist.so.cc | 253 +++++++++++++++++++++++++++ llvm_mode/afl-llvm-lto-whitelist.so.cc | 244 -------------------------- llvm_mode/afl-llvm-pass.so.cc | 4 +- llvm_mode/cmplog-instructions-pass.cc | 4 +- llvm_mode/cmplog-routines-pass.cc | 4 +- llvm_mode/compare-transform-pass.so.cc | 4 +- llvm_mode/split-compares-pass.so.cc | 4 +- llvm_mode/split-switches-pass.so.cc | 4 +- src/afl-common.c | 4 +- src/afl-fuzz-redqueen.c | 4 +- src/afl-fuzz.c | 6 +- test/test-performance.sh | 4 +- test/test.sh | 40 ++--- 37 files changed, 598 insertions(+), 575 deletions(-) create mode 100644 gcc_plugin/README.instrument_file.md delete mode 100644 gcc_plugin/README.whitelist.md create mode 100644 llvm_mode/README.instrument_file.md delete mode 100644 llvm_mode/README.whitelist.md delete mode 100644 llvm_mode/TODO create mode 100644 llvm_mode/afl-llvm-lto-instrumentlist.so.cc delete mode 100644 llvm_mode/afl-llvm-lto-whitelist.so.cc diff --git a/README.md b/README.md index 104f56ea..dd32e28e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ AFL++ Logo - ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=master) + ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) Release Version: [2.65c](https://github.com/AFLplusplus/AFLplusplus/releases) @@ -40,7 +40,7 @@ * InsTrim, a very effective CFG llvm_mode instrumentation implementation for large targets: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim) - * C. Holler's afl-fuzz Python mutator module and llvm_mode whitelist support: [https://github.com/choller/afl](https://github.com/choller/afl) + * C. Holler's afl-fuzz Python mutator module and llvm_mode instrument file support: [https://github.com/choller/afl](https://github.com/choller/afl) * Custom mutator by a library (instead of Python) by kyakdan @@ -70,7 +70,7 @@ | Persistent mode | | x | x | x86[_64]/arm[64] | x | | LAF-Intel / CompCov | | x | | x86[_64]/arm[64] | x86[_64]/arm | | CmpLog | | x | | x86[_64]/arm[64] | | - | Whitelist | | x | x | (x)(3) | | + | Instrument file list | | x | x | (x)(3) | | | Non-colliding coverage | | x(4) | | (x)(5) | | | InsTrim | | x | | | | | Ngram prev_loc coverage | | x(6) | | | | @@ -297,7 +297,7 @@ Using the LAF Intel performance enhancements are also recommended, see [llvm_mode/README.laf-intel.md](llvm_mode/README.laf-intel.md) Using partial instrumentation is also recommended, see -[llvm_mode/README.whitelist.md](llvm_mode/README.whitelist.md) +[llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md) When testing libraries, you need to find or write a simple program that reads data from stdin or from a file and passes it to the tested library. In such a diff --git a/docs/Changelog.md b/docs/Changelog.md index 1ecea274..6718ecde 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,10 @@ sending a mail to . ### Version ++2.65d (dev) + - renamed the main branch on Github to "stable" + - renamed master/slave to main/secondary + - renamed blacklist/whitelist to ignorelist/instrumentlist -> + AFL_LLVM_INSTRUMENT_FILE and AFL_GCC_INSTRUMENT_FILE - afl-fuzz: - -S secondary nodes now only sync from the main node to increase performance, the -M main node still syncs from everyone. Added checks @@ -40,8 +44,8 @@ sending a mail to . - WHITELIST feature now supports wildcards (thanks to sirmc) - small change to cmplog to make it work with current llvm 11-dev - added AFL_LLVM_LAF_ALL, sets all laf-intel settings - - LTO whitelist functionality rewritten, now main, _init etc functions - need not to be whitelisted anymore + - LTO instrument_files functionality rewritten, now main, _init etc functions + need not to be instrument_filesed anymore - fixed crash in compare-transform-pass when strcasecmp/strncasecmp was tried to be instrumented with LTO - fixed crash in cmplog with LTO @@ -249,7 +253,7 @@ sending a mail to . the original script is still present as afl-cmin.bash - afl-showmap: -i dir option now allows processing multiple inputs using the forkserver. This is for enhanced speed in afl-cmin. - - added blacklist and whitelisting function check in all modules of llvm_mode + - added blacklist and instrument_filesing function check in all modules of llvm_mode - added fix from Debian project to compile libdislocator and libtokencap - libdislocator: AFL_ALIGNED_ALLOC to force size alignment to max_align_t @@ -304,7 +308,7 @@ sending a mail to . performance loss of ~10% - added test/test-performance.sh script - (re)added gcc_plugin, fast inline instrumentation is not yet finished, - however it includes the whitelisting and persistance feature! by hexcoder- + however it includes the instrument_filesing and persistance feature! by hexcoder- - gcc_plugin tests added to testing framework @@ -392,7 +396,7 @@ sending a mail to . - more cpu power for afl-system-config - added forkserver patch to afl-tmin, makes it much faster (originally from github.com/nccgroup/TriforceAFL) - - added whitelist support for llvm_mode via AFL_LLVM_WHITELIST to allow + - added instrument_files support for llvm_mode via AFL_LLVM_WHITELIST to allow only to instrument what is actually interesting. Gives more speed and less map pollution (originally by choller@mozilla) - added Python Module mutator support, python2.7-dev is autodetected. diff --git a/docs/PATCHES.md b/docs/PATCHES.md index a6783523..b2cff43a 100644 --- a/docs/PATCHES.md +++ b/docs/PATCHES.md @@ -28,7 +28,7 @@ afl-qemu-optimize-map.diff by mh(at)mh-sec(dot)de + AFLfast additions (github.com/mboehme/aflfast) were incorporated. + Qemu 3.1 upgrade with enhancement patches (github.com/andreafioraldi/afl) + Python mutator modules support (github.com/choller/afl) -+ Whitelisting in LLVM mode (github.com/choller/afl) ++ Instrument file list in LLVM mode (github.com/choller/afl) + forkserver patch for afl-tmin (github.com/nccgroup/TriforceAFL) diff --git a/docs/env_variables.md b/docs/env_variables.md index 867e937e..87344331 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -204,14 +204,14 @@ Then there are a few specific features that are only available in llvm_mode: See llvm_mode/README.laf-intel.md for more information. -### WHITELIST +### INSTRUMENT_FILE This feature allows selectively instrumentation of the source - - Setting AFL_LLVM_WHITELIST with a filename will only instrument those + - Setting AFL_LLVM_INSTRUMENT_FILE with a filename will only instrument those files that match the names listed in this file. - See llvm_mode/README.whitelist.md for more information. + See llvm_mode/README.instrument_file.md for more information. ### NOT_ZERO @@ -236,14 +236,14 @@ Then there are a few specific features that are only available in llvm_mode: Then there are a few specific features that are only available in the gcc_plugin: -### WHITELIST +### INSTRUMENT_FILE This feature allows selective instrumentation of the source - - Setting AFL_GCC_WHITELIST with a filename will only instrument those + - Setting AFL_GCC_INSTRUMENT_FILE with a filename will only instrument those files that match the names listed in this file (one filename per line). - See gcc_plugin/README.whitelist.md for more information. + See gcc_plugin/README.instrument_file.md for more information. ## 3) Settings for afl-fuzz diff --git a/docs/perf_tips.md b/docs/perf_tips.md index fcd03db7..7a690b77 100644 --- a/docs/perf_tips.md +++ b/docs/perf_tips.md @@ -66,8 +66,8 @@ then using laf-intel (see llvm_mode/README.laf-intel.md) will help `afl-fuzz` a to get to the important parts in the code. If you are only interested in specific parts of the code being fuzzed, you can -whitelist the files that are actually relevant. This improves the speed and -accuracy of afl. See llvm_mode/README.whitelist.md +instrument_files the files that are actually relevant. This improves the speed and +accuracy of afl. See llvm_mode/README.instrument_file.md Also use the InsTrim mode on larger binaries, this improves performance and coverage a lot. diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile index 60f04bb7..bf5c53e0 100644 --- a/gcc_plugin/GNUmakefile +++ b/gcc_plugin/GNUmakefile @@ -156,7 +156,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 7eff326a..f720112f 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -152,7 +152,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/README.instrument_file.md b/gcc_plugin/README.instrument_file.md new file mode 100644 index 00000000..d0eaf6ff --- /dev/null +++ b/gcc_plugin/README.instrument_file.md @@ -0,0 +1,73 @@ +======================================== +Using afl++ with partial instrumentation +======================================== + + This file describes how you can selectively instrument only the source files + that are interesting to you using the gcc instrumentation provided by + afl++. + + Plugin by hexcoder-. + + +## 1) Description and purpose + +When building and testing complex programs where only a part of the program is +the fuzzing target, it often helps to only instrument the necessary parts of +the program, leaving the rest uninstrumented. This helps to focus the fuzzer +on the important parts of the program, avoiding undesired noise and +disturbance by uninteresting code being exercised. + +For this purpose, I have added a "partial instrumentation" support to the gcc +plugin of AFLFuzz that allows you to specify on a source file level which files +should be compiled with or without instrumentation. + + +## 2) Building the gcc plugin + +The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ +subdirectory. There is nothing specifically to do :) + + +## 3) How to use the partial instrumentation mode + +In order to build with partial instrumentation, you need to build with +afl-gcc-fast and afl-g++-fast respectively. The only required change is +that you need to set the environment variable AFL_GCC_INSTRUMENT_FILE when calling +the compiler. + +The environment variable must point to a file containing all the filenames +that should be instrumented. For matching, the filename that is being compiled +must end in the filename entry contained in this instrument list (to avoid breaking +the matching when absolute paths are used during compilation). + +For example if your source tree looks like this: + +``` +project/ +project/feature_a/a1.cpp +project/feature_a/a2.cpp +project/feature_b/b1.cpp +project/feature_b/b2.cpp +``` + +and you only want to test feature_a, then create a instrument list file containing: + +``` +feature_a/a1.cpp +feature_a/a2.cpp +``` + +However if the instrument list file contains only this, it works as well: + +``` +a1.cpp +a2.cpp +``` + +but it might lead to files being unwantedly instrumented if the same filename +exists somewhere else in the project directories. + +The created instrument list file is then set to AFL_GCC_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the instrument list, the compiler will +issue a warning at the end stating that no blocks were instrumented. If you +didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/README.whitelist.md b/gcc_plugin/README.whitelist.md deleted file mode 100644 index 8ad2068d..00000000 --- a/gcc_plugin/README.whitelist.md +++ /dev/null @@ -1,73 +0,0 @@ -======================================== -Using afl++ with partial instrumentation -======================================== - - This file describes how you can selectively instrument only the source files - that are interesting to you using the gcc instrumentation provided by - afl++. - - Plugin by hexcoder-. - - -## 1) Description and purpose - -When building and testing complex programs where only a part of the program is -the fuzzing target, it often helps to only instrument the necessary parts of -the program, leaving the rest uninstrumented. This helps to focus the fuzzer -on the important parts of the program, avoiding undesired noise and -disturbance by uninteresting code being exercised. - -For this purpose, I have added a "partial instrumentation" support to the gcc -plugin of AFLFuzz that allows you to specify on a source file level which files -should be compiled with or without instrumentation. - - -## 2) Building the gcc plugin - -The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ -subdirectory. There is nothing specifically to do :) - - -## 3) How to use the partial instrumentation mode - -In order to build with partial instrumentation, you need to build with -afl-gcc-fast and afl-g++-fast respectively. The only required change is -that you need to set the environment variable AFL_GCC_WHITELIST when calling -the compiler. - -The environment variable must point to a file containing all the filenames -that should be instrumented. For matching, the filename that is being compiled -must end in the filename entry contained in this whitelist (to avoid breaking -the matching when absolute paths are used during compilation). - -For example if your source tree looks like this: - -``` -project/ -project/feature_a/a1.cpp -project/feature_a/a2.cpp -project/feature_b/b1.cpp -project/feature_b/b2.cpp -``` - -and you only want to test feature_a, then create a whitelist file containing: - -``` -feature_a/a1.cpp -feature_a/a2.cpp -``` - -However if the whitelist file contains only this, it works as well: - -``` -a1.cpp -a2.cpp -``` - -but it might lead to files being unwantedly instrumented if the same filename -exists somewhere else in the project directories. - -The created whitelist file is then set to AFL_GCC_WHITELIST when you compile -your program. For each file that didn't match the whitelist, the compiler will -issue a warning at the end stating that no blocks were instrumented. If you -didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index bd780b40..af0beca7 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -306,47 +306,47 @@ int main(int argc, char **argv, char **envp) { if (argc < 2 || strcmp(argv[1], "-h") == 0) { - printf( - cCYA - "afl-gcc-fast" VERSION cRST - " initially by , maintainer: hexcoder-\n" - "\n" - "afl-gcc-fast [options]\n" - "\n" - "This is a helper application for afl-fuzz. It serves as a drop-in " - "replacement\n" - "for gcc, letting you recompile third-party code with the required " - "runtime\n" - "instrumentation. A common use pattern would be one of the " - "following:\n\n" - - " CC=%s/afl-gcc-fast ./configure\n" - " CXX=%s/afl-g++-fast ./configure\n\n" - - "In contrast to the traditional afl-gcc tool, this version is " - "implemented as\n" - "a GCC plugin and tends to offer improved performance with slow " - "programs\n" - "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" - - "Environment variables used:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_DEBUG: enable developer debugging output\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - "AFL_GCC_WHITELIST: enable whitelisting (selective instrumentation)\n" - - "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " - "\"%s\".\n\n", - BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); + printf(cCYA + "afl-gcc-fast" VERSION cRST + " initially by , maintainer: hexcoder-\n" + "\n" + "afl-gcc-fast [options]\n" + "\n" + "This is a helper application for afl-fuzz. It serves as a drop-in " + "replacement\n" + "for gcc, letting you recompile third-party code with the required " + "runtime\n" + "instrumentation. A common use pattern would be one of the " + "following:\n\n" + + " CC=%s/afl-gcc-fast ./configure\n" + " CXX=%s/afl-g++-fast ./configure\n\n" + + "In contrast to the traditional afl-gcc tool, this version is " + "implemented as\n" + "a GCC plugin and tends to offer improved performance with slow " + "programs\n" + "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" + + "Environment variables used:\n" + "AFL_CC: path to the C compiler to use\n" + "AFL_CXX: path to the C++ compiler to use\n" + "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_DEBUG: enable developer debugging output\n" + "AFL_HARDEN: adds code hardening to catch memory bugs\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + "AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " + "filename\n" + + "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " + "\"%s\".\n\n", + BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); exit(1); @@ -357,12 +357,15 @@ int main(int argc, char **argv, char **envp) { SAYF(cCYA "afl-gcc-fast" VERSION cRST " initially by , maintainer: hexcoder-\n"); - if (getenv("AFL_GCC_WHITELIST") == NULL) { + if (getenv("AFL_GCC_INSTRUMENT_FILE") == NULL && + getenv("AFL_GCC_WHITELIST") == NULL) { - SAYF(cYEL "Warning:" cRST - " using afl-gcc-fast without using AFL_GCC_WHITELIST currently " - "produces worse results than afl-gcc. Even better, use " - "llvm_mode for now.\n"); + SAYF( + cYEL + "Warning:" cRST + " using afl-gcc-fast without using AFL_GCC_INSTRUMENT_FILE currently " + "produces worse results than afl-gcc. Even better, use " + "llvm_mode for now.\n"); } diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc index 08f7d748..c5614aca 100644 --- a/gcc_plugin/afl-gcc-pass.so.cc +++ b/gcc_plugin/afl-gcc-pass.so.cc @@ -2,7 +2,7 @@ // There are some TODOs in this file: // - fix instrumentation via external call // - fix inline instrumentation -// - implement whitelist feature +// - implement instrument list feature // - dont instrument blocks that are uninteresting // - implement neverZero // @@ -95,7 +95,7 @@ static int be_quiet = 0; static unsigned int inst_ratio = 100; static bool inst_ext = true; -static std::list myWhitelist; +static std::list myInstrumentList; static unsigned int ext_call_instrument(function *fun) { @@ -414,7 +414,7 @@ class afl_pass : public gimple_opt_pass { unsigned int execute(function *fun) override { - if (!myWhitelist.empty()) { + if (!myInstrumentList.empty()) { bool instrumentBlock = false; std::string instFilename; @@ -436,8 +436,8 @@ class afl_pass : public gimple_opt_pass { /* Continue only if we know where we actually are */ if (!instFilename.empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -462,13 +462,14 @@ class afl_pass : public gimple_opt_pass { } /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. */ + * not in the instrument list, so we skip instrumentation. */ if (!instrumentBlock) { if (!be_quiet) { if (!instFilename.empty()) - SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n", + SAYF(cYEL "[!] " cBRI + "Not in instrument list, skipping %s line %u...\n", instFilename.c_str(), instLine); else SAYF(cYEL "[!] " cBRI "No filename information found, skipping it"); @@ -562,26 +563,32 @@ int plugin_init(struct plugin_name_args * plugin_info, } - char *instWhiteListFilename = getenv("AFL_GCC_WHITELIST"); - if (instWhiteListFilename) { + char *instInstrumentListFilename = getenv("AFL_GCC_INSTRUMENT_FILE"); + if (!instInstrumentListFilename) + instInstrumentListFilename = getenv("AFL_GCC_WHITELIST"); + if (instInstrumentListFilename) { std::string line; std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) PFATAL("Unable to open AFL_GCC_WHITELIST"); + fileStream.open(instInstrumentListFilename); + if (!fileStream) PFATAL("Unable to open AFL_GCC_INSTRUMENT_FILE"); getline(fileStream, line); while (fileStream) { - myWhitelist.push_back(line); + myInstrumentList.push_back(line); getline(fileStream, line); } - } else if (!be_quiet && getenv("AFL_LLVM_WHITELIST")) + } else if (!be_quiet && (getenv("AFL_LLVM_WHITELIST") || + + getenv("AFL_LLVM_INSTRUMENT_FILE"))) { SAYF(cYEL "[-] " cRST - "AFL_LLVM_WHITELIST environment variable detected - did you mean " - "AFL_GCC_WHITELIST?\n"); + "AFL_LLVM_INSTRUMENT_FILE environment variable detected - did " + "you mean AFL_GCC_INSTRUMENT_FILE?\n"); + + } /* Go go gadget */ register_callback(plugin_info->base_name, PLUGIN_INFO, NULL, diff --git a/include/config.h b/include/config.h index 087e0a76..5ee93389 100644 --- a/include/config.h +++ b/include/config.h @@ -234,7 +234,7 @@ /* Sync interval (every n havoc cycles): */ -#define SYNC_INTERVAL 5 +#define SYNC_INTERVAL 8 /* Output directory reuse grace period (minutes): */ diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile index 4cc55d92..b5d026ef 100644 --- a/llvm_mode/GNUmakefile +++ b/llvm_mode/GNUmakefile @@ -253,7 +253,7 @@ ifeq "$(TEST_MMAP)" "1" LDFLAGS += -Wno-deprecated-declarations endif - PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../afl-ld-lto ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so + PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../afl-ld-lto ../afl-llvm-lto-instrumentlist.so ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so # If prerequisites are not given, warn, do not build anything, and exit with code 0 ifeq "$(LLVMVER)" "" @@ -332,7 +332,7 @@ ifeq "$(LLVM_MIN_4_0_1)" "0" endif $(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o -../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o +../afl-llvm-lto-instrumentlist.so: afl-llvm-lto-instrumentlist.so.cc afl-llvm-common.o ifeq "$(LLVM_LTO)" "1" $(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o endif @@ -403,7 +403,7 @@ all_done: test_build install: all install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../afl-clang-lto ]; then set -e; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../afl-llvm-rt-lto*.o ../afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../afl-clang-lto ]; then set -e; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ../afl-llvm-lto-instrumentation.so ../afl-llvm-lto-instrim.so ../afl-llvm-rt-lto*.o ../afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi if [ -f ../afl-ld-lto ]; then set -e; install -m 755 ../afl-ld-lto $${DESTDIR}$(BIN_PATH); fi if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index 991127a7..75548266 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -74,7 +74,7 @@ struct InsTrim : public ModulePass { InsTrim() : ModulePass(ID), generator(0) { - initWhitelist(); + initInstrumentList(); } @@ -271,7 +271,7 @@ struct InsTrim : public ModulePass { } - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; // if the function below our minimum size skip it (1 or 2) if (F.size() < function_minimum_size) { continue; } diff --git a/llvm_mode/README.instrument_file.md b/llvm_mode/README.instrument_file.md new file mode 100644 index 00000000..347bd3c6 --- /dev/null +++ b/llvm_mode/README.instrument_file.md @@ -0,0 +1,79 @@ +# Using afl++ with partial instrumentation + + This file describes how you can selectively instrument only the source files + that are interesting to you using the LLVM instrumentation provided by + afl++ + + Originally developed by Christian Holler (:decoder) . + +## 1) Description and purpose + +When building and testing complex programs where only a part of the program is +the fuzzing target, it often helps to only instrument the necessary parts of +the program, leaving the rest uninstrumented. This helps to focus the fuzzer +on the important parts of the program, avoiding undesired noise and +disturbance by uninteresting code being exercised. + +For this purpose, I have added a "partial instrumentation" support to the LLVM +mode of AFLFuzz that allows you to specify on a source file level which files +should be compiled with or without instrumentation. + + +## 2) Building the LLVM module + +The new code is part of the existing afl++ LLVM module in the llvm_mode/ +subdirectory. There is nothing specifically to do :) + + +## 3) How to use the partial instrumentation mode + +In order to build with partial instrumentation, you need to build with +afl-clang-fast and afl-clang-fast++ respectively. The only required change is +that you need to set the environment variable AFL_LLVM_INSTRUMENT_FILE when calling +the compiler. + +The environment variable must point to a file containing all the filenames +that should be instrumented. For matching, the filename that is being compiled +must end in the filename entry contained in this the instrument file list (to avoid breaking +the matching when absolute paths are used during compilation). + +For example if your source tree looks like this: + +``` +project/ +project/feature_a/a1.cpp +project/feature_a/a2.cpp +project/feature_b/b1.cpp +project/feature_b/b2.cpp +``` + +and you only want to test feature_a, then create a the instrument file list file containing: + +``` +feature_a/a1.cpp +feature_a/a2.cpp +``` + +However if the the instrument file list file contains only this, it works as well: + +``` +a1.cpp +a2.cpp +``` + +but it might lead to files being unwantedly instrumented if the same filename +exists somewhere else in the project directories. + +The created the instrument file list file is then set to AFL_LLVM_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the the instrument file list, the compiler will +issue a warning at the end stating that no blocks were instrumented. If you +didn't intend to instrument that file, then you can safely ignore that warning. + +For old LLVM versions this feature might require to be compiled with debug +information (-g), however at least from llvm version 6.0 onwards this is not +required anymore (and might hurt performance and crash detection, so better not +use -g). + +## 4) UNIX-style filename pattern matching +You can add UNIX-style pattern matching in the the instrument file list entries. See `man +fnmatch` for the syntax. We do not set any of the `fnmatch` flags. diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md index 517cb62a..4641fa89 100644 --- a/llvm_mode/README.lto.md +++ b/llvm_mode/README.lto.md @@ -7,7 +7,7 @@ This version requires a current llvm 11 compiled from the github master. 1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better coverage than anything else that is out there in the AFL world -2. You can use it together with llvm_mode: laf-intel and whitelisting +2. You can use it together with llvm_mode: laf-intel and the instrument file listing features and can be combined with cmplog/Redqueen 3. It only works with llvm 11 (current github master state) @@ -108,7 +108,7 @@ make install Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc. -Also whitelisting (AFL_LLVM_WHITELIST -> [README.whitelist.md](README.whitelist.md)) and +Also the instrument file listing (AFL_LLVM_INSTRUMENT_FILE -> [README.instrument_file.md](README.instrument_file.md)) and laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work. InsTrim (control flow graph instrumentation) is supported and recommended! (set `AFL_LLVM_INSTRUMENT=CFG`) diff --git a/llvm_mode/README.md b/llvm_mode/README.md index c24aef49..e2e22751 100644 --- a/llvm_mode/README.md +++ b/llvm_mode/README.md @@ -108,8 +108,8 @@ directory. Several options are present to make llvm_mode faster or help it rearrange the code to make afl-fuzz path discovery easier. -If you need just to instrument specific parts of the code, you can whitelist -which C/C++ files to actually instrument. See [README.whitelist](README.whitelist.md) +If you need just to instrument specific parts of the code, you can the instrument file list +which C/C++ files to actually instrument. See [README.instrument_file](README.instrument_file.md) For splitting memcmp, strncmp, etc. please see [README.laf-intel](README.laf-intel.md) diff --git a/llvm_mode/README.whitelist.md b/llvm_mode/README.whitelist.md deleted file mode 100644 index 6393fae8..00000000 --- a/llvm_mode/README.whitelist.md +++ /dev/null @@ -1,79 +0,0 @@ -# Using afl++ with partial instrumentation - - This file describes how you can selectively instrument only the source files - that are interesting to you using the LLVM instrumentation provided by - afl++ - - Originally developed by Christian Holler (:decoder) . - -## 1) Description and purpose - -When building and testing complex programs where only a part of the program is -the fuzzing target, it often helps to only instrument the necessary parts of -the program, leaving the rest uninstrumented. This helps to focus the fuzzer -on the important parts of the program, avoiding undesired noise and -disturbance by uninteresting code being exercised. - -For this purpose, I have added a "partial instrumentation" support to the LLVM -mode of AFLFuzz that allows you to specify on a source file level which files -should be compiled with or without instrumentation. - - -## 2) Building the LLVM module - -The new code is part of the existing afl++ LLVM module in the llvm_mode/ -subdirectory. There is nothing specifically to do :) - - -## 3) How to use the partial instrumentation mode - -In order to build with partial instrumentation, you need to build with -afl-clang-fast and afl-clang-fast++ respectively. The only required change is -that you need to set the environment variable AFL_LLVM_WHITELIST when calling -the compiler. - -The environment variable must point to a file containing all the filenames -that should be instrumented. For matching, the filename that is being compiled -must end in the filename entry contained in this whitelist (to avoid breaking -the matching when absolute paths are used during compilation). - -For example if your source tree looks like this: - -``` -project/ -project/feature_a/a1.cpp -project/feature_a/a2.cpp -project/feature_b/b1.cpp -project/feature_b/b2.cpp -``` - -and you only want to test feature_a, then create a whitelist file containing: - -``` -feature_a/a1.cpp -feature_a/a2.cpp -``` - -However if the whitelist file contains only this, it works as well: - -``` -a1.cpp -a2.cpp -``` - -but it might lead to files being unwantedly instrumented if the same filename -exists somewhere else in the project directories. - -The created whitelist file is then set to AFL_LLVM_WHITELIST when you compile -your program. For each file that didn't match the whitelist, the compiler will -issue a warning at the end stating that no blocks were instrumented. If you -didn't intend to instrument that file, then you can safely ignore that warning. - -For old LLVM versions this feature might require to be compiled with debug -information (-g), however at least from llvm version 6.0 onwards this is not -required anymore (and might hurt performance and crash detection, so better not -use -g). - -## 4) UNIX-style filename pattern matching -You can add UNIX-style pattern matching in the whitelist entries. See `man -fnmatch` for the syntax. We do not set any of the `fnmatch` flags. diff --git a/llvm_mode/TODO b/llvm_mode/TODO deleted file mode 100644 index 2729d688..00000000 --- a/llvm_mode/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO for afl-ld: -* handle libfoo.a object archives - -TODO for afl-llvm-lto-instrumentation: -* better algo for putting stuff in the map? -* try to predict how long the instrumentation process will take - -TODO for afl-llvm-lto-whitelist -* different solution then renaming? - diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 3b0225c2..f1b03682 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -227,13 +227,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode) { - if (getenv("AFL_LLVM_WHITELIST") != NULL) { + if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST")) { cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-lto-whitelist.so", obj_path); + alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); } @@ -762,7 +763,7 @@ int main(int argc, char **argv, char **envp) { #if LLVM_VERSION_MAJOR <= 6 instrument_mode = INSTRUMENT_AFL; #else - if (getenv("AFL_LLVM_WHITELIST")) + if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) instrument_mode = INSTRUMENT_AFL; else instrument_mode = INSTRUMENT_PCGUARD; @@ -810,8 +811,11 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " "together"); - if (instrument_mode == INSTRUMENT_PCGUARD && getenv("AFL_LLVM_WHITELIST")) - WARNF("Instrumentation type PCGUARD does not support AFL_LLVM_WHITELIST!"); + if (instrument_mode == INSTRUMENT_PCGUARD && + (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST"))) + WARNF( + "Instrumentation type PCGUARD does not support " + "AFL_LLVM_INSTRUMENT_FILE!"); if (argc < 2 || strcmp(argv[1], "-h") == 0) { @@ -861,7 +865,8 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " "function calls\n" "AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" - "AFL_LLVM_WHITELIST: enable whitelisting (selective " + "AFL_LLVM_INSTRUMENT_FILE: enable the instrument file listing " + "(selective " "instrumentation)\n" "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" "AFL_PATH: path to instrumenting pass and runtime " diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc index 6c7222cd..47b49358 100644 --- a/llvm_mode/afl-llvm-common.cc +++ b/llvm_mode/afl-llvm-common.cc @@ -18,7 +18,7 @@ using namespace llvm; -static std::list myWhitelist; +static std::list myInstrumentList; char *getBBName(const llvm::BasicBlock *BB) { @@ -44,13 +44,13 @@ char *getBBName(const llvm::BasicBlock *BB) { } /* Function that we never instrument or analyze */ -/* Note: this blacklist check is also called in isInWhitelist() */ -bool isBlacklisted(const llvm::Function *F) { +/* Note: this ignore check is also called in isInInstrumentList() */ +bool isIgnoreFunction(const llvm::Function *F) { // Starting from "LLVMFuzzer" these are functions used in libfuzzer based // fuzzing campaign installations, e.g. oss-fuzz - static const char *Blacklist[] = { + static const char *ignoreList[] = { "asan.", "llvm.", @@ -73,9 +73,9 @@ bool isBlacklisted(const llvm::Function *F) { }; - for (auto const &BlacklistFunc : Blacklist) { + for (auto const &ignoreListFunc : ignoreList) { - if (F->getName().startswith(BlacklistFunc)) { return true; } + if (F->getName().startswith(ignoreListFunc)) { return true; } } @@ -83,19 +83,22 @@ bool isBlacklisted(const llvm::Function *F) { } -void initWhitelist() { +void initInstrumentList() { - char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); - if (instWhiteListFilename) { + char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE"); + if (!instrumentListFilename) + instrumentListFilename = getenv("AFL_LLVM_WHITELIST"); + if (instrumentListFilename) { std::string line; std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); + fileStream.open(instrumentListFilename); + if (!fileStream) + report_fatal_error("Unable to open AFL_LLVM_INSTRUMENT_FILE"); getline(fileStream, line); while (fileStream) { - myWhitelist.push_back(line); + myInstrumentList.push_back(line); getline(fileStream, line); } @@ -104,14 +107,14 @@ void initWhitelist() { } -bool isInWhitelist(llvm::Function *F) { +bool isInInstrumentList(llvm::Function *F) { // is this a function with code? If it is external we dont instrument it - // anyway and cant be in the whitelist. Or if it is blacklisted. - if (!F->size() || isBlacklisted(F)) return false; + // anyway and cant be in the the instrument file list. Or if it is ignored. + if (!F->size() || isIgnoreFunction(F)) return false; - // if we do not have a whitelist return true - if (myWhitelist.empty()) return true; + // if we do not have a the instrument file list return true + if (myInstrumentList.empty()) return true; // let's try to get the filename for the function auto bb = &F->getEntryBlock(); @@ -147,8 +150,8 @@ bool isInWhitelist(llvm::Function *F) { /* Continue only if we know where we actually are */ if (!instFilename.str().empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -185,8 +188,8 @@ bool isInWhitelist(llvm::Function *F) { /* Continue only if we know where we actually are */ if (!instFilename.str().empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -215,7 +218,7 @@ bool isInWhitelist(llvm::Function *F) { else { // we could not find out the location. in this case we say it is not - // in the whitelist + // in the the instrument file list return false; diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h index 50ad3abc..38e0c830 100644 --- a/llvm_mode/afl-llvm-common.h +++ b/llvm_mode/afl-llvm-common.h @@ -33,9 +33,9 @@ typedef long double max_align_t; #endif char * getBBName(const llvm::BasicBlock *BB); -bool isBlacklisted(const llvm::Function *F); -void initWhitelist(); -bool isInWhitelist(llvm::Function *F); +bool isIgnoreFunction(const llvm::Function *F); +void initInstrumentList(); +bool isInInstrumentList(llvm::Function *F); unsigned long long int calculateCollisions(uint32_t edges); #endif diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc index 4b89c9d0..ca2b5886 100644 --- a/llvm_mode/afl-llvm-lto-instrim.so.cc +++ b/llvm_mode/afl-llvm-lto-instrim.so.cc @@ -562,16 +562,17 @@ struct InsTrimLTO : public ModulePass { // if the function below our minimum size skip it (1 or 2) if (F.size() < function_minimum_size) continue; - if (isBlacklisted(&F)) continue; + if (isIgnoreFunction(&F)) continue; functions++; - // whitelist check + // the instrument file list check AttributeList Attrs = F.getAttributes(); if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { if (debug) - fprintf(stderr, "DEBUG: Function %s is not whitelisted\n", + fprintf(stderr, + "DEBUG: Function %s is not the instrument file listed\n", F.getName().str().c_str()); continue; diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 0d3015d7..af2db3ff 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -196,14 +196,15 @@ bool AFLLTOPass::runOnModule(Module &M) { // fprintf(stderr, "DEBUG: Function %s\n", F.getName().str().c_str()); if (F.size() < function_minimum_size) continue; - if (isBlacklisted(&F)) continue; + if (isIgnoreFunction(&F)) continue; - // whitelist check + // the instrument file list check AttributeList Attrs = F.getAttributes(); if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { if (debug) - fprintf(stderr, "DEBUG: Function %s is not whitelisted\n", + fprintf(stderr, + "DEBUG: Function %s is not the instrument file listed\n", F.getName().str().c_str()); continue; diff --git a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc new file mode 100644 index 00000000..6e6199e9 --- /dev/null +++ b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc @@ -0,0 +1,253 @@ +/* + american fuzzy lop++ - LLVM-mode instrumentation pass + --------------------------------------------------- + + Written by Laszlo Szekeres and + Michal Zalewski + + LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted + from afl-as.c are Michal's fault. + + Copyright 2015, 2016 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This library is plugged into LLVM when invoking clang through afl-clang-fast. + It tells the compiler to add code roughly equivalent to the bits discussed + in ../afl-as.h. + + */ + +#define AFL_LLVM_PASS + +#include "config.h" +#include "debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/IR/CFG.h" + +#include "afl-llvm-common.h" + +using namespace llvm; + +namespace { + +class AFLcheckIfInstrument : public ModulePass { + + public: + static char ID; + AFLcheckIfInstrument() : ModulePass(ID) { + + int entries = 0; + + if (getenv("AFL_DEBUG")) debug = 1; + + char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE"); + if (!instrumentListFilename) + instrumentListFilename = getenv("AFL_LLVM_WHITELIST"); + if (instrumentListFilename) { + + std::string line; + std::ifstream fileStream; + fileStream.open(instrumentListFilename); + if (!fileStream) + report_fatal_error("Unable to open AFL_LLVM_INSTRUMENT_FILE"); + getline(fileStream, line); + while (fileStream) { + + myInstrumentList.push_back(line); + getline(fileStream, line); + entries++; + + } + + } else + + PFATAL( + "afl-llvm-lto-instrumentlist.so loaded without " + "AFL_LLVM_INSTRUMENT_FILE?!"); + + if (debug) + SAYF(cMGN "[D] " cRST + "loaded the instrument file list %s with %d entries\n", + instrumentListFilename, entries); + + } + + bool runOnModule(Module &M) override; + + // StringRef getPassName() const override { + + // return "American Fuzzy Lop Instrumentation"; + // } + + protected: + std::list myInstrumentList; + int debug = 0; + +}; + +} // namespace + +char AFLcheckIfInstrument::ID = 0; + +bool AFLcheckIfInstrument::runOnModule(Module &M) { + + /* Show a banner */ + + char be_quiet = 0; + setvbuf(stdout, NULL, _IONBF, 0); + + if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { + + SAYF(cCYA "afl-llvm-lto-instrumentlist" VERSION cRST + " by Marc \"vanHauser\" Heuse \n"); + + } else if (getenv("AFL_QUIET")) + + be_quiet = 1; + + for (auto &F : M) { + + if (F.size() < 1) continue; + // fprintf(stderr, "F:%s\n", F.getName().str().c_str()); + if (isIgnoreFunction(&F)) continue; + + BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); + + if (!myInstrumentList.empty()) { + + bool instrumentFunction = false; + + /* Get the current location using debug information. + * For now, just instrument the block if we are not able + * to determine our location. */ + DebugLoc Loc = IP->getDebugLoc(); + if (Loc) { + + DILocation *cDILoc = dyn_cast(Loc.getAsMDNode()); + + unsigned int instLine = cDILoc->getLine(); + StringRef instFilename = cDILoc->getFilename(); + + if (instFilename.str().empty()) { + + /* If the original location is empty, try using the inlined location + */ + DILocation *oDILoc = cDILoc->getInlinedAt(); + if (oDILoc) { + + instFilename = oDILoc->getFilename(); + instLine = oDILoc->getLine(); + + } + + } + + (void)instLine; + + if (debug) + SAYF(cMGN "[D] " cRST "function %s is in file %s\n", + F.getName().str().c_str(), instFilename.str().c_str()); + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) == + 0) { + + instrumentFunction = true; + break; + + } + + } + + } + + } + + } + + /* Either we couldn't figure out our location or the location is + * not the instrument file listed, so we skip instrumentation. + * We do this by renaming the function. */ + if (instrumentFunction == true) { + + if (debug) + SAYF(cMGN "[D] " cRST "function %s is in the instrument file list\n", + F.getName().str().c_str()); + + } else { + + if (debug) + SAYF(cMGN "[D] " cRST + "function %s is NOT in the instrument file list\n", + F.getName().str().c_str()); + + auto & Ctx = F.getContext(); + AttributeList Attrs = F.getAttributes(); + AttrBuilder NewAttrs; + NewAttrs.addAttribute("skipinstrument"); + F.setAttributes( + Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); + + } + + } else { + + PFATAL("InstrumentList is empty"); + + } + + } + + return true; + +} + +static void registerAFLcheckIfInstrumentpass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { + + PM.add(new AFLcheckIfInstrument()); + +} + +static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass( + PassManagerBuilder::EP_ModuleOptimizerEarly, + registerAFLcheckIfInstrumentpass); + +static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass0( + PassManagerBuilder::EP_EnabledOnOptLevel0, + registerAFLcheckIfInstrumentpass); + diff --git a/llvm_mode/afl-llvm-lto-whitelist.so.cc b/llvm_mode/afl-llvm-lto-whitelist.so.cc deleted file mode 100644 index b1f791f4..00000000 --- a/llvm_mode/afl-llvm-lto-whitelist.so.cc +++ /dev/null @@ -1,244 +0,0 @@ -/* - american fuzzy lop++ - LLVM-mode instrumentation pass - --------------------------------------------------- - - Written by Laszlo Szekeres and - Michal Zalewski - - LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted - from afl-as.c are Michal's fault. - - Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This library is plugged into LLVM when invoking clang through afl-clang-fast. - It tells the compiler to add code roughly equivalent to the bits discussed - in ../afl-as.h. - - */ - -#define AFL_LLVM_PASS - -#include "config.h" -#include "debug.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/Debug.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/IR/CFG.h" - -#include "afl-llvm-common.h" - -using namespace llvm; - -namespace { - -class AFLwhitelist : public ModulePass { - - public: - static char ID; - AFLwhitelist() : ModulePass(ID) { - - int entries = 0; - - if (getenv("AFL_DEBUG")) debug = 1; - - char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); - if (instWhiteListFilename) { - - std::string line; - std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); - getline(fileStream, line); - while (fileStream) { - - myWhitelist.push_back(line); - getline(fileStream, line); - entries++; - - } - - } else - - PFATAL("afl-llvm-lto-whitelist.so loaded without AFL_LLVM_WHITELIST?!"); - - if (debug) - SAYF(cMGN "[D] " cRST "loaded whitelist %s with %d entries\n", - instWhiteListFilename, entries); - - } - - bool runOnModule(Module &M) override; - - // StringRef getPassName() const override { - - // return "American Fuzzy Lop Instrumentation"; - // } - - protected: - std::list myWhitelist; - int debug = 0; - -}; - -} // namespace - -char AFLwhitelist::ID = 0; - -bool AFLwhitelist::runOnModule(Module &M) { - - /* Show a banner */ - - char be_quiet = 0; - setvbuf(stdout, NULL, _IONBF, 0); - - if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { - - SAYF(cCYA "afl-llvm-lto-whitelist" VERSION cRST - " by Marc \"vanHauser\" Heuse \n"); - - } else if (getenv("AFL_QUIET")) - - be_quiet = 1; - - for (auto &F : M) { - - if (F.size() < 1) continue; - // fprintf(stderr, "F:%s\n", F.getName().str().c_str()); - if (isBlacklisted(&F)) continue; - - BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt(); - IRBuilder<> IRB(&(*IP)); - - if (!myWhitelist.empty()) { - - bool instrumentFunction = false; - - /* Get the current location using debug information. - * For now, just instrument the block if we are not able - * to determine our location. */ - DebugLoc Loc = IP->getDebugLoc(); - if (Loc) { - - DILocation *cDILoc = dyn_cast(Loc.getAsMDNode()); - - unsigned int instLine = cDILoc->getLine(); - StringRef instFilename = cDILoc->getFilename(); - - if (instFilename.str().empty()) { - - /* If the original location is empty, try using the inlined location - */ - DILocation *oDILoc = cDILoc->getInlinedAt(); - if (oDILoc) { - - instFilename = oDILoc->getFilename(); - instLine = oDILoc->getLine(); - - } - - } - - (void)instLine; - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is in file %s\n", - F.getName().str().c_str(), instFilename.str().c_str()); - /* Continue only if we know where we actually are */ - if (!instFilename.str().empty()) { - - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { - - /* We don't check for filename equality here because - * filenames might actually be full paths. Instead we - * check that the actual filename ends in the filename - * specified in the list. */ - if (instFilename.str().length() >= it->length()) { - - if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) == - 0) { - - instrumentFunction = true; - break; - - } - - } - - } - - } - - } - - /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. - * We do this by renaming the function. */ - if (instrumentFunction == true) { - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is in whitelist\n", - F.getName().str().c_str()); - - } else { - - if (debug) - SAYF(cMGN "[D] " cRST "function %s is NOT in whitelist\n", - F.getName().str().c_str()); - - auto & Ctx = F.getContext(); - AttributeList Attrs = F.getAttributes(); - AttrBuilder NewAttrs; - NewAttrs.addAttribute("skipinstrument"); - F.setAttributes( - Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); - - } - - } else { - - PFATAL("Whitelist is empty"); - - } - - } - - return true; - -} - -static void registerAFLwhitelistpass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { - - PM.add(new AFLwhitelist()); - -} - -static RegisterStandardPasses RegisterAFLwhitelistpass( - PassManagerBuilder::EP_ModuleOptimizerEarly, registerAFLwhitelistpass); - -static RegisterStandardPasses RegisterAFLwhitelistpass0( - PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLwhitelistpass); - diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 7997df51..90cf3eb4 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -74,7 +74,7 @@ class AFLCoverage : public ModulePass { static char ID; AFLCoverage() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -307,7 +307,7 @@ bool AFLCoverage::runOnModule(Module &M) { fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(), F.size()); - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; if (F.size() < function_minimum_size) continue; diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc index c5a6ff8b..f929361a 100644 --- a/llvm_mode/cmplog-instructions-pass.cc +++ b/llvm_mode/cmplog-instructions-pass.cc @@ -59,7 +59,7 @@ class CmpLogInstructions : public ModulePass { static char ID; CmpLogInstructions() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -170,7 +170,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { /* iterate over all functions, bbs and instruction and add suitable calls */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/cmplog-routines-pass.cc b/llvm_mode/cmplog-routines-pass.cc index 792a45b9..318193a4 100644 --- a/llvm_mode/cmplog-routines-pass.cc +++ b/llvm_mode/cmplog-routines-pass.cc @@ -59,7 +59,7 @@ class CmpLogRoutines : public ModulePass { static char ID; CmpLogRoutines() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -118,7 +118,7 @@ bool CmpLogRoutines::hookRtns(Module &M) { /* iterate over all functions, bbs and instruction and add suitable calls */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 96abeebb..2d1ab1cc 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -58,7 +58,7 @@ class CompareTransform : public ModulePass { static char ID; CompareTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -124,7 +124,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, * strcmp/memcmp/strncmp/strcasecmp/strncasecmp */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 2c4ed71c..651fa5b4 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -55,7 +55,7 @@ class SplitComparesTransform : public ModulePass { static char ID; SplitComparesTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -102,7 +102,7 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { * all integer comparisons with >= and <= predicates to the icomps vector */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc index 4a6ca3d9..44075c94 100644 --- a/llvm_mode/split-switches-pass.so.cc +++ b/llvm_mode/split-switches-pass.so.cc @@ -60,7 +60,7 @@ class SplitSwitchesTransform : public ModulePass { static char ID; SplitSwitchesTransform() : ModulePass(ID) { - initWhitelist(); + initInstrumentList(); } @@ -312,7 +312,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { * all switches to switches vector for later processing */ for (auto &F : M) { - if (!isInWhitelist(&F)) continue; + if (!isInInstrumentList(&F)) continue; for (auto &BB : F) { diff --git a/src/afl-common.c b/src/afl-common.c index 79d419cd..8995b57e 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -58,7 +58,7 @@ char *afl_environment_variables[] = { //"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally "AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI", - "AFL_GCC_WHITELIST", "AFL_GCJ", "AFL_HANG_TMOUT", "AFL_HARDEN", + "AFL_GCC_INSTRUMENT_FILE", "AFL_GCJ", "AFL_HANG_TMOUT", "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IMPORT_FIRST", "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", @@ -71,7 +71,7 @@ char *afl_environment_variables[] = { "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_ALL", "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR", "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", - "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_LLVM_SKIP_NEVERZERO", + "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 43850eb5..44953a52 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -435,7 +435,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u32 fails; u8 found_one = 0; - /* loop cmps are useless, detect and blacklist them */ + /* loop cmps are useless, detect and ignores them */ u64 s_v0, s_v1; u8 s_v0_fixed = 1, s_v1_fixed = 1; u8 s_v0_inc = 1, s_v1_inc = 1; @@ -743,7 +743,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, afl->pass_stats[k].faileds || afl->pass_stats[k].total == 0xff)) { - afl->shm.cmp_map->headers[k].hits = 0; // blacklist this cmp + afl->shm.cmp_map->headers[k].hits = 0; // ignores this cmp } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f25f8bb6..e4e2669c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -790,8 +790,8 @@ int main(int argc, char **argv_orig, char **envp) { OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator and llvm_mode whitelisting from github.com/choller/afl"); - OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); + OKF("Python Mutator and llvm_mode instrument file list from " + "github.com/choller/afl"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && @@ -1280,7 +1280,7 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->is_main_node)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); } + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } } else { diff --git a/test/test-performance.sh b/test/test-performance.sh index 87eea665..cee46060 100755 --- a/test/test-performance.sh +++ b/test/test-performance.sh @@ -21,8 +21,8 @@ unset AFL_USE_ASAN unset AFL_USE_MSAN unset AFL_CC unset AFL_PRELOAD -unset AFL_GCC_WHITELIST -unset AFL_LLVM_WHITELIST +unset AFL_GCC_INSTRUMENT_FILE +unset AFL_LLVM_INSTRUMENT_FILE unset AFL_LLVM_INSTRIM unset AFL_LLVM_LAF_SPLIT_SWITCHES unset AFL_LLVM_LAF_TRANSFORM_COMPARES diff --git a/test/test.sh b/test/test.sh index a7d9fc49..90920215 100755 --- a/test/test.sh +++ b/test/test.sh @@ -62,8 +62,8 @@ unset AFL_USE_UBSAN unset AFL_TMPDIR unset AFL_CC unset AFL_PRELOAD -unset AFL_GCC_WHITELIST -unset AFL_LLVM_WHITELIST +unset AFL_GCC_INSTRUMENT_FILE +unset AFL_LLVM_INSTRUMENT_FILE unset AFL_LLVM_INSTRIM unset AFL_LLVM_LAF_SPLIT_SWITCHES unset AFL_LLVM_LAF_TRANSFORM_COMPARES @@ -386,20 +386,20 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } rm -f test-compcov.compcov test.out - echo foobar.c > whitelist.txt - AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 + echo foobar.c > instrumentlist.txt + AFL_DEBUG=1 AFL_LLVM_INSTRUMENT_FILE=instrumentlist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && test_compcov_binary_functionality ./test-compcov && { grep -q "No instrumentation targets found" test.out && { - $ECHO "$GREEN[+] llvm_mode whitelist feature works correctly" + $ECHO "$GREEN[+] llvm_mode instrumentlist feature works correctly" } || { - $ECHO "$RED[!] llvm_mode whitelist feature failed" + $ECHO "$RED[!] llvm_mode instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] llvm_mode whitelist feature compilation failed" + $ECHO "$RED[!] llvm_mode instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { @@ -459,20 +459,20 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && { } rm -f test-instr.plain - echo foobar.c > whitelist.txt - AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 + echo foobar.c > instrumentlist.txt + AFL_DEBUG=1 AFL_LLVM_INSTRUMENT_FILE=instrumentlist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && { grep -q "No instrumentation targets found" test.out && { - $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly" + $ECHO "$GREEN[+] llvm_mode LTO instrumentlist feature works correctly" } || { - $ECHO "$RED[!] llvm_mode LTO whitelist feature failed" + $ECHO "$RED[!] llvm_mode LTO instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed" + $ECHO "$RED[!] llvm_mode LTO instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m none -o /dev/null -q -r ./test-persistent && { @@ -569,20 +569,20 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { rm -f test-instr.plain.gccpi # now for the special gcc_plugin things - echo foobar.c > whitelist.txt - AFL_GCC_WHITELIST=whitelist.txt ../afl-gcc-fast -o test-compcov test-compcov.c > /dev/null 2>&1 + echo foobar.c > instrumentlist.txt + AFL_GCC_INSTRUMENT_FILE=instrumentlist.txt ../afl-gcc-fast -o test-compcov test-compcov.c > /dev/null 2>&1 test -e test-compcov && test_compcov_binary_functionality ./test-compcov && { echo 1 | ../afl-showmap -m ${MEM_LIMIT} -o - -r -- ./test-compcov 2>&1 | grep -q "Captured 1 tuples" && { - $ECHO "$GREEN[+] gcc_plugin whitelist feature works correctly" + $ECHO "$GREEN[+] gcc_plugin instrumentlist feature works correctly" } || { - $ECHO "$RED[!] gcc_plugin whitelist feature failed" + $ECHO "$RED[!] gcc_plugin instrumentlist feature failed" CODE=1 } } || { - $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" + $ECHO "$RED[!] gcc_plugin instrumentlist feature compilation failed" CODE=1 } - rm -f test-compcov test.out whitelist.txt + rm -f test-compcov test.out instrumentlist.txt ../afl-gcc-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { -- cgit 1.4.1 From be83f06b2f3e575716974c4bd4b0d79a68ab6441 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:25:33 +0200 Subject: renaming remains fixed --- docs/Changelog.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 6718ecde..eede6751 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -34,18 +34,18 @@ sending a mail to . - the default instrumentation is now PCGUARD if the llvm version is >= 7, as it is faster and provides better coverage. The original afl instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is - automatically done when the WHITELIST feature is used. + automatically done when the instrument_file list feature is used. - PCGUARD mode is now even better because we made it collision free - plus it has a fixed map size, so it is also faster! :) - some targets want a ld variant for LD that is not gcc/clang but ld, added afl-ld-lto to solve this - lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which needs 3.8.0) - - WHITELIST feature now supports wildcards (thanks to sirmc) + - instrument_file list feature now supports wildcards (thanks to sirmc) - small change to cmplog to make it work with current llvm 11-dev - added AFL_LLVM_LAF_ALL, sets all laf-intel settings - LTO instrument_files functionality rewritten, now main, _init etc functions - need not to be instrument_filesed anymore + need not to be listed anymore - fixed crash in compare-transform-pass when strcasecmp/strncasecmp was tried to be instrumented with LTO - fixed crash in cmplog with LTO @@ -253,7 +253,7 @@ sending a mail to . the original script is still present as afl-cmin.bash - afl-showmap: -i dir option now allows processing multiple inputs using the forkserver. This is for enhanced speed in afl-cmin. - - added blacklist and instrument_filesing function check in all modules of llvm_mode + - added ignore and instrument_file list function check in all modules of llvm_mode - added fix from Debian project to compile libdislocator and libtokencap - libdislocator: AFL_ALIGNED_ALLOC to force size alignment to max_align_t @@ -308,7 +308,7 @@ sending a mail to . performance loss of ~10% - added test/test-performance.sh script - (re)added gcc_plugin, fast inline instrumentation is not yet finished, - however it includes the instrument_filesing and persistance feature! by hexcoder- + however it includes the instrument_files listing and persistance feature! by hexcoder- - gcc_plugin tests added to testing framework @@ -396,7 +396,7 @@ sending a mail to . - more cpu power for afl-system-config - added forkserver patch to afl-tmin, makes it much faster (originally from github.com/nccgroup/TriforceAFL) - - added instrument_files support for llvm_mode via AFL_LLVM_WHITELIST to allow + - added instrument_files support for llvm_mode via AFL_LLVM_INSTRUMENT_FILE to allow only to instrument what is actually interesting. Gives more speed and less map pollution (originally by choller@mozilla) - added Python Module mutator support, python2.7-dev is autodetected. -- cgit 1.4.1 From b201279ae5e4066ffa7f11d58f0efd73938aa8dd Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:27:53 +0200 Subject: text fix --- docs/perf_tips.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/perf_tips.md b/docs/perf_tips.md index 7a690b77..46a45001 100644 --- a/docs/perf_tips.md +++ b/docs/perf_tips.md @@ -66,7 +66,7 @@ then using laf-intel (see llvm_mode/README.laf-intel.md) will help `afl-fuzz` a to get to the important parts in the code. If you are only interested in specific parts of the code being fuzzed, you can -instrument_files the files that are actually relevant. This improves the speed and +list the files that are actually relevant. This improves the speed and accuracy of afl. See llvm_mode/README.instrument_file.md Also use the InsTrim mode on larger binaries, this improves performance and -- cgit 1.4.1 From e9dce3149606877883df01cc66f99da0addf79ee Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:35:42 +0200 Subject: comments fixed --- llvm_mode/afl-llvm-common.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc index 47b49358..d70ccaeb 100644 --- a/llvm_mode/afl-llvm-common.cc +++ b/llvm_mode/afl-llvm-common.cc @@ -110,10 +110,10 @@ void initInstrumentList() { bool isInInstrumentList(llvm::Function *F) { // is this a function with code? If it is external we dont instrument it - // anyway and cant be in the the instrument file list. Or if it is ignored. + // anyway and cant be in the instrument file list. Or if it is ignored. if (!F->size() || isIgnoreFunction(F)) return false; - // if we do not have a the instrument file list return true + // if we do not have any instrument file list entries return true if (myInstrumentList.empty()) return true; // let's try to get the filename for the function @@ -218,7 +218,7 @@ bool isInInstrumentList(llvm::Function *F) { else { // we could not find out the location. in this case we say it is not - // in the the instrument file list + // in the instrument file list return false; -- cgit 1.4.1 From 2aaa60e4fc45bac022f7170ccfb57d63bf23569d Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:39:55 +0200 Subject: comments fix --- llvm_mode/afl-llvm-lto-instrumentlist.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc index 6e6199e9..96c30fcb 100644 --- a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc @@ -200,7 +200,7 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) { } /* Either we couldn't figure out our location or the location is - * not the instrument file listed, so we skip instrumentation. + * not listed in the instrument file list, so we skip instrumentation. * We do this by renaming the function. */ if (instrumentFunction == true) { -- cgit 1.4.1 From d8984180377fb244d43990feb7cda2d212924ab3 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:43:14 +0200 Subject: restore credit for afl-tmin fork server patch --- src/afl-fuzz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4e2669c..15a68096 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -792,6 +792,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Power schedules from github.com/mboehme/aflfast"); OKF("Python Mutator and llvm_mode instrument file list from " "github.com/choller/afl"); + OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && -- cgit 1.4.1 From 52a0410d926bff61e2c4a854713c2cd29d3b67b1 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:49:07 +0200 Subject: fix text --- llvm_mode/README.instrument_file.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm_mode/README.instrument_file.md b/llvm_mode/README.instrument_file.md index 347bd3c6..a27eacc6 100644 --- a/llvm_mode/README.instrument_file.md +++ b/llvm_mode/README.instrument_file.md @@ -47,14 +47,14 @@ project/feature_b/b1.cpp project/feature_b/b2.cpp ``` -and you only want to test feature_a, then create a the instrument file list file containing: +and you only want to test feature_a, then create a instrument file list file containing: ``` feature_a/a1.cpp feature_a/a2.cpp ``` -However if the the instrument file list file contains only this, it works as well: +However if the instrument file list file contains only this, it works as well: ``` a1.cpp @@ -64,8 +64,8 @@ a2.cpp but it might lead to files being unwantedly instrumented if the same filename exists somewhere else in the project directories. -The created the instrument file list file is then set to AFL_LLVM_INSTRUMENT_FILE when you compile -your program. For each file that didn't match the the instrument file list, the compiler will +The created instrument file list file is then set to AFL_LLVM_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the instrument file list, the compiler will issue a warning at the end stating that no blocks were instrumented. If you didn't intend to instrument that file, then you can safely ignore that warning. @@ -75,5 +75,5 @@ required anymore (and might hurt performance and crash detection, so better not use -g). ## 4) UNIX-style filename pattern matching -You can add UNIX-style pattern matching in the the instrument file list entries. See `man +You can add UNIX-style pattern matching in the instrument file list entries. See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags. -- cgit 1.4.1 From 4d2ccd18f6434a06b80857c4ee5fa6c6e1ae502c Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:55:58 +0200 Subject: comments fix --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 44953a52..724da407 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -435,7 +435,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u32 fails; u8 found_one = 0; - /* loop cmps are useless, detect and ignores them */ + /* loop cmps are useless, detect and ignore them */ u64 s_v0, s_v1; u8 s_v0_fixed = 1, s_v1_fixed = 1; u8 s_v0_inc = 1, s_v1_inc = 1; @@ -743,7 +743,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, afl->pass_stats[k].faileds || afl->pass_stats[k].total == 0xff)) { - afl->shm.cmp_map->headers[k].hits = 0; // ignores this cmp + afl->shm.cmp_map->headers[k].hits = 0; // ignore this cmp } -- cgit 1.4.1 From 6b98157c1a235c10ed5f9fc3220aa1869ea8f3e4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Jul 2020 09:15:47 +0200 Subject: v2.66c release preparation --- README.md | 4 ++-- TODO.md | 2 +- docs/Changelog.md | 2 +- include/config.h | 2 +- src/afl-fuzz.c | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dd32e28e..14a42b7e 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) - Release Version: [2.65c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [2.66c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.65d + Github Version: 2.66d includes all necessary/interesting changes from Google's afl 2.56b diff --git a/TODO.md b/TODO.md index 55b886e4..8085bc07 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # TODO list for AFL++ -## Roadmap 2.65+ +## Roadmap 2.66+ - AFL_MAP_SIZE for qemu_mode and unicorn_mode - namespace for targets? e.g. network diff --git a/docs/Changelog.md b/docs/Changelog.md index eede6751..1bf77839 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++2.65d (dev) +### Version ++2.66c (release) - renamed the main branch on Github to "stable" - renamed master/slave to main/secondary - renamed blacklist/whitelist to ignorelist/instrumentlist -> diff --git a/include/config.h b/include/config.h index 5ee93389..e8f52f45 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.65d" +#define VERSION "++2.66c" /****************************************************** * * diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 15a68096..e4e2669c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -792,7 +792,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Power schedules from github.com/mboehme/aflfast"); OKF("Python Mutator and llvm_mode instrument file list from " "github.com/choller/afl"); - OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && -- cgit 1.4.1 From 4ec29928bfeb812fad77d8f9104f30c897a42374 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Jul 2020 09:30:14 +0200 Subject: because github errors reput typo fix --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 44953a52..724da407 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -435,7 +435,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u32 fails; u8 found_one = 0; - /* loop cmps are useless, detect and ignores them */ + /* loop cmps are useless, detect and ignore them */ u64 s_v0, s_v1; u8 s_v0_fixed = 1, s_v1_fixed = 1; u8 s_v0_inc = 1, s_v1_inc = 1; @@ -743,7 +743,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, afl->pass_stats[k].faileds || afl->pass_stats[k].total == 0xff)) { - afl->shm.cmp_map->headers[k].hits = 0; // ignores this cmp + afl->shm.cmp_map->headers[k].hits = 0; // ignore this cmp } -- cgit 1.4.1 From 97cef46b62800cd505ef1a34e3ff61eafd5bce54 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Jul 2020 10:03:34 +0200 Subject: warn on deprecated env vars --- docs/Changelog.md | 1 + include/envs.h | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-common.c | 74 ++++++++++------------------ src/afl-fuzz-state.c | 55 ++++++++++++++++----- 4 files changed, 205 insertions(+), 61 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index e6e0116a..afb9dea6 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,7 @@ sending a mail to . - renamed master/slave to main/secondary - renamed blacklist/whitelist to ignorelist/instrumentlist -> AFL_LLVM_INSTRUMENT_FILE and AFL_GCC_INSTRUMENT_FILE + - warn on deprecated environment variables - afl-fuzz: - -S secondary nodes now only sync from the main node to increase performance, the -M main node still syncs from everyone. Added checks diff --git a/include/envs.h b/include/envs.h index 0651f9da..86222418 100644 --- a/include/envs.h +++ b/include/envs.h @@ -1,3 +1,139 @@ +#ifndef _ENVS_H + +#define _ENVS_H + +static char *afl_environment_deprecated[] = { + + "AFL_LLVM_WHITELIST", + "AFL_GCC_WHITELIST", + "AFL_DEFER_FORKSRV", + "AFL_POST_LIBRARY", + "AFL_PERSISTENT", + NULL + +}; + +static char *afl_environment_variables[] = { + + "AFL_ALIGNED_ALLOC", + "AFL_ALLOW_TMP", + "AFL_ANALYZE_HEX", + "AFL_AS", + "AFL_AUTORESUME", + "AFL_AS_FORCE_INSTRUMENT", + "AFL_BENCH_JUST_ONE", + "AFL_BENCH_UNTIL_CRASH", + "AFL_CAL_FAST", + "AFL_CC", + "AFL_CMIN_ALLOW_ANY", + "AFL_CMIN_CRASHES_ONLY", + "AFL_CODE_END", + "AFL_CODE_START", + "AFL_COMPCOV_BINNAME", + "AFL_COMPCOV_LEVEL", + "AFL_CUSTOM_MUTATOR_LIBRARY", + "AFL_CUSTOM_MUTATOR_ONLY", + "AFL_CXX", + "AFL_DEBUG", + "AFL_DEBUG_CHILD_OUTPUT", + "AFL_DEBUG_GDB", + "AFL_DISABLE_TRIM", + "AFL_DONT_OPTIMIZE", + "AFL_DUMB_FORKSRV", + "AFL_ENTRYPOINT", + "AFL_EXIT_WHEN_DONE", + "AFL_FAST_CAL", + "AFL_FORCE_UI", + "AFL_GCC_INSTRUMENT_FILE", + "AFL_GCJ", + "AFL_HANG_TMOUT", + "AFL_HARDEN", + "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", + "AFL_IMPORT_FIRST", + "AFL_INST_LIBS", + "AFL_INST_RATIO", + "AFL_KEEP_TRACES", + "AFL_KEEP_ASSEMBLY", + "AFL_LD_HARD_FAIL", + "AFL_LD_LIMIT_MB", + "AFL_LD_NO_CALLOC_OVER", + "AFL_LD_PASSTHROUGH", + "AFL_REAL_LD", + "AFL_LD_PRELOAD", + "AFL_LD_VERBOSE", + "AFL_LLVM_CMPLOG", + "AFL_LLVM_INSTRIM", + "AFL_LLVM_CTX", + "AFL_LLVM_INSTRUMENT", + "AFL_LLVM_INSTRIM_LOOPHEAD", + "AFL_LLVM_LTO_AUTODICTIONARY", + "AFL_LLVM_AUTODICTIONARY", + "AFL_LLVM_SKIPSINGLEBLOCK", + "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", + "AFL_LLVM_LAF_SPLIT_COMPARES", + "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", + "AFL_LLVM_LAF_SPLIT_FLOATS", + "AFL_LLVM_LAF_SPLIT_SWITCHES", + "AFL_LLVM_LAF_ALL", + "AFL_LLVM_LAF_TRANSFORM_COMPARES", + "AFL_LLVM_MAP_ADDR", + "AFL_LLVM_MAP_DYNAMIC", + "AFL_LLVM_NGRAM_SIZE", + "AFL_NGRAM_SIZE", + "AFL_LLVM_NOT_ZERO", + "AFL_LLVM_INSTRUMENT_FILE", + "AFL_LLVM_SKIP_NEVERZERO", + "AFL_NO_AFFINITY", + "AFL_LLVM_LTO_STARTID", + "AFL_LLVM_LTO_DONTWRITEID", + "AFL_NO_ARITH", + "AFL_NO_BUILTIN", + "AFL_NO_CPU_RED", + "AFL_NO_FORKSRV", + "AFL_NO_UI", + "AFL_NO_PYTHON", + "AFL_UNTRACER_FILE", + "AFL_LLVM_USE_TRACE_PC", + "AFL_NO_X86", // not really an env but we dont want to warn on it + "AFL_MAP_SIZE", + "AFL_MAPSIZE", + "AFL_PATH", + "AFL_PERFORMANCE_FILE", + "AFL_PRELOAD", + "AFL_PYTHON_MODULE", + "AFL_QEMU_COMPCOV", + "AFL_QEMU_COMPCOV_DEBUG", + "AFL_QEMU_DEBUG_MAPS", + "AFL_QEMU_DISABLE_CACHE", + "AFL_QEMU_PERSISTENT_ADDR", + "AFL_QEMU_PERSISTENT_CNT", + "AFL_QEMU_PERSISTENT_GPR", + "AFL_QEMU_PERSISTENT_HOOK", + "AFL_QEMU_PERSISTENT_RET", + "AFL_QEMU_PERSISTENT_RETADDR_OFFSET", + "AFL_QUIET", + "AFL_RANDOM_ALLOC_CANARY", + "AFL_REAL_PATH", + "AFL_SHUFFLE_QUEUE", + "AFL_SKIP_BIN_CHECK", + "AFL_SKIP_CPUFREQ", + "AFL_SKIP_CRASHES", + "AFL_TMIN_EXACT", + "AFL_TMPDIR", + "AFL_TOKEN_FILE", + "AFL_TRACE_PC", + "AFL_USE_ASAN", + "AFL_USE_MSAN", + "AFL_USE_TRACE_PC", + "AFL_USE_UBSAN", + "AFL_USE_CFISAN", + "AFL_WINE_PATH", + "AFL_NO_SNAPSHOT", + NULL + +}; extern char *afl_environment_variables[]; +#endif + diff --git a/src/afl-common.c b/src/afl-common.c index 8995b57e..c023789b 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -46,50 +46,6 @@ u8 be_quiet = 0; u8 *doc_path = ""; u8 last_intr = 0; -char *afl_environment_variables[] = { - - "AFL_ALIGNED_ALLOC", "AFL_ALLOW_TMP", "AFL_ANALYZE_HEX", "AFL_AS", - "AFL_AUTORESUME", "AFL_AS_FORCE_INSTRUMENT", "AFL_BENCH_JUST_ONE", - "AFL_BENCH_UNTIL_CRASH", "AFL_CAL_FAST", "AFL_CC", "AFL_CMIN_ALLOW_ANY", - "AFL_CMIN_CRASHES_ONLY", "AFL_CODE_END", "AFL_CODE_START", - "AFL_COMPCOV_BINNAME", "AFL_COMPCOV_LEVEL", "AFL_CUSTOM_MUTATOR_LIBRARY", - "AFL_CUSTOM_MUTATOR_ONLY", "AFL_CXX", "AFL_DEBUG", "AFL_DEBUG_CHILD_OUTPUT", - "AFL_DEBUG_GDB", - //"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally - "AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV", - "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI", - "AFL_GCC_INSTRUMENT_FILE", "AFL_GCJ", "AFL_HANG_TMOUT", "AFL_HARDEN", - "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IMPORT_FIRST", - "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", - "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", - "AFL_LD_PASSTHROUGH", "AFL_REAL_LD", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", - "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX", - "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", - "AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY", - "AFL_LLVM_SKIPSINGLEBLOCK", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", - "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", - "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", - "AFL_LLVM_LAF_ALL", "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR", - "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", - "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE", "AFL_LLVM_SKIP_NEVERZERO", - "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", - "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", - "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", - "AFL_NO_X86", // not really an env but we dont want to warn on it - "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE", - //"AFL_PERSISTENT", // not implemented anymore, so warn additionally - "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV", - "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", - "AFL_QEMU_PERSISTENT_ADDR", "AFL_QEMU_PERSISTENT_CNT", - "AFL_QEMU_PERSISTENT_GPR", "AFL_QEMU_PERSISTENT_HOOK", - "AFL_QEMU_PERSISTENT_RET", "AFL_QEMU_PERSISTENT_RETADDR_OFFSET", - "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", "AFL_REAL_PATH", - "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ", - "AFL_SKIP_CRASHES", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", - "AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", - "AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", - NULL}; - void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { u32 i = 0; @@ -449,14 +405,14 @@ void check_environment_vars(char **envp) { if (be_quiet) { return; } - int index = 0, found = 0; + int index = 0, issue_detected = 0; char *env, *val; while ((env = envp[index++]) != NULL) { if (strncmp(env, "ALF_", 4) == 0) { WARNF("Potentially mistyped AFL environment variable: %s", env); - found++; + issue_detected = 1; } else if (strncmp(env, "AFL_", 4) == 0) { @@ -474,6 +430,7 @@ void check_environment_vars(char **envp) { "AFL environment variable %s defined but is empty, this can " "lead to unexpected consequences", afl_environment_variables[i]); + issue_detected = 1; } @@ -485,10 +442,31 @@ void check_environment_vars(char **envp) { } + i = 0; + while (match == 0 && afl_environment_deprecated[i] != NULL) { + + if (strncmp(env, afl_environment_deprecated[i], + strlen(afl_environment_deprecated[i])) == 0 && + env[strlen(afl_environment_deprecated[i])] == '=') { + + match = 1; + + WARNF("AFL environment variable %s is deprecated!", + afl_environment_deprecated[i]); + issue_detected = 1; + + } else { + + i++; + + } + + } + if (match == 0) { WARNF("Mistyped AFL environment variable: %s", env); - found++; + issue_detected = 1; } @@ -496,7 +474,7 @@ void check_environment_vars(char **envp) { } - if (found) { sleep(2); } + if (issue_detected) { sleep(2); } } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ece2d170..e0e43f54 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -164,14 +164,14 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { void read_afl_environment(afl_state_t *afl, char **envp) { - int index = 0, found = 0; + int index = 0, issue_detected = 0; char *env; while ((env = envp[index++]) != NULL) { if (strncmp(env, "ALF_", 4) == 0) { WARNF("Potentially mistyped AFL environment variable: %s", env); - found++; + issue_detected = 1; } else if (strncmp(env, "AFL_", 4) == 0) { @@ -307,15 +307,6 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_tmpdir = (u8 *)get_afl_env(afl_environment_variables[i]); - } else if (!strncmp(env, "AFL_POST_LIBRARY", - - afl_environment_variable_len)) { - - FATAL( - "AFL_POST_LIBRARY is deprecated, use " - "AFL_CUSTOM_MUTATOR_LIBRARY instead, see " - "docs/custom_mutators.md"); - } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LIBRARY", afl_environment_variable_len)) { @@ -352,10 +343,48 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } + i = 0; + while (match == 0 && afl_environment_variables[i] != NULL) { + + if (strncmp(env, afl_environment_variables[i], + strlen(afl_environment_variables[i])) == 0 && + env[strlen(afl_environment_variables[i])] == '=') { + + match = 1; + + } else { + + i++; + + } + + } + + i = 0; + while (match == 0 && afl_environment_deprecated[i] != NULL) { + + if (strncmp(env, afl_environment_deprecated[i], + strlen(afl_environment_deprecated[i])) == 0 && + env[strlen(afl_environment_deprecated[i])] == '=') { + + match = 1; + + WARNF("AFL environment variable %s is deprecated!", + afl_environment_deprecated[i]); + issue_detected = 1; + + } else { + + i++; + + } + + } + if (match == 0) { WARNF("Mistyped AFL environment variable: %s", env); - found++; + issue_detected = 1; } @@ -363,7 +392,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } - if (found) { sleep(2); } + if (issue_detected) { sleep(2); } } -- cgit 1.4.1 From 4515e06ca8620183c536af9f55a47b78fb7c708a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Jul 2020 15:50:25 +0200 Subject: updated unicorn version --- unicorn_mode/UNICORNAFL_VERSION | 2 +- unicorn_mode/samples/persistent/harness.c | 2 +- unicorn_mode/unicornafl | 2 +- unicorn_mode/update_uc_ref.sh | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION index 21a8657d..02736b77 100644 --- a/unicorn_mode/UNICORNAFL_VERSION +++ b/unicorn_mode/UNICORNAFL_VERSION @@ -1 +1 @@ -0ca7a8f2 +c6d66471 diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c index 30013b4c..eae3f1fc 100644 --- a/unicorn_mode/samples/persistent/harness.c +++ b/unicorn_mode/samples/persistent/harness.c @@ -204,7 +204,7 @@ int main(int argc, char **argv, char **envp) { // Map memory. mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL); - printf("Len: %lx\n", len); + /* printf("Len: %lx\n", len); */ fflush(stdout); // write machine code to be emulated to memory diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl index 0ca7a8f2..c6d66471 160000 --- a/unicorn_mode/unicornafl +++ b/unicorn_mode/unicornafl @@ -1 +1 @@ -Subproject commit 0ca7a8f22b8bb028eb9fe053c0974a60ee640f18 +Subproject commit c6d6647161a32bae88785a618fcd828d1711d9e6 diff --git a/unicorn_mode/update_uc_ref.sh b/unicorn_mode/update_uc_ref.sh index 21450e69..a2613942 100755 --- a/unicorn_mode/update_uc_ref.sh +++ b/unicorn_mode/update_uc_ref.sh @@ -21,10 +21,10 @@ fi git submodule init && git submodule update || exit 1 cd ./unicornafl || exit 1 -git fetch origin master 1>/dev/null || exit 1 +git fetch origin dev 1>/dev/null || exit 1 git stash 1>/dev/null 2>/dev/null git stash drop 1>/dev/null 2>/dev/null -git checkout master +git checkout dev if [ -z "$NEW_VERSION" ]; then # No version provided, take HEAD. -- cgit 1.4.1 From 857046ede5a7bd54a725bfd4367de55011cca94d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Jul 2020 15:57:48 +0200 Subject: Revert "updated unicorn version" This reverts commit 4515e06ca8620183c536af9f55a47b78fb7c708a. --- unicorn_mode/UNICORNAFL_VERSION | 2 +- unicorn_mode/samples/persistent/harness.c | 2 +- unicorn_mode/unicornafl | 2 +- unicorn_mode/update_uc_ref.sh | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION index 02736b77..21a8657d 100644 --- a/unicorn_mode/UNICORNAFL_VERSION +++ b/unicorn_mode/UNICORNAFL_VERSION @@ -1 +1 @@ -c6d66471 +0ca7a8f2 diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c index eae3f1fc..30013b4c 100644 --- a/unicorn_mode/samples/persistent/harness.c +++ b/unicorn_mode/samples/persistent/harness.c @@ -204,7 +204,7 @@ int main(int argc, char **argv, char **envp) { // Map memory. mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL); - /* printf("Len: %lx\n", len); */ + printf("Len: %lx\n", len); fflush(stdout); // write machine code to be emulated to memory diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl index c6d66471..0ca7a8f2 160000 --- a/unicorn_mode/unicornafl +++ b/unicorn_mode/unicornafl @@ -1 +1 @@ -Subproject commit c6d6647161a32bae88785a618fcd828d1711d9e6 +Subproject commit 0ca7a8f22b8bb028eb9fe053c0974a60ee640f18 diff --git a/unicorn_mode/update_uc_ref.sh b/unicorn_mode/update_uc_ref.sh index a2613942..21450e69 100755 --- a/unicorn_mode/update_uc_ref.sh +++ b/unicorn_mode/update_uc_ref.sh @@ -21,10 +21,10 @@ fi git submodule init && git submodule update || exit 1 cd ./unicornafl || exit 1 -git fetch origin dev 1>/dev/null || exit 1 +git fetch origin master 1>/dev/null || exit 1 git stash 1>/dev/null 2>/dev/null git stash drop 1>/dev/null 2>/dev/null -git checkout dev +git checkout master if [ -z "$NEW_VERSION" ]; then # No version provided, take HEAD. -- cgit 1.4.1 From f2efea4b46584b134bf9016f24548d07934b6632 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Jul 2020 16:05:04 +0200 Subject: Revert "Revert "updated unicorn version"" This reverts commit 857046ede5a7bd54a725bfd4367de55011cca94d. --- unicorn_mode/UNICORNAFL_VERSION | 2 +- unicorn_mode/samples/persistent/harness.c | 2 +- unicorn_mode/unicornafl | 2 +- unicorn_mode/update_uc_ref.sh | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION index 21a8657d..02736b77 100644 --- a/unicorn_mode/UNICORNAFL_VERSION +++ b/unicorn_mode/UNICORNAFL_VERSION @@ -1 +1 @@ -0ca7a8f2 +c6d66471 diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c index 30013b4c..eae3f1fc 100644 --- a/unicorn_mode/samples/persistent/harness.c +++ b/unicorn_mode/samples/persistent/harness.c @@ -204,7 +204,7 @@ int main(int argc, char **argv, char **envp) { // Map memory. mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL); - printf("Len: %lx\n", len); + /* printf("Len: %lx\n", len); */ fflush(stdout); // write machine code to be emulated to memory diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl index 0ca7a8f2..c6d66471 160000 --- a/unicorn_mode/unicornafl +++ b/unicorn_mode/unicornafl @@ -1 +1 @@ -Subproject commit 0ca7a8f22b8bb028eb9fe053c0974a60ee640f18 +Subproject commit c6d6647161a32bae88785a618fcd828d1711d9e6 diff --git a/unicorn_mode/update_uc_ref.sh b/unicorn_mode/update_uc_ref.sh index 21450e69..a2613942 100755 --- a/unicorn_mode/update_uc_ref.sh +++ b/unicorn_mode/update_uc_ref.sh @@ -21,10 +21,10 @@ fi git submodule init && git submodule update || exit 1 cd ./unicornafl || exit 1 -git fetch origin master 1>/dev/null || exit 1 +git fetch origin dev 1>/dev/null || exit 1 git stash 1>/dev/null 2>/dev/null git stash drop 1>/dev/null 2>/dev/null -git checkout master +git checkout dev if [ -z "$NEW_VERSION" ]; then # No version provided, take HEAD. -- cgit 1.4.1 From 00abb999e3c051c5c7c6349c385d77d25dea8e7f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Jul 2020 18:24:00 +0200 Subject: v2.66d init --- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index afb9dea6..57b2b4a2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++2.66d (devel) + - ... ? + + ### Version ++2.66c (release) - renamed the main branch on Github to "stable" - renamed master/slave to main/secondary diff --git a/include/config.h b/include/config.h index e8f52f45..7de74009 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.66c" +#define VERSION "++2.66d" /****************************************************** * * -- cgit 1.4.1 From 1aa7c87ea8ef0925f2ce372b25e4a8ce8f19c943 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 1 Jul 2020 21:14:34 +0100 Subject: libtokencap illumos/solaris support proposal. --- libtokencap/Makefile | 13 +++++++------ libtokencap/libtokencap.so.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 63b87bb0..8bdfa5ac 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -35,13 +35,14 @@ _UNIQ=_QINU_ _____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=) ______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl") - _OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ)) - __OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ)) - ___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ)) - ____OS_TARGET = $(___OS_TARGET:$(_UNIQ)Haiku=$(_UNIQ)) -_____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=) + _OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ)) + __OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ)) + ___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ)) + ____OS_TARGET = $(___OS_TARGET:$(_UNIQ)Haiku=$(_UNIQ)) + _____OS_TARGET = $(____OS_TARGET:$(_UNIQ)SunOS=$(_UNIQ)) +______OS_TARGET = $(____OS_TARGET:$(_UNIQ)$(UNAME_S)=) -TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so) +TARGETS = $(_____OS_TARGET:$(_UNIQ)=libtokencap.so) LDFLAGS += $(______OS_DL) diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 600d2a5d..6ed35551 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -35,7 +35,7 @@ #if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \ !defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ && \ - !defined(__HAIKU__) + !defined(__HAIKU__) && !defined(__sun) #error "Sorry, this library is unsupported in this platform for now!" #endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \ !__NetBSD__*/ @@ -52,6 +52,10 @@ #include #elif defined __HAIKU__ #include +#elif defined __sun + /* For map addresses the old struct is enough */ + #include + #include #endif #include @@ -237,6 +241,8 @@ static void __tokencap_load_mappings(void) { image_info ii; int32_t group = 0; + __tokencap_ro_loaded = 1; + while (get_next_image_info(0, &group, &ii) == B_OK) { __tokencap_ro[__tokencap_ro_cnt].st = ii.text; @@ -246,6 +252,38 @@ static void __tokencap_load_mappings(void) { } +#elif defined __sun + prmap_t *c, *map; + char path[PATH_MAX]; + ssize_t r; + size_t hint; + int fd; + + snprintf(path, sizeof(path), "/proc/%ld/map", getpid()); + fd = open(path, O_RDONLY); + hint = (1 << 20); + map = malloc(hint); + + __tokencap_ro_loaded = 1; + + for (; (r = pread(fd, map, hint, 0)) == hint; ) { + + hint <<= 1; + map = realloc(map, hint); + + } + + for (c = map; c++; r -= sizeof(prmap_t)) { + + __tokencap_ro[__tokencap_ro_cnt].st = c->pr_vaddr; + __tokencap_ro[__tokencap_ro_cnt].en = c->pr_vaddr + c->pr_size; + + if (++__tokencap_ro_cnt == MAX_MAPPINGS) break; + + } + + free(map); + close(fd); #endif } -- cgit 1.4.1 From c671ecb5110b10a66e29f1605fe0abfd63a19468 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 2 Jul 2020 10:23:56 +0100 Subject: Fix map list iteration. --- libtokencap/libtokencap.so.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 6ed35551..baf9fae6 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -273,7 +273,7 @@ static void __tokencap_load_mappings(void) { } - for (c = map; c++; r -= sizeof(prmap_t)) { + for (c = map; r > 0; c++ , r -= sizeof(prmap_t)) { __tokencap_ro[__tokencap_ro_cnt].st = c->pr_vaddr; __tokencap_ro[__tokencap_ro_cnt].en = c->pr_vaddr + c->pr_size; -- cgit 1.4.1 From 139665c01dce7b85941d6e1b61aaebd06e316cba Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 3 Jul 2020 10:20:10 +0200 Subject: ubsan options --- src/afl-analyze.c | 29 ++++++++++++++++++++++++++--- src/afl-forkserver.c | 29 +++++++++++++++++++++++++++-- src/afl-showmap.c | 29 ++++++++++++++++++++++++++--- src/afl-tmin.c | 29 ++++++++++++++++++++++++++--- 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 56284f6f..e6dd0fca 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -772,15 +772,38 @@ static void set_up_environment(void) { setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" + "allocator_may_return_null=1:" "symbolize=0:" - "allocator_may_return_null=1", + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); + + setenv("UBSAN_OPTIONS", + "halt_on_error=1:" + "abort_on_error=1:" + "malloc_context_size=0:" + "allocator_may_return_null=1:" + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "symbolize=0:" "abort_on_error=1:" + "msan_track_origins=0" "allocator_may_return_null=1:" - "msan_track_origins=0", 0); + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); if (get_afl_env("AFL_PRELOAD")) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 419ce28e..47493eba 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -434,7 +434,27 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "detect_leaks=0:" "malloc_context_size=0:" "symbolize=0:" - "allocator_may_return_null=1", + "allocator_may_return_null=1:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); + + /* Set sane defaults for UBSAN if nothing else specified. */ + + setenv("UBSAN_OPTIONS", + "halt_on_error=1:" + "abort_on_error=1:" + "malloc_context_size=0:" + "allocator_may_return_null=1:" + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); /* MSAN is tricky, because it doesn't support abort_on_error=1 at this @@ -446,7 +466,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "abort_on_error=1:" "malloc_context_size=0:" "allocator_may_return_null=1:" - "msan_track_origins=0", + "msan_track_origins=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); fsrv->init_child_func(fsrv, argv); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 883398ff..71e975a1 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -456,15 +456,38 @@ static void set_up_environment(afl_forkserver_t *fsrv) { setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" + "allocator_may_return_null=1:" "symbolize=0:" - "allocator_may_return_null=1", + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); + + setenv("UBSAN_OPTIONS", + "halt_on_error=1:" + "abort_on_error=1:" + "malloc_context_size=0:" + "allocator_may_return_null=1:" + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "symbolize=0:" "abort_on_error=1:" + "msan_track_origins=0" "allocator_may_return_null=1:" - "msan_track_origins=0", 0); + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); if (get_afl_env("AFL_PRELOAD")) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 2db1eae7..68fcdd14 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -701,15 +701,38 @@ static void set_up_environment(afl_forkserver_t *fsrv) { setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" + "allocator_may_return_null=1:" "symbolize=0:" - "allocator_may_return_null=1", + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); + + setenv("UBSAN_OPTIONS", + "halt_on_error=1:" + "abort_on_error=1:" + "malloc_context_size=0:" + "allocator_may_return_null=1:" + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "symbolize=0:" "abort_on_error=1:" + "msan_track_origins=0" "allocator_may_return_null=1:" - "msan_track_origins=0", 0); + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", 0); if (get_afl_env("AFL_PRELOAD")) { -- cgit 1.4.1 From e6d4d29af559142062476ad4c7c243c5f1769fd9 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 3 Jul 2020 15:21:33 +0100 Subject: llvm mode shared segment fix for FreeBSD. MAP_EXCL|MAP_FIXED is a (genuine) equivalent to Linux's MAP_FIXED_NOREPLACE. --- llvm_mode/afl-llvm-rt.o.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index f81d13ee..9db43e35 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -53,7 +53,11 @@ #define CONST_PRIO 5 #ifndef MAP_FIXED_NOREPLACE - #define MAP_FIXED_NOREPLACE MAP_FIXED +# ifdef MAP_EXCL + #define MAP_FIXED_NOREPLACE MAP_EXCL|MAP_FIXED +#else + #define MAP_FIXED_NOREPLACE MAP_FIXED +# endif #endif #include -- cgit 1.4.1 From 4fd145c52e29b73e4a8ded70f682aa37c3652f01 Mon Sep 17 00:00:00 2001 From: Elia Geretto Date: Fri, 3 Jul 2020 18:37:53 +0200 Subject: llvm_mode: Fix typo in compiler wrapper --- llvm_mode/afl-clang-fast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index f1b03682..07c3c07c 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -660,7 +660,7 @@ int main(int argc, char **argv, char **envp) { } if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || - strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) { + strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) instrument_mode = INSTRUMENT_PCGUARD; -- cgit 1.4.1 From 29102d6bf169bc26171d9b24430ac4e8a1c91452 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 4 Jul 2020 12:36:53 +0100 Subject: libdislocator: hugepage enabled for illumos too. --- libdislocator/libdislocator.so.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libdislocator/libdislocator.so.c b/libdislocator/libdislocator.so.c index 7a70fd15..b93f43c1 100644 --- a/libdislocator/libdislocator.so.c +++ b/libdislocator/libdislocator.so.c @@ -166,7 +166,7 @@ static u32 alloc_canary; static void *__dislocator_alloc(size_t len) { - u8 * ret; + u8 * ret, *base; size_t tlen; int flags, fd, sp; @@ -189,6 +189,7 @@ static void *__dislocator_alloc(size_t len) { /* We will also store buffer length and a canary below the actual buffer, so let's add 8 bytes for that. */ + base = NULL; tlen = (1 + PG_COUNT(rlen + 8)) * PAGE_SIZE; flags = MAP_PRIVATE | MAP_ANONYMOUS; fd = -1; @@ -201,12 +202,19 @@ static void *__dislocator_alloc(size_t len) { if (sp) flags |= MAP_HUGETLB; #elif defined(__FreeBSD__) if (sp) flags |= MAP_ALIGNED_SUPER; + #elif defined(__sun) + if (sp) { + + base = (void *)(caddr_t)(1<<21); + flags |= MAP_ALIGN; + + } #endif #else (void)sp; #endif - ret = (u8 *)mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0); + ret = (u8 *)mmap(base, tlen, PROT_READ | PROT_WRITE, flags, fd, 0); #if defined(USEHUGEPAGE) /* We try one more time with regular call */ if (ret == MAP_FAILED) { @@ -217,6 +225,8 @@ static void *__dislocator_alloc(size_t len) { flags &= -MAP_HUGETLB; #elif defined(__FreeBSD__) flags &= -MAP_ALIGNED_SUPER; + #elif defined(__sun) + flags &= -MAP_ALIGN; #endif ret = (u8 *)mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0); -- cgit 1.4.1 From 147b0a151c8707a40d9e208e4ae4d817704488f9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Jul 2020 17:34:03 +0200 Subject: fix laf-intel/compare-transform-pass for 32-Bit --- llvm_mode/compare-transform-pass.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 2d1ab1cc..5119d656 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -475,7 +475,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt())); Value * icmp = cur_lenchk_IRB.CreateICmpEQ(sizedValue, - ConstantInt::get(Int64Ty, i)); + ConstantInt::get(sizedValue->getType(), i)); cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb); cur_lenchk_bb->getTerminator()->eraseFromParent(); -- cgit 1.4.1 From 7d0af01d8ba1627238407a97496c0d21faf7a8fe Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 5 Jul 2020 11:05:33 +0200 Subject: fix rtf.dict --- dictionaries/rtf.dict | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dictionaries/rtf.dict b/dictionaries/rtf.dict index 8b8f0cad..148d9fd8 100644 --- a/dictionaries/rtf.dict +++ b/dictionaries/rtf.dict @@ -87,11 +87,11 @@ "PU_TWIPS" # headers and gooters -"\headerr" -"\headerf" -"\footerl" -"\footerr" -"\footerf" +"\\headerr" +"\\headerf" +"\\footerl" +"\\footerr" +"\\footerf" # misc "\\chftn" -- cgit 1.4.1 From 95fd080ca17743717d38b8b002d30b09a5a16748 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 5 Jul 2020 11:08:22 +0200 Subject: code format --- libdislocator/libdislocator.so.c | 3 ++- libtokencap/libtokencap.so.c | 16 ++++++++-------- llvm_mode/afl-llvm-rt.o.c | 10 +++++----- llvm_mode/compare-transform-pass.so.cc | 4 ++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/libdislocator/libdislocator.so.c b/libdislocator/libdislocator.so.c index b93f43c1..2324e390 100644 --- a/libdislocator/libdislocator.so.c +++ b/libdislocator/libdislocator.so.c @@ -205,10 +205,11 @@ static void *__dislocator_alloc(size_t len) { #elif defined(__sun) if (sp) { - base = (void *)(caddr_t)(1<<21); + base = (void *)(caddr_t)(1 << 21); flags |= MAP_ALIGN; } + #endif #else (void)sp; diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index baf9fae6..21bac082 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -254,10 +254,10 @@ static void __tokencap_load_mappings(void) { #elif defined __sun prmap_t *c, *map; - char path[PATH_MAX]; - ssize_t r; - size_t hint; - int fd; + char path[PATH_MAX]; + ssize_t r; + size_t hint; + int fd; snprintf(path, sizeof(path), "/proc/%ld/map", getpid()); fd = open(path, O_RDONLY); @@ -266,14 +266,14 @@ static void __tokencap_load_mappings(void) { __tokencap_ro_loaded = 1; - for (; (r = pread(fd, map, hint, 0)) == hint; ) { - - hint <<= 1; + for (; (r = pread(fd, map, hint, 0)) == hint;) { + + hint <<= 1; map = realloc(map, hint); } - for (c = map; r > 0; c++ , r -= sizeof(prmap_t)) { + for (c = map; r > 0; c++, r -= sizeof(prmap_t)) { __tokencap_ro[__tokencap_ro_cnt].st = c->pr_vaddr; __tokencap_ro[__tokencap_ro_cnt].en = c->pr_vaddr + c->pr_size; diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 9db43e35..0efde7aa 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -53,11 +53,11 @@ #define CONST_PRIO 5 #ifndef MAP_FIXED_NOREPLACE -# ifdef MAP_EXCL - #define MAP_FIXED_NOREPLACE MAP_EXCL|MAP_FIXED -#else - #define MAP_FIXED_NOREPLACE MAP_FIXED -# endif + #ifdef MAP_EXCL + #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED + #else + #define MAP_FIXED_NOREPLACE MAP_FIXED + #endif #endif #include diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 5119d656..2f165ea6 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -474,8 +474,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (cur_lenchk_bb) { IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt())); - Value * icmp = cur_lenchk_IRB.CreateICmpEQ(sizedValue, - ConstantInt::get(sizedValue->getType(), i)); + Value * icmp = cur_lenchk_IRB.CreateICmpEQ( + sizedValue, ConstantInt::get(sizedValue->getType(), i)); cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb); cur_lenchk_bb->getTerminator()->eraseFromParent(); -- cgit 1.4.1 From 20e63078f0b3034d88cf0c2a001236cec4e12441 Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Sun, 5 Jul 2020 05:19:34 +0200 Subject: Fix generation of afl-system-config.8 and afl-whatsup.8 Without this patch, afl-system-config.8 varied between build hosts because it contained lines such as ./afl-system-config: line 30: sysctl: command not found ./afl-system-config: line 31: /sys/kernel/mm/transparent_hugepage/enabled: Permission denied It is recommended to boot the kernel with lots of security off See https://reproducible-builds.org/ for why this matters. afl-system-config.8 is generated by the %.8 target in GNUmakefile that calls commands with -hh to fill the OPTIONS section of man-pages. This PR was done while working on reproducible builds for openSUSE. --- afl-system-config | 2 +- afl-whatsup | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/afl-system-config b/afl-system-config index 1e180d8b..34db61aa 100755 --- a/afl-system-config +++ b/afl-system-config @@ -1,5 +1,5 @@ #!/bin/sh -test "$1" = "-h" && { +test "$1" = "-h" -o "$1" = "-hh" && { echo 'afl-system-config by Marc Heuse ' echo echo $0 diff --git a/afl-whatsup b/afl-whatsup index 1a276964..1f3a8219 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -20,7 +20,7 @@ echo "$0 status check tool for afl-fuzz by Michal Zalewski" echo -test "$1" = "-h" && { +test "$1" = "-h" -o "$1" = "-hh" && { echo $0 [-s] output_directory echo echo Options: -- cgit 1.4.1 From 8644c42482f02f7cd86decbc00ba29aa9c0ce9c0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 5 Jul 2020 13:48:14 +0200 Subject: check for enough plot data --- afl-plot | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/afl-plot b/afl-plot index 1074552a..66c16870 100755 --- a/afl-plot +++ b/afl-plot @@ -68,6 +68,15 @@ if [ ! -f "$inputdir/plot_data" ]; then fi +LINES=`cat "$inputdir/plot_data" | wc -l` + +if [ "$LINES" -lt 3 ]; then + + echo "[-] Error: plot_data carries too little data, let it run longer." 1>&2 + exit 1 + +fi + BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`" test "$BANNER" = "" && BANNER="(none)" -- cgit 1.4.1 From 37697127dce10ec89e07c20fb63d0c7dbeb3586c Mon Sep 17 00:00:00 2001 From: Toralf Förster Date: Sun, 5 Jul 2020 15:35:24 +0200 Subject: afl-plot: scale y-axis of low_freq.png with integers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toralf Förster --- afl-plot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/afl-plot b/afl-plot index 66c16870..cde2db0b 100755 --- a/afl-plot +++ b/afl-plot @@ -127,6 +127,7 @@ set key outside set autoscale xfixmin set autoscale xfixmax +set ytics auto plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ '' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\ @@ -136,6 +137,7 @@ plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' lin set terminal png truecolor enhanced size 1000,200 butt set output '$outputdir/low_freq.png' +set ytics 1 plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\ '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\ @@ -144,6 +146,7 @@ plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb set terminal png truecolor enhanced size 1000,200 butt set output '$outputdir/exec_speed.png' +set ytics auto plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\ '$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier; -- cgit 1.4.1 From b5a00312e02748cf217358f2fcc0c22275c1fc48 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 6 Jul 2020 10:27:48 +0200 Subject: rtf.dict: make it more complete (and unique) and fix some entries --- dictionaries/rtf.dict | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/dictionaries/rtf.dict b/dictionaries/rtf.dict index 148d9fd8..2d5019ef 100644 --- a/dictionaries/rtf.dict +++ b/dictionaries/rtf.dict @@ -3,10 +3,12 @@ # charset "\\ansi" "\\mac" +"\\pc" "\\pca" # font table "\\fnil" +"\\fRoman" "\\fswiss" "\\fmodern" "\\fscript" @@ -28,6 +30,7 @@ "\\cb" # pictures +"\\pict" "\\macpict" "\\pmmetafile" "\\wmetafile" @@ -40,36 +43,15 @@ "\\pich" "\\picwgoal" "\\pichgoal" +"\\picscalex" "\\picscaley" "\\picscaled" "\\piccropt" "\\piccropb" "\\piccropl" "\\piccropr" -"\\brdrs" -"\\brdrdb" -"\\brdrth" -"\\brdrsh" -"\\brdrdot" -"\\brdrhair" -"\\brdrw" -"\\brdrcf" -"\\shading" -"\\bghoriz" -"\\bgvert" -"\\bgfdiag" -"\\bgbdiag" -"\\bgcross" -"\\bgdcross" -"\\bgdkhoriz" -"\\bgdkvert" -"\\bgdkfdiag" -"\\bgdkbdiag" -"\\bgdkcross" -"\\bgdkdcross" -"\\cfpat" -"\\cbpat" "\\bin" +# these strings are probably not necessary "MM_TEXT" "MM_LOMETRIC" "MM_HIMETRIC" @@ -86,7 +68,8 @@ "PU_HIENGLISH" "PU_TWIPS" -# headers and gooters +# headers and footers +"\\headerl" "\\headerr" "\\headerf" "\\footerl" @@ -94,17 +77,22 @@ "\\footerf" # misc -"\\chftn" "\\*\\footnote" "\\*\\annotation" +"\\xe" +"\\txe" +"\\rxe" "\\bxe" "\\ixe" "\\tcf" "\\tcl" "\\*\\bkmkstart" "\\*\\bkmkend" +"\\bkmkcolf" +"\\bkmkcoll" # metadata +"\\info" "\\title" "\\subject" "\\author" @@ -128,10 +116,13 @@ "\\nofwords" "\\nofchars" "\\id" +"\\field" "\\flddirty" "\\fldedit" "\\fldlock" "\\fldpriv" +"\\*\\fldinst" +"\\fldrslt" # objects "\\objemb" @@ -166,16 +157,14 @@ # macintosh editor "\\bkmkpub" "\\pubauto" -"\\objalias" -"\\objsect" # formating "\\deftab" "\\hyphhotz" "\\linestart" "\\fracwidth" -"\\*\nextfile" -"\\*\template" +"\\*\\nextfile" +"\\*\\template" "\\makebackup" "\\defformat" "\\psover" -- cgit 1.4.1 From 75fa1ac3b00a01a0ae02addcedae0e09d674930e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 6 Jul 2020 14:10:14 +0200 Subject: warn rather than fail if AFL_MAP_SIZE is set and not understood by instrumenter --- TODO.md | 5 +++++ gcc_plugin/afl-gcc-fast.c | 2 +- llvm_mode/afl-clang-fast.c | 2 +- src/afl-gcc.c | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/TODO.md b/TODO.md index 8085bc07..d8ad6183 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,11 @@ gcc_plugin: - laf-intel - better instrumentation (seems to be better with gcc-9+) +better documentation: + - flow graph + - short intro + - faq (how to increase stability, speed, many parallel ...) + qemu_mode: - update to 5.x (if the performance bug if gone) - non colliding instrumentation diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index af0beca7..fa1c70d7 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -379,7 +379,7 @@ int main(int argc, char **argv, char **envp) { u32 map_size = atoi(ptr); if (map_size != MAP_SIZE) - FATAL("AFL_MAP_SIZE is not supported by afl-gcc-fast"); + WARN("AFL_MAP_SIZE is not supported by afl-gcc-fast"); } diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 07c3c07c..f634a05c 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -939,7 +939,7 @@ int main(int argc, char **argv, char **envp) { u32 map_size = atoi(ptr2); if (map_size != MAP_SIZE) - FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast"); + WARN("AFL_MAP_SIZE is not supported by afl-clang-fast"); } diff --git a/src/afl-gcc.c b/src/afl-gcc.c index b8ff7e77..2482869e 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -465,7 +465,7 @@ int main(int argc, char **argv) { u32 map_size = atoi(ptr); if (map_size != MAP_SIZE) { - FATAL("AFL_MAP_SIZE is not supported by afl-gcc"); + WARN("AFL_MAP_SIZE is not supported by afl-gcc"); } -- cgit 1.4.1 From 0aed549df102cde6a60dc9ef57524413e978814f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 6 Jul 2020 14:11:21 +0200 Subject: warn rather than fail if AFL_MAP_SIZE is set and not understood by instrumenter --- gcc_plugin/afl-gcc-fast.c | 2 +- llvm_mode/afl-clang-fast.c | 2 +- src/afl-gcc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index fa1c70d7..b1bacfbd 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -379,7 +379,7 @@ int main(int argc, char **argv, char **envp) { u32 map_size = atoi(ptr); if (map_size != MAP_SIZE) - WARN("AFL_MAP_SIZE is not supported by afl-gcc-fast"); + WARNF("AFL_MAP_SIZE is not supported by afl-gcc-fast"); } diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index f634a05c..72262c1e 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -939,7 +939,7 @@ int main(int argc, char **argv, char **envp) { u32 map_size = atoi(ptr2); if (map_size != MAP_SIZE) - WARN("AFL_MAP_SIZE is not supported by afl-clang-fast"); + WARNF("AFL_MAP_SIZE is not supported by afl-clang-fast"); } diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 2482869e..8d91164b 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -465,7 +465,7 @@ int main(int argc, char **argv) { u32 map_size = atoi(ptr); if (map_size != MAP_SIZE) { - WARN("AFL_MAP_SIZE is not supported by afl-gcc"); + WARNF("AFL_MAP_SIZE is not supported by afl-gcc"); } -- cgit 1.4.1 From 2f5cdb72c896d44d8aa613c94e9c102aa3bddcae Mon Sep 17 00:00:00 2001 From: Toralf Förster Date: Mon, 6 Jul 2020 19:23:13 +0200 Subject: afl-plot: set xlabel to show that times are in UTC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toralf Förster --- afl-plot | 2 ++ 1 file changed, 2 insertions(+) diff --git a/afl-plot b/afl-plot index cde2db0b..0faed0ec 100755 --- a/afl-plot +++ b/afl-plot @@ -127,6 +127,8 @@ set key outside set autoscale xfixmin set autoscale xfixmax +set xlabel "all times in UTC" font "small" + set ytics auto plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ -- cgit 1.4.1 From cbe029664e9e4d718119d8f1758c1bcc6c8dbfce Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 7 Jul 2020 12:59:00 +0200 Subject: fix issue #446 --- llvm_mode/split-compares-pass.so.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 651fa5b4..82645224 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -640,7 +640,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { BranchInst::Create(end_bb, signequal_bb); - /* create a new bb which is executed if exponents are equal */ + /* create a new bb which is executed if exponents are satisfying the compare */ BasicBlock *middle_bb = BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb); @@ -711,7 +711,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { case CmpInst::FCMP_UGT: Instruction *icmp_exponent; icmp_exponent = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1); + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGE, m_e0, m_e1); signequal_bb->getInstList().insert( BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); icmp_exponent_result = @@ -720,7 +720,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: icmp_exponent = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1); + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULE, m_e0, m_e1); signequal_bb->getInstList().insert( BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); icmp_exponent_result = @@ -738,7 +738,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { { auto term = signequal_bb->getTerminator(); - /* if the exponents are different do a fraction cmp */ + /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal_bb); term->eraseFromParent(); -- cgit 1.4.1 From 70bd0f799de1a907627b28ad80a447634299839b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Jul 2020 09:39:26 +0200 Subject: fix afl-whatsup if fuzzer_stats is still empty --- afl-whatsup | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/afl-whatsup b/afl-whatsup index 1f3a8219..abcddbf1 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -162,7 +162,8 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do ALIVE_CNT=$((ALIVE_CNT + 1)) - EXEC_SEC=$((execs_done / RUN_UNIX)) + EXEC_SEC=0 + test -z "$RUN_UNIX" -o "$RUN_UNIX" = 0 || EXEC_SEC=$((execs_done / RUN_UNIX)) PATH_PERC=$((cur_path * 100 / paths_total)) TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX)) @@ -184,7 +185,9 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do echo " ${RED}timeout_ratio $TIMEOUT_PERC%${NC}" fi - if [ $EXEC_SEC -lt 100 ]; then + if [ $EXEC_SEC -eq 0 ]; then + echo " ${YELLOW}no data yet, 0 execs/sec${NC}" + elif [ $EXEC_SEC -lt 100 ]; then echo " ${RED}slow execution, $EXEC_SEC execs/sec${NC}" fi -- cgit 1.4.1 From 83790d65afb52a055d093451a50ce55690a25002 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Jul 2020 11:16:39 +0200 Subject: eliminate race condition for cpu affinity on -M/-S --- docs/Changelog.md | 4 ++- include/config.h | 4 +++ src/afl-fuzz-init.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++------- src/afl-fuzz.c | 24 +++++++------ 4 files changed, 105 insertions(+), 24 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 57b2b4a2..18e4e97e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,7 +10,9 @@ sending a mail to . ### Version ++2.66d (devel) - - ... ? + - afl-fuzz: + - eliminated CPU affinity race condition for -S/-M runs + - small fixes to afl-plot, afl-whatsup and man page creation ### Version ++2.66c (release) diff --git a/include/config.h b/include/config.h index 7de74009..4503c3e9 100644 --- a/include/config.h +++ b/include/config.h @@ -380,6 +380,10 @@ #define CMPLOG_SHM_ENV_VAR "__AFL_CMPLOG_SHM_ID" +/* CPU Affinity lockfile env var */ + +#define CPU_AFFINITY_ENV_VAR "__AFL_LOCKFILE" + /* Uncomment this to use inferior block-coverage-based instrumentation. Note that you need to recompile the target binary for this to have any effect: */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a2e849dc..e51b4729 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -36,14 +36,11 @@ void bind_to_free_cpu(afl_state_t *afl) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) cpu_set_t c; #elif defined(__NetBSD__) - cpuset_t * c; + cpuset_t *c; #elif defined(__sun) - psetid_t c; + psetid_t c; #endif - u8 cpu_used[4096] = {0}; - u32 i; - if (afl->cpu_core_count < 2) { return; } if (afl->afl_env.afl_no_affinity) { @@ -53,13 +50,46 @@ void bind_to_free_cpu(afl_state_t *afl) { } + u8 cpu_used[4096] = {0}, lockfile[PATH_MAX] = ""; + u32 i; + + if (afl->sync_id) { + + s32 lockfd, first = 1; + + snprintf(lockfile, sizeof(lockfile), "%s/.affinity_lock", afl->sync_dir); + setenv(CPU_AFFINITY_ENV_VAR, lockfile, 1); + + do { + + if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { + + if (first) { + + WARNF("CPU affinity lock file present, waiting ..."); + first = 0; + + } + + usleep(1000); + + } + + } while (lockfd < 0); + + close(lockfd); + + } + #if defined(__linux__) + DIR * d; struct dirent *de; d = opendir("/proc"); if (!d) { + if (lockfile[0]) unlink(lockfile); WARNF("Unable to access /proc - can't scan for free CPU cores."); return; @@ -67,11 +97,6 @@ void bind_to_free_cpu(afl_state_t *afl) { ACTF("Checking CPU core loadout..."); - /* Introduce some jitter, in case multiple AFL tasks are doing the same - thing at the same time... */ - - usleep(R(1000) * 250); - /* Scan all /proc//status entries, checking for Cpus_allowed_list. Flag all processes bound to a specific CPU using cpu_used[]. This will fail for some exotic binding setups, but is likely good enough in almost @@ -114,20 +139,29 @@ void bind_to_free_cpu(afl_state_t *afl) { } closedir(d); + #elif defined(__FreeBSD__) || defined(__DragonFly__) + struct kinfo_proc *procs; size_t nprocs; size_t proccount; int s_name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]); - if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return; + if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) { + + if (lockfile[0]) unlink(lockfile); + return; + + } + proccount = nprocs / sizeof(*procs); nprocs = nprocs * 4 / 3; procs = ck_alloc(nprocs); if (sysctl(s_name, s_name_l, procs, &nprocs, NULL, 0) != 0) { + if (lockfile[0]) unlink(lockfile); ck_free(procs); return; @@ -136,6 +170,7 @@ void bind_to_free_cpu(afl_state_t *afl) { for (i = 0; i < proccount; i++) { #if defined(__FreeBSD__) + if (!strcmp(procs[i].ki_comm, "idle")) continue; // fix when ki_oncpu = -1 @@ -145,16 +180,21 @@ void bind_to_free_cpu(afl_state_t *afl) { if (oncpu != -1 && oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 60) cpu_used[oncpu] = 1; + #elif defined(__DragonFly__) + if (procs[i].kp_lwp.kl_cpuid < sizeof(cpu_used) && procs[i].kp_lwp.kl_pctcpu > 10) cpu_used[procs[i].kp_lwp.kl_cpuid] = 1; + #endif } ck_free(procs); + #elif defined(__NetBSD__) + struct kinfo_proc2 *procs; size_t nprocs; size_t proccount; @@ -163,13 +203,20 @@ void bind_to_free_cpu(afl_state_t *afl) { CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0}; size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]); - if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return; + if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) { + + if (lockfile[0]) unlink(lockfile); + return; + + } + proccount = nprocs / sizeof(struct kinfo_proc2); procs = ck_alloc(nprocs * sizeof(struct kinfo_proc2)); s_name[5] = proccount; if (sysctl(s_name, s_name_l, procs, &nprocs, NULL, 0) != 0) { + if (lockfile[0]) unlink(lockfile); ck_free(procs); return; @@ -183,7 +230,9 @@ void bind_to_free_cpu(afl_state_t *afl) { } ck_free(procs); + #elif defined(__sun) + kstat_named_t *n; kstat_ctl_t * m; kstat_t * k; @@ -198,6 +247,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (!k) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -205,6 +255,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (kstat_read(m, k, NULL)) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -220,6 +271,7 @@ void bind_to_free_cpu(afl_state_t *afl) { k = kstat_lookup(m, "cpu_stat", i, NULL); if (kstat_read(m, k, &cs)) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -233,6 +285,7 @@ void bind_to_free_cpu(afl_state_t *afl) { } kstat_close(m); + #else #warning \ "For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus" @@ -241,7 +294,9 @@ void bind_to_free_cpu(afl_state_t *afl) { size_t cpu_start = 0; try: + #if !defined(__ANDROID__) + for (i = cpu_start; i < afl->cpu_core_count; i++) { if (!cpu_used[i]) { break; } @@ -251,6 +306,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (i == afl->cpu_core_count) { #else + for (i = afl->cpu_core_count - cpu_start - 1; i > -1; i--) if (!cpu_used[i]) break; if (i == -1) { @@ -274,18 +330,25 @@ void bind_to_free_cpu(afl_state_t *afl) { afl->cpu_aff = i; #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) + CPU_ZERO(&c); CPU_SET(i, &c); + #elif defined(__NetBSD__) + c = cpuset_create(); if (c == NULL) PFATAL("cpuset_create failed"); cpuset_set(i, c); + #elif defined(__sun) + pset_create(&c); if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); + #endif #if defined(__linux__) + if (sched_setaffinity(0, sizeof(c), &c)) { if (cpu_start == afl->cpu_core_count) { @@ -302,6 +365,7 @@ if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); } #elif defined(__FreeBSD__) || defined(__DragonFly__) + if (pthread_setaffinity_np(pthread_self(), sizeof(c), &c)) { if (cpu_start == afl->cpu_core_count) @@ -314,6 +378,7 @@ if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); } #elif defined(__NetBSD__) + if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { if (cpu_start == afl->cpu_core_count) @@ -326,7 +391,9 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { } cpuset_destroy(c); + #elif defined(__sun) + if (pset_bind(c, P_PID, getpid(), NULL)) { if (cpu_start == afl->cpu_core_count) @@ -339,11 +406,17 @@ if (pset_bind(c, P_PID, getpid(), NULL)) { } pset_destroy(c); + #else + // this will need something for other platforms // TODO: Solaris/Illumos has processor_bind ... might worth a try + #endif + if (lockfile[0]) unlink(lockfile); + // we leave the environment variable to ensure a cleanup for other processes + } #endif /* HAVE_AFFINITY */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4e2669c..f7f247f3 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -42,19 +42,21 @@ static void at_exit() { int i; char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL}; - char *ptr = getenv("__AFL_TARGET_PID1"); + char *ptr; + ptr = getenv(CPU_AFFINITY_ENV_VAR); + if (ptr && *ptr) unlink(ptr); + + ptr = getenv("__AFL_TARGET_PID1"); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); ptr = getenv("__AFL_TARGET_PID2"); - if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); i = 0; while (list[i] != NULL) { ptr = getenv(list[i]); - if (ptr && *ptr) { #ifdef USEMMAP @@ -1011,17 +1013,19 @@ int main(int argc, char **argv_orig, char **envp) { } + check_crash_handling(); + check_cpu_governor(afl); + get_core_count(afl); + atexit(at_exit); + + setup_dirs_fds(afl); + #ifdef HAVE_AFFINITY bind_to_free_cpu(afl); #endif /* HAVE_AFFINITY */ - check_crash_handling(); - check_cpu_governor(afl); - - atexit(at_exit); - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); @@ -1038,12 +1042,10 @@ int main(int argc, char **argv_orig, char **envp) { } - setup_dirs_fds(afl); - if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { WARNF("no -M main node found. You need to run one main instance!"); - sleep(5); + sleep(3); } -- cgit 1.4.1 From 7c8d8233966c5f3009710efeb9c9efb50015ebbb Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Jul 2020 12:07:29 +0200 Subject: dockerfile updates --- Dockerfile | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 905e8265..0b1645b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # has focal has gcc-10 but not g++-10 ... # -FROM ubuntu:20.04 +FROM ubuntu:20.04 AS aflplusplus MAINTAINER afl++ team LABEL "about"="AFLplusplus docker image" @@ -20,7 +20,7 @@ RUN apt-get update && apt-get upgrade -y && \ python3 python3-dev python3-setuptools python-is-python3 \ libtool libtool-bin \ libglib2.0-dev \ - wget vim jupp nano \ + wget vim jupp nano bash-completion \ apt-utils apt-transport-https ca-certificates gnupg dialog \ libpixman-1-dev @@ -46,17 +46,15 @@ RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 0 RUN rm -rf /var/cache/apt/archives/* -ARG CC=gcc-10 -ARG CXX=g++-10 -ARG LLVM_CONFIG=llvm-config-11 +ENV LLVM_CONFIG=llvm-config-11 +ENV AFL_SKIP_CPUFREQ=1 -RUN git clone https://github.com/AFLplusplus/AFLplusplus -RUN cd AFLplusplus && export REAL_CXX=g++-10 && make distrib && \ - make install && make clean +RUN git clone https://github.com/AFLplusplus/AFLplusplus /AFLplusplus +RUN cd /AFLplusplus && export REAL_CXX=g++-10 && export CC=gcc-10 && \ + export CXX=g++-10 && make distrib && make install && make clean -RUN git clone https://github.com/vanhauser-thc/afl-cov afl-cov -RUN cd afl-cov && make install +RUN git clone https://github.com/vanhauser-thc/afl-cov /afl-cov +RUN cd /afl-cov && make install RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc -ENV AFL_SKIP_CPUFREQ=1 -- cgit 1.4.1 From 90adc2cb853482ae058a4b09719502ec6c3c22b8 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 9 Jul 2020 15:43:05 +0100 Subject: illumos littlefixes: little typo for cpu binding and even tough gcc plugin less good than LLVM, clang is more buggy on this os. --- gcc_plugin/GNUmakefile | 7 ++++++- src/afl-fuzz-init.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile index bf5c53e0..002437cb 100644 --- a/gcc_plugin/GNUmakefile +++ b/gcc_plugin/GNUmakefile @@ -70,9 +70,14 @@ ifeq "$(TEST_MMAP)" "1" endif ifneq "$(shell uname -s)" "Haiku" - LDFLAGS += -lrt + LDFLAGS += -lrt endif +ifeq "$(shell uname -s)" "SunOS" + PLUGIN_FLAGS += -I/usr/include/gmp +endif + + PROGS = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index e51b4729..e95ae95f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -398,7 +398,7 @@ if (pset_bind(c, P_PID, getpid(), NULL)) { if (cpu_start == afl->cpu_core_count) PFATAL("pset_bind failed for cpu %d, exit", i); - WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i); + WARNF("pset_bind failed to CPU %d, trying next CPU", i); cpu_start++; goto try ; -- cgit 1.4.1 From 84a320f834b8138b9b3193e977cd170d1d445a44 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Jul 2020 21:31:15 +0200 Subject: skip -fuse-ld parameters when in LTO mode --- llvm_mode/afl-clang-fast.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 72262c1e..fa15a278 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -378,6 +378,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; + + if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) + continue; cc_params[cc_par_cnt++] = cur; -- cgit 1.4.1 From 60bb1afc727bdade0504e14a8d781c1a37fcda28 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Jul 2020 21:32:06 +0200 Subject: code format --- llvm_mode/split-compares-pass.so.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 82645224..1333bd41 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -640,7 +640,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { BranchInst::Create(end_bb, signequal_bb); - /* create a new bb which is executed if exponents are satisfying the compare */ + /* create a new bb which is executed if exponents are satisfying the compare + */ BasicBlock *middle_bb = BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb); @@ -738,7 +739,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { { auto term = signequal_bb->getTerminator(); - /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ + /* if the exponents are satifying the compare do a fraction cmp in + * middle_bb */ BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal_bb); term->eraseFromParent(); -- cgit 1.4.1 From c3a6065a2109f2d4a2bddbb2985b19e19a1487de Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Jul 2020 23:02:04 +0200 Subject: shm + mem info in travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4271b821..793796f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,6 +51,7 @@ script: - gcc -v - clang -v - sudo -E ./afl-system-config + - free ; sysctl -a|grep -i shm ; ipcs -m -l ; ipcs -m - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LLVM_CONFIG=`pwd`/"$NAME" ; make source-only ASAN_BUILD=1 ; fi - if [ "$TRAVIS_OS_NAME" = "linux" -a "$TRAVIS_CPU_ARCH" = "amd64" ]; then make distrib ASAN_BUILD=1 ; fi - if [ "$TRAVIS_CPU_ARCH" = "arm64" ] ; then echo DEBUG ; find / -name llvm-config.h 2>/dev/null; apt-cache search clang | grep clang- ; apt-cache search llvm | grep llvm- ; dpkg -l | egrep 'clang|llvm'; echo DEBUG ; export LLVM_CONFIG=llvm-config-6.0 ; make ASAN_BUILD=1 ; cd qemu_mode && sh ./build_qemu_support.sh ; cd .. ; fi -- cgit 1.4.1 From 2981f2025f28a690511db3c6a8e230d6b8ff348c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Jul 2020 23:14:33 +0200 Subject: increase shm for travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 793796f4..dda57bbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,7 +51,8 @@ script: - gcc -v - clang -v - sudo -E ./afl-system-config - - free ; sysctl -a|grep -i shm ; ipcs -m -l ; ipcs -m + - sudo sysctl -w kernel.shmmax=10000000000 + - free ; sudo sysctl -a|grep -i shm ; ipcs -m -l ; ipcs -m - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LLVM_CONFIG=`pwd`/"$NAME" ; make source-only ASAN_BUILD=1 ; fi - if [ "$TRAVIS_OS_NAME" = "linux" -a "$TRAVIS_CPU_ARCH" = "amd64" ]; then make distrib ASAN_BUILD=1 ; fi - if [ "$TRAVIS_CPU_ARCH" = "arm64" ] ; then echo DEBUG ; find / -name llvm-config.h 2>/dev/null; apt-cache search clang | grep clang- ; apt-cache search llvm | grep llvm- ; dpkg -l | egrep 'clang|llvm'; echo DEBUG ; export LLVM_CONFIG=llvm-config-6.0 ; make ASAN_BUILD=1 ; cd qemu_mode && sh ./build_qemu_support.sh ; cd .. ; fi -- cgit 1.4.1 From 571031a46730a7f0d5a99ff373d7bdc8c2561149 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 11 Jul 2020 00:56:35 +0200 Subject: fix several cases in floating point comparison splitting --- llvm_mode/split-compares-pass.so.cc | 362 ++++++++++++++++++++++++------------ 1 file changed, 238 insertions(+), 124 deletions(-) diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 1333bd41..615253ce 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -80,6 +80,7 @@ class SplitComparesTransform : public ModulePass { size_t splitIntCompares(Module &M, unsigned bitw); size_t splitFPCompares(Module &M); bool simplifyCompares(Module &M); + bool simplifyFPCompares(Module &M); bool simplifyIntSignedness(Module &M); size_t nextPowerOfTwo(size_t in); @@ -89,12 +90,10 @@ class SplitComparesTransform : public ModulePass { char SplitComparesTransform::ID = 0; -/* This function splits ICMP instructions with xGE or xLE predicates into two - * ICMP instructions with predicate xGT or xLT and EQ */ -bool SplitComparesTransform::simplifyCompares(Module &M) { - +/* This function splits FCMP instructions with xGE or xLE predicates into two + * FCMP instructions with predicate xGT or xLT and EQ */ +bool SplitComparesTransform::simplifyFPCompares(Module &M) { LLVMContext & C = M.getContext(); - std::vector icomps; std::vector fcomps; IntegerType * Int1Ty = IntegerType::getInt1Ty(C); @@ -112,24 +111,6 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { if ((selectcmpInst = dyn_cast(&IN))) { - if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE || - selectcmpInst->getPredicate() == CmpInst::ICMP_SGE || - selectcmpInst->getPredicate() == CmpInst::ICMP_ULE || - selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) { - - auto op0 = selectcmpInst->getOperand(0); - auto op1 = selectcmpInst->getOperand(1); - - IntegerType *intTyOp0 = dyn_cast(op0->getType()); - IntegerType *intTyOp1 = dyn_cast(op1->getType()); - - /* this is probably not needed but we do it anyway */ - if (!intTyOp0 || !intTyOp1) { continue; } - - icomps.push_back(selectcmpInst); - - } - if (enableFPSplit && (selectcmpInst->getPredicate() == CmpInst::FCMP_OGE || selectcmpInst->getPredicate() == CmpInst::FCMP_UGE || @@ -159,105 +140,159 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { } - if (!icomps.size() && !fcomps.size()) { return false; } + if (!fcomps.size()) { return false; } - for (auto &IcmpInst : icomps) { + /* transform for floating point */ + for (auto &FcmpInst : fcomps) { - BasicBlock *bb = IcmpInst->getParent(); + BasicBlock *bb = FcmpInst->getParent(); - auto op0 = IcmpInst->getOperand(0); - auto op1 = IcmpInst->getOperand(1); + auto op0 = FcmpInst->getOperand(0); + auto op1 = FcmpInst->getOperand(1); /* find out what the new predicate is going to be */ - auto pred = dyn_cast(IcmpInst)->getPredicate(); + auto pred = dyn_cast(FcmpInst)->getPredicate(); CmpInst::Predicate new_pred; switch (pred) { - case CmpInst::ICMP_UGE: - new_pred = CmpInst::ICMP_UGT; + case CmpInst::FCMP_UGE: + new_pred = CmpInst::FCMP_UGT; break; - case CmpInst::ICMP_SGE: - new_pred = CmpInst::ICMP_SGT; + case CmpInst::FCMP_OGE: + new_pred = CmpInst::FCMP_OGT; break; - case CmpInst::ICMP_ULE: - new_pred = CmpInst::ICMP_ULT; + case CmpInst::FCMP_ULE: + new_pred = CmpInst::FCMP_ULT; break; - case CmpInst::ICMP_SLE: - new_pred = CmpInst::ICMP_SLT; + case CmpInst::FCMP_OLE: + new_pred = CmpInst::FCMP_OLT; break; default: // keep the compiler happy continue; } - /* split before the icmp instruction */ - BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst)); + /* split before the fcmp instruction */ + BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst)); /* the old bb now contains a unconditional jump to the new one (end_bb) * we need to delete it later */ - /* create the ICMP instruction with new_pred and add it to the old basic - * block bb it is now at the position where the old IcmpInst was */ - Instruction *icmp_np; - icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1); + /* create the FCMP instruction with new_pred and add it to the old basic + * block bb it is now at the position where the old FcmpInst was */ + Instruction *fcmp_np; + fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1); bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), - icmp_np); + fcmp_np); - /* create a new basic block which holds the new EQ icmp */ - Instruction *icmp_eq; + /* create a new basic block which holds the new EQ fcmp */ + Instruction *fcmp_eq; /* insert middle_bb before end_bb */ BasicBlock *middle_bb = BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb); - icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1); - middle_bb->getInstList().push_back(icmp_eq); + fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1); + middle_bb->getInstList().push_back(fcmp_eq); /* add an unconditional branch to the end of middle_bb with destination * end_bb */ BranchInst::Create(end_bb, middle_bb); /* replace the uncond branch with a conditional one, which depends on the - * new_pred icmp. True goes to end, false to the middle (injected) bb */ + * new_pred fcmp. True goes to end, false to the middle (injected) bb */ auto term = bb->getTerminator(); - BranchInst::Create(end_bb, middle_bb, icmp_np, bb); + BranchInst::Create(end_bb, middle_bb, fcmp_np, bb); term->eraseFromParent(); - /* replace the old IcmpInst (which is the first inst in end_bb) with a PHI + /* replace the old FcmpInst (which is the first inst in end_bb) with a PHI * inst to wire up the loose ends */ PHINode *PN = PHINode::Create(Int1Ty, 2, ""); - /* the first result depends on the outcome of icmp_eq */ - PN->addIncoming(icmp_eq, middle_bb); - /* if the source was the original bb we know that the icmp_np yielded true + /* the first result depends on the outcome of fcmp_eq */ + PN->addIncoming(fcmp_eq, middle_bb); + /* if the source was the original bb we know that the fcmp_np yielded true * hence we can hardcode this value */ PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb); - /* replace the old IcmpInst with our new and shiny PHI inst */ - BasicBlock::iterator ii(IcmpInst); - ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN); + /* replace the old FcmpInst with our new and shiny PHI inst */ + BasicBlock::iterator ii(FcmpInst); + ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN); } - /* now for floating point */ - for (auto &FcmpInst : fcomps) { + return true; - BasicBlock *bb = FcmpInst->getParent(); +} - auto op0 = FcmpInst->getOperand(0); - auto op1 = FcmpInst->getOperand(1); +/* This function splits ICMP instructions with xGE or xLE predicates into two + * ICMP instructions with predicate xGT or xLT and EQ */ +bool SplitComparesTransform::simplifyCompares(Module &M) { + + LLVMContext & C = M.getContext(); + std::vector icomps; + IntegerType * Int1Ty = IntegerType::getInt1Ty(C); + + /* iterate over all functions, bbs and instruction and add + * all integer comparisons with >= and <= predicates to the icomps vector */ + for (auto &F : M) { + + if (!isInInstrumentList(&F)) continue; + + for (auto &BB : F) { + + for (auto &IN : BB) { + + CmpInst *selectcmpInst = nullptr; + + if ((selectcmpInst = dyn_cast(&IN))) { + + if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE || + selectcmpInst->getPredicate() == CmpInst::ICMP_SGE || + selectcmpInst->getPredicate() == CmpInst::ICMP_ULE || + selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) { + + auto op0 = selectcmpInst->getOperand(0); + auto op1 = selectcmpInst->getOperand(1); + + IntegerType *intTyOp0 = dyn_cast(op0->getType()); + IntegerType *intTyOp1 = dyn_cast(op1->getType()); + + /* this is probably not needed but we do it anyway */ + if (!intTyOp0 || !intTyOp1) { continue; } + + icomps.push_back(selectcmpInst); + + } + + } + + } + + } + + } + + if (!icomps.size()) { return false; } + + for (auto &IcmpInst : icomps) { + + BasicBlock *bb = IcmpInst->getParent(); + + auto op0 = IcmpInst->getOperand(0); + auto op1 = IcmpInst->getOperand(1); /* find out what the new predicate is going to be */ - auto pred = dyn_cast(FcmpInst)->getPredicate(); + auto pred = dyn_cast(IcmpInst)->getPredicate(); CmpInst::Predicate new_pred; switch (pred) { - case CmpInst::FCMP_UGE: - new_pred = CmpInst::FCMP_UGT; + case CmpInst::ICMP_UGE: + new_pred = CmpInst::ICMP_UGT; break; - case CmpInst::FCMP_OGE: - new_pred = CmpInst::FCMP_OGT; + case CmpInst::ICMP_SGE: + new_pred = CmpInst::ICMP_SGT; break; - case CmpInst::FCMP_ULE: - new_pred = CmpInst::FCMP_ULT; + case CmpInst::ICMP_ULE: + new_pred = CmpInst::ICMP_ULT; break; - case CmpInst::FCMP_OLE: - new_pred = CmpInst::FCMP_OLT; + case CmpInst::ICMP_SLE: + new_pred = CmpInst::ICMP_SLT; break; default: // keep the compiler happy continue; @@ -265,25 +300,25 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { } /* split before the icmp instruction */ - BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst)); + BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst)); /* the old bb now contains a unconditional jump to the new one (end_bb) * we need to delete it later */ /* create the ICMP instruction with new_pred and add it to the old basic * block bb it is now at the position where the old IcmpInst was */ - Instruction *fcmp_np; - fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1); + Instruction *icmp_np; + icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1); bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), - fcmp_np); + icmp_np); - /* create a new basic block which holds the new EQ fcmp */ - Instruction *fcmp_eq; + /* create a new basic block which holds the new EQ icmp */ + Instruction *icmp_eq; /* insert middle_bb before end_bb */ BasicBlock *middle_bb = BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb); - fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1); - middle_bb->getInstList().push_back(fcmp_eq); + icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1); + middle_bb->getInstList().push_back(icmp_eq); /* add an unconditional branch to the end of middle_bb with destination * end_bb */ BranchInst::Create(end_bb, middle_bb); @@ -291,20 +326,20 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { /* replace the uncond branch with a conditional one, which depends on the * new_pred icmp. True goes to end, false to the middle (injected) bb */ auto term = bb->getTerminator(); - BranchInst::Create(end_bb, middle_bb, fcmp_np, bb); + BranchInst::Create(end_bb, middle_bb, icmp_np, bb); term->eraseFromParent(); /* replace the old IcmpInst (which is the first inst in end_bb) with a PHI * inst to wire up the loose ends */ PHINode *PN = PHINode::Create(Int1Ty, 2, ""); /* the first result depends on the outcome of icmp_eq */ - PN->addIncoming(fcmp_eq, middle_bb); + PN->addIncoming(icmp_eq, middle_bb); /* if the source was the original bb we know that the icmp_np yielded true * hence we can hardcode this value */ PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb); /* replace the old IcmpInst with our new and shiny PHI inst */ - BasicBlock::iterator ii(FcmpInst); - ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN); + BasicBlock::iterator ii(IcmpInst); + ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN); } @@ -696,7 +731,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } /* compare the exponents of the operands */ + Instruction *icmp_exponents_equal; Instruction *icmp_exponent_result; + BasicBlock *signequal2_bb = signequal_bb; switch (FcmpInst->getPredicate()) { case CmpInst::FCMP_OEQ: @@ -708,22 +745,52 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_exponent_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, m_e0, m_e1); break; + /* compare the exponents of the operands (signs are equal) + * if exponents are equal -> proceed to mantissa comparison + * else get result depending on sign + */ case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: Instruction *icmp_exponent; - icmp_exponent = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGE, m_e0, m_e1); + icmp_exponents_equal = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1); signequal_bb->getInstList().insert( - BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); + BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponents_equal); + + // shortcut for unequal exponents + signequal2_bb = signequal_bb->splitBasicBlock(BasicBlock::iterator(signequal_bb->getTerminator())); + + /* if the exponents are equal goto middle_bb else to signequal2_bb */ + term = signequal_bb->getTerminator(); + BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, signequal_bb); + term->eraseFromParent(); + + icmp_exponent = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1); + signequal2_bb->getInstList().insert( + BasicBlock::iterator(signequal2_bb->getTerminator()), icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: - icmp_exponent = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULE, m_e0, m_e1); + icmp_exponents_equal = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1); signequal_bb->getInstList().insert( - BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); + BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponents_equal); + + // shortcut for unequal exponents + signequal2_bb = signequal_bb->splitBasicBlock(BasicBlock::iterator(signequal_bb->getTerminator())); + + /* if the exponents are equal goto middle_bb else to signequal2_bb */ + term = signequal_bb->getTerminator(); + BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, signequal_bb); + term->eraseFromParent(); + + icmp_exponent = + CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1); + signequal2_bb->getInstList().insert( + BasicBlock::iterator(signequal2_bb->getTerminator()), icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; @@ -732,16 +799,35 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } - signequal_bb->getInstList().insert( - BasicBlock::iterator(signequal_bb->getTerminator()), + signequal2_bb->getInstList().insert( + BasicBlock::iterator(signequal2_bb->getTerminator()), icmp_exponent_result); { - auto term = signequal_bb->getTerminator(); - /* if the exponents are satifying the compare do a fraction cmp in - * middle_bb */ - BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal_bb); + term = signequal2_bb->getTerminator(); + + switch (FcmpInst->getPredicate()) { + case CmpInst::FCMP_OEQ: + /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ + BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal2_bb); + break; + case CmpInst::FCMP_ONE: + case CmpInst::FCMP_UNE: + /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ + BranchInst::Create(end_bb, middle_bb, icmp_exponent_result, signequal2_bb); + break; + case CmpInst::FCMP_OGT: + case CmpInst::FCMP_UGT: + case CmpInst::FCMP_OLT: + case CmpInst::FCMP_ULT: + BranchInst::Create(end_bb, signequal2_bb); + break; + default: + continue; + + } + term->eraseFromParent(); } @@ -802,44 +888,67 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { /* compare the fractions of the operands */ Instruction *icmp_fraction_result; + Instruction *icmp_fraction_result2; + BasicBlock * middle2_bb = middle_bb; + PHINode *PN2 = nullptr; switch (FcmpInst->getPredicate()) { case CmpInst::FCMP_OEQ: icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1); + middle2_bb->getInstList().insert( + BasicBlock::iterator(middle2_bb->getTerminator()), icmp_fraction_result); + break; case CmpInst::FCMP_UNE: case CmpInst::FCMP_ONE: icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1); + middle2_bb->getInstList().insert( + BasicBlock::iterator(middle2_bb->getTerminator()), icmp_fraction_result); + break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: - Instruction *icmp_fraction; - icmp_fraction = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1); - middle_bb->getInstList().insert( - BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction); - icmp_fraction_result = - BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0); - break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: - icmp_fraction = - CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1); - middle_bb->getInstList().insert( - BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction); - icmp_fraction_result = - BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0); + { + middle2_bb = middle_bb->splitBasicBlock(BasicBlock::iterator(middle_bb->getTerminator())); + + BasicBlock * negative_bb = + BasicBlock::Create(C, "negative_value", middle2_bb->getParent(), middle2_bb); + BasicBlock * positive_bb = + BasicBlock::Create(C, "positive_value", negative_bb->getParent(), negative_bb); + + if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT + || + FcmpInst->getPredicate() == CmpInst::FCMP_UGT) { + negative_bb->getInstList().push_back(icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); + positive_bb->getInstList().push_back(icmp_fraction_result2 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); + } else { + negative_bb->getInstList().push_back(icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); + positive_bb->getInstList().push_back(icmp_fraction_result2 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); + } + BranchInst::Create(middle2_bb, negative_bb); + BranchInst::Create(middle2_bb, positive_bb); + + term = middle_bb->getTerminator(); + BranchInst::Create(negative_bb, positive_bb, t_s0, middle_bb); + term->eraseFromParent(); + + PN2 = PHINode::Create(Int1Ty, 2, ""); + PN2->addIncoming(icmp_fraction_result, negative_bb); + PN2->addIncoming(icmp_fraction_result2, positive_bb); + middle2_bb->getInstList().insert( + BasicBlock::iterator(middle2_bb->getTerminator()), PN2); + + } break; default: continue; } - middle_bb->getInstList().insert( - BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction_result); - PHINode *PN = PHINode::Create(Int1Ty, 3, ""); switch (FcmpInst->getPredicate()) { @@ -851,7 +960,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { /* unequal exponents cannot be equal values, too */ PN->addIncoming(ConstantInt::get(Int1Ty, 0), signequal_bb); /* fractions comparison */ - PN->addIncoming(icmp_fraction_result, middle_bb); + PN->addIncoming(icmp_fraction_result, middle2_bb); break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: @@ -859,25 +968,25 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { /* goto true branch */ PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb); /* unequal exponents are unequal values, too */ - PN->addIncoming(ConstantInt::get(Int1Ty, 1), signequal_bb); + PN->addIncoming(icmp_exponent_result, signequal_bb); /* fractions comparison */ - PN->addIncoming(icmp_fraction_result, middle_bb); + PN->addIncoming(icmp_fraction_result, middle2_bb); break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: /* if op1 is negative goto true branch, else go on comparing */ PN->addIncoming(t_s1, bb); - PN->addIncoming(icmp_exponent_result, signequal_bb); - PN->addIncoming(icmp_fraction_result, middle_bb); + PN->addIncoming(icmp_exponent_result, signequal2_bb); + PN->addIncoming(PN2, middle2_bb); break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: /* if op0 is negative goto true branch, else go on comparing */ PN->addIncoming(t_s0, bb); - PN->addIncoming(icmp_exponent_result, signequal_bb); - PN->addIncoming(icmp_fraction_result, middle_bb); + PN->addIncoming(icmp_exponent_result, signequal2_bb); + PN->addIncoming(PN2, middle2_bb); break; default: continue; @@ -1117,24 +1226,29 @@ bool SplitComparesTransform::runOnModule(Module &M) { enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL; - simplifyCompares(M); - - simplifyIntSignedness(M); - if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) { errs() << "Split-compare-pass by laf.intel@gmail.com, extended by " "heiko@hexco.de\n"; - if (enableFPSplit) + if (enableFPSplit) { + + simplifyFPCompares(M); + errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M) << " FP comparisons splitted\n"; + } + } else be_quiet = 1; + simplifyCompares(M); + + simplifyIntSignedness(M); + switch (bitw) { case 64: -- cgit 1.4.1 From b126a5d5a8d90dcc10ccb890b379c3dfdc5cf8d4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 12 Jul 2020 13:44:25 +0200 Subject: LTO: autodict default, instrim disabled --- docs/Changelog.md | 5 ++ llvm_mode/afl-clang-fast.c | 20 ++--- llvm_mode/afl-llvm-lto-instrim.so.cc | 6 +- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 6 +- llvm_mode/split-compares-pass.so.cc | 107 +++++++++++++++++---------- 5 files changed, 86 insertions(+), 58 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 18e4e97e..b0bda6dc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,6 +12,11 @@ sending a mail to . ### Version ++2.66d (devel) - afl-fuzz: - eliminated CPU affinity race condition for -S/-M runs + - llvm_mode: + - fix for laf-intel float splitting + - LTO: autodictionary mode is a default + - LTO: instrim instrumentation disabled, only classic support used + as it is always better - small fixes to afl-plot, afl-whatsup and man page creation diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index fa15a278..8823b6a5 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -311,12 +311,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD); cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; - if (instrument_mode == INSTRUMENT_CFG) - cc_params[cc_par_cnt++] = - alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so", obj_path); - else - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); + /* + The current LTO instrim mode is not good, so we disable it + if (instrument_mode == INSTRUMENT_CFG) + cc_params[cc_par_cnt++] = + alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so", + obj_path); else + */ + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); cc_params[cc_par_cnt++] = lto_flag; } else { @@ -378,9 +381,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; - - if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) - continue; + + if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; cc_params[cc_par_cnt++] = cur; diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc index ca2b5886..880963ac 100644 --- a/llvm_mode/afl-llvm-lto-instrim.so.cc +++ b/llvm_mode/afl-llvm-lto-instrim.so.cc @@ -73,7 +73,7 @@ struct InsTrimLTO : public ModulePass { protected: uint32_t function_minimum_size = 1; char * skip_nozero = NULL; - int afl_global_id = 1, debug = 0, autodictionary = 0; + int afl_global_id = 1, debug = 0, autodictionary = 1; uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0; uint64_t map_addr = 0x10000; @@ -127,10 +127,6 @@ struct InsTrimLTO : public ModulePass { /* Process environment variables */ - if (getenv("AFL_LLVM_AUTODICTIONARY") || - getenv("AFL_LLVM_LTO_AUTODICTIONARY")) - autodictionary = 1; - if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0; if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) { diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index af2db3ff..3c1d3565 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -86,7 +86,7 @@ class AFLLTOPass : public ModulePass { bool runOnModule(Module &M) override; protected: - int afl_global_id = 1, debug = 0, autodictionary = 0; + int afl_global_id = 1, debug = 0, autodictionary = 1; uint32_t function_minimum_size = 1; uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0; uint64_t map_addr = 0x10000; @@ -120,10 +120,6 @@ bool AFLLTOPass::runOnModule(Module &M) { be_quiet = 1; - if (getenv("AFL_LLVM_AUTODICTIONARY") || - getenv("AFL_LLVM_LTO_AUTODICTIONARY")) - autodictionary = 1; - if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0; if (getenv("AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK") || diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 615253ce..0681fbd6 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -93,6 +93,7 @@ char SplitComparesTransform::ID = 0; /* This function splits FCMP instructions with xGE or xLE predicates into two * FCMP instructions with predicate xGT or xLT and EQ */ bool SplitComparesTransform::simplifyFPCompares(Module &M) { + LLVMContext & C = M.getContext(); std::vector fcomps; IntegerType * Int1Ty = IntegerType::getInt1Ty(C); @@ -733,7 +734,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { /* compare the exponents of the operands */ Instruction *icmp_exponents_equal; Instruction *icmp_exponent_result; - BasicBlock *signequal2_bb = signequal_bb; + BasicBlock * signequal2_bb = signequal_bb; switch (FcmpInst->getPredicate()) { case CmpInst::FCMP_OEQ: @@ -755,20 +756,24 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_exponents_equal = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1); signequal_bb->getInstList().insert( - BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponents_equal); + BasicBlock::iterator(signequal_bb->getTerminator()), + icmp_exponents_equal); // shortcut for unequal exponents - signequal2_bb = signequal_bb->splitBasicBlock(BasicBlock::iterator(signequal_bb->getTerminator())); + signequal2_bb = signequal_bb->splitBasicBlock( + BasicBlock::iterator(signequal_bb->getTerminator())); /* if the exponents are equal goto middle_bb else to signequal2_bb */ - term = signequal_bb->getTerminator(); - BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, signequal_bb); - term->eraseFromParent(); + term = signequal_bb->getTerminator(); + BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, + signequal_bb); + term->eraseFromParent(); icmp_exponent = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1); signequal2_bb->getInstList().insert( - BasicBlock::iterator(signequal2_bb->getTerminator()), icmp_exponent); + BasicBlock::iterator(signequal2_bb->getTerminator()), + icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; @@ -777,20 +782,24 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_exponents_equal = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1); signequal_bb->getInstList().insert( - BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponents_equal); + BasicBlock::iterator(signequal_bb->getTerminator()), + icmp_exponents_equal); // shortcut for unequal exponents - signequal2_bb = signequal_bb->splitBasicBlock(BasicBlock::iterator(signequal_bb->getTerminator())); + signequal2_bb = signequal_bb->splitBasicBlock( + BasicBlock::iterator(signequal_bb->getTerminator())); /* if the exponents are equal goto middle_bb else to signequal2_bb */ - term = signequal_bb->getTerminator(); - BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, signequal_bb); - term->eraseFromParent(); + term = signequal_bb->getTerminator(); + BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal, + signequal_bb); + term->eraseFromParent(); icmp_exponent = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1); signequal2_bb->getInstList().insert( - BasicBlock::iterator(signequal2_bb->getTerminator()), icmp_exponent); + BasicBlock::iterator(signequal2_bb->getTerminator()), + icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; @@ -808,21 +817,26 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { term = signequal2_bb->getTerminator(); switch (FcmpInst->getPredicate()) { + case CmpInst::FCMP_OEQ: - /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ - BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal2_bb); + /* if the exponents are satifying the compare do a fraction cmp in + * middle_bb */ + BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, + signequal2_bb); break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: - /* if the exponents are satifying the compare do a fraction cmp in middle_bb */ - BranchInst::Create(end_bb, middle_bb, icmp_exponent_result, signequal2_bb); + /* if the exponents are satifying the compare do a fraction cmp in + * middle_bb */ + BranchInst::Create(end_bb, middle_bb, icmp_exponent_result, + signequal2_bb); break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: - BranchInst::Create(end_bb, signequal2_bb); - break; + BranchInst::Create(end_bb, signequal2_bb); + break; default: continue; @@ -890,14 +904,15 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { Instruction *icmp_fraction_result; Instruction *icmp_fraction_result2; BasicBlock * middle2_bb = middle_bb; - PHINode *PN2 = nullptr; + PHINode * PN2 = nullptr; switch (FcmpInst->getPredicate()) { case CmpInst::FCMP_OEQ: icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1); middle2_bb->getInstList().insert( - BasicBlock::iterator(middle2_bb->getTerminator()), icmp_fraction_result); + BasicBlock::iterator(middle2_bb->getTerminator()), + icmp_fraction_result); break; case CmpInst::FCMP_UNE: @@ -905,36 +920,50 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1); middle2_bb->getInstList().insert( - BasicBlock::iterator(middle2_bb->getTerminator()), icmp_fraction_result); + BasicBlock::iterator(middle2_bb->getTerminator()), + icmp_fraction_result); break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: case CmpInst::FCMP_OLT: - case CmpInst::FCMP_ULT: - { - middle2_bb = middle_bb->splitBasicBlock(BasicBlock::iterator(middle_bb->getTerminator())); + case CmpInst::FCMP_ULT: { + + middle2_bb = middle_bb->splitBasicBlock( + BasicBlock::iterator(middle_bb->getTerminator())); - BasicBlock * negative_bb = - BasicBlock::Create(C, "negative_value", middle2_bb->getParent(), middle2_bb); - BasicBlock * positive_bb = - BasicBlock::Create(C, "positive_value", negative_bb->getParent(), negative_bb); + BasicBlock *negative_bb = BasicBlock::Create( + C, "negative_value", middle2_bb->getParent(), middle2_bb); + BasicBlock *positive_bb = BasicBlock::Create( + C, "positive_value", negative_bb->getParent(), negative_bb); - if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT - || + if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT || FcmpInst->getPredicate() == CmpInst::FCMP_UGT) { - negative_bb->getInstList().push_back(icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); - positive_bb->getInstList().push_back(icmp_fraction_result2 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); + + negative_bb->getInstList().push_back( + icmp_fraction_result = CmpInst::Create( + Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); + positive_bb->getInstList().push_back( + icmp_fraction_result2 = CmpInst::Create( + Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); + } else { - negative_bb->getInstList().push_back(icmp_fraction_result = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); - positive_bb->getInstList().push_back(icmp_fraction_result2 = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); + + negative_bb->getInstList().push_back( + icmp_fraction_result = CmpInst::Create( + Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1)); + positive_bb->getInstList().push_back( + icmp_fraction_result2 = CmpInst::Create( + Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1)); + } + BranchInst::Create(middle2_bb, negative_bb); BranchInst::Create(middle2_bb, positive_bb); - term = middle_bb->getTerminator(); + term = middle_bb->getTerminator(); BranchInst::Create(negative_bb, positive_bb, t_s0, middle_bb); - term->eraseFromParent(); + term->eraseFromParent(); PN2 = PHINode::Create(Int1Ty, 2, ""); PN2->addIncoming(icmp_fraction_result, negative_bb); @@ -942,8 +971,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { middle2_bb->getInstList().insert( BasicBlock::iterator(middle2_bb->getTerminator()), PN2); - } - break; + } break; + default: continue; -- cgit 1.4.1 From abb0d47985d22d8090540e987b2173d80c574439 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 12 Jul 2020 23:53:29 +0200 Subject: little untracer enhancements --- examples/afl_untracer/TODO | 2 ++ examples/afl_untracer/afl-untracer.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 examples/afl_untracer/TODO diff --git a/examples/afl_untracer/TODO b/examples/afl_untracer/TODO new file mode 100644 index 00000000..fffffacf --- /dev/null +++ b/examples/afl_untracer/TODO @@ -0,0 +1,2 @@ + * add shmem fuzzing + * add snapshot feature? diff --git a/examples/afl_untracer/afl-untracer.c b/examples/afl_untracer/afl-untracer.c index 664e691c..dc2cd378 100644 --- a/examples/afl_untracer/afl-untracer.c +++ b/examples/afl_untracer/afl-untracer.c @@ -56,6 +56,7 @@ #include #include #include +#include #if defined(__linux__) #include @@ -395,7 +396,7 @@ static void __afl_map_shm(void) { } /* Fork server logic. */ -static void __afl_start_forkserver(void) { +inline static void __afl_start_forkserver(void) { u8 tmp[4] = {0, 0, 0, 0}; u32 status = 0; @@ -411,7 +412,7 @@ static void __afl_start_forkserver(void) { } -static u32 __afl_next_testcase(u8 *buf, u32 max_len) { +inline static u32 __afl_next_testcase(u8 *buf, u32 max_len) { s32 status; @@ -437,7 +438,7 @@ static u32 __afl_next_testcase(u8 *buf, u32 max_len) { } -static void __afl_end_testcase(int status) { +inline static void __afl_end_testcase(int status) { if (write(FORKSRV_FD + 1, &status, 4) != 4) do_exit = 1; // fprintf(stderr, "write2 %d\n", do_exit); @@ -673,6 +674,8 @@ static void *(*o_function)(u8 *buf, int len); /* the MAIN function */ int main(int argc, char *argv[]) { + (void) personality(ADDR_NO_RANDOMIZE); // disable ASLR + pid = getpid(); if (getenv("AFL_DEBUG")) debug = 1; @@ -706,6 +709,9 @@ int main(int argc, char *argv[]) { while (1) { + // instead of fork() we could also use the snapshot lkm or do our own mini + // snapshot feature like in https://github.com/marcinguy/fuzzer + // -> snapshot.c if ((pid = fork()) == -1) PFATAL("fork failed"); if (pid) { @@ -738,6 +744,9 @@ int main(int argc, char *argv[]) { } +#ifndef _DEBUG +inline +#endif static void fuzz() { // STEP 3: call the function to fuzz, also the functions you might @@ -753,4 +762,3 @@ static void fuzz() { // END STEP 3 } - -- cgit 1.4.1 From 5a26656ea1095083def4c82918116b2d5cb2e641 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 13 Jul 2020 10:35:43 +0200 Subject: add floating point test cases. One for fuzzing (test-floatingpoint.c) and one for testing all cases with the instrumented program (test-fp_cases.c) --- test/test-floatingpoint.c | 18 +++++ test/test-fp_cases.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++ test/test.sh | 22 +++++- 3 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 test/test-floatingpoint.c create mode 100644 test/test-fp_cases.c diff --git a/test/test-floatingpoint.c b/test/test-floatingpoint.c new file mode 100644 index 00000000..f78b5d9f --- /dev/null +++ b/test/test-floatingpoint.c @@ -0,0 +1,18 @@ +#include +#include + +int main(void) +{ + long double magic; + + ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); + if (bytes_read < (ssize_t)sizeof(magic)) { + return 1; + } + + if( (-magic == 15.0 + 0.5 + 0.125 + 0.03125 + 0.0078125) ){ /* 15 + 1/2 + 1/8 + 1/32 + 1/128 */ + abort(); + } + + return 0; +} diff --git a/test/test-fp_cases.c b/test/test-fp_cases.c new file mode 100644 index 00000000..006ae32f --- /dev/null +++ b/test/test-fp_cases.c @@ -0,0 +1,190 @@ +/* test cases for floating point comparison transformations + * compile with -DFLOAT_TYPE=float + * or -DFLOAT_TYPE=double + * or -DFLOAT_TYPE="long double" + */ + + +#include + +int main() { + volatile FLOAT_TYPE a,b; + /* different values */ + a = -2.1; b = -2; /* signs equal, exp equal, mantissa > */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = 1.8; b = 2.1; /* signs equal, exp differ, mantissa > */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = 2; b = 2.1; /* signs equal, exp equal, mantissa < */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = -2; b = -1.8; /* signs equal, exp differ, mantissa < */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = -1; b = 1; /* signs differ, exp equal, mantissa equal */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = -1; b = 0; /* signs differ, exp differ, mantissa equal */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = -2; b = 2.8; /* signs differ, exp equal, mantissa < */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + a = -2; b = 1.8; /* signs differ, exp differ, mantissa < */ + assert((a < b)); + assert((a <= b)); + assert(!(a > b)); + assert(!(a >= b)); + assert((a != b)); + assert(!(a == b)); + + + a = -2; b = -2.1; /* signs equal, exp equal, mantissa > */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 2.1; b = 1.8; /* signs equal, exp differ, mantissa > */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 2.1; b = 2; /* signs equal, exp equal, mantissa < */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = -1.8; b = -2; /* signs equal, exp differ, mantissa < */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 1; b = -1; /* signs differ, exp equal, mantissa equal */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 0; b = -1; /* signs differ, exp differ, mantissa equal */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 2.8; b = -2; /* signs differ, exp equal, mantissa < */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + a = 1.8; b = -2; /* signs differ, exp differ, mantissa < */ + assert((a > b)); + assert((a >= b)); + assert(!(a < b)); + assert(!(a <= b)); + assert((a != b)); + assert(!(a == b)); + + /* equal values */ + a = 0; b = 0; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); + + a = -0; b = 0; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); + + a = 1; b = 1; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); + + a = 0.5; b = 0.5; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); + + a = -1; b = -1; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); + + a = -0.5; b = -0.5; + assert(!(a < b)); + assert((a <= b)); + assert(!(a > b)); + assert((a >= b)); + assert(!(a != b)); + assert((a == b)); +} diff --git a/test/test.sh b/test/test.sh index 90920215..d76c1902 100755 --- a/test/test.sh +++ b/test/test.sh @@ -372,8 +372,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { $ECHO "$YELLOW[-] llvm_mode InsTrim not compiled, cannot test" INCOMPLETE=1 } - AFL_LLVM_INSTRUMENT=AFL - AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > test.out 2>&1 + AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > test.out 2>&1 test -e test-compcov.compcov && test_compcov_binary_functionality ./test-compcov.compcov && { grep --binary-files=text -Eq " [ 123][0-9][0-9] location| [3-9][0-9] location" test.out && { $ECHO "$GREEN[+] llvm_mode laf-intel/compcov feature works correctly" @@ -386,6 +385,25 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } rm -f test-compcov.compcov test.out + AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 AFL_LLVM_LAF_SPLIT_FLOATS=1 ../afl-clang-fast -o test-floatingpoint test-floatingpoint.c > test.out 2>&1 + test -e test-floatingpoint && { + mkdir -p in + echo 0 > in/in + $ECHO "$GREY[*] running afl-fuzz with floating point splitting, this will take max. 16 seconds" + { + AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -V16 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 + } >>errors 2>&1 + test -n "$( ls out/queue/id:000002* 2>/dev/null )" && { + $ECHO "$GREEN[+] llvm_mode laf-intel floatingpoint splitting feature works correctly" + } || { + $ECHO "$RED[!] llvm_mode laf-intel floatingpoint splitting feature failed" + CODE=1 + } + } || { + $ECHO "$RED[!] llvm_mode laf-intel floatingpoint splitting feature compilation failed" + CODE=1 + } + rm -f test-floatingpoint test.out in/in echo foobar.c > instrumentlist.txt AFL_DEBUG=1 AFL_LLVM_INSTRUMENT_FILE=instrumentlist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && test_compcov_binary_functionality ./test-compcov && { -- cgit 1.4.1 From 6b79e1f76dee1dc5775b1e10edfa5b2180f553f8 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 13 Jul 2020 11:27:08 +0200 Subject: test.sh: FP fuzzing: check for crashes --- test/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index d76c1902..9938a051 100755 --- a/test/test.sh +++ b/test/test.sh @@ -393,7 +393,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { { AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -V16 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 } >>errors 2>&1 - test -n "$( ls out/queue/id:000002* 2>/dev/null )" && { + test -n "$( ls out/crashes/id:* 2>/dev/null )" && { $ECHO "$GREEN[+] llvm_mode laf-intel floatingpoint splitting feature works correctly" } || { $ECHO "$RED[!] llvm_mode laf-intel floatingpoint splitting feature failed" -- cgit 1.4.1 From 4d929f80fbf22eeb09612a575bcd1a4141b9a8a9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 13 Jul 2020 17:57:02 +0200 Subject: fix for laf intel float split not enabled if not not on a tty --- .custom-format.py | 3 ++- docs/Changelog.md | 3 ++- examples/afl_untracer/README.md | 1 + examples/afl_untracer/afl-untracer.c | 14 ++++++++------ llvm_mode/split-compares-pass.so.cc | 4 ++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.custom-format.py b/.custom-format.py index 6f1b0bfa..60f6d9c3 100755 --- a/.custom-format.py +++ b/.custom-format.py @@ -32,7 +32,8 @@ if CLANG_FORMAT_BIN is None: p = subprocess.Popen(["clang-format-10", "--version"], stdout=subprocess.PIPE) o, _ = p.communicate() o = str(o, "utf-8") - o = o[len("clang-format version "):].strip() + o = re.sub(r".*ersion ", "", o) + #o = o[len("clang-format version "):].strip() o = o[:o.find(".")] o = int(o) except: diff --git a/docs/Changelog.md b/docs/Changelog.md index b0bda6dc..8fb85ce6 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -13,7 +13,8 @@ sending a mail to . - afl-fuzz: - eliminated CPU affinity race condition for -S/-M runs - llvm_mode: - - fix for laf-intel float splitting + - fixes for laf-intel float splitting (thanks to mark-griffin for + reporting) - LTO: autodictionary mode is a default - LTO: instrim instrumentation disabled, only classic support used as it is always better diff --git a/examples/afl_untracer/README.md b/examples/afl_untracer/README.md index e59792cb..9cb13527 100644 --- a/examples/afl_untracer/README.md +++ b/examples/afl_untracer/README.md @@ -32,6 +32,7 @@ To easily run the scripts without needing to run the GUI with Ghidra: /opt/ghidra/support/analyzeHeadless /tmp/ tmp$$ -import libtestinstr.so -postscript ./ghidra_get_patchpoints.java rm -rf /tmp/tmp$$ ``` +The file is created at `~/Desktop/patches.txt` ### Fuzzing diff --git a/examples/afl_untracer/afl-untracer.c b/examples/afl_untracer/afl-untracer.c index dc2cd378..68658bfd 100644 --- a/examples/afl_untracer/afl-untracer.c +++ b/examples/afl_untracer/afl-untracer.c @@ -74,6 +74,9 @@ // STEP 1: +/* here you need to specify the parameter for the target function */ +static void *(*o_function)(u8 *buf, int len); + /* use stdin (1) or a file on the commandline (0) */ static u32 use_stdin = 1; @@ -668,13 +671,10 @@ static void sigtrap_handler(int signum, siginfo_t *si, void *context) { } -/* here you need to specify the parameter for the target function */ -static void *(*o_function)(u8 *buf, int len); - /* the MAIN function */ int main(int argc, char *argv[]) { - (void) personality(ADDR_NO_RANDOMIZE); // disable ASLR + (void)personality(ADDR_NO_RANDOMIZE); // disable ASLR pid = getpid(); if (getenv("AFL_DEBUG")) debug = 1; @@ -745,9 +745,10 @@ int main(int argc, char *argv[]) { } #ifndef _DEBUG -inline +inline #endif -static void fuzz() { + static void + fuzz() { // STEP 3: call the function to fuzz, also the functions you might // need to call to prepare the function and - important! - @@ -762,3 +763,4 @@ static void fuzz() { // END STEP 3 } + diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index 0681fbd6..55128ca2 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -1263,8 +1263,6 @@ bool SplitComparesTransform::runOnModule(Module &M) { if (enableFPSplit) { - simplifyFPCompares(M); - errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M) << " FP comparisons splitted\n"; @@ -1274,6 +1272,8 @@ bool SplitComparesTransform::runOnModule(Module &M) { be_quiet = 1; + if (enableFPSplit) simplifyFPCompares(M); + simplifyCompares(M); simplifyIntSignedness(M); -- cgit 1.4.1 From e137b40eb5a2b66a356c32e410cf676ede3f6f0d Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 13 Jul 2020 16:22:18 +0000 Subject: Haiku build fix. librt is necessary for Linux primarly and SunOS --- GNUmakefile | 8 ++++---- examples/afl_network_proxy/afl-network-client.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 748cd73c..f44ef95e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -65,7 +65,7 @@ endif ifeq "$(shell uname)" "SunOS" CFLAGS_OPT += -Wno-format-truncation - LDFLAGS=-lkstat + LDFLAGS=-lkstat -lrt endif ifdef STATIC @@ -196,7 +196,7 @@ else endif ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl + LDFLAGS += -ldl -lrt endif ifneq "$(findstring FreeBSD, $(shell uname))" "" @@ -254,13 +254,13 @@ ifeq "$(shell echo '$(HASH)include @$(HASH)include @int ma else SHMAT_OK=0 override CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -Wno-deprecated-declarations -lrt + LDFLAGS += -Wno-deprecated-declarations endif ifdef TEST_MMAP SHMAT_OK=0 override CFLAGS += -DUSEMMAP=1 - LDFLAGS += -Wno-deprecated-declarations -lrt + LDFLAGS += -Wno-deprecated-declarations endif all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done diff --git a/examples/afl_network_proxy/afl-network-client.c b/examples/afl_network_proxy/afl-network-client.c index 5af41055..7c4d8b35 100644 --- a/examples/afl_network_proxy/afl-network-client.c +++ b/examples/afl_network_proxy/afl-network-client.c @@ -34,7 +34,9 @@ #include #include #include +#ifndef USEMMAP #include +#endif #include #include #include -- cgit 1.4.1 From 95276f7da6ed9dd72556236f505a8997bee23387 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 13 Jul 2020 23:17:21 +0200 Subject: test float splitting increase timeout to 30 seconds --- test/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.sh b/test/test.sh index 9938a051..e901176e 100755 --- a/test/test.sh +++ b/test/test.sh @@ -389,9 +389,9 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { test -e test-floatingpoint && { mkdir -p in echo 0 > in/in - $ECHO "$GREY[*] running afl-fuzz with floating point splitting, this will take max. 16 seconds" + $ECHO "$GREY[*] running afl-fuzz with floating point splitting, this will take max. 30 seconds" { - AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -V16 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 + AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -V30 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/crashes/id:* 2>/dev/null )" && { $ECHO "$GREEN[+] llvm_mode laf-intel floatingpoint splitting feature works correctly" -- cgit 1.4.1 From 383b280531a92a8b81d112a9acb4e44c08987be0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 14 Jul 2020 23:26:11 +0200 Subject: added frida gum extension --- examples/afl_frida/Makefile | 23 ++ examples/afl_frida/README.md | 38 +++ examples/afl_frida/afl-frida.c | 312 ++++++++++++++++++++++++ examples/afl_frida/afl-frida.h | 53 ++++ examples/afl_frida/libtestinstr.c | 35 +++ examples/afl_network_proxy/afl-network-client.c | 2 +- src/afl-fuzz.c | 5 +- test/test-floatingpoint.c | 24 +- test/test-fp_cases.c | 73 ++++-- 9 files changed, 525 insertions(+), 40 deletions(-) create mode 100644 examples/afl_frida/Makefile create mode 100644 examples/afl_frida/README.md create mode 100644 examples/afl_frida/afl-frida.c create mode 100644 examples/afl_frida/afl-frida.h create mode 100644 examples/afl_frida/libtestinstr.c diff --git a/examples/afl_frida/Makefile b/examples/afl_frida/Makefile new file mode 100644 index 00000000..5d482e54 --- /dev/null +++ b/examples/afl_frida/Makefile @@ -0,0 +1,23 @@ +ifdef DEBUG + OPT=-O0 -D_DEBUG=\"1\" +else + OPT=-O3 -funroll-loops +endif + +all: afl-frida libtestinstr.so + +libfrida-gum.a: + @echo Download and extract frida-gum-devkit-VERSION-PLATFORM.tar.xz for your platform from https://github.com/frida/frida/releases/latest + @exit 1 + +afl-frida: afl-frida.c libfrida-gum.a + $(CC) -g $(OPT) -o afl-frida -I. -fpermissive -fPIC afl-frida.c ../../afl-llvm-rt.o libfrida-gum.a -ldl -lresolv -pthread + +libtestinstr.so: libtestinstr.c + $(CC) -g -O0 -fPIC -o libtestinstr.so -shared libtestinstr.c + +clean: + rm -f afl-frida *~ core *.o libtestinstr.so + +deepclean: clean + rm -f libfrida-gum.a frida-gum* diff --git a/examples/afl_frida/README.md b/examples/afl_frida/README.md new file mode 100644 index 00000000..93e8f35a --- /dev/null +++ b/examples/afl_frida/README.md @@ -0,0 +1,38 @@ +# afl-frida - faster fuzzing of binary-only libraries + +## Introduction + +afl-frida is an example skeleton file which can easily be used to fuzz +a closed source library. + +It requires less memory and is x5-10 faster than qemu_mode but does not +provide interesting features like compcov or cmplog. + +## How-to + +### Modify afl-frida.c + +Read and modify afl-frida.c then `make`. +To adapt afl-frida.c to your needs, read the header of the file and then +search and edit the `STEP 1`, `STEP 2` and `STEP 3` locations. + +### Fuzzing + +Example (after modifying afl-frida.c to your needs and compile it): +``` +afl-fuzz -i in -o out -- ./afl-frida +``` +(or even remote via afl-network-proxy). + +### Testing and debugging + +For testing/debugging you can try: +``` +make DEBUG=1 +AFL_DEBUG=1 gdb ./afl-frida +``` +and then you can easily set breakpoints to "breakpoint" and "fuzz". + +# Background + +This code ist copied for a larger part from https://github.com/meme/hotwax diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c new file mode 100644 index 00000000..c24e05b7 --- /dev/null +++ b/examples/afl_frida/afl-frida.c @@ -0,0 +1,312 @@ +/* + american fuzzy lop++ - afl-frida skeleton example + ------------------------------------------------- + + Copyright 2020 AFLplusplus Project. All rights reserved. + + Written mostly by meme -> https://github.com/meme/hotwax + + Modificationy by Marc Heuse + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + HOW-TO + ====== + + You only need to change the following: + + 1. set the defines and function call parameters. + 2. dl load the library you want to fuzz, lookup the functions you need + and setup the calls to these. + 3. in the while loop you call the functions in the necessary order - + incl the cleanup. the cleanup is important! + + Just look these steps up in the code, look for "// STEP x:" + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __APPLE__ + #include +#endif + + +// STEP 1: + +// The presets are for the example libtestinstr.so: + +/* What is the name of the library to fuzz */ +#define TARGET_LIBRARY "libtestinstr.so" + +/* What is the name of the function to fuzz */ +#define TARGET_FUNCTION "testinstr" + +/* here you need to specify the parameter for the target function */ +static void *(*o_function)(uint8_t *, int); + +// END STEP 1 + + +#include "frida-gum.h" + +G_BEGIN_DECLS + +#define GUM_TYPE_FAKE_EVENT_SINK (gum_fake_event_sink_get_type()) +G_DECLARE_FINAL_TYPE(GumFakeEventSink, gum_fake_event_sink, GUM, + FAKE_EVENT_SINK, GObject) + +struct _GumFakeEventSink { + + GObject parent; + GumEventType mask; + +}; + +GumEventSink *gum_fake_event_sink_new(void); +void gum_fake_event_sink_reset(GumFakeEventSink *self); + +G_END_DECLS + +static void gum_fake_event_sink_iface_init(gpointer g_iface, + gpointer iface_data); +static void gum_fake_event_sink_finalize(GObject *obj); +static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink); +static void gum_fake_event_sink_process(GumEventSink *sink, const GumEvent *ev); +void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, + gpointer user_data); +void afl_setup(void); +void afl_start_forkserver(void); +int __afl_persistent_loop(unsigned int max_cnt); + +static void gum_fake_event_sink_class_init(GumFakeEventSinkClass *klass) { + + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->finalize = gum_fake_event_sink_finalize; + +} + +static void gum_fake_event_sink_iface_init(gpointer g_iface, + gpointer iface_data) { + + GumEventSinkInterface *iface = (GumEventSinkInterface *) g_iface; + iface->query_mask = gum_fake_event_sink_query_mask; + iface->process = gum_fake_event_sink_process; + +} + +G_DEFINE_TYPE_EXTENDED(GumFakeEventSink, gum_fake_event_sink, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE(GUM_TYPE_EVENT_SINK, + gum_fake_event_sink_iface_init)) + +#include "../../config.h" + +// Shared memory fuzzing. +int __afl_sharedmem_fuzzing = 1; +extern unsigned int *__afl_fuzz_len; +extern unsigned char *__afl_fuzz_ptr; + +// Notify AFL about persistent mode. +static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; +int __afl_persistent_loop(unsigned int); + +// Notify AFL about deferred forkserver. +static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; +void __afl_manual_init(); + +// Because we do our own logging. +extern uint8_t * __afl_area_ptr; + +// Frida stuff below. +typedef struct { + + GumAddress base_address; + guint64 code_start, code_end; + +} range_t; + +inline static void afl_maybe_log(guint64 current_pc) { + + static __thread guint64 previous_pc; + + current_pc = (current_pc >> 4) ^ (current_pc << 8); + current_pc &= MAP_SIZE - 1; + + __afl_area_ptr[current_pc ^ previous_pc]++; + previous_pc = current_pc >> 1; + +} + +static void on_basic_block(GumCpuContext *context, gpointer user_data) { + + afl_maybe_log((guint64)user_data); + +} + +void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, + gpointer user_data) { + + range_t *range = (range_t *)user_data; + + const cs_insn *instr; + gboolean begin = TRUE; + while (gum_stalker_iterator_next(iterator, &instr)) { + + if (begin) { + + guint64 current_pc = instr->address - range->base_address; + gum_stalker_iterator_put_callout(iterator, on_basic_block, + (gpointer)current_pc, NULL); + begin = FALSE; + + } + + gum_stalker_iterator_keep(iterator); + + } + +} + +static void gum_fake_event_sink_init(GumFakeEventSink *self) { } + +static void gum_fake_event_sink_finalize(GObject *obj) { + + G_OBJECT_CLASS(gum_fake_event_sink_parent_class)->finalize(obj); + +} + +GumEventSink *gum_fake_event_sink_new(void) { + + GumFakeEventSink *sink; + sink = (GumFakeEventSink *) g_object_new(GUM_TYPE_FAKE_EVENT_SINK, NULL); + return GUM_EVENT_SINK(sink); + +} + +void gum_fake_event_sink_reset(GumFakeEventSink *self) { } + +static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink) { + + return 0; + +} + +static void gum_fake_event_sink_process(GumEventSink * sink, + const GumEvent *ev) { } + +/* Because this CAN be called more than once, it will return the LAST range */ +static int enumerate_ranges(const GumRangeDetails *details, + gpointer user_data) { + + GumMemoryRange *code_range = (GumMemoryRange *)user_data; + memcpy(code_range, details->range, sizeof(*code_range)); + return 0; + +} + +int main() { + + // STEP 2: load the library you want to fuzz and lookup the functions, + // inclusive of the cleanup functions. + // If there is just one function, then there is nothing to change + // or add here. + + void *dl = dlopen(TARGET_LIBRARY, RTLD_LAZY); + if (!dl) { + + fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY); + exit(-1); + + } + + if (!(o_function = dlsym(dl, TARGET_FUNCTION))) { + + fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION); + exit(-1); + + } + + // END STEP 2 + + gum_init_embedded(); + if (!gum_stalker_is_supported()) { + + gum_deinit_embedded(); + return 1; + + } + + GumStalker *stalker = gum_stalker_new(); + + GumAddress base_address = gum_module_find_base_address(TARGET_LIBRARY); + + GumMemoryRange code_range; + gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges, + &code_range); + guint64 code_start = code_range.base_address - base_address; + guint64 code_end = (code_range.base_address + code_range.size) - base_address; + + range_t instr_range = {base_address, code_start, code_end}; + + GumStalkerTransformer *transformer = + gum_stalker_transformer_make_from_callback(instr_basic_block, + &instr_range, NULL); + + GumEventSink *event_sink = gum_fake_event_sink_new(); + + __afl_manual_init(); + + // + // any expensive target library initialization that has to be done just once + // - put that here + // + + gum_stalker_follow_me(stalker, transformer, event_sink); + + while (__afl_persistent_loop(UINT32_MAX) != 0) { + +#ifdef _DEBUG + fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__a + fprintf(stderr, "RECV:"); + for (int i = 0; i < *__afl_fuzz_len; i++) + fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); + fprintf(stderr,"\n"); +#endif + + // STEP 3: ensure the minimum length is present and setup the target + // function to fuzz. + + if (*__afl_fuzz_len > 0) { + + __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate + (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len); + + } + + // END STEP 3 + + } + + gum_stalker_unfollow_me(stalker); + + while (gum_stalker_garbage_collect(stalker)) + g_usleep(10000); + + g_object_unref(stalker); + g_object_unref(transformer); + g_object_unref(event_sink); + gum_deinit_embedded(); + + return 0; + +} diff --git a/examples/afl_frida/afl-frida.h b/examples/afl_frida/afl-frida.h new file mode 100644 index 00000000..efa3440f --- /dev/null +++ b/examples/afl_frida/afl-frida.h @@ -0,0 +1,53 @@ +extern int is_persistent; + +G_BEGIN_DECLS + +#define GUM_TYPE_FAKE_EVENT_SINK (gum_fake_event_sink_get_type()) + +G_DECLARE_FINAL_TYPE(GumFakeEventSink, gum_fake_event_sink, GUM, + FAKE_EVENT_SINK, GObject) + +struct _GumFakeEventSink { + + GObject parent; + GumEventType mask; + +}; + +GumEventSink *gum_fake_event_sink_new(void); +void gum_fake_event_sink_reset(GumFakeEventSink *self); + +G_END_DECLS + +typedef struct { + + GumAddress base_address; + guint64 code_start, code_end; + +} range_t; + +void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, + gpointer user_data); +#pragma once + +void afl_setup(void); +void afl_start_forkserver(void); +int __afl_persistent_loop(unsigned int max_cnt); + +inline static inline void afl_maybe_log(guint64 current_pc) { + + extern unsigned int afl_instr_rms; + extern uint8_t * afl_area_ptr; + + static __thread guint64 previous_pc; + + current_pc = (current_pc >> 4) ^ (current_pc << 8); + current_pc &= MAP_SIZE - 1; + + if (current_pc >= afl_instr_rms) return; + + afl_area_ptr[current_pc ^ previous_pc]++; + previous_pc = current_pc >> 1; + +} + diff --git a/examples/afl_frida/libtestinstr.c b/examples/afl_frida/libtestinstr.c new file mode 100644 index 00000000..96b1cf21 --- /dev/null +++ b/examples/afl_frida/libtestinstr.c @@ -0,0 +1,35 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + diff --git a/examples/afl_network_proxy/afl-network-client.c b/examples/afl_network_proxy/afl-network-client.c index 7c4d8b35..a2451fdc 100644 --- a/examples/afl_network_proxy/afl-network-client.c +++ b/examples/afl_network_proxy/afl-network-client.c @@ -35,7 +35,7 @@ #include #include #ifndef USEMMAP -#include + #include #endif #include #include diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f7f247f3..872ed9ae 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -266,6 +266,8 @@ int main(int argc, char **argv_orig, char **envp) { gettimeofday(&tv, &tz); rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid()); + afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing + while ((opt = getopt(argc, argv, "+c:i:I:o:f:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) { @@ -563,7 +565,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); } afl->fsrv.qemu_mode = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; } @@ -580,7 +581,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); } afl->unicorn_mode = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; } @@ -591,7 +591,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->use_wine) { FATAL("Multiple -W options not supported"); } afl->fsrv.qemu_mode = 1; afl->use_wine = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = 0; } diff --git a/test/test-floatingpoint.c b/test/test-floatingpoint.c index f78b5d9f..76cdccf0 100644 --- a/test/test-floatingpoint.c +++ b/test/test-floatingpoint.c @@ -1,18 +1,20 @@ #include #include -int main(void) -{ - long double magic; +int main(void) { - ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); - if (bytes_read < (ssize_t)sizeof(magic)) { - return 1; - } + long double magic; - if( (-magic == 15.0 + 0.5 + 0.125 + 0.03125 + 0.0078125) ){ /* 15 + 1/2 + 1/8 + 1/32 + 1/128 */ - abort(); - } + ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); + if (bytes_read < (ssize_t)sizeof(magic)) { return 1; } + + if ((-magic == 15.0 + 0.5 + 0.125 + 0.03125 + + 0.0078125)) { /* 15 + 1/2 + 1/8 + 1/32 + 1/128 */ + abort(); + + } + + return 0; - return 0; } + diff --git a/test/test-fp_cases.c b/test/test-fp_cases.c index 006ae32f..b0f792bc 100644 --- a/test/test-fp_cases.c +++ b/test/test-fp_cases.c @@ -4,13 +4,14 @@ * or -DFLOAT_TYPE="long double" */ - #include int main() { - volatile FLOAT_TYPE a,b; + + volatile FLOAT_TYPE a, b; /* different values */ - a = -2.1; b = -2; /* signs equal, exp equal, mantissa > */ + a = -2.1; + b = -2; /* signs equal, exp equal, mantissa > */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -18,7 +19,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1.8; b = 2.1; /* signs equal, exp differ, mantissa > */ + a = 1.8; + b = 2.1; /* signs equal, exp differ, mantissa > */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -26,7 +28,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2; b = 2.1; /* signs equal, exp equal, mantissa < */ + a = 2; + b = 2.1; /* signs equal, exp equal, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -34,7 +37,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = -1.8; /* signs equal, exp differ, mantissa < */ + a = -2; + b = -1.8; /* signs equal, exp differ, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -42,7 +46,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1; b = 1; /* signs differ, exp equal, mantissa equal */ + a = -1; + b = 1; /* signs differ, exp equal, mantissa equal */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -50,7 +55,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1; b = 0; /* signs differ, exp differ, mantissa equal */ + a = -1; + b = 0; /* signs differ, exp differ, mantissa equal */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -58,7 +64,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = 2.8; /* signs differ, exp equal, mantissa < */ + a = -2; + b = 2.8; /* signs differ, exp equal, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -66,7 +73,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = 1.8; /* signs differ, exp differ, mantissa < */ + a = -2; + b = 1.8; /* signs differ, exp differ, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -74,8 +82,8 @@ int main() { assert((a != b)); assert(!(a == b)); - - a = -2; b = -2.1; /* signs equal, exp equal, mantissa > */ + a = -2; + b = -2.1; /* signs equal, exp equal, mantissa > */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -83,7 +91,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.1; b = 1.8; /* signs equal, exp differ, mantissa > */ + a = 2.1; + b = 1.8; /* signs equal, exp differ, mantissa > */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -91,7 +100,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.1; b = 2; /* signs equal, exp equal, mantissa < */ + a = 2.1; + b = 2; /* signs equal, exp equal, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -99,7 +109,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1.8; b = -2; /* signs equal, exp differ, mantissa < */ + a = -1.8; + b = -2; /* signs equal, exp differ, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -107,7 +118,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1; b = -1; /* signs differ, exp equal, mantissa equal */ + a = 1; + b = -1; /* signs differ, exp equal, mantissa equal */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -115,7 +127,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 0; b = -1; /* signs differ, exp differ, mantissa equal */ + a = 0; + b = -1; /* signs differ, exp differ, mantissa equal */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -123,7 +136,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.8; b = -2; /* signs differ, exp equal, mantissa < */ + a = 2.8; + b = -2; /* signs differ, exp equal, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -131,7 +145,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1.8; b = -2; /* signs differ, exp differ, mantissa < */ + a = 1.8; + b = -2; /* signs differ, exp differ, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -140,7 +155,8 @@ int main() { assert(!(a == b)); /* equal values */ - a = 0; b = 0; + a = 0; + b = 0; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -148,7 +164,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -0; b = 0; + a = -0; + b = 0; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -156,7 +173,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = 1; b = 1; + a = 1; + b = 1; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -164,7 +182,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = 0.5; b = 0.5; + a = 0.5; + b = 0.5; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -172,7 +191,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -1; b = -1; + a = -1; + b = -1; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -180,11 +200,14 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -0.5; b = -0.5; + a = -0.5; + b = -0.5; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); assert((a >= b)); assert(!(a != b)); assert((a == b)); + } + -- cgit 1.4.1 From c5963f707c9a1b1ec0d869d90fabf09072093e1d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 14 Jul 2020 23:42:47 +0200 Subject: make fuzzing of test-floatingpoint reproducible --- test/test-floatingpoint.c | 2 +- test/test.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test-floatingpoint.c b/test/test-floatingpoint.c index 76cdccf0..8f691c2c 100644 --- a/test/test-floatingpoint.c +++ b/test/test-floatingpoint.c @@ -3,7 +3,7 @@ int main(void) { - long double magic; + float magic; ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); if (bytes_read < (ssize_t)sizeof(magic)) { return 1; } diff --git a/test/test.sh b/test/test.sh index e901176e..15082070 100755 --- a/test/test.sh +++ b/test/test.sh @@ -388,10 +388,10 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 AFL_LLVM_LAF_SPLIT_FLOATS=1 ../afl-clang-fast -o test-floatingpoint test-floatingpoint.c > test.out 2>&1 test -e test-floatingpoint && { mkdir -p in - echo 0 > in/in + echo ZZ > in/in $ECHO "$GREY[*] running afl-fuzz with floating point splitting, this will take max. 30 seconds" { - AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -V30 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 + AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -s1 -V30 -m ${MEM_LIMIT} -i in -o out -- ./test-floatingpoint >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/crashes/id:* 2>/dev/null )" && { $ECHO "$GREEN[+] llvm_mode laf-intel floatingpoint splitting feature works correctly" -- cgit 1.4.1 From a8726b8254f2f8c429c8b3e1c2d30b9f7baa6e93 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 15 Jul 2020 00:08:38 +0200 Subject: ensure afl-frida uses persistent mode --- docs/Changelog.md | 2 ++ examples/afl_frida/README.md | 10 +++------- examples/afl_frida/afl-frida.c | 8 ++++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 8fb85ce6..50f5629f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,6 +18,8 @@ sending a mail to . - LTO: autodictionary mode is a default - LTO: instrim instrumentation disabled, only classic support used as it is always better + - added afl-frida gum solution to examples/afl_frida (mostly imported + from https://github.com/meme/hotwax/) - small fixes to afl-plot, afl-whatsup and man page creation diff --git a/examples/afl_frida/README.md b/examples/afl_frida/README.md index 93e8f35a..33bd67c8 100644 --- a/examples/afl_frida/README.md +++ b/examples/afl_frida/README.md @@ -24,14 +24,10 @@ afl-fuzz -i in -o out -- ./afl-frida ``` (or even remote via afl-network-proxy). -### Testing and debugging +# Speed and stability -For testing/debugging you can try: -``` -make DEBUG=1 -AFL_DEBUG=1 gdb ./afl-frida -``` -and then you can easily set breakpoints to "breakpoint" and "fuzz". +The speed is very good, about x12 of fork() qemu_mode. +However the stability is low. Reason is currently unknown. # Background diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c index c24e05b7..ff10ffb7 100644 --- a/examples/afl_frida/afl-frida.c +++ b/examples/afl_frida/afl-frida.c @@ -39,6 +39,7 @@ #ifndef __APPLE__ #include + #include #endif @@ -216,6 +217,10 @@ static int enumerate_ranges(const GumRangeDetails *details, int main() { +#ifndef __APPLE__ + (void)personality(ADDR_NO_RANDOMIZE); // disable ASLR +#endif + // STEP 2: load the library you want to fuzz and lookup the functions, // inclusive of the cleanup functions. // If there is just one function, then there is nothing to change @@ -264,6 +269,9 @@ int main() { GumEventSink *event_sink = gum_fake_event_sink_new(); + // to ensure that the signatures are not optimized out + memcpy(__afl_area_ptr, (void*)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1); + memcpy(__afl_area_ptr + 32, (void*)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR) + 1); __afl_manual_init(); // -- cgit 1.4.1 From 133dfc8b69ece83bd7b1e59e81f09815ff5b8e44 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 15 Jul 2020 10:32:07 +0200 Subject: update documentation --- examples/afl_frida/README.md | 2 +- examples/afl_untracer/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/afl_frida/README.md b/examples/afl_frida/README.md index 33bd67c8..1ee19a68 100644 --- a/examples/afl_frida/README.md +++ b/examples/afl_frida/README.md @@ -20,7 +20,7 @@ search and edit the `STEP 1`, `STEP 2` and `STEP 3` locations. Example (after modifying afl-frida.c to your needs and compile it): ``` -afl-fuzz -i in -o out -- ./afl-frida +LD_LIBRARY_PATH=/path/to/the/target/library afl-fuzz -i in -o out -- ./afl-frida ``` (or even remote via afl-network-proxy). diff --git a/examples/afl_untracer/README.md b/examples/afl_untracer/README.md index 9cb13527..ada0c916 100644 --- a/examples/afl_untracer/README.md +++ b/examples/afl_untracer/README.md @@ -39,7 +39,7 @@ The file is created at `~/Desktop/patches.txt` Example (after modifying afl-untracer.c to your needs, compiling and creating patches.txt): ``` -AFL_UNTRACER_FILE=./patches.txt afl-fuzz -i in -o out -- ./afl-untracer +LD_LIBRARY_PATH=/path/to/target/library AFL_UNTRACER_FILE=./patches.txt afl-fuzz -i in -o out -- ./afl-untracer ``` (or even remote via afl-network-proxy). -- cgit 1.4.1 From ee77fe4094273f6b618aa72b2aa0d79efd8bd31e Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 15 Jul 2020 10:35:38 +0200 Subject: improve len encoding in redqueen --- src/afl-fuzz-redqueen.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 724da407..a42e1b52 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -277,9 +277,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 * o_buf_8 = &orig_buf[idx]; u32 its_len = len - idx; - *status = 0; + // *status = 0; - if (SHAPE_BYTES(h->shape) == 8) { + if (SHAPE_BYTES(h->shape) >= 8) { if (its_len >= 8 && *buf_64 == pattern && *o_buf_64 == o_pattern) { @@ -290,7 +290,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), SWAP64(o_pattern), idx, orig_buf, buf, @@ -304,7 +304,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 4 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) { if (its_len >= 4 && *buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) { @@ -316,7 +316,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), SWAP32(o_pattern), idx, orig_buf, buf, @@ -330,7 +330,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 2 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) { if (its_len >= 2 && *buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) { @@ -342,7 +342,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), SWAP16(o_pattern), idx, orig_buf, buf, @@ -356,7 +356,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 1 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 1 && *status != 1) { if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) { @@ -482,6 +482,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { for (idx = 0; idx < len && fails < 8; ++idx) { + status = 0; if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, orig_buf, buf, len, 1, &status))) { @@ -499,6 +500,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } + status = 0; if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx, orig_buf, buf, len, 1, &status))) { -- cgit 1.4.1 From 08d3169df4950458a8b401f6140c8e98fdb3cd81 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 15 Jul 2020 16:58:40 +0200 Subject: fix afl-frida --- examples/afl_frida/Makefile | 2 +- examples/afl_frida/afl-frida.c | 260 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 241 insertions(+), 21 deletions(-) diff --git a/examples/afl_frida/Makefile b/examples/afl_frida/Makefile index 5d482e54..c154f3a4 100644 --- a/examples/afl_frida/Makefile +++ b/examples/afl_frida/Makefile @@ -11,7 +11,7 @@ libfrida-gum.a: @exit 1 afl-frida: afl-frida.c libfrida-gum.a - $(CC) -g $(OPT) -o afl-frida -I. -fpermissive -fPIC afl-frida.c ../../afl-llvm-rt.o libfrida-gum.a -ldl -lresolv -pthread + $(CC) -g $(OPT) -o afl-frida -Wno-format -Wno-pointer-sign -I. -fpermissive -fPIC afl-frida.c ../../afl-llvm-rt.o libfrida-gum.a -ldl -lresolv -pthread libtestinstr.so: libtestinstr.c $(CC) -g -O0 -fPIC -o libtestinstr.so -shared libtestinstr.c diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c index ff10ffb7..76732aeb 100644 --- a/examples/afl_frida/afl-frida.c +++ b/examples/afl_frida/afl-frida.c @@ -42,6 +42,7 @@ #include #endif +int debug = 0; // STEP 1: @@ -58,7 +59,6 @@ static void *(*o_function)(uint8_t *, int); // END STEP 1 - #include "frida-gum.h" G_BEGIN_DECLS @@ -100,7 +100,7 @@ static void gum_fake_event_sink_class_init(GumFakeEventSinkClass *klass) { static void gum_fake_event_sink_iface_init(gpointer g_iface, gpointer iface_data) { - GumEventSinkInterface *iface = (GumEventSinkInterface *) g_iface; + GumEventSinkInterface *iface = (GumEventSinkInterface *)g_iface; iface->query_mask = gum_fake_event_sink_query_mask; iface->process = gum_fake_event_sink_process; @@ -113,20 +113,20 @@ G_DEFINE_TYPE_EXTENDED(GumFakeEventSink, gum_fake_event_sink, G_TYPE_OBJECT, 0, #include "../../config.h" // Shared memory fuzzing. -int __afl_sharedmem_fuzzing = 1; -extern unsigned int *__afl_fuzz_len; +int __afl_sharedmem_fuzzing = 1; +extern unsigned int * __afl_fuzz_len; extern unsigned char *__afl_fuzz_ptr; // Notify AFL about persistent mode. static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; -int __afl_persistent_loop(unsigned int); +int __afl_persistent_loop(unsigned int); // Notify AFL about deferred forkserver. static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; -void __afl_manual_init(); +void __afl_manual_init(); // Because we do our own logging. -extern uint8_t * __afl_area_ptr; +extern uint8_t *__afl_area_ptr; // Frida stuff below. typedef struct { @@ -140,6 +140,8 @@ inline static void afl_maybe_log(guint64 current_pc) { static __thread guint64 previous_pc; + // fprintf(stderr, "PC: %p\n", current_pc); + current_pc = (current_pc >> 4) ^ (current_pc << 8); current_pc &= MAP_SIZE - 1; @@ -165,10 +167,14 @@ void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, if (begin) { - guint64 current_pc = instr->address - range->base_address; - gum_stalker_iterator_put_callout(iterator, on_basic_block, - (gpointer)current_pc, NULL); - begin = FALSE; + if (instr->address >= range->code_start && + instr->address <= range->code_end) { + + gum_stalker_iterator_put_callout(iterator, on_basic_block, + (gpointer)instr->address, NULL); + begin = FALSE; + + } } @@ -178,7 +184,9 @@ void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, } -static void gum_fake_event_sink_init(GumFakeEventSink *self) { } +static void gum_fake_event_sink_init(GumFakeEventSink *self) { + +} static void gum_fake_event_sink_finalize(GObject *obj) { @@ -189,12 +197,14 @@ static void gum_fake_event_sink_finalize(GObject *obj) { GumEventSink *gum_fake_event_sink_new(void) { GumFakeEventSink *sink; - sink = (GumFakeEventSink *) g_object_new(GUM_TYPE_FAKE_EVENT_SINK, NULL); + sink = (GumFakeEventSink *)g_object_new(GUM_TYPE_FAKE_EVENT_SINK, NULL); return GUM_EVENT_SINK(sink); } -void gum_fake_event_sink_reset(GumFakeEventSink *self) { } +void gum_fake_event_sink_reset(GumFakeEventSink *self) { + +} static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink) { @@ -202,8 +212,201 @@ static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink) { } +typedef struct library_list { + + uint8_t *name; + uint64_t addr_start, addr_end; + +} library_list_t; + +#define MAX_LIB_COUNT 256 +static library_list_t liblist[MAX_LIB_COUNT]; +static u32 liblist_cnt; + +void read_library_information() { + +#if defined(__linux__) + FILE *f; + u8 buf[1024], *b, *m, *e, *n; + + if ((f = fopen("/proc/self/maps", "r")) == NULL) { + + fprintf(stderr, "Error: cannot open /proc/self/maps\n"); + exit(-1); + + } + + if (debug) fprintf(stderr, "Library list:\n"); + while (fgets(buf, sizeof(buf), f)) { + + if (strstr(buf, " r-x")) { + + if (liblist_cnt >= MAX_LIB_COUNT) { + + fprintf( + stderr, + "Warning: too many libraries to old, maximum count of %d reached\n", + liblist_cnt); + return; + + } + + b = buf; + m = index(buf, '-'); + e = index(buf, ' '); + if ((n = rindex(buf, '/')) == NULL) n = rindex(buf, ' '); + if (n && + ((*n >= '0' && *n <= '9') || *n == '[' || *n == '{' || *n == '(')) + n = NULL; + else + n++; + if (b && m && e && n && *n) { + + *m++ = 0; + *e = 0; + if (n[strlen(n) - 1] == '\n') n[strlen(n) - 1] = 0; + + if (rindex(n, '/') != NULL) { + + n = rindex(n, '/'); + n++; + + } + + liblist[liblist_cnt].name = strdup(n); + liblist[liblist_cnt].addr_start = strtoull(b, NULL, 16); + liblist[liblist_cnt].addr_end = strtoull(m, NULL, 16); + if (debug) + fprintf( + stderr, "%s:%llx (%llx-%llx)\n", liblist[liblist_cnt].name, + liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, + liblist[liblist_cnt].addr_start, + liblist[liblist_cnt].addr_end - 1); + liblist_cnt++; + + } + + } + + } + + if (debug) fprintf(stderr, "\n"); + +#elif defined(__FreeBSD__) + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()}; + char * buf, *start, *end; + size_t miblen = sizeof(mib) / sizeof(mib[0]); + size_t len; + + if (debug) fprintf(stderr, "Library list:\n"); + if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) { return; } + + len = len * 4 / 3; + + buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + if (buf == MAP_FAILED) { return; } + if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) { + + munmap(buf, len); + return; + + } + + start = buf; + end = buf + len; + + while (start < end) { + + struct kinfo_vmentry *region = (struct kinfo_vmentry *)start; + size_t size = region->kve_structsize; + + if (size == 0) { break; } + + if ((region->kve_protection & KVME_PROT_READ) && + !(region->kve_protection & KVME_PROT_EXEC)) { + + liblist[liblist_cnt].name = + region->kve_path[0] != '\0' ? strdup(region->kve_path) : 0; + liblist[liblist_cnt].addr_start = region->kve_start; + liblist[liblist_cnt].addr_end = region->kve_end; + + if (debug) { + + fprintf(stderr, "%s:%x (%lx-%lx)\n", liblist[liblist_cnt].name, + liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, + liblist[liblist_cnt].addr_start, + liblist[liblist_cnt].addr_end - 1); + + } + + liblist_cnt++; + + } + + start += size; + + } + +#endif + +} + +library_list_t *find_library(char *name) { + + char *filename = rindex(name, '/'); + + if (filename) + filename++; + else + filename = name; + +#if defined(__linux__) + u32 i; + for (i = 0; i < liblist_cnt; i++) + if (strcmp(liblist[i].name, filename) == 0) return &liblist[i]; +#elif defined(__APPLE__) && defined(__LP64__) + kern_return_t err; + static library_list_t lib; + + // get the list of all loaded modules from dyld + // the task_info mach API will get the address of the dyld all_image_info + // struct for the given task from which we can get the names and load + // addresses of all modules + task_dyld_info_data_t task_dyld_info; + mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; + err = task_info(mach_task_self(), TASK_DYLD_INFO, + (task_info_t)&task_dyld_info, &count); + + const struct dyld_all_image_infos *all_image_infos = + (const struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; + const struct dyld_image_info *image_infos = all_image_infos->infoArray; + + for (size_t i = 0; i < all_image_infos->infoArrayCount; i++) { + + const char * image_name = image_infos[i].imageFilePath; + mach_vm_address_t image_load_address = + (mach_vm_address_t)image_infos[i].imageLoadAddress; + if (strstr(image_name, name)) { + + lib.name = name; + lib.addr_start = (u64)image_load_address; + lib.addr_end = 0; + return &lib; + + } + + } + +#endif + + return NULL; + +} + static void gum_fake_event_sink_process(GumEventSink * sink, - const GumEvent *ev) { } + const GumEvent *ev) { + +} /* Because this CAN be called more than once, it will return the LAST range */ static int enumerate_ranges(const GumRangeDetails *details, @@ -243,6 +446,16 @@ int main() { // END STEP 2 + read_library_information(); + library_list_t *lib = find_library(TARGET_LIBRARY); + + if (lib == NULL) { + + fprintf(stderr, "Could not find target library\n"); + exit(-1); + + } + gum_init_embedded(); if (!gum_stalker_is_supported()) { @@ -253,15 +466,20 @@ int main() { GumStalker *stalker = gum_stalker_new(); - GumAddress base_address = gum_module_find_base_address(TARGET_LIBRARY); + /* + This does not work here as we load a shared library. pretty sure this + would also be easily solvable with frida gum, but I already have all the + code I need from afl-untracer + GumAddress base_address = gum_module_find_base_address(TARGET_LIBRARY); GumMemoryRange code_range; gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges, &code_range); guint64 code_start = code_range.base_address - base_address; guint64 code_end = (code_range.base_address + code_range.size) - base_address; - range_t instr_range = {base_address, code_start, code_end}; + */ + range_t instr_range = {0, lib->addr_start, lib->addr_end}; GumStalkerTransformer *transformer = gum_stalker_transformer_make_from_callback(instr_basic_block, @@ -270,8 +488,9 @@ int main() { GumEventSink *event_sink = gum_fake_event_sink_new(); // to ensure that the signatures are not optimized out - memcpy(__afl_area_ptr, (void*)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1); - memcpy(__afl_area_ptr + 32, (void*)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR) + 1); + memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1); + memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR, + sizeof(AFL_DEFER_FORKSVR) + 1); __afl_manual_init(); // @@ -296,7 +515,7 @@ int main() { if (*__afl_fuzz_len > 0) { - __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate + __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len); } @@ -318,3 +537,4 @@ int main() { return 0; } + -- cgit 1.4.1 From 2077309c8d84f2f18c773b4e1b1638cff333a88e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 16 Jul 2020 00:24:37 +0200 Subject: fix afl-frida --- examples/afl_frida/afl-frida.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c index 76732aeb..7038e1bd 100644 --- a/examples/afl_frida/afl-frida.c +++ b/examples/afl_frida/afl-frida.c @@ -127,6 +127,7 @@ void __afl_manual_init(); // Because we do our own logging. extern uint8_t *__afl_area_ptr; + static __thread guint64 previous_pc; // Frida stuff below. typedef struct { @@ -138,9 +139,7 @@ typedef struct { inline static void afl_maybe_log(guint64 current_pc) { - static __thread guint64 previous_pc; - - // fprintf(stderr, "PC: %p\n", current_pc); + // fprintf(stderr, "PC: %p ^ %p\n", current_pc, previous_pc); current_pc = (current_pc >> 4) ^ (current_pc << 8); current_pc &= MAP_SIZE - 1; @@ -502,6 +501,8 @@ int main() { while (__afl_persistent_loop(UINT32_MAX) != 0) { + previous_pc = 0; // Required! + #ifdef _DEBUG fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__a fprintf(stderr, "RECV:"); -- cgit 1.4.1 From 1ec2615a3ed98b991315a40217407136514b53f1 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Jul 2020 00:53:08 +0200 Subject: tiny fixes --- .gitignore | 4 ++++ examples/afl_frida/afl-frida.c | 4 ++-- src/afl-gcc.c | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1000cc6f..1b7904ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .test .test2 +.sync_tmp *.o *.so *.pyc +*.dSYM afl-analyze afl-as afl-clang @@ -55,3 +57,5 @@ test/unittests/unit_rand test/unittests/unit_hash examples/afl_network_proxy/afl-network-server examples/afl_network_proxy/afl-network-client +in +out diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c index 7038e1bd..2ad5a72a 100644 --- a/examples/afl_frida/afl-frida.c +++ b/examples/afl_frida/afl-frida.c @@ -126,8 +126,8 @@ static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; void __afl_manual_init(); // Because we do our own logging. -extern uint8_t *__afl_area_ptr; - static __thread guint64 previous_pc; +extern uint8_t * __afl_area_ptr; +static __thread guint64 previous_pc; // Frida stuff below. typedef struct { diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 8d91164b..22e6be8e 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -132,6 +132,9 @@ static void edit_params(u32 argc, char **argv) { name = argv[0]; + /* This should never happen but fixes a scan-build warning */ + if (!name) { FATAL("Empty argv set"); } + } else { ++name; -- cgit 1.4.1 From a84c958647a97ec9f43c2e534715d85213075778 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Jul 2020 01:00:39 +0200 Subject: fixed mem leak in redqueen --- src/afl-fuzz-redqueen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index a42e1b52..3f5fc23a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -177,6 +177,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; ck_free(backup); + ck_free(rng); + rng = NULL; + while (ranges) { rng = ranges; @@ -185,10 +188,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { rng = NULL; } - - ck_free(rng); - rng = NULL; - // save the input with the high entropy if (needs_write) { -- cgit 1.4.1 From 4314e59af9a2224443fa38ac8145eba305189d97 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Jul 2020 02:03:52 +0200 Subject: code format --- src/afl-fuzz-redqueen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 3f5fc23a..c53e0e06 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -188,6 +188,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { rng = NULL; } + // save the input with the high entropy if (needs_write) { -- cgit 1.4.1 From f465a75b6592e4c30b0465f63beda166a8e09045 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Jul 2020 02:17:05 +0200 Subject: added initial defork example --- examples/defork/Makefile | 64 +++++++++++++++++++++++++++++++++++++++ examples/defork/README.md | 11 +++++++ examples/defork/defork.c | 52 +++++++++++++++++++++++++++++++ examples/defork/forking_target | Bin 0 -> 19520 bytes examples/defork/forking_target.c | 46 ++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+) create mode 100644 examples/defork/Makefile create mode 100644 examples/defork/README.md create mode 100644 examples/defork/defork.c create mode 100755 examples/defork/forking_target create mode 100644 examples/defork/forking_target.c diff --git a/examples/defork/Makefile b/examples/defork/Makefile new file mode 100644 index 00000000..e8240dba --- /dev/null +++ b/examples/defork/Makefile @@ -0,0 +1,64 @@ +# +# american fuzzy lop++ - defork +# ---------------------------------- +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +.PHONY: all install clean + +PREFIX ?= /usr/local +BIN_PATH = $(PREFIX)/bin +HELPER_PATH = $(PREFIX)/lib/afl + +CFLAGS = -fPIC -Wall -Wextra +LDFLAGS = -shared + +UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) +UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? + +_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) +LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) +LDFLAGS += $(LDFLAGS_ADD) + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 + +CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep -q gcc; echo $$?) +CC_IS_GCC:sh=$(CC) --version 2>/dev/null | grep -q gcc; echo $$? +CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?) +CC_IS_ARMCOMPILER:sh=$(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$? + +_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) +__M32FLAG=$(_M32FLAG:00=-mbe32) +___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) +M32FLAG=$(___M32FLAG) +#ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" +# ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) +# M32FLAG = -mbe32 +# endif +#endif + +all: defork32.so defork64.so + +defork32.so: defork.c + -@$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork32 build failure (that's fine)" + +defork64.so: defork.c + -@$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork64 build failure (that's fine)" + +install: defork32.so defork64.so + install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ + if [ -f defork32.so ]; then set -e; install -m 755 defork32.so $(DESTDIR)$(HELPER_PATH)/; fi + if [ -f defork64.so ]; then set -e; install -m 755 defork64.so $(DESTDIR)$(HELPER_PATH)/; fi + +target: + ../../afl-clang forking_target.c -o forking_target -Wall -Wextra -Werror + +clean: + rm -f defork32.so defork64.so forking_target diff --git a/examples/defork/README.md b/examples/defork/README.md new file mode 100644 index 00000000..7e950323 --- /dev/null +++ b/examples/defork/README.md @@ -0,0 +1,11 @@ +# defork + +when the target forks, this breaks all normal fuzzing runs. +Sometimes, though, it is enough to just run the child process. +If this is the case, then this LD_PRELOAD library will always return 0 on fork, +the target will belive it is running as the child, post-fork. + +This is defork.c from the amazing preeny project +https://github.com/zardus/preeny + +It is altered for afl++ to work with its fork-server: the initial fork will go through, the second fork will be blocked. diff --git a/examples/defork/defork.c b/examples/defork/defork.c new file mode 100644 index 00000000..46810326 --- /dev/null +++ b/examples/defork/defork.c @@ -0,0 +1,52 @@ +#define __GNU_SOURCE +#include +#include +#include +#include + +#include "../../include/config.h" + +/* we want to fork once (for the afl++ forkserver), + then immediately return as child on subsequent forks. */ +static bool forked = 0; + +pid_t (*original_fork)(void); + +/* In case we are not running in afl, we use a dummy original_fork */ +static pid_t nop(void) { + + return 0; + +} + +__attribute__((constructor)) void preeny_fork_orig() { + + if (getenv(SHM_ENV_VAR)) { + + printf("defork: running in AFL++. Allowing forkserver.\n"); + original_fork = dlsym(RTLD_NEXT, "socket"); + + } else { + + printf("defork: no AFL++ detected. Disabling fork from the start.\n"); + original_fork = &nop; + + } + +} + +pid_t fork(void) { + + printf("called fork. forked state is %d\n", (int) forked); + fflush(stdout); + /* If we forked before, or if we're in the child (pid==0), + we don't want to fork anymore, else, we are still in the forkserver. + The forkserver parent needs to fork infinite times, each child should never + fork again. This can be written without branches and I hate myself for it. + */ + pid_t ret = !forked && original_fork(); + forked = !ret; + return ret; + +} + diff --git a/examples/defork/forking_target b/examples/defork/forking_target new file mode 100755 index 00000000..0f7a04fc Binary files /dev/null and b/examples/defork/forking_target differ diff --git a/examples/defork/forking_target.c b/examples/defork/forking_target.c new file mode 100644 index 00000000..ff1d6e37 --- /dev/null +++ b/examples/defork/forking_target.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +/* This is an example target for defork.c - fuzz using +``` +mkdir in; echo a > ./in/a +AFL_PRELOAD=./defork64.so ../../afl-fuzz -i in -o out -- ./forking_target @@ +``` +*/ + +int main(int argc, char **argv) { + + if (argc < 2) { + + printf("Example tool to test defork.\nUsage ./forking_target \n"); + return -1; + + } + + pid_t pid = fork(); + if (pid == 0) { + + printf("We're in the child.\n"); + FILE *f = fopen(argv[1], "r"); + char buf[4096]; + fread(buf, 1, 4096, f); + uint32_t offset = buf[100] + (buf[101] << 8); + char test_val = buf[offset]; + return test_val < 100; + + } else if (pid < 0) { + + perror("fork"); + return -1; + + } else { + + printf("We are in the parent - defork didn't work! :( (pid=%d)\n", (int) pid); + + } + + return 0; + +} -- cgit 1.4.1 From 0b0366d9b4bc7ddea154174a81934dcc9911af12 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Jul 2020 02:27:07 +0200 Subject: removed debug print and code format --- examples/defork/defork.c | 2 -- examples/defork/forking_target.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/defork/defork.c b/examples/defork/defork.c index 46810326..f71d1124 100644 --- a/examples/defork/defork.c +++ b/examples/defork/defork.c @@ -37,8 +37,6 @@ __attribute__((constructor)) void preeny_fork_orig() { pid_t fork(void) { - printf("called fork. forked state is %d\n", (int) forked); - fflush(stdout); /* If we forked before, or if we're in the child (pid==0), we don't want to fork anymore, else, we are still in the forkserver. The forkserver parent needs to fork infinite times, each child should never diff --git a/examples/defork/forking_target.c b/examples/defork/forking_target.c index ff1d6e37..98f6365a 100644 --- a/examples/defork/forking_target.c +++ b/examples/defork/forking_target.c @@ -37,10 +37,12 @@ int main(int argc, char **argv) { } else { - printf("We are in the parent - defork didn't work! :( (pid=%d)\n", (int) pid); + printf("We are in the parent - defork didn't work! :( (pid=%d)\n", + (int)pid); } return 0; } + -- cgit 1.4.1 From 6513bca07e590024480a95de8c57c9547987032d Mon Sep 17 00:00:00 2001 From: Sergio Paganoni Date: Thu, 16 Jul 2020 11:47:36 +0200 Subject: Update post_library_gif.so.c (#454) --- examples/custom_mutators/post_library_gif.so.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_mutators/post_library_gif.so.c b/examples/custom_mutators/post_library_gif.so.c index 9b76ead5..2d72400c 100644 --- a/examples/custom_mutators/post_library_gif.so.c +++ b/examples/custom_mutators/post_library_gif.so.c @@ -83,7 +83,7 @@ typedef struct post_state { } post_state_t; -void *afl afl_custom_init(void *afl) { +void *afl_custom_init(void *afl) { post_state_t *state = malloc(sizeof(post_state_t)); if (!state) { -- 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(-) 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