diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-analyze.c | 2 | ||||
-rw-r--r-- | src/afl-as.c | 2 | ||||
-rw-r--r-- | src/afl-common.c | 18 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 4 | ||||
-rw-r--r-- | src/afl-fuzz-mutators.c | 207 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 197 | ||||
-rw-r--r-- | src/afl-fuzz-python.c | 55 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 19 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 77 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 6 | ||||
-rw-r--r-- | src/afl-fuzz.c | 18 | ||||
-rw-r--r-- | src/afl-showmap.c | 3 | ||||
-rw-r--r-- | src/afl-tmin.c | 2 |
13 files changed, 351 insertions, 259 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 8f48b1d0..4e973672 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -723,7 +723,7 @@ static void set_up_environment(void) { } - prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, getpid()); + prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid()); } diff --git a/src/afl-as.c b/src/afl-as.c index 486a6afa..cf7f8bb6 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -233,7 +233,7 @@ static void edit_params(int argc, char **argv) { } modified_file = - alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), (u32)time(NULL)); + alloc_printf("%s/.afl-%u-%u.s", tmp_dir, (u32)getpid(), (u32)time(NULL)); wrap_things_up: diff --git a/src/afl-common.c b/src/afl-common.c index 54b2e790..d9d57863 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -64,15 +64,15 @@ char *afl_environment_variables[] = { "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_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_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_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_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_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_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_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 diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 2289183c..d4966889 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -437,13 +437,13 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) { sprintf(ret, "src:%06u", afl->current_entry); - sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); - if (afl->splicing_with >= 0) { sprintf(ret + strlen(ret), "+%06d", afl->splicing_with); } + + sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); sprintf(ret + strlen(ret), ",op:%s", afl->stage_short); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index beb89092..027add49 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -26,27 +26,55 @@ #include "afl-fuzz.h" -void load_custom_mutator(afl_state_t *, const char *); +struct custom_mutator *load_custom_mutator(afl_state_t *, const char *); +#ifdef USE_PYTHON +struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *); +#endif -void setup_custom_mutator(afl_state_t *afl) { +void setup_custom_mutators(afl_state_t *afl) { /* Try mutator library first */ - u8 *fn = afl->afl_env.afl_custom_mutator_library; + struct custom_mutator *mutator; + u8 * fn = afl->afl_env.afl_custom_mutator_library; + u32 prev_mutator_count = 0; if (fn) { - if (afl->limit_time_sig) { - + if (afl->limit_time_sig) FATAL( "MOpt and custom mutator are mutually exclusive. We accept pull " "requests that integrates MOpt with the optional mutators " - "(custom/radamsa/redquenn/...)."); + "(custom/radamsa/redqueen/...)."); - } + u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,"); + + if (likely(!fn_token)) { - load_custom_mutator(afl, fn); + mutator = load_custom_mutator(afl, fn); + list_append(&afl->custom_mutator_list, mutator); + afl->custom_mutators_count++; - return; + } else { + + while (fn_token) { + + if (*fn_token) { // strsep can be empty if ";;" + + if (afl->not_on_tty && afl->debug) + SAYF("[Custom] Processing: %s\n", fn_token); + prev_mutator_count = afl->custom_mutators_count; + mutator = load_custom_mutator(afl, fn_token); + list_append(&afl->custom_mutator_list, mutator); + afl->custom_mutators_count++; + if (prev_mutator_count > afl->custom_mutators_count) + FATAL("Maximum Custom Mutator count reached."); + fn_token = (u8 *)strsep((char **)&fn, ";:,"); + + } + + } + + } } @@ -65,7 +93,9 @@ void setup_custom_mutator(afl_state_t *afl) { } - load_custom_mutator_py(afl, module_name); + struct custom_mutator *mutator = load_custom_mutator_py(afl, module_name); + afl->custom_mutators_count++; + list_append(&afl->custom_mutator_list, mutator); } @@ -80,114 +110,87 @@ void setup_custom_mutator(afl_state_t *afl) { } -void destroy_custom_mutator(afl_state_t *afl) { +void destroy_custom_mutators(afl_state_t *afl) { - if (afl->mutator) { + if (afl->custom_mutators_count) { - afl->mutator->afl_custom_deinit(afl->mutator->data); + LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, { - if (afl->mutator->dh) { dlclose(afl->mutator->dh); } + if (!el->data) { FATAL("Deintializing NULL mutator"); } + el->afl_custom_deinit(el->data); + if (el->dh) dlclose(el->dh); - if (afl->mutator->pre_save_buf) { + if (el->pre_save_buf) { - ck_free(afl->mutator->pre_save_buf); - afl->mutator->pre_save_buf = NULL; - afl->mutator->pre_save_size = 0; + ck_free(el->pre_save_buf); + el->pre_save_buf = NULL; + el->pre_save_size = 0; - } + } - ck_free(afl->mutator); - afl->mutator = NULL; + ck_free(el); + + }); } } -void load_custom_mutator(afl_state_t *afl, const char *fn) { +struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { - void *dh; - afl->mutator = ck_alloc(sizeof(struct custom_mutator)); - afl->mutator->pre_save_buf = NULL; - afl->mutator->pre_save_size = 0; + void * dh; + struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator)); - afl->mutator->name = fn; + mutator->name = fn; ACTF("Loading custom mutator library from '%s'...", fn); dh = dlopen(fn, RTLD_NOW); - if (!dh) { FATAL("%s", dlerror()); } - afl->mutator->dh = dh; + if (!dh) FATAL("%s", dlerror()); + mutator->dh = dh; /* Mutator */ - /* "afl_custom_init", required */ - afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); - if (!afl->mutator->afl_custom_init) { - - FATAL("Symbol 'afl_custom_init' not found."); - - } - - /* "afl_custom_deinit", required */ - afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); - if (!afl->mutator->afl_custom_deinit) { - - FATAL("Symbol 'afl_custom_deinit' not found."); - - } + /* "afl_custom_init", optional for backward compatibility */ + mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); + if (!mutator->afl_custom_init) WARNF("Symbol 'afl_custom_init' not found."); /* "afl_custom_fuzz" or "afl_custom_mutator", required */ - afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); - if (!afl->mutator->afl_custom_fuzz) { + mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); + if (!mutator->afl_custom_fuzz) { /* Try "afl_custom_mutator" for backward compatibility */ WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'."); - afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator"); - if (!afl->mutator->afl_custom_fuzz) { - + mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator"); + if (!mutator->afl_custom_fuzz) FATAL("Symbol 'afl_custom_mutator' not found."); - } - } /* "afl_custom_pre_save", optional */ - afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); - if (!afl->mutator->afl_custom_pre_save) { - + mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); + if (!mutator->afl_custom_pre_save) WARNF("Symbol 'afl_custom_pre_save' not found."); - } - u8 notrim = 0; /* "afl_custom_init_trim", optional */ - afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); - if (!afl->mutator->afl_custom_init_trim) { - + mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); + if (!mutator->afl_custom_init_trim) WARNF("Symbol 'afl_custom_init_trim' not found."); - } - /* "afl_custom_trim", optional */ - afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); - if (!afl->mutator->afl_custom_trim) { - - WARNF("Symbol 'afl_custom_trim' not found."); - - } + mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); + if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found."); /* "afl_custom_post_trim", optional */ - afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); - if (!afl->mutator->afl_custom_post_trim) { - + mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); + if (!mutator->afl_custom_post_trim) WARNF("Symbol 'afl_custom_post_trim' not found."); - } - if (notrim) { - afl->mutator->afl_custom_init_trim = NULL; - afl->mutator->afl_custom_trim = NULL; - afl->mutator->afl_custom_post_trim = NULL; + mutator->afl_custom_init_trim = NULL; + mutator->afl_custom_trim = NULL; + mutator->afl_custom_post_trim = NULL; WARNF( "Custom mutator does not implement all three trim APIs, standard " "trimming will be used."); @@ -195,53 +198,42 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { } /* "afl_custom_havoc_mutation", optional */ - afl->mutator->afl_custom_havoc_mutation = - dlsym(dh, "afl_custom_havoc_mutation"); - if (!afl->mutator->afl_custom_havoc_mutation) { - + mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); + if (!mutator->afl_custom_havoc_mutation) WARNF("Symbol 'afl_custom_havoc_mutation' not found."); - } - /* "afl_custom_havoc_mutation", optional */ - afl->mutator->afl_custom_havoc_mutation_probability = + mutator->afl_custom_havoc_mutation_probability = dlsym(dh, "afl_custom_havoc_mutation_probability"); - if (!afl->mutator->afl_custom_havoc_mutation_probability) { - + if (!mutator->afl_custom_havoc_mutation_probability) WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found."); - } - /* "afl_custom_queue_get", optional */ - afl->mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get"); - if (!afl->mutator->afl_custom_queue_get) { - + mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get"); + if (!mutator->afl_custom_queue_get) WARNF("Symbol 'afl_custom_queue_get' not found."); - } - /* "afl_custom_queue_new_entry", optional */ - afl->mutator->afl_custom_queue_new_entry = - dlsym(dh, "afl_custom_queue_new_entry"); - if (!afl->mutator->afl_custom_queue_new_entry) { - + mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); + if (!mutator->afl_custom_queue_new_entry) WARNF("Symbol 'afl_custom_queue_new_entry' not found"); - } - OKF("Custom mutator '%s' installed successfully.", fn); /* Initialize the custom mutator */ - if (afl->mutator->afl_custom_init) { + if (mutator->afl_custom_init) + mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); - afl->mutator->data = - afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation); + mutator->stacked_custom_prob = + 6; // like one of the default mutations in havoc - } + return mutator; } -u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { +u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, + struct custom_mutator *mutator) { u8 needs_write = 0, fault = 0; u32 trim_exec = 0; @@ -254,8 +246,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Initialize trimming in the custom mutator */ afl->stage_cur = 0; - afl->stage_max = - afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); + afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); if (unlikely(afl->stage_max) < 0) { FATAL("custom_init_trim error ret: %d", afl->stage_max); @@ -278,7 +269,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 cksum; - size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf); + size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf); if (unlikely(!retbuf)) { @@ -318,8 +309,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } /* Tell the custom mutator that the trimming was successful */ - afl->stage_cur = - afl->mutator->afl_custom_post_trim(afl->mutator->data, 1); + afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 1); if (afl->not_on_tty && afl->debug) { @@ -331,8 +321,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } else { /* Tell the custom mutator that the trimming was unsuccessful */ - afl->stage_cur = - afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); + afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); if (unlikely(afl->stage_cur < 0)) { FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 6d399a03..ddd15c84 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -384,16 +384,20 @@ u8 fuzz_one_original(afl_state_t *afl) { #else - if (unlikely(afl->mutator) && unlikely(afl->mutator->afl_custom_queue_get)) { + if (unlikely(afl->custom_mutators_count)) { /* The custom mutator will decide to skip this test case or not. */ - if (!afl->mutator->afl_custom_queue_get(afl->mutator->data, - afl->queue_cur->fname)) { + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - return 1; + if (el->afl_custom_queue_get && + !el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) { - } + return 1; + + } + + }); } @@ -1646,13 +1650,13 @@ custom_mutator_stage: * CUSTOM MUTATORS * *******************/ - if (likely(!afl->mutator)) { goto havoc_stage; } - if (likely(!afl->mutator->afl_custom_fuzz)) { goto havoc_stage; } + if (likely(!afl->custom_mutators_count)) { goto havoc_stage; } afl->stage_name = "custom mutator"; afl->stage_short = "custom"; afl->stage_max = HAVOC_CYCLES * perf_score / afl->havoc_div / 100; afl->stage_val_type = STAGE_VAL_NONE; + bool has_custom_fuzz = false; if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; } @@ -1660,98 +1664,112 @@ custom_mutator_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - struct queue_entry *target; - u32 tid; - u8 * new_buf; + if (el->afl_custom_fuzz) { - retry_external_pick: - /* Pick a random other queue entry for passing to external API */ - do { + has_custom_fuzz = true; - tid = rand_below(afl, afl->queued_paths); + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; + ++afl->stage_cur) { - } while (tid == afl->current_entry && afl->queued_paths > 1); + struct queue_entry *target; + u32 tid; + u8 * new_buf; - target = afl->queue; + retry_external_pick: + /* Pick a random other queue entry for passing to external API */ + do { - while (tid >= 100) { + tid = rand_below(afl, afl->queued_paths); - target = target->next_100; - tid -= 100; + } while (tid == afl->current_entry && afl->queued_paths > 1); - } + target = afl->queue; - while (tid--) { + while (tid >= 100) { - target = target->next; + target = target->next_100; + tid -= 100; - } + } - /* Make sure that the target has a reasonable length. */ + while (tid--) { - while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 1) { + target = target->next; - target = target->next; - ++afl->splicing_with; + } - } + /* Make sure that the target has a reasonable length. */ - if (!target) { goto retry_external_pick; } + while (target && (target->len < 2 || target == afl->queue_cur) && + afl->queued_paths > 1) { - /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + target = target->next; + ++afl->splicing_with; - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + } - u8 *mutated_buf = NULL; + if (!target) { goto retry_external_pick; } - size_t mutated_size = afl->mutator->afl_custom_fuzz( - afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len, - max_seed_size); + /* Read the additional testcase into a new buffer. */ + fd = open(target->fname, O_RDONLY); + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - if (unlikely(!mutated_buf)) { + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); + ck_read(fd, new_buf, target->len, target->fname); + close(fd); - FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); + u8 *mutated_buf = NULL; - } + size_t mutated_size = + el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, + target->len, max_seed_size); - if (mutated_size > 0) { + if (unlikely(!mutated_buf)) { - if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { + FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); - goto abandon_entry; + } - } + if (mutated_size > 0) { + + if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { + + goto abandon_entry; + + } - /* If we're finding new stuff, let's run for a bit longer, limits - permitting. */ + /* If we're finding new stuff, let's run for a bit longer, limits + permitting. */ - if (afl->queued_paths != havoc_queued) { + if (afl->queued_paths != havoc_queued) { - if (perf_score <= afl->havoc_max_mult * 100) { + if (perf_score <= afl->havoc_max_mult * 100) { - afl->stage_max *= 2; - perf_score *= 2; + afl->stage_max *= 2; + perf_score *= 2; + + } + + havoc_queued = afl->queued_paths; + + } } - havoc_queued = afl->queued_paths; + /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ + /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. + */ + memcpy(out_buf, in_buf, len); } } - /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ - /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. */ - memcpy(out_buf, in_buf, len); + }); - } + if (!has_custom_fuzz) goto havoc_stage; new_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -1803,20 +1821,26 @@ havoc_stage: havoc_queued = afl->queued_paths; - u8 stacked_custom = (afl->mutator && afl->mutator->afl_custom_havoc_mutation); - u8 stacked_custom_prob = 6; // like one of the default mutations in havoc + if (afl->custom_mutators_count) { - if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) { + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - stacked_custom_prob = - afl->mutator->afl_custom_havoc_mutation_probability(afl->mutator->data); - if (stacked_custom_prob > 100) { + if (el->stacked_custom && el->afl_custom_havoc_mutation_probability) { - FATAL( - "The probability returned by afl_custom_havoc_mutation_propability " - "has to be in the range 0-100."); + el->stacked_custom_prob = + el->afl_custom_havoc_mutation_probability(el->data); + if (el->stacked_custom_prob > 100) { - } + FATAL( + "The probability returned by " + "afl_custom_havoc_mutation_propability " + "has to be in the range 0-100."); + + } + + } + + }); } @@ -1831,28 +1855,37 @@ havoc_stage: for (i = 0; i < use_stacking; ++i) { - if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { + if (afl->custom_mutators_count) { - u8 * custom_havoc_buf = NULL; - size_t new_len = afl->mutator->afl_custom_havoc_mutation( - afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); - if (unlikely(!custom_havoc_buf)) { + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - FATAL("Error in custom_havoc (return %zd)", new_len); + if (el->stacked_custom && + rand_below(afl, 100) < el->stacked_custom_prob) { - } + u8 * custom_havoc_buf = NULL; + size_t new_len = el->afl_custom_havoc_mutation( + el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); + if (unlikely(!custom_havoc_buf)) { + + FATAL("Error in custom_havoc (return %zd)", new_len); - if (likely(new_len > 0 && custom_havoc_buf)) { + } - temp_len = new_len; - if (out_buf != custom_havoc_buf) { + if (likely(new_len > 0 && custom_havoc_buf)) { - ck_maybe_grow(BUF_PARAMS(out), temp_len); - memcpy(out_buf, custom_havoc_buf, temp_len); + temp_len = new_len; + if (out_buf != custom_havoc_buf) { + + ck_maybe_grow(BUF_PARAMS(out), temp_len); + memcpy(out_buf, custom_havoc_buf, temp_len); + + } + + } } - } + }); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 64cabcad..832dba06 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -71,7 +71,7 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, PyTuple_SetItem(py_args, 1, py_value); - /* max_size */ +/* max_size */ #if PY_MAJOR_VERSION >= 3 py_value = PyLong_FromLong(max_size); #else @@ -295,80 +295,75 @@ void deinit_py(void *py_mutator) { } -void load_custom_mutator_py(afl_state_t *afl, char *module_name) { +struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, + char * module_name) { - afl->mutator = ck_alloc(sizeof(struct custom_mutator)); - afl->mutator->pre_save_buf = NULL; - afl->mutator->pre_save_size = 0; + struct custom_mutator *mutator; - afl->mutator->name = module_name; + mutator = ck_alloc(sizeof(struct custom_mutator)); + mutator->pre_save_buf = NULL; + mutator->pre_save_size = 0; + + mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); py_mutator_t *py_mutator; py_mutator = init_py_module(afl, module_name); - afl->mutator->data = py_mutator; + mutator->data = py_mutator; if (!py_mutator) { FATAL("Failed to load python mutator."); } PyObject **py_functions = py_mutator->py_functions; - if (py_functions[PY_FUNC_INIT]) { - - afl->mutator->afl_custom_init = unsupported; - - } - - if (py_functions[PY_FUNC_DEINIT]) { - - afl->mutator->afl_custom_deinit = deinit_py; + if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; } - } + if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; } /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator is quite different from the custom mutator. */ - afl->mutator->afl_custom_fuzz = fuzz_py; + mutator->afl_custom_fuzz = fuzz_py; if (py_functions[PY_FUNC_PRE_SAVE]) { - afl->mutator->afl_custom_pre_save = pre_save_py; + mutator->afl_custom_pre_save = pre_save_py; } if (py_functions[PY_FUNC_INIT_TRIM]) { - afl->mutator->afl_custom_init_trim = init_trim_py; + mutator->afl_custom_init_trim = init_trim_py; } if (py_functions[PY_FUNC_POST_TRIM]) { - afl->mutator->afl_custom_post_trim = post_trim_py; + mutator->afl_custom_post_trim = post_trim_py; } - if (py_functions[PY_FUNC_TRIM]) { afl->mutator->afl_custom_trim = trim_py; } + if (py_functions[PY_FUNC_TRIM]) { mutator->afl_custom_trim = trim_py; } if (py_functions[PY_FUNC_HAVOC_MUTATION]) { - afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py; + mutator->afl_custom_havoc_mutation = havoc_mutation_py; } if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) { - afl->mutator->afl_custom_havoc_mutation_probability = + mutator->afl_custom_havoc_mutation_probability = havoc_mutation_probability_py; } if (py_functions[PY_FUNC_QUEUE_GET]) { - afl->mutator->afl_custom_queue_get = queue_get_py; + mutator->afl_custom_queue_get = queue_get_py; } if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) { - afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py; + mutator->afl_custom_queue_new_entry = queue_new_entry_py; } @@ -377,6 +372,8 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { /* Initialize the custom mutator */ init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF)); + return mutator; + } size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { @@ -545,7 +542,7 @@ size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, PyTuple_SetItem(py_args, 0, py_value); - /* max_size */ +/* max_size */ #if PY_MAJOR_VERSION >= 3 py_value = PyLong_FromLong(max_size); #else @@ -627,7 +624,7 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) { py_args = PyTuple_New(1); - // File name +// File name #if PY_MAJOR_VERSION >= 3 py_value = PyUnicode_FromString(filename); #else @@ -677,7 +674,7 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, py_args = PyTuple_New(2); - // New queue +// New queue #if PY_MAJOR_VERSION >= 3 py_value = PyUnicode_FromString(filename_new_queue); #else diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f998c06b..cfeb6c5e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -140,15 +140,22 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { afl->last_path_time = get_cur_time(); - if (afl->mutator && afl->mutator->afl_custom_queue_new_entry) { + if (afl->custom_mutators_count) { - u8 *fname_orig = NULL; + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - /* At the initialization stage, queue_cur is NULL */ - if (afl->queue_cur) { fname_orig = afl->queue_cur->fname; } + if (el->afl_custom_queue_new_entry) { - afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, - fname_orig); + u8 *fname_orig = NULL; + + /* At the initialization stage, queue_cur is NULL */ + if (afl->queue_cur) fname_orig = afl->queue_cur->fname; + + el->afl_custom_queue_new_entry(el->data, fname, fname_orig); + + } + + }); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 692026d4..4a22dad6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -30,13 +30,37 @@ #include "cmplog.h" +#ifdef PROFILING +u64 time_spent_working = 0; +#endif + /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { +#ifdef PROFILING + static u64 time_spent_start = 0; + struct timespec spec; + if (time_spent_start) { + + u64 current; + clock_gettime(CLOCK_REALTIME, &spec); + current = (spec.tv_sec * 1000000000) + spec.tv_nsec; + time_spent_working += (current - time_spent_start); + + } + +#endif + fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon); + +#ifdef PROFILING + clock_gettime(CLOCK_REALTIME, &spec); + time_spent_start = (spec.tv_sec * 1000000000) + spec.tv_nsec; +#endif + // TODO: Don't classify for faults? classify_counts(fsrv); return res; @@ -65,21 +89,40 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { #endif - if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) { + if (unlikely(afl->custom_mutators_count)) { + + u8 * new_buf = NULL; + ssize_t new_size = len; + void * new_mem = mem; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_pre_save) { + + new_size = + el->afl_custom_pre_save(el->data, new_mem, new_size, &new_buf); - u8 *new_buf = NULL; + } + + new_mem = new_buf; - size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, - len, &new_buf); + }); - if (unlikely(!new_buf)) { + if (unlikely(!new_buf && (new_size <= 0))) { FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size); - } + } else if (likely(new_buf)) { + + /* everything as planned. use the new data. */ + afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size); - /* everything as planned. use the new data. */ - afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size); + } else { + + /* custom mutators do not has a custom_pre_save function */ + afl_fsrv_write_to_testcase(&afl->fsrv, mem, len); + + } } else { @@ -489,9 +532,23 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Custom mutator trimmer */ - if (afl->mutator && afl->mutator->afl_custom_trim) { + if (afl->custom_mutators_count) { + + u8 trimmed_case = 0; + bool custom_trimmed = false; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_trim) { + + trimmed_case = trim_case_custom(afl, q, in_buf, el); + custom_trimmed = true; + + } + + }); - return trim_case_custom(afl, q, in_buf); + if (custom_trimmed) return trimmed_case; } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 3cbb2d8c..014ed34d 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -72,7 +72,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "start_time : %llu\n" "last_update : %llu\n" "run_time : %llu\n" - "fuzzer_pid : %d\n" + "fuzzer_pid : %u\n" "cycles_done : %llu\n" "cycles_wo_finds : %llu\n" "execs_done : %llu\n" @@ -106,7 +106,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "target_mode : %s%s%s%s%s%s%s%s\n" "command_line : %s\n", afl->start_time / 1000, cur_time / 1000, - (cur_time - afl->start_time) / 1000, getpid(), + (cur_time - afl->start_time) / 1000, (u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds, afl->fsrv.total_execs, afl->fsrv.total_execs / @@ -792,7 +792,7 @@ void show_stats(afl_state_t *afl) { } - if (afl->mutator) { + if (afl->custom_mutators_count) { sprintf(tmp, "%s/%s", u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5920f5c0..aaf615e9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -27,6 +27,10 @@ #include "cmplog.h" #include <limits.h> +#ifdef PROFILING +extern u64 time_spent_working; +#endif + static u8 *get_libradamsa_path(u8 *own_loc) { u8 *tmp, *cp, *rsl, *own_copy; @@ -644,10 +648,7 @@ int main(int argc, char **argv_orig, char **envp) { } afl->limit_time_puppet = limit_time_puppet2; - - SAYF("limit_time_puppet %d\n", afl->limit_time_puppet); afl->swarm_now = 0; - if (afl->limit_time_puppet == 0) { afl->key_puppet = 1; } int i; @@ -1073,7 +1074,7 @@ int main(int argc, char **argv_orig, char **envp) { setup_dirs_fds(afl); - setup_custom_mutator(afl); + setup_custom_mutators(afl); setup_cmdline_file(afl, argv + optind); @@ -1351,10 +1352,17 @@ stop_fuzzing: } +#ifdef PROFILING + SAYF(cYEL "[!] " cRST + "Profiling information: %llu ms total work, %llu ns/run\n", + time_spent_working / 1000000, + time_spent_working / afl->fsrv.total_execs); +#endif + fclose(afl->fsrv.plot_file); destroy_queue(afl); destroy_extras(afl); - destroy_custom_mutator(afl); + destroy_custom_mutators(afl); afl_shm_deinit(&afl->shm); afl_fsrv_deinit(&afl->fsrv); if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index a51d520d..ed59f2f5 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -865,7 +865,8 @@ int main(int argc, char **argv_orig, char **envp) { } - stdin_file = alloc_printf("%s/.afl-showmap-temp-%u", use_dir, getpid()); + stdin_file = + alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 98568473..e15dc72d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -619,7 +619,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } - out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid()); + out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid()); } |