From 89512d4e05e18d83b634adc00afdd8ad6fb94df5 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 24 Mar 2020 22:40:14 +0100 Subject: fixed call of custom mutators --- src/afl-fuzz-mutators.c | 6 +++--- src/afl-fuzz-one.c | 8 ++++---- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-run.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0ded4ba1..3e6ad466 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -213,7 +213,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u8 * retbuf = NULL; size_t retlen = 0; - afl->mutator->afl_custom_trim(afl, &retbuf, &retlen); + afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf, &retlen); if (retlen > orig_len) FATAL( @@ -250,7 +250,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, 1); + afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 1); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)", @@ -259,7 +259,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, 0); + afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index cc150cfe..bcd9135a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -360,7 +360,7 @@ u8 fuzz_one_original(afl_state_t *afl) { /* The custom mutator will decide to skip this test case or not. */ - if (!afl->mutator->afl_custom_queue_get(afl, afl->queue_cur->fname)) + if (!afl->mutator->afl_custom_queue_get(afl->mutator->data, afl->queue_cur->fname)) return 1; } @@ -1611,7 +1611,7 @@ custom_mutator_stage: close(fd); size_t mutated_size = afl->mutator->afl_custom_fuzz( - afl, &out_buf, len, new_buf, target->len, max_seed_size); + afl->mutator->data, &out_buf, len, new_buf, target->len, max_seed_size); ck_free(new_buf); @@ -1702,7 +1702,7 @@ havoc_stage: if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) { stacked_custom_prob = - afl->mutator->afl_custom_havoc_mutation_probability(afl); + afl->mutator->afl_custom_havoc_mutation_probability(afl->mutator->data); if (stacked_custom_prob > 100) FATAL( "The probability returned by afl_custom_havoc_mutation_propability " @@ -1723,7 +1723,7 @@ havoc_stage: if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { - temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf, + temp_len = afl->mutator->afl_custom_havoc_mutation(afl->mutator->data, &out_buf, temp_len, MAX_FILE); } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f49e1f1e..b036969f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -147,7 +147,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { /* At the initialization stage, queue_cur is NULL */ if (afl->queue_cur) fname_orig = afl->queue_cur->fname; - afl->mutator->afl_custom_queue_new_entry(afl, fname, fname_orig); + afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, fname_orig); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8c4b5941..2b207a9e 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -218,9 +218,9 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { u8 * new_data; size_t new_size = - afl->mutator->afl_custom_pre_save(afl, mem, len, &new_data); + afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, len, &new_data); ck_write(fd, new_data, new_size, afl->fsrv.out_file); - ck_free(new_data); + free(new_data); } else { -- cgit 1.4.1 From 6d3dc83c5dde31ccb74e04815a04b85b05761b30 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 25 Mar 2020 11:31:01 +0100 Subject: code format --- examples/custom_mutators/custom_mutator_helpers.h | 11 +- examples/custom_mutators/example.c | 29 ++++-- include/afl-fuzz.h | 19 ++-- include/common.h | 25 +++-- llvm_mode/afl-clang-fast.c | 38 +++---- src/afl-fuzz-mutators.c | 22 ++-- src/afl-fuzz-one.c | 7 +- src/afl-fuzz-python.c | 46 +++++---- src/afl-fuzz-queue.c | 3 +- src/afl-fuzz-run.c | 8 +- src/afl-fuzz-stats.c | 119 +++++++++++----------- 11 files changed, 175 insertions(+), 152 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index 844ccf94..cd3a15f0 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -7,11 +7,13 @@ #define RAND_BELOW(limit) (rand() % (limit)) -typedef struct{} afl_t; +typedef struct { + +} afl_t; static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { - static s8 interesting_8[] = {INTERESTING_8}; + static s8 interesting_8[] = {INTERESTING_8}; static s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; static s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; @@ -111,8 +113,8 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]; break; case 1: - *(u64 *)(out_buf + byte_idx) = - SWAP64((s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); + *(u64 *)(out_buf + byte_idx) = SWAP64( + (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); break; } @@ -266,3 +268,4 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } #endif + diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 560a5919..2df17dec 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -23,7 +23,6 @@ static const char *commands[] = { }; - typedef struct my_mutator { afl_t *afl; @@ -34,21 +33,26 @@ typedef struct my_mutator { /** * Initialize this custom mutator * - * @param[in] afl a pointer to the internal state object. Can be ignored for now. - * @param[in] seed A seed for this mutator - the same seed should always mutate in the same way. + * @param[in] afl a pointer to the internal state object. Can be ignored for + * now. + * @param[in] seed A seed for this mutator - the same seed should always mutate + * in the same way. * @return Pointer to the data object this custom mutator instance should use. * There may be multiple instances of this mutator in one afl-fuzz run! * Returns NULL on error. */ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { - srand(seed); // needed also by surgical_havoc_mutate() + srand(seed); // needed also by surgical_havoc_mutate() my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); if (!data) { + perror("afl_custom_init alloc"); return NULL; + } + data->afl = afl; return data; @@ -71,8 +75,8 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { */ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { + size_t add_buf_size, // add_buf can be NULL + size_t max_size) { // Make sure that the packet size does not exceed the maximum size expected by // the fuzzer @@ -113,7 +117,8 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, * will release the memory after saving the test case. * @return Size of the output buffer after processing */ -size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { +size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, + uint8_t **out_buf) { size_t out_buf_size; @@ -183,7 +188,8 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * the memory after saving the test case. * @param[out] out_buf_size Pointer to the size of the trimmed test case */ -void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, size_t *out_buf_size) { +void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, + size_t *out_buf_size) { *out_buf_size = trim_buf_size - 1; @@ -233,8 +239,8 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * not produce data larger than max_size. * @return Size of the mutated output. */ -size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, size_t buf_size, - size_t max_size) { +size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, + size_t buf_size, size_t max_size) { if (buf_size == 0) { @@ -292,7 +298,8 @@ uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) { * @param filename_new_queue File name of the new queue entry * @param filename_orig_queue File name of the original queue entry */ -void afl_custom_queue_new_entry(my_mutator_t *data, const uint8_t *filename_new_queue, +void afl_custom_queue_new_entry(my_mutator_t * data, + const uint8_t *filename_new_queue, const uint8_t *filename_orig_queue) { /* Additional analysis on the original or new test case */ diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 7dddefb0..d610ac29 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -290,8 +290,8 @@ typedef struct py_mutator { PyObject *py_module; PyObject *py_functions[PY_FUNC_COUNT]; - void *afl_state; - void *py_data; + void * afl_state; + void * py_data; } py_mutator_t; @@ -592,7 +592,7 @@ struct custom_mutator { const char *name; void * dh; - void *data; /* custom mutator data ptr */ + void *data; /* custom mutator data ptr */ /* hooks for the custom mutator function */ @@ -620,8 +620,8 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, - u8 *add_buf, size_t add_buf_size, size_t max_size); + size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, u8 *add_buf, + size_t add_buf_size, size_t max_size); /** * A post-processing function to use right before AFL writes the test case to @@ -711,8 +711,8 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, - size_t buf_size, size_t max_size); + size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, size_t buf_size, + size_t max_size); /** * Return the probability (in percentage) that afl_custom_havoc_mutation @@ -748,9 +748,8 @@ struct custom_mutator { * @param filename_orig_queue File name of the original queue entry. This * argument can be NULL while initializing the fuzzer */ - void (*afl_custom_queue_new_entry)(void *data, - const u8 * filename_new_queue, - const u8 * filename_orig_queue); + void (*afl_custom_queue_new_entry)(void *data, const u8 *filename_new_queue, + const u8 *filename_orig_queue); /** * Deinitialize the custom mutator. * diff --git a/include/common.h b/include/common.h index 97076004..8b21b55f 100644 --- a/include/common.h +++ b/include/common.h @@ -78,7 +78,7 @@ static u64 get_cur_time_us(void) { Will return buf for convenience. */ static u8 *stringify_int(u8 *buf, size_t len, u64 val) { - +\ #define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ do { \ \ @@ -233,23 +233,22 @@ static u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { } - /* Unsafe Describe integer. The buf sizes are not checked. This is unsafe but fast. Will return buf for convenience. */ static u8 *u_stringify_int(u8 *buf, u64 val) { - -#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ - do { \ - \ - if (val < (_divisor) * (_limit_mult)) { \ - \ - sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ - return buf; \ - \ - } \ - \ +\ +#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ + do { \ + \ + if (val < (_divisor) * (_limit_mult)) { \ + \ + sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ + return buf; \ + \ + } \ + \ } while (0) /* 0-9999 */ diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 34df5671..7050e22d 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -485,37 +485,37 @@ static void edit_params(u32 argc, char **argv) { // if (maybe_linking) { - if (x_set) { + if (x_set) { - cc_params[cc_par_cnt++] = "-x"; - cc_params[cc_par_cnt++] = "none"; + cc_params[cc_par_cnt++] = "-x"; + cc_params[cc_par_cnt++] = "none"; - } + } #ifndef __ANDROID__ - switch (bit_mode) { + switch (bit_mode) { - case 0: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); - break; + case 0: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); + break; - case 32: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path); + case 32: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); - break; + break; - case 64: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path); + case 64: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); - break; + break; - } + } #endif diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 3e6ad466..0b0c3394 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -78,8 +78,7 @@ void destroy_custom_mutator(afl_state_t *afl) { afl->mutator->afl_custom_deinit(afl->mutator->data); - if (afl->mutator->dh) - dlclose(afl->mutator->dh); + if (afl->mutator->dh) dlclose(afl->mutator->dh); ck_free(afl->mutator); afl->mutator = NULL; @@ -103,11 +102,13 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* 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."); + 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."); + if (!afl->mutator->afl_custom_deinit) + FATAL("Symbol 'afl_custom_deinit' not found."); /* "afl_custom_fuzz" or "afl_custom_mutator", required */ afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); @@ -198,7 +199,8 @@ 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 = + afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, @@ -206,7 +208,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (afl->stage_cur < afl->stage_max) { - sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec)); + sprintf(afl->stage_name_buf, "ptrim %s", + u_stringify_int(val_buf, trim_exec)); u32 cksum; @@ -250,7 +253,8 @@ 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 = + afl->mutator->afl_custom_post_trim(afl->mutator->data, 1); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)", @@ -259,7 +263,8 @@ 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 = + afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); @@ -304,3 +309,4 @@ abort_trimming: return fault; } + diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bcd9135a..7cc5e0d9 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -360,7 +360,8 @@ u8 fuzz_one_original(afl_state_t *afl) { /* 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)) + if (!afl->mutator->afl_custom_queue_get(afl->mutator->data, + afl->queue_cur->fname)) return 1; } @@ -1723,8 +1724,8 @@ havoc_stage: if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { - temp_len = afl->mutator->afl_custom_havoc_mutation(afl->mutator->data, &out_buf, - temp_len, MAX_FILE); + temp_len = afl->mutator->afl_custom_havoc_mutation( + afl->mutator->data, &out_buf, temp_len, MAX_FILE); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index d3027d2b..418497d0 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -29,8 +29,10 @@ #ifdef USE_PYTHON static void *unsupported(afl_state_t *afl, unsigned int seed) { + FATAL("Python Mutator cannot be called twice yet"); return NULL; + } size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, @@ -77,7 +79,8 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, PyTuple_SetItem(py_args, 2, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); Py_DECREF(py_args); @@ -99,7 +102,6 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, } - static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (!module_name) return NULL; @@ -223,7 +225,8 @@ void finalize_py_module(void *py_mutator) { } -static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int seed) { +static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, + unsigned int seed) { PyObject *py_args, *py_value; @@ -244,7 +247,8 @@ static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int see PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args); + py_value = + PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args); Py_DECREF(py_args); @@ -289,9 +293,7 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { py_mutator_t *py_mutator; py_mutator = init_py_module(afl, module_name); - if (!py_mutator) { - FATAL("Failed to load python mutator."); - } + if (!py_mutator) { FATAL("Failed to load python mutator."); } PyObject **py_functions = py_mutator->py_functions; @@ -334,7 +336,6 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } - size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { size_t out_buf_size; @@ -350,7 +351,8 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args); Py_DECREF(py_args); @@ -386,7 +388,8 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -424,7 +427,8 @@ u32 post_trim_py(void *py_mutator, u8 success) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -451,7 +455,8 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { PyObject *py_args, *py_value; py_args = PyTuple_New(0); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -503,8 +508,9 @@ size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, PyTuple_SetItem(py_args, 1, py_value); - py_value = - PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], + py_args); Py_DECREF(py_args); @@ -533,7 +539,9 @@ u8 havoc_mutation_probability_py(void *py_mutator) { py_args = PyTuple_New(0); py_value = PyObject_CallObject( - ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args); + ((py_mutator_t *)py_mutator) + ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], + py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -573,7 +581,8 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) { PyTuple_SetItem(py_args, 0, py_value); // Call Python function - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -642,8 +651,9 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, PyTuple_SetItem(py_args, 1, py_value); // Call - py_value = - PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], + py_args); Py_DECREF(py_args); if (py_value == NULL) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b036969f..73da449a 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -147,7 +147,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { /* At the initialization stage, queue_cur is NULL */ if (afl->queue_cur) fname_orig = afl->queue_cur->fname; - afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, fname_orig); + afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, + fname_orig); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 2b207a9e..e8ef3049 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -217,8 +217,8 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (afl->mutator && afl->mutator->afl_custom_pre_save) { u8 * new_data; - size_t new_size = - afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, len, &new_data); + size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, + len, &new_data); ck_write(fd, new_data, new_size, afl->fsrv.out_file); free(new_data); @@ -627,8 +627,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 remove_pos = remove_len; sprintf(afl->stage_name_buf, "trim %s/%s", - u_stringify_int(val_bufs[0], remove_len), - u_stringify_int(val_bufs[1], remove_len)); + u_stringify_int(val_bufs[0], remove_len), + u_stringify_int(val_bufs[1], remove_len)); afl->stage_cur = 0; afl->stage_max = q->len / remove_len; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index dc16df8f..5536c201 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -361,9 +361,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -406,8 +406,7 @@ void show_stats(afl_state_t *afl) { (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 || afl->in_bitmap || afl->crash_mode)) { - u_stringify_time_diff(time_tmp, cur_ms, - afl->last_path_time); + u_stringify_time_diff(time_tmp, cur_ms, afl->last_path_time); SAYF(bV bSTOP " last new path : " cRST "%-33s ", time_tmp); } else { @@ -446,9 +445,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -477,9 +476,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -533,30 +532,27 @@ void show_stats(afl_state_t *afl) { if (afl->stats_avg_exec < 100) { - sprintf(tmp, "%s/sec (%s)", - u_stringify_float(IB(0), afl->stats_avg_exec), - afl->stats_avg_exec < 20 ? "zzzz..." : "slow!"); + sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec), + afl->stats_avg_exec < 20 ? "zzzz..." : "slow!"); SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp); } else { - sprintf(tmp, "%s/sec", - u_stringify_float(IB(0), afl->stats_avg_exec)); + sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec)); SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp); } - sprintf(tmp, "%s (%s%s unique)", - u_stringify_int(IB(0), afl->total_tmouts), - u_stringify_int(IB(1), afl->unique_tmouts), - (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); + sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_tmouts), + u_stringify_int(IB(1), afl->unique_tmouts), + (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp); /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); @@ -567,12 +563,12 @@ void show_stats(afl_state_t *afl) { } else { sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]), - u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]), + u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); } @@ -582,12 +578,12 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32])); SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP " pending : " cRST "%-10s" bSTG bV "\n", @@ -595,12 +591,12 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32])); SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP " pend fav : " cRST "%-10s" bSTG bV "\n", @@ -621,25 +617,26 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO])); SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP " imported : " cRST "%-10s" bSTG bV "\n", tmp, - afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) : (u8 *)"n/a"); + afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) + : (u8 *)"n/a"); sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]), - u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]), - u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]), - u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]), - u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]), - u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]), + u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]), + u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]), + u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]), + u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]), + u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA])); SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp); @@ -660,14 +657,14 @@ void show_stats(afl_state_t *afl) { if (afl->shm.cmplog_mode) { sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]), - u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]), - u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]), + u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]), + u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS])); SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", tmp); @@ -675,10 +672,10 @@ void show_stats(afl_state_t *afl) { } else { sprintf(tmp, "%s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", tmp); -- cgit 1.4.1 From e9c7610cb7d309f4c7fd1fd6435c29e736869772 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 25 Mar 2020 21:54:52 +0100 Subject: edited custom mutator pre_save api --- docs/custom_mutators.md | 2 +- examples/custom_mutators/example.c | 25 +++++++++++------ include/afl-fuzz.h | 12 +++++++-- src/afl-fuzz-mutators.c | 21 ++++++++++++++- src/afl-fuzz-python.c | 55 +++++++++++++++++++++++++++++++++----- src/afl-fuzz-run.c | 52 +++++++++++++++++++++++++++++------ 6 files changed, 140 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 14d8f518..ecbd50ba 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -30,7 +30,7 @@ C/C++: void afl_custom_init(unsigned int seed); size_t afl_custom_fuzz(uint8_t** buf, size_t buf_size, uint8_t* add_buf, size_t add_buf_size, size_t max_size); -size_t afl_custom_pre_save(uint8_t* buf, size_t buf_size, uint8_t** out_buf); +size_t afl_custom_write_to_testcase(uint8_t* buf, size_t buf_size, uint8_t** out_buf); uint32_t afl_custom_init_trim(uint8_t* buf, size_t buf_size); void afl_custom_trim(uint8_t** out_buf, size_t* out_buf_size); uint32_t afl_custom_post_trim(uint8_t success); diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 2df17dec..3e708db8 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -12,6 +12,7 @@ #include #include #include +#include #define DATA_SIZE (100) @@ -112,21 +113,29 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case - * @param[out] out_buf Pointer to the buffer containing the test case after + * @param[in] out_buf Pointer to the buffer containing the test case after * processing. External library should allocate memory for out_buf. AFL++ * will release the memory after saving the test case. - * @return Size of the output buffer after processing + * out_buf will always be at least as large as buf. + * @param[in] out_buf_size The maximum size we may use. + * In case we need to have this bigger, simply return that. + * @return Size of the output buffer after processing or the needed amount. + * return 0 to indicate the original buf should be used. */ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, - uint8_t **out_buf) { + uint8_t *out_buf, size_t out_buf_size) { - size_t out_buf_size; + // In case we need more than out_buf_size, we return that amount and get + // called again. + if (out_buf_size < 32000) return 32000; + memcpy(out_buf, buf, buf_size); out_buf_size = buf_size; - - // External mutator should allocate memory for `out_buf` - *out_buf = malloc(out_buf_size); - memcpy(*out_buf, buf, out_buf_size); + out_buf[0] = 'A'; + out_buf[1] = 'F'; + out_buf[2] = 'L'; + out_buf[3] = '+'; + out_buf[4] = '+'; return out_buf_size; diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index d610ac29..8bf66403 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -30,6 +30,9 @@ #define AFL_MAIN #define MESSAGES_TO_STDOUT +/* We preallocate a buffer of this size for afl_custom_pre_save */ +#define PRE_SAVE_BUF_INIT_SIZE (16384) + #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif @@ -293,6 +296,9 @@ typedef struct py_mutator { void * afl_state; void * py_data; + PyObject *scratch_buf; + size_t scratch_size; + } py_mutator_t; #endif @@ -591,6 +597,8 @@ struct custom_mutator { const char *name; void * dh; + u8 * pre_save_buf; + size_t pre_save_size; void *data; /* custom mutator data ptr */ @@ -639,7 +647,7 @@ struct custom_mutator { * @return Size of the output buffer after processing */ size_t (*afl_custom_pre_save)(void *data, u8 *buf, size_t buf_size, - u8 **out_buf); + u8 *out_buf, size_t out_buf_size); /** * This method is called at the start of each trimming operation and receives @@ -775,7 +783,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); -size_t pre_save_py(void *, u8 *, size_t, u8 **); +size_t pre_save_py(void *, u8 *, size_t, u8 *, size_t); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); void trim_py(void *, u8 **, size_t *); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0b0c3394..fac97f8e 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -80,6 +80,14 @@ void destroy_custom_mutator(afl_state_t *afl) { if (afl->mutator->dh) dlclose(afl->mutator->dh); + if (afl->mutator->pre_save_buf) { + + ck_free(afl->mutator->pre_save_buf); + afl->mutator->pre_save_buf = NULL; + afl->mutator->pre_save_size = 0; + + } + ck_free(afl->mutator); afl->mutator = NULL; @@ -91,6 +99,8 @@ void 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; afl->mutator->name = fn; ACTF("Loading custom mutator library from '%s'...", fn); @@ -125,9 +135,18 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_pre_save", optional */ afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); - if (!afl->mutator->afl_custom_pre_save) + if (!afl->mutator->afl_custom_pre_save) { + WARNF("Symbol 'afl_custom_pre_save' not found."); + } else { + + /* if we have a pre_save hook, prealloc some memory. */ + afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); + afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; + + } + u8 notrim = 0; /* "afl_custom_init_trim", optional */ afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 418497d0..b053e8d5 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -287,6 +287,8 @@ void deinit_py(void *py_mutator) { void 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; afl->mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); @@ -305,8 +307,14 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { is quite different from the custom mutator. */ afl->mutator->afl_custom_fuzz = fuzz_py; - if (py_functions[PY_FUNC_PRE_SAVE]) + if (py_functions[PY_FUNC_PRE_SAVE]) { + afl->mutator->afl_custom_pre_save = pre_save_py; + /* if we have a pre_save hook, prealloc some memory. */ + afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); + afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; + + } if (py_functions[PY_FUNC_INIT_TRIM]) afl->mutator->afl_custom_init_trim = init_trim_py; @@ -336,10 +344,33 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } -size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { +size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, + size_t out_buf_size) { - size_t out_buf_size; + size_t py_out_buf_size; PyObject *py_args, *py_value; + + if (((py_mutator_t *)py_mutator)->scratch_buf) { + + /* We are being recalled from an earlier run + where we didn't have enough mem. */ + if (((py_mutator_t *)py_mutator)->scratch_size < out_buf_size) { + + FATAL("out_buf is still too small after resizing in custom mutator."); + + } + + py_value = ((py_mutator_t *)py_mutator)->scratch_buf; + py_out_buf_size = ((py_mutator_t *)py_mutator)->scratch_size; + ((py_mutator_t *)py_mutator)->scratch_buf = NULL; + py_out_buf_size = 0; + + memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); + Py_DECREF(py_value); + return py_out_buf_size; + + } + py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { @@ -358,11 +389,21 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { if (py_value != NULL) { - out_buf_size = PyByteArray_Size(py_value); - *out_buf = malloc(out_buf_size); - memcpy(*out_buf, PyByteArray_AsString(py_value), out_buf_size); + py_out_buf_size = PyByteArray_Size(py_value); + if (py_out_buf_size > out_buf_size) { + + /* Not enough space! + We will get called again right after resizing the buf. + Keep the references to our data for now. */ + ((py_mutator_t *)py_mutator)->scratch_buf = py_value; + ((py_mutator_t *)py_mutator)->scratch_size = py_out_buf_size; + return py_out_buf_size; + + } + + memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); - return out_buf_size; + return py_out_buf_size; } else { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index e8ef3049..a539b469 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -216,14 +216,49 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (afl->mutator && afl->mutator->afl_custom_pre_save) { - u8 * new_data; - size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, - len, &new_data); - ck_write(fd, new_data, new_size, afl->fsrv.out_file); - free(new_data); + if (unlikely(afl->mutator->pre_save_size < len)) { + + afl->mutator->pre_save_buf = + ck_realloc(afl->mutator->pre_save_buf, len * sizeof(u8)); + afl->mutator->pre_save_size = len; + + } + + u8 buf_written = 0; + while (!buf_written) { + + buf_written = 1; + size_t new_size = afl->mutator->afl_custom_pre_save( + afl->mutator->data, mem, len, afl->mutator->pre_save_buf, + afl->mutator->pre_save_size); + + if (unlikely(new_size) == 0) { + + /* custom_pre_save wants us to use the old buf */ + ck_write(fd, mem, len, afl->fsrv.out_file); + + } else if (unlikely(new_size) > afl->mutator->pre_save_size) { + + /* The custom func needs more space. + Realloc and call again. */ + afl->mutator->pre_save_buf = + ck_realloc(afl->mutator->pre_save_buf, new_size * sizeof(u8)); + afl->mutator->pre_save_size = new_size; + buf_written = 0; + continue; + + } else { + + /* everything as planned. use the new data. */ + ck_write(fd, afl->mutator->pre_save_buf, new_size, afl->fsrv.out_file); + + } + + } } else { + /* boring uncustom. */ ck_write(fd, mem, len, afl->fsrv.out_file); } @@ -505,8 +540,8 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_cur = 0; afl->stage_max = 0; - /* For every file queued by this fuzzer, parse ID and see if we have looked - at it before; exec a test case if not. */ + /* For every file queued by this fuzzer, parse ID and see if we have + looked at it before; exec a test case if not. */ while ((qd_ent = readdir(qd))) { @@ -645,7 +680,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (afl->stop_soon || fault == FAULT_ERROR) goto abort_trimming; - /* Note that we don't keep track of crashes or hangs here; maybe TODO? */ + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); -- cgit 1.4.1 From fc4b03ee747366a5df1dd692851b961b93947eed Mon Sep 17 00:00:00 2001 From: Rishi Ranjan <43873720+rish9101@users.noreply.github.com> Date: Thu, 26 Mar 2020 23:17:48 +0530 Subject: Code Format (#275) --- src/afl-fuzz-stats.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 5536c201..53c162a2 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -361,9 +361,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -445,9 +445,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -476,9 +476,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -552,7 +552,7 @@ void show_stats(afl_state_t *afl) { /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); -- cgit 1.4.1 From d6a7630fe2938621db05e616fe6b1b21dfaf21b3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 26 Mar 2020 19:44:44 +0100 Subject: more api --- docs/custom_mutators.md | 3 +- examples/custom_mutators/example.c | 35 ++++++++++++++++++++---- include/afl-fuzz.h | 19 ++++++------- src/afl-fuzz-mutators.c | 11 +------- src/afl-fuzz-python.c | 56 ++++++++++---------------------------- src/afl-fuzz-run.c | 45 ++++++------------------------ src/afl-fuzz-stats.c | 14 +++++----- 7 files changed, 71 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index ecbd50ba..2163b2d5 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -27,7 +27,7 @@ performed with the custom mutator. C/C++: ```c -void afl_custom_init(unsigned int seed); +void afl_custom_init(void *afl, unsigned int seed); size_t afl_custom_fuzz(uint8_t** buf, size_t buf_size, uint8_t* add_buf, size_t add_buf_size, size_t max_size); size_t afl_custom_write_to_testcase(uint8_t* buf, size_t buf_size, uint8_t** out_buf); @@ -39,6 +39,7 @@ uint8_t afl_custom_havoc_mutation_probability(void); uint8_t afl_custom_queue_get(const uint8_t* filename); void afl_custom_queue_new_entry(const uint8_t* filename_new_queue, const uint8_t* filename_orig_queue); +void afl_custom_deinit(void *data); ``` Python: diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 3e708db8..04b72c77 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -15,6 +15,7 @@ #include #define DATA_SIZE (100) +#define INITIAL_BUF_SIZE (16384) static const char *commands[] = { @@ -28,6 +29,8 @@ typedef struct my_mutator { afl_t *afl; // any additional data here! + size_t pre_save_size; + u8 * pre_save_buf; } my_mutator_t; @@ -56,6 +59,16 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { data->afl = afl; + data->pre_save_buf = malloc(INITIAL_BUF_SIZE); + if (!data->pre_save_buf) { + + free(data); + return NULL; + + } + + data->pre_save_size = INITIAL_BUF_SIZE; + return data; } @@ -125,12 +138,23 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t *out_buf, size_t out_buf_size) { - // In case we need more than out_buf_size, we return that amount and get - // called again. - if (out_buf_size < 32000) return 32000; + if (data->pre_save_size < buf_size + 5) { + + data->pre_save_buf = realloc(data->pre_save_buf, buf_size + 5); + if (!data->pre_save_buf) { + + perror("custom mutator realloc"); + free(data); + return -1; + + } + + data->pre_save_size = buf_size + 5; + + } - memcpy(out_buf, buf, buf_size); - out_buf_size = buf_size; + memcpy(out_buf + 5, buf, buf_size); + out_buf_size = buf_size + 5; out_buf[0] = 'A'; out_buf[1] = 'F'; out_buf[2] = 'L'; @@ -322,6 +346,7 @@ void afl_custom_queue_new_entry(my_mutator_t * data, */ void afl_custom_deinit(my_mutator_t *data) { + free(data->pre_save_buf); free(data); } diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 8bf66403..530a4b6a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -30,9 +30,6 @@ #define AFL_MAIN #define MESSAGES_TO_STDOUT -/* We preallocate a buffer of this size for afl_custom_pre_save */ -#define PRE_SAVE_BUF_INIT_SIZE (16384) - #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif @@ -296,8 +293,8 @@ typedef struct py_mutator { void * afl_state; void * py_data; - PyObject *scratch_buf; - size_t scratch_size; + u8 * pre_save_buf; + size_t pre_save_size; } py_mutator_t; @@ -641,13 +638,13 @@ struct custom_mutator { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case - * @param[out] out_buf Pointer to the buffer of storing the test case after - * processing. External library should allocate memory for out_buf. AFL++ - * will release the memory after saving the test case. - * @return Size of the output buffer after processing + * @param[out] out_buf Pointer to the buffer storing the test case after + * processing. External library should allocate memory for out_buf. + * It can chose to alter buf in-place, if the space is large enough. + * @return Size of the output buffer. */ size_t (*afl_custom_pre_save)(void *data, u8 *buf, size_t buf_size, - u8 *out_buf, size_t out_buf_size); + u8 **out_buf); /** * This method is called at the start of each trimming operation and receives @@ -783,7 +780,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); -size_t pre_save_py(void *, u8 *, size_t, u8 *, size_t); +size_t pre_save_py(void *, u8 *, size_t, u8 **); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); void trim_py(void *, u8 **, size_t *); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index fac97f8e..9d8610c0 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -135,18 +135,9 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_pre_save", optional */ afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); - if (!afl->mutator->afl_custom_pre_save) { - + if (!afl->mutator->afl_custom_pre_save) WARNF("Symbol 'afl_custom_pre_save' not found."); - } else { - - /* if we have a pre_save hook, prealloc some memory. */ - afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); - afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; - - } - u8 notrim = 0; /* "afl_custom_init_trim", optional */ afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index b053e8d5..6fbdb678 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -307,14 +307,8 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { is quite different from the custom mutator. */ afl->mutator->afl_custom_fuzz = fuzz_py; - if (py_functions[PY_FUNC_PRE_SAVE]) { - + if (py_functions[PY_FUNC_PRE_SAVE]) afl->mutator->afl_custom_pre_save = pre_save_py; - /* if we have a pre_save hook, prealloc some memory. */ - afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); - afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; - - } if (py_functions[PY_FUNC_INIT_TRIM]) afl->mutator->afl_custom_init_trim = init_trim_py; @@ -344,39 +338,18 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } -size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, - size_t out_buf_size) { - - size_t py_out_buf_size; - PyObject *py_args, *py_value; - - if (((py_mutator_t *)py_mutator)->scratch_buf) { - - /* We are being recalled from an earlier run - where we didn't have enough mem. */ - if (((py_mutator_t *)py_mutator)->scratch_size < out_buf_size) { - - FATAL("out_buf is still too small after resizing in custom mutator."); - - } - - py_value = ((py_mutator_t *)py_mutator)->scratch_buf; - py_out_buf_size = ((py_mutator_t *)py_mutator)->scratch_size; - ((py_mutator_t *)py_mutator)->scratch_buf = NULL; - py_out_buf_size = 0; +size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { - memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); - Py_DECREF(py_value); - return py_out_buf_size; - - } + size_t py_out_buf_size; + PyObject * py_args, *py_value; + py_mutator_t *py = (py_mutator_t *)py_mutator; py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); - FATAL("Failed to convert arguments"); + FATAL("Failed to convert arguments in custom pre_save"); } @@ -390,25 +363,26 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, if (py_value != NULL) { py_out_buf_size = PyByteArray_Size(py_value); - if (py_out_buf_size > out_buf_size) { + + if (py_out_buf_size > py->pre_save_size) { /* Not enough space! - We will get called again right after resizing the buf. - Keep the references to our data for now. */ - ((py_mutator_t *)py_mutator)->scratch_buf = py_value; - ((py_mutator_t *)py_mutator)->scratch_size = py_out_buf_size; - return py_out_buf_size; + Let's resize our buf */ + py->pre_save_buf = ck_realloc(py->pre_save_buf, py_out_buf_size); + py->pre_save_size = py_out_buf_size; } - memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); + memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); + + *out_buf = py->pre_save_buf; return py_out_buf_size; } else { PyErr_Print(); - FATAL("Call failed"); + FATAL("Python custom mutator: pre_save call failed."); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index a539b469..a43bfad2 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -214,47 +214,18 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { lseek(fd, 0, SEEK_SET); - if (afl->mutator && afl->mutator->afl_custom_pre_save) { + if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) { - if (unlikely(afl->mutator->pre_save_size < len)) { + u8 *new_buf = NULL; - afl->mutator->pre_save_buf = - ck_realloc(afl->mutator->pre_save_buf, len * sizeof(u8)); - afl->mutator->pre_save_size = len; + size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, + len, &new_buf); - } - - u8 buf_written = 0; - while (!buf_written) { - - buf_written = 1; - size_t new_size = afl->mutator->afl_custom_pre_save( - afl->mutator->data, mem, len, afl->mutator->pre_save_buf, - afl->mutator->pre_save_size); - - if (unlikely(new_size) == 0) { - - /* custom_pre_save wants us to use the old buf */ - ck_write(fd, mem, len, afl->fsrv.out_file); - - } else if (unlikely(new_size) > afl->mutator->pre_save_size) { - - /* The custom func needs more space. - Realloc and call again. */ - afl->mutator->pre_save_buf = - ck_realloc(afl->mutator->pre_save_buf, new_size * sizeof(u8)); - afl->mutator->pre_save_size = new_size; - buf_written = 0; - continue; - - } else { - - /* everything as planned. use the new data. */ - ck_write(fd, afl->mutator->pre_save_buf, new_size, afl->fsrv.out_file); + if (unlikely(new_size <= 0 || !new_buf)) + FATAL("Custom_pre_save failed (ret: %ld)", new_size); - } - - } + /* everything as planned. use the new data. */ + ck_write(fd, new_buf, new_size, afl->fsrv.out_file); } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 53c162a2..5536c201 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -361,9 +361,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -445,9 +445,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -476,9 +476,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -552,7 +552,7 @@ void show_stats(afl_state_t *afl) { /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); -- cgit 1.4.1 From 71f8cc9dd2b38405755c2727997730d525b73b7e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Mar 2020 21:59:08 +0100 Subject: almost --- include/afl-fuzz.h | 21 ++++++++++ include/alloc-inl.h | 40 +++++++++++++++++++ src/afl-fuzz-globals.c | 2 + src/afl-fuzz-one.c | 103 +++++++++++++++++++++---------------------------- 4 files changed, 106 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 530a4b6a..2154d860 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -583,6 +583,27 @@ typedef struct afl_state { u8 clean_trace_custom[MAP_SIZE]; u8 first_trace[MAP_SIZE]; +/*needed for afl_fuzz_one */ +// TODO: see which we can reuse + u8 *out_buf; + size_t out_size; + + u8 *out_scratch_buf; + size_t out_scratch_size; + + u8 *eff_buf; + size_t eff_size; + + u8 *in_buf; + size_t in_size; + + u8 *in_scratch_buf; + size_t in_scratch_size; + + u8 *ex_buf; + size_t ex_size; + + } afl_state_t; /* A global pointer to all instances is needed (for now) for signals to arrive diff --git a/include/alloc-inl.h b/include/alloc-inl.h index c8783d96..75b038c1 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -35,6 +35,9 @@ #include "types.h" #include "debug.h" +/* Initial size used for ck_maybe_grow */ +#define INITIAL_GROWTH_SIZE (64) + // Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators #ifndef _WANT_ORIGINAL_AFL_ALLOC @@ -764,5 +767,42 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, #endif /* _WANT_ORIGINAL_AFL_ALLOC */ +/* This function makes sure *size is > size_needed after call. + It will realloc *buf otherwise. + *size will grow exponentially as per: + https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ + Will FATAL if size_needed is <1 or *size is negative. + @return For convenience, this function returns *buf. + */ +static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) { + + /* Oops. found a bug? */ + if (unlikely(size_needed < 1)) FATAL("cannot grow to non-positive size"); + + /* No need to realloc */ + if (likely(*size >= size_needed)) return *buf; + if (unlikely(*size < 0)) FATAL("Negative size detected!"); + /* No inital size was set */ + if (*size == 0) *size = INITIAL_GROWTH_SIZE; + while (*size < size_needed) { + *size *= 2; + } + *buf = ck_realloc(*buf, *size); + return *buf; + +} + +/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ +static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, size_t *size2) { + void *scratch_buf = *buf1; + size_t scratch_size = *size1; + *buf1 = *buf2; + *size1 = *size2; + *buf2 = scratch_buf; + *size2 = scratch_size; +} + +#undef INITIAL_GROWTH_SIZE + #endif /* ! _HAVE_ALLOC_INL_H */ diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c index 88633a1b..6de33596 100644 --- a/src/afl-fuzz-globals.c +++ b/src/afl-fuzz-globals.c @@ -79,6 +79,8 @@ list_t afl_states = {.element_prealloc_count = 0}; void afl_state_init(afl_state_t *afl) { + /* thanks to this memset, growing vars like out_buf + and out_size are NULL/0 by default. */ memset(afl, 0, sizeof(afl_state_t)); afl->w_init = 0.9; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 7cc5e0d9..6c1d69ad 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -347,6 +347,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 @@ -427,7 +430,7 @@ u8 fuzz_one_original(afl_state_t *afl) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_alloc_nozero(len); + out_buf = ck_maybe_grow((void **)&afl->out_buf, &afl->out_size, len); afl->subseq_tmouts = 0; @@ -719,7 +722,7 @@ u8 fuzz_one_original(afl_state_t *afl) { /* Initialize effector map for the next step (see comments below). Always flag first and last byte as doing something. */ - eff_map = ck_alloc(EFF_ALEN(len)); + eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len)); eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { @@ -1443,7 +1446,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_alloc(len + MAX_DICT_FILE); + ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); for (i = 0; i <= len; ++i) { @@ -1466,7 +1469,6 @@ skip_interest: if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { - ck_free(ex_tmp); goto abandon_entry; } @@ -1480,8 +1482,6 @@ skip_interest: } - ck_free(ex_tmp); - new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; @@ -1607,14 +1607,16 @@ custom_mutator_stage: /* Read the additional testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname); - new_buf = ck_alloc_nozero(target->len); + + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); ck_read(fd, new_buf, target->len, target->fname); close(fd); + // TODO: clean up this mess. size_t mutated_size = afl->mutator->afl_custom_fuzz( afl->mutator->data, &out_buf, len, new_buf, target->len, max_seed_size); - ck_free(new_buf); + if (mutated_size > len) afl->out_size = mutated_size; if (mutated_size > 0) { @@ -1642,7 +1644,7 @@ custom_mutator_stage: } - if (mutated_size < len) out_buf = ck_realloc(out_buf, len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); memcpy(out_buf, in_buf, len); } @@ -1955,7 +1957,7 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - new_buf = ck_alloc_nozero(temp_len + clone_len); + new_buf = ck_maybe_grow((void **)&afl->out_scratch_buf, &afl->out_scratch_size, temp_len + clone_len); /* Head */ @@ -1975,7 +1977,8 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - ck_free(out_buf); + + swap_bufs((void **)&afl->out_buf, &afl->out_size, (void **)&afl->out_scratch_buf, &afl->out_scratch_size); out_buf = new_buf; temp_len += clone_len; @@ -2069,7 +2072,7 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_alloc_nozero(temp_len + extra_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2085,7 +2088,7 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_alloc_nozero(temp_len + extra_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2099,7 +2102,7 @@ havoc_stage: memcpy(new_buf + insert_at + extra_len, out_buf + insert_at, temp_len - insert_at); - ck_free(out_buf); + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); out_buf = new_buf; temp_len += extra_len; @@ -2116,7 +2119,7 @@ havoc_stage: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - if (temp_len < len) out_buf = ck_realloc(out_buf, len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); temp_len = len; memcpy(out_buf, in_buf, len); @@ -2178,7 +2181,6 @@ retry_splicing: if (in_buf != orig_in) { - ck_free(in_buf); in_buf = orig_in; len = afl->queue_cur->len; @@ -2222,7 +2224,7 @@ retry_splicing: if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname); - new_buf = ck_alloc_nozero(target->len); + new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); ck_read(fd, new_buf, target->len, target->fname); @@ -2236,7 +2238,6 @@ retry_splicing: if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - ck_free(new_buf); goto retry_splicing; } @@ -2249,10 +2250,10 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); + swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); in_buf = new_buf; - ck_free(out_buf); - out_buf = ck_alloc_nozero(len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); memcpy(out_buf, in_buf, len); goto custom_mutator_stage; @@ -2280,12 +2281,14 @@ radamsa_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - /* Read the additional testcase into a new buffer. */ - u8 *save_buf = ck_alloc_nozero(len); + /* Read the additional testcase. + We'll reuse in_scratch, as it is free at this point. + */ + u8 *save_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), len); memcpy(save_buf, out_buf, len); u32 max_len = len + choose_block_len(afl, HAVOC_BLK_XL); - u8 *new_buf = ck_alloc_nozero(max_len); + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), max_len); u8 *tmp_buf; for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { @@ -2307,17 +2310,12 @@ radamsa_stage: if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { - ck_free(save_buf); - ck_free(new_buf); goto abandon_entry; } } - ck_free(save_buf); - ck_free(new_buf); - new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_finds[STAGE_RADAMSA] += new_hit_cnt - orig_hit_cnt; @@ -2347,10 +2345,6 @@ abandon_entry: munmap(orig_in, afl->queue_cur->len); - if (in_buf != orig_in) ck_free(in_buf); - ck_free(out_buf); - ck_free(eff_map); - return ret_val; #undef FLIP_BIT @@ -2449,7 +2443,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_alloc_nozero(len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); afl->subseq_tmouts = 0; @@ -2728,7 +2722,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { /* Initialize effector map for the next step (see comments below). Always flag first and last byte as doing something. */ - eff_map = ck_alloc(EFF_ALEN(len)); + eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len)); eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { @@ -3452,7 +3446,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_alloc(len + MAX_DICT_FILE); + ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); for (i = 0; i <= len; ++i) { @@ -3475,7 +3469,6 @@ skip_interest: if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { - ck_free(ex_tmp); goto abandon_entry; } @@ -3489,8 +3482,6 @@ skip_interest: } /* for i = 0; i <= len */ - ck_free(ex_tmp); - new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; @@ -3894,7 +3885,7 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); - new_buf = ck_alloc_nozero(temp_len + clone_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); /* Head */ @@ -3915,7 +3906,7 @@ pacemaker_fuzzing: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - ck_free(out_buf); + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); out_buf = new_buf; temp_len += clone_len; MOpt_globals.cycles_v2[STAGE_Clone75] += 1; @@ -3968,7 +3959,7 @@ pacemaker_fuzzing: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - if (temp_len < len) out_buf = ck_realloc(out_buf, len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); temp_len = len; memcpy(out_buf, in_buf, len); @@ -4046,7 +4037,6 @@ pacemaker_fuzzing: if (in_buf != orig_in) { - ck_free(in_buf); in_buf = orig_in; len = afl->queue_cur->len; @@ -4091,7 +4081,7 @@ pacemaker_fuzzing: if (fd < 0) PFATAL("Unable to open '%s'", target->fname); - new_buf = ck_alloc_nozero(target->len); + new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); ck_read(fd, new_buf, target->len, target->fname); @@ -4105,7 +4095,6 @@ pacemaker_fuzzing: if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - ck_free(new_buf); goto retry_splicing_puppet; } @@ -4118,9 +4107,9 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); + swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); in_buf = new_buf; - ck_free(out_buf); - out_buf = ck_alloc_nozero(len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); memcpy(out_buf, in_buf, len); goto havoc_stage_puppet; @@ -4155,10 +4144,6 @@ pacemaker_fuzzing: munmap(orig_in, afl->queue_cur->len); - if (in_buf != orig_in) ck_free(in_buf); - ck_free(out_buf); - ck_free(eff_map); - if (afl->key_puppet == 1) { if (unlikely( @@ -4380,18 +4365,13 @@ u8 fuzz_one(afl_state_t *afl) { int key_val_lv = 0; #ifdef _AFL_DOCUMENT_MUTATIONS - if (afl->do_document == 0) { - - char *fn = alloc_printf("%s/mutations", afl->out_dir); - if (fn) { - - afl->do_document = mkdir(fn, 0700); // if it exists we do not care - afl->do_document = 1; - ck_free(fn); - } else + u8 path_buf[PATH_MAX]; + if (afl->do_document == 0) { - PFATAL("malloc()"); + snprintf(path_buf, PATH_MAX, "%s/mutations", afl->out_dir); + afl->do_document = mkdir(path_buf, 0700); // if it exists we do not care + afl->do_document = 1; } else { @@ -4419,5 +4399,8 @@ u8 fuzz_one(afl_state_t *afl) { return key_val_lv; + +#undef BUF_PARAMS + } -- cgit 1.4.1 From b7f3d180aab790a1d0d677abe21b29a3de4485d6 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Mar 2020 23:06:57 +0100 Subject: not allocating paths anymore --- src/afl-fuzz-bitmap.c | 39 ++++++++++++++++++--------------------- src/afl-fuzz-globals.c | 7 +++++++ src/afl-fuzz-init.c | 13 ++++--------- src/afl-fuzz-queue.c | 27 +++++++++++---------------- 4 files changed, 40 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 0d5b542d..bb01ad21 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -31,13 +31,13 @@ void write_bitmap(afl_state_t *afl) { - u8 *fname; + u8 fname[PATH_MAX]; s32 fd; if (!afl->bitmap_changed) return; afl->bitmap_changed = 0; - fname = alloc_printf("%s/fuzz_bitmap", afl->out_dir); + snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir); fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) PFATAL("Unable to open '%s'", fname); @@ -45,7 +45,6 @@ void write_bitmap(afl_state_t *afl) { ck_write(fd, afl->virgin_bits, MAP_SIZE, fname); close(fd); - ck_free(fname); } @@ -462,14 +461,15 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) { static void write_crash_readme(afl_state_t *afl) { - u8 * fn = alloc_printf("%s/crashes/README.txt", afl->out_dir); + u8 fn[PATH_MAX]; s32 fd; FILE *f; u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + sprintf(fn, "%s/crashes/README.txt", afl->out_dir); + fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); - ck_free(fn); /* Do not die on errors here - that would be impolite. */ @@ -520,11 +520,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) return 0; - u8 *fn = ""; + u8 *queue_fn = ""; u8 hnb; s32 fd; u8 keeping = 0, res; + u8 fn[PATH_MAX]; + /* Update path frequency. */ u32 cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); @@ -556,16 +558,16 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths, + queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths, describe_op(afl, hnb)); #else - fn = alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); + queue_fn = alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); #endif /* ^!SIMPLE_FILES */ - add_to_queue(afl, fn, len, 0); + add_to_queue(afl, queue_fn, len, 0); if (hnb == 2) { @@ -584,9 +586,9 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(res == FAULT_ERROR)) FATAL("Unable to execute target application"); - fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", fn); - ck_write(fd, mem, len, fn); + fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", queue_fn); + ck_write(fd, mem, len, queue_fn); close(fd); keeping = 1; @@ -642,12 +644,12 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir, + snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir, afl->unique_hangs, describe_op(afl, 0)); #else - fn = alloc_printf("%s/hangs/id_%06llu", afl->out_dir, afl->unique_hangs); + snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, afl->unique_hangs); #endif /* ^!SIMPLE_FILES */ @@ -685,14 +687,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, - afl->unique_crashes, afl->kill_signal, - describe_op(afl, 0)); + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); #else - fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir, - afl->unique_crashes, afl->kill_signal); + snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, afl->unique_crashes, afl->kill_signal); #endif /* ^!SIMPLE_FILES */ @@ -729,8 +728,6 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ck_write(fd, mem, len, fn); close(fd); - ck_free(fn); - return keeping; } diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c index 6de33596..3e573dd2 100644 --- a/src/afl-fuzz-globals.c +++ b/src/afl-fuzz-globals.c @@ -349,6 +349,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { void afl_state_deinit(afl_state_t *afl) { + free(afl->out_buf); + free(afl->out_scratch_buf); + free(afl->eff_buf); + free(afl->in_buf); + free(afl->in_scratch_buf); + free(afl->ex_buf); + list_remove(&afl_states, afl); } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 038c4393..1033c587 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -76,18 +76,17 @@ void bind_to_free_cpu(afl_state_t *afl) { while ((de = readdir(d))) { - u8 * fn; + u8 fn[PATH_MAX]; FILE *f; u8 tmp[MAX_LINE]; u8 has_vmsize = 0; if (!isdigit(de->d_name[0])) continue; - fn = alloc_printf("/proc/%s/status", de->d_name); + snprintf(fn, PATH_MAX, "/proc/%s/status", de->d_name); if (!(f = fopen(fn, "r"))) { - ck_free(fn); continue; } @@ -111,7 +110,6 @@ void bind_to_free_cpu(afl_state_t *afl) { } - ck_free(fn); fclose(f); } @@ -369,9 +367,9 @@ void read_testcases(afl_state_t *afl) { struct stat st; + u8 dfn[PATH_MAX]; + snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); - u8 *dfn = alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir, - nl[i]->d_name); u8 passed_det = 0; @@ -384,8 +382,6 @@ void read_testcases(afl_state_t *afl) { if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { - ck_free(fn2); - ck_free(dfn); continue; } @@ -401,7 +397,6 @@ void read_testcases(afl_state_t *afl) { and probably very time-consuming. */ if (!access(dfn, F_OK)) passed_det = 1; - ck_free(dfn); add_to_queue(afl, fn2, st.st_size, passed_det); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 73da449a..b5ae1255 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -30,18 +30,15 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { - u8 *fn = strrchr(q->fname, '/'); + u8 fn[PATH_MAX]; s32 fd; - fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir, - fn + 1); + snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, strrchr(q->fname, '/') + 1); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) PFATAL("Unable to create '%s'", fn); close(fd); - ck_free(fn); - q->passed_det = 1; } @@ -51,10 +48,13 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { - u8 *fn = strrchr(q->fname, '/') + 1, *ldest; + u8 fn[PATH_MAX]; + u8 ldest[PATH_MAX]; + + u8 *fn_name = strrchr(q->fname, '/') + 1; - ldest = alloc_printf("../../%s", fn); - fn = alloc_printf("%s/queue/.state/variable_behavior/%s", afl->out_dir, fn); + sprintf(ldest, "../../%s", fn_name); + sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name); if (symlink(ldest, fn)) { @@ -64,9 +64,6 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { } - ck_free(ldest); - ck_free(fn); - q->var_behavior = 1; } @@ -76,14 +73,13 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { - u8 *fn; + u8 fn[PATH_MAX]; if (state == q->fs_redundant) return; q->fs_redundant = state; - fn = strrchr(q->fname, '/'); - fn = alloc_printf("%s/queue/.state/redundant_edges/%s", afl->out_dir, fn + 1); + sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, strrchr(q->fname, '/') + 1); if (state) { @@ -99,8 +95,6 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } - ck_free(fn); - } /* Append new test case to the queue. */ @@ -114,6 +108,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->n_fuzz = 1; + q->trace_mini = NULL; if (q->depth > afl->max_depth) afl->max_depth = q->depth; -- cgit 1.4.1 From 762421b355877c7bbe65f50a9cc659bbf178ab4a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Mar 2020 23:23:11 +0100 Subject: less allocs --- src/afl-fuzz-stats.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 5536c201..d6403830 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -33,16 +33,16 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, struct rusage rus; unsigned long long int cur_time = get_cur_time(); - u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); + u8 fn[PATH_MAX]; s32 fd; FILE * f; + snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); + fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) PFATAL("Unable to create '%s'", fn); - ck_free(fn); - f = fdopen(fd, "w"); if (!f) PFATAL("fdopen() failed"); -- cgit 1.4.1 From 34c090a31db7939558bf0047f0f1693bbde76c1f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 27 Mar 2020 12:09:06 +0100 Subject: add CFI sanitizer --- README.md | 2 +- docs/Changelog.md | 1 + docs/env_variables.md | 4 +++- docs/notes_for_asan.md | 2 +- llvm_mode/LLVMInsTrim.so.cc | 1 + llvm_mode/afl-clang-fast.c | 21 +++++++++++++++++++-- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 1 + llvm_mode/afl-llvm-pass.so.cc | 1 + src/afl-common.c | 2 +- 9 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 781c8b49..827a7aec 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,7 @@ superior to blind fuzzing or coverage-only tools. ## Instrumenting programs for use with AFL PLEASE NOTE: llvm_mode compilation with afl-clang-fast/afl-clang-fast++ -instead of afl-gcc/afl-g++ is much faster and has a few cool features. +instead of afl-gcc/afl-g++ is much faster and has many cool features. See llvm_mode/ - however few code does not compile with llvm. We support llvm versions 3.8.0 to 11. diff --git a/docs/Changelog.md b/docs/Changelog.md index 6af269ce..198909d1 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -31,6 +31,7 @@ sending a mail to . the last 5 queue entries - rare: puts focus on queue entries that hits rare branches, also ignores runtime + - llvm_mode: added Control Flow Integrity sanatizer (AFL_USE_CFISAN) - LTO collision free instrumented added in llvm_mode with afl-clang-lto - note that this mode is amazing, but quite some targets won't compile - Added llvm_mode NGRAM prev_loc coverage by Adrean Herrera diff --git a/docs/env_variables.md b/docs/env_variables.md index 98f27bdf..ae283b1c 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -31,7 +31,9 @@ tools make fairly broad use of environmental variables: (You can also enable MSAN via AFL_USE_MSAN; ASAN and MSAN come with the same gotchas; the modes are mutually exclusive. UBSAN can be enabled - similarly by setting the environment variable AFL_USE_UBSAN=1) + similarly by setting the environment variable AFL_USE_UBSAN=1. Finally + there is the Control Flow Integrity sanitizer that can be activated by + AFL_USE_CFISAN=1) - Setting AFL_CC, AFL_CXX, and AFL_AS lets you use alternate downstream compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries diff --git a/docs/notes_for_asan.md b/docs/notes_for_asan.md index b65873be..6a4806c0 100644 --- a/docs/notes_for_asan.md +++ b/docs/notes_for_asan.md @@ -29,7 +29,7 @@ Note that ASAN is incompatible with -static, so be mindful of that. (You can also use AFL_USE_MSAN=1 to enable MSAN instead.) NOTE: if you run several slaves only one should run the target compiled with -ASAN (and UBSAN), the others should run the target with no sanitizers +ASAN (and UBSAN, CFISAN), the others should run the target with no sanitizers compiled in. There is also the option of generating a corpus using a non-ASAN binary, and diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index a94eb907..c4033523 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -513,6 +513,7 @@ struct InsTrim : public ModulePass { getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", + getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); OKF("Instrumented %u locations (%llu, %llu) (%s mode)\n", total_instr, diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 7050e22d..c45c8799 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -135,7 +135,7 @@ static void find_obj(u8 *argv0) { /* Copy argv to cc_params, making the necessary edits. */ -static void edit_params(u32 argc, char **argv) { +static void edit_params(u32 argc, char **argv, char **envp) { u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0; u8 has_llvm_config = 0; @@ -395,6 +395,22 @@ static void edit_params(u32 argc, char **argv) { } + if (getenv("AFL_USE_CFISAN")) { + + if (!lto_mode) { + + uint32_t i = 0, found = 0; + while (envp[i] != NULL && !found) + if (strncmp("-flto", envp[i++], 5) == 0) + found = 1; + if (!found) cc_params[cc_par_cnt++] = "-flto"; + + } + cc_params[cc_par_cnt++] = "-fsanitize=cfi"; + cc_params[cc_par_cnt++] = "-fvisibility=hidden"; + + } + #ifdef USE_TRACE_PC if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || @@ -596,6 +612,7 @@ int main(int argc, char **argv, char **envp) { "AFL_USE_ASAN: activate address sanitizer\n" "AFL_USE_MSAN: activate memory sanitizer\n" "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + "AFL_USE_CFISAN: activate control flow sanitizer\n" "AFL_LLVM_WHITELIST: enable whitelisting (selective " "instrumentation)\n" "AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" @@ -685,7 +702,7 @@ int main(int argc, char **argv, char **envp) { find_obj(argv[0]); #endif - edit_params(argc, argv); + edit_params(argc, argv, envp); if (debug) { diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index febb8950..8bf485af 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -396,6 +396,7 @@ bool AFLLTOPass::runOnModule(Module &M) { getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", + getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); OKF("Instrumented %u locations with no collisions (on average %llu " "collisions would be in afl-gcc/afl-clang-fast) (%s mode).", diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index fefd9edd..e8f449b1 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -572,6 +572,7 @@ bool AFLCoverage::runOnModule(Module &M) { getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", + getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); OKF("Instrumented %u locations (%s mode, ratio %u%%).", inst_blocks, modeline, inst_ratio); diff --git a/src/afl-common.c b/src/afl-common.c index 8c4d53e8..e10de6b3 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -73,7 +73,7 @@ char * afl_environment_variables[] = { "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_WINE_PATH", NULL}; + "AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", NULL}; void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { -- cgit 1.4.1 From e71c2937de8a19cf9b3627b86894cafabcd45513 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Mar 2020 23:30:15 +0100 Subject: code format --- examples/custom_mutators/example.c | 1 + include/afl-fuzz.h | 17 ++++++++--------- include/alloc-inl.h | 13 ++++++++++--- llvm_mode/afl-clang-fast.c | 10 +++++----- llvm_mode/afl-llvm-pass.so.cc | 7 ++++++- src/afl-fuzz-bitmap.c | 22 +++++++++++++--------- src/afl-fuzz-init.c | 11 ++++------- src/afl-fuzz-one.c | 30 +++++++++++++----------------- src/afl-fuzz-queue.c | 8 +++++--- src/afl-fuzz-stats.c | 2 +- 10 files changed, 66 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 8a45d87f..4b0a461b 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -149,6 +149,7 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, data->pre_save_size = buf_size + 5; } + *out_buf = data->pre_save_buf; memcpy(*out_buf + 5, buf, buf_size); diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 2154d860..32eaf4af 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -583,27 +583,26 @@ typedef struct afl_state { u8 clean_trace_custom[MAP_SIZE]; u8 first_trace[MAP_SIZE]; -/*needed for afl_fuzz_one */ -// TODO: see which we can reuse - u8 *out_buf; + /*needed for afl_fuzz_one */ + // TODO: see which we can reuse + u8 * out_buf; size_t out_size; - u8 *out_scratch_buf; + u8 * out_scratch_buf; size_t out_scratch_size; - u8 *eff_buf; + u8 * eff_buf; size_t eff_size; - u8 *in_buf; + u8 * in_buf; size_t in_size; - u8 *in_scratch_buf; + u8 * in_scratch_buf; size_t in_scratch_size; - u8 *ex_buf; + u8 * ex_buf; size_t ex_size; - } afl_state_t; /* A global pointer to all instances is needed (for now) for signals to arrive diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 75b038c1..92d29c1e 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -774,7 +774,8 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, Will FATAL if size_needed is <1 or *size is negative. @return For convenience, this function returns *buf. */ -static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) { +static inline void *ck_maybe_grow(void **buf, size_t *size, + size_t size_needed) { /* Oops. found a bug? */ if (unlikely(size_needed < 1)) FATAL("cannot grow to non-positive size"); @@ -785,21 +786,27 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) /* No inital size was set */ if (*size == 0) *size = INITIAL_GROWTH_SIZE; while (*size < size_needed) { + *size *= 2; + } + *buf = ck_realloc(*buf, *size); return *buf; } /* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ -static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, size_t *size2) { - void *scratch_buf = *buf1; +static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, + size_t *size2) { + + void * scratch_buf = *buf1; size_t scratch_size = *size1; *buf1 = *buf2; *size1 = *size2; *buf2 = scratch_buf; *size2 = scratch_size; + } #undef INITIAL_GROWTH_SIZE diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index c45c8799..99bc8d03 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -397,15 +397,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("AFL_USE_CFISAN")) { - if (!lto_mode) { - + if (!lto_mode) { + uint32_t i = 0, found = 0; while (envp[i] != NULL && !found) - if (strncmp("-flto", envp[i++], 5) == 0) - found = 1; + if (strncmp("-flto", envp[i++], 5) == 0) found = 1; if (!found) cc_params[cc_par_cnt++] = "-flto"; - + } + cc_params[cc_par_cnt++] = "-fsanitize=cfi"; cc_params[cc_par_cnt++] = "-fvisibility=hidden"; diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 1c0a3c93..f6ead9ec 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -132,8 +132,11 @@ class AFLCoverage : public ModulePass { char AFLCoverage::ID = 0; /* needed up to 3.9.0 */ -#if LLVM_VERSION_MAJOR == 3 && (LLVM_VERSION_MINOR < 9 || (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1)) +#if LLVM_VERSION_MAJOR == 3 && \ + (LLVM_VERSION_MINOR < 9 || \ + (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1)) uint64_t PowerOf2Ceil(unsigned in) { + uint64_t in64 = in - 1; in64 |= (in64 >> 1); in64 |= (in64 >> 2); @@ -142,7 +145,9 @@ uint64_t PowerOf2Ceil(unsigned in) { in64 |= (in64 >> 16); in64 |= (in64 >> 32); return in64 + 1; + } + #endif bool AFLCoverage::runOnModule(Module &M) { diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index bb01ad21..8ca286b2 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -31,7 +31,7 @@ void write_bitmap(afl_state_t *afl) { - u8 fname[PATH_MAX]; + u8 fname[PATH_MAX]; s32 fd; if (!afl->bitmap_changed) return; @@ -461,7 +461,7 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) { static void write_crash_readme(afl_state_t *afl) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; FILE *f; @@ -558,12 +558,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths, - describe_op(afl, hnb)); + queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, + afl->queued_paths, describe_op(afl, hnb)); #else - queue_fn = alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); + queue_fn = + alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); #endif /* ^!SIMPLE_FILES */ @@ -645,11 +646,12 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir, - afl->unique_hangs, describe_op(afl, 0)); + afl->unique_hangs, describe_op(afl, 0)); #else - snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, afl->unique_hangs); + snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, + afl->unique_hangs); #endif /* ^!SIMPLE_FILES */ @@ -687,11 +689,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, + afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); #else - snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, afl->unique_crashes, afl->kill_signal); + snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, + afl->unique_crashes, afl->kill_signal); #endif /* ^!SIMPLE_FILES */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1033c587..19092204 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -76,7 +76,7 @@ void bind_to_free_cpu(afl_state_t *afl) { while ((de = readdir(d))) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; FILE *f; u8 tmp[MAX_LINE]; u8 has_vmsize = 0; @@ -85,11 +85,7 @@ void bind_to_free_cpu(afl_state_t *afl) { snprintf(fn, PATH_MAX, "/proc/%s/status", de->d_name); - if (!(f = fopen(fn, "r"))) { - - continue; - - } + if (!(f = fopen(fn, "r"))) { continue; } while (fgets(tmp, MAX_LINE, f)) { @@ -368,7 +364,8 @@ void read_testcases(afl_state_t *afl) { struct stat st; u8 dfn[PATH_MAX]; - snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); + snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, + nl[i]->d_name); u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); u8 passed_det = 0; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 6c1d69ad..c731ebc6 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1957,7 +1957,9 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow((void **)&afl->out_scratch_buf, &afl->out_scratch_size, temp_len + clone_len); + new_buf = + ck_maybe_grow((void **)&afl->out_scratch_buf, + &afl->out_scratch_size, temp_len + clone_len); /* Head */ @@ -1977,8 +1979,8 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - - swap_bufs((void **)&afl->out_buf, &afl->out_size, (void **)&afl->out_scratch_buf, &afl->out_scratch_size); + swap_bufs((void **)&afl->out_buf, &afl->out_size, + (void **)&afl->out_scratch_buf, &afl->out_scratch_size); out_buf = new_buf; temp_len += clone_len; @@ -2072,7 +2074,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2088,7 +2091,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2236,11 +2240,7 @@ retry_splicing: locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff); - if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - - goto retry_splicing; - - } + if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } /* Split somewhere between the first and last differing byte. */ @@ -2308,11 +2308,7 @@ radamsa_stage: } - if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { - - goto abandon_entry; - - } + if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; } } @@ -3885,7 +3881,8 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + temp_len + clone_len); /* Head */ @@ -4399,7 +4396,6 @@ u8 fuzz_one(afl_state_t *afl) { return key_val_lv; - #undef BUF_PARAMS } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b5ae1255..4f1bd041 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -30,10 +30,11 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; - snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, strrchr(q->fname, '/') + 1); + snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, + strrchr(q->fname, '/') + 1); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) PFATAL("Unable to create '%s'", fn); @@ -79,7 +80,8 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { q->fs_redundant = state; - sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, strrchr(q->fname, '/') + 1); + sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, + strrchr(q->fname, '/') + 1); if (state) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d6403830..7fde2fdc 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -33,7 +33,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, struct rusage rus; unsigned long long int cur_time = get_cur_time(); - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; FILE * f; -- cgit 1.4.1 From 5bd8aa489b9d9db4bb330a7515666ad11eab24b4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 00:44:52 +0100 Subject: fixed leak --- include/alloc-inl.h | 2 ++ src/afl-fuzz-init.c | 1 + src/afl-fuzz-one.c | 10 +++++----- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 92d29c1e..ed1e0397 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -788,10 +788,12 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, while (*size < size_needed) { *size *= 2; + if ((*size) < 0) FATAL("size_t overflow"); } *buf = ck_realloc(*buf, *size); + return *buf; } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 19092204..a69c3b61 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -379,6 +379,7 @@ void read_testcases(afl_state_t *afl) { if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { + free(fn2); continue; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c731ebc6..024b4665 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -430,7 +430,7 @@ u8 fuzz_one_original(afl_state_t *afl) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_maybe_grow((void **)&afl->out_buf, &afl->out_size, len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); afl->subseq_tmouts = 0; @@ -1958,8 +1958,7 @@ havoc_stage: clone_to = rand_below(afl, temp_len); new_buf = - ck_maybe_grow((void **)&afl->out_scratch_buf, - &afl->out_scratch_size, temp_len + clone_len); + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); /* Head */ @@ -1979,9 +1978,9 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - swap_bufs((void **)&afl->out_buf, &afl->out_size, - (void **)&afl->out_scratch_buf, &afl->out_scratch_size); + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); out_buf = new_buf; + new_buf = NULL; temp_len += clone_len; } @@ -2108,6 +2107,7 @@ havoc_stage: swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); out_buf = new_buf; + new_buf = NULL; temp_len += extra_len; break; -- cgit 1.4.1 From 8c94a3d17714aed316619dea72b25251e2629ed7 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 01:14:24 +0100 Subject: added nullptr fix by h1994st --- src/afl-fuzz-mutators.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 9d8610c0..41bc69c8 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -192,7 +192,7 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (afl->mutator->afl_custom_init) - afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + afl->mutator->data = afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); } -- cgit 1.4.1 From 9785b15ed264951b006093f9ee4564820c153593 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 04:57:44 +0100 Subject: more custom mutator remodelling --- examples/custom_mutators/custom_mutator_helpers.h | 61 ++++++++++++ examples/custom_mutators/example.c | 113 ++++++++++++---------- examples/post_library/post_library.so.c | 84 +++++++++++----- examples/post_library/post_library_png.so.c | 71 +++++++++++--- include/afl-fuzz.h | 41 +++++--- src/afl-fuzz-cmplog.c | 9 +- src/afl-fuzz-globals.c | 2 + src/afl-fuzz-init.c | 14 ++- src/afl-fuzz-mutators.c | 24 ++--- src/afl-fuzz-one.c | 29 +++++- src/afl-fuzz-python.c | 64 +++++++----- src/afl-fuzz-run.c | 9 +- 12 files changed, 370 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index cd3a15f0..0dc00d96 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -5,8 +5,18 @@ #include "types.h" #include +#define INITIAL_GROWTH_SIZE (64) + #define RAND_BELOW(limit) (rand() % (limit)) +/* Use in a struct: creates a name_buf and a name_size variable. */ +#define BUF_VAR(type, name) \ + type * name##_buf; \ + size_t name##_size; +/* this filles in `&structptr->something_buf, &structptr->something_size`. */ +#define BUF_PARAMS(struct, name) \ + (void **)&struct->name##_buf, &struct->name##_size + typedef struct { } afl_t; @@ -267,5 +277,56 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } +/* This function makes sure *size is > size_needed after call. + It changes buf and size in-place, if needed. + It will realloc *buf otherwise. + *size will grow exponentially as per: + https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ + Will return NULL if size_needed is <1 or *size is negative or malloc Failed. + @return For convenience, this function returns *buf. NULL on error. + */ +static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { + + /* Oops. found a bug? */ + if (unlikely(size_needed < 1)) return NULL; + + /* No need to realloc */ + if (likely(*size >= size_needed)) return *buf; + if (unlikely(*size < 0)) return NULL; + /* No inital size was set */ + if (*size == 0) *size = INITIAL_GROWTH_SIZE; + while (*size < size_needed) { + + *size *= 2; + if ((*size) < 0) { + + /* An overflow occurred. Fall back to size_needed */ + *size = size_needed; + + } + + } + + *buf = realloc(*buf, *size); + + return *buf; + +} + +/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ +static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, + size_t *size2) { + + void * scratch_buf = *buf1; + size_t scratch_size = *size1; + *buf1 = *buf2; + *size1 = *size2; + *buf2 = scratch_buf; + *size2 = scratch_size; + +} + +#undef INITIAL_GROWTH_SIZE + #endif diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 4b0a461b..54fc9d47 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -15,7 +15,6 @@ #include #define DATA_SIZE (100) -#define INITIAL_BUF_SIZE (16384) static const char *commands[] = { @@ -28,9 +27,19 @@ static const char *commands[] = { typedef struct my_mutator { afl_t *afl; + // any additional data here! - size_t pre_save_size; - u8 * pre_save_buf; + uint8_t *trim_buf; + size_t trim_buf_size; + int trimmming_steps; + int cur_step; + + // Reused buffers: + BUF_VAR(u8, fuzz); + BUF_VAR(u8, data); + BUF_VAR(u8, havoc); + BUF_VAR(u8, trim_out); + BUF_VAR(u8, pre_save); } my_mutator_t; @@ -59,16 +68,6 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { data->afl = afl; - data->pre_save_buf = malloc(INITIAL_BUF_SIZE); - if (!data->pre_save_buf) { - - free(data); - return NULL; - - } - - data->pre_save_size = INITIAL_BUF_SIZE; - return data; } @@ -85,20 +84,25 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must not * produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output. Negative return will abort fuzzing. */ -size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, - uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { +size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, + u8 **out_buf, uint8_t *add_buf, + size_t add_buf_size, // add_buf can be NULL + size_t max_size) { // Make sure that the packet size does not exceed the maximum size expected by // the fuzzer size_t mutated_size = DATA_SIZE <= max_size ? DATA_SIZE : max_size; - if (mutated_size > buf_size) *buf = realloc(*buf, mutated_size); + // maybe_grow is optimized to be quick for reused buffers. + u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), mutated_size); + if (!mutated_out) { + + perror("custom mutator allocation (maybe_grow)"); + return -1; /* afl-fuzz will very likely error out after this. */ - uint8_t *mutated_out = *buf; + } // Randomly select a command string to add as a header to the packet memcpy(mutated_out, commands[rand() % 3], 3); @@ -112,6 +116,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, } + *out_buf = mutated_out; return mutated_size; } @@ -137,11 +142,10 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (data->pre_save_size < buf_size + 5) { - data->pre_save_buf = realloc(data->pre_save_buf, buf_size + 5); + data->pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); if (!data->pre_save_buf) { - perror("custom mutator realloc"); - free(data); + perror("custom mutator realloc failed."); return -1; } @@ -164,11 +168,6 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, } -static uint8_t *trim_buf; -static size_t trim_buf_size; -static int trimmming_steps; -static int cur_step; - /** * This method is called at the start of each trimming operation and receives * the initial buffer. It should return the amount of iteration steps possible @@ -193,20 +192,20 @@ static int cur_step; int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { // We simply trim once - trimmming_steps = 1; + data->trimmming_steps = 1; - cur_step = 0; - trim_buf = buf; - trim_buf_size = buf_size; + data->cur_step = 0; + data->trim_buf = buf; + data->trim_buf_size = buf_size; - return trimmming_steps; + return data->trimmming_steps; } /** * This method is called for each trimming operation. It doesn't have any * arguments because we already have the initial buffer from init_trim and we - * can memorize the current state in global variables. This can also save + * can memorize the current state in *data. This can also save * reparsing steps for each iteration. It should return the trimmed input * buffer, where the returned data must not exceed the initial input data in * length. Returning anything that is larger than the original data (passed @@ -216,19 +215,18 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[out] out_buf Pointer to the buffer containing the trimmed test case. - * External library should allocate memory for out_buf. AFL++ will release - * the memory after saving the test case. - * @param[out] out_buf_size Pointer to the size of the trimmed test case + * External library should allocate memory for out_buf. + * AFL++ will not release the memory after saving the test case. + * Keep a ref in *data. + * @return Pointer to the size of the trimmed test case */ -void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, - size_t *out_buf_size) { +size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { - *out_buf_size = trim_buf_size - 1; + size_t ret = data->trim_buf_size - 1; - // External mutator should allocate memory for `out_buf` - *out_buf = malloc(*out_buf_size); + *out_buf = maybe_grow(BUF_PARAMS(data, trim_out), ret); // Remove the last byte of the trimming input - memcpy(*out_buf, trim_buf, *out_buf_size); + memcpy(*out_buf, data->trim_buf, ret); } @@ -248,12 +246,12 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { if (success) { - ++cur_step; - return cur_step; + ++data->cur_step; + return data->cur_step; } - return trimmming_steps; + return data->trimmming_steps; } @@ -264,26 +262,33 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * (Optional) * * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of input data + * @param[out] out_buf The output buffer. buf can be reused, if the content + * fits. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. * @return Size of the mutated output. */ -size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, - size_t buf_size, size_t max_size) { +size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size) { if (buf_size == 0) { - *buf = realloc(*buf, 1); - **buf = rand() % 256; + *out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1); + **out_buf = rand() % 256; buf_size = 1; + } else { + + // We reuse buf here. It's legal and faster. + *out_buf = buf; + } size_t victim = rand() % buf_size; - (*buf)[victim] += rand() % 10; + (*out_buf)[victim] += rand() % 10; return buf_size; @@ -346,6 +351,10 @@ void afl_custom_queue_new_entry(my_mutator_t * data, void afl_custom_deinit(my_mutator_t *data) { free(data->pre_save_buf); + free(data->havoc_buf); + free(data->data_buf); + free(data->fuzz_buf); + free(data->trim_out_buf); free(data); } diff --git a/examples/post_library/post_library.so.c b/examples/post_library/post_library.so.c index 5d2685cd..735aae9b 100644 --- a/examples/post_library/post_library.so.c +++ b/examples/post_library/post_library.so.c @@ -3,6 +3,7 @@ -------------------------------------------------- Originally written by Michal Zalewski + Edited by Dominik Maier, 2020 Copyright 2015 Google Inc. All rights reserved. @@ -41,22 +42,23 @@ AFL will call the afl_postprocess() function for every mutated output buffer. From there, you have three choices: - 1) If you don't want to modify the test case, simply return the original - buffer pointer ('in_buf'). + 1) If you don't want to modify the test case, simply set `*out_buf = in_buf` + and return the original `len`. 2) If you want to skip this test case altogether and have AFL generate a - new one, return NULL. Use this sparingly - it's faster than running - the target program with patently useless inputs, but still wastes CPU - time. + new one, return 0 or set `*out_buf = NULL`. + Use this sparingly - it's faster than running the target program + with patently useless inputs, but still wastes CPU time. 3) If you want to modify the test case, allocate an appropriately-sized buffer, move the data into that buffer, make the necessary changes, and - then return the new pointer. You can update *len if necessary, too. + then return the new pointer as out_buf. Return an appropriate len + afterwards. Note that the buffer will *not* be freed for you. To avoid memory leaks, you need to free it or reuse it on subsequent calls (as shown below). - *** DO NOT MODIFY THE ORIGINAL 'in_buf' BUFFER. *** + *** Feel free to reuse the original 'in_buf' BUFFER and return it. *** Aight. The example below shows a simple postprocessor that tries to make sure that all input files start with "GIF89a". @@ -74,47 +76,83 @@ #define HEADER "GIF89a" -/* The actual postprocessor routine called by afl-fuzz: */ +typedef struct post_state { + + unsigned char *buf; + size_t size; + +} post_state_t; + +void *afl_postprocess_init(void *afl) { + + post_state_t *state = malloc(sizeof(post_state_t)); + if (!state) { -const unsigned char *afl_postprocess(const unsigned char *in_buf, - unsigned int * len) { + perror("malloc"); + return NULL; - static unsigned char *saved_buf; - unsigned char * new_buf; + } + + state->buf = calloc(sizeof(unsigned char), 4096); + if (!state->buf) { return NULL; } + + return state; + +} + +/* The actual postprocessor routine called by afl-fuzz: */ + +size_t afl_postprocess(post_state_t *data, unsigned char *in_buf, + unsigned int len, unsigned char **out_buf) { /* Skip execution altogether for buffers shorter than 6 bytes (just to - show how it's done). We can trust *len to be sane. */ + show how it's done). We can trust len to be sane. */ - if (*len < strlen(HEADER)) return NULL; + if (len < strlen(HEADER)) return 0; /* Do nothing for buffers that already start with the expected header. */ - if (!memcmp(in_buf, HEADER, strlen(HEADER))) return in_buf; + if (!memcmp(in_buf, HEADER, strlen(HEADER))) { + + *out_buf = in_buf; + return len; + + } /* Allocate memory for new buffer, reusing previous allocation if possible. */ - new_buf = realloc(saved_buf, *len); + *out_buf = realloc(data->buf, len); /* If we're out of memory, the most graceful thing to do is to return the original buffer and give up on modifying it. Let AFL handle OOM on its own later on. */ - if (!new_buf) return in_buf; - saved_buf = new_buf; + if (!*out_buf) { + + *out_buf = in_buf; + return len; + + } /* Copy the original data to the new location. */ - memcpy(new_buf, in_buf, *len); + memcpy(*out_buf, in_buf, len); /* Insert the new header. */ - memcpy(new_buf, HEADER, strlen(HEADER)); + memcpy(*out_buf, HEADER, strlen(HEADER)); - /* Return modified buffer. No need to update *len in this particular case, - as we're not changing it. */ + /* Return the new len. It hasn't changed, so it's just len. */ - return new_buf; + return len; } +/* Gets called afterwards */ +void afl_postprocess_deinit(post_state_t *data) { + + free(data->buf); + free(data); + +} diff --git a/examples/post_library/post_library_png.so.c b/examples/post_library/post_library_png.so.c index 60ab318f..8597c88c 100644 --- a/examples/post_library/post_library_png.so.c +++ b/examples/post_library/post_library_png.so.c @@ -5,6 +5,7 @@ Originally written by Michal Zalewski Copyright 2015 Google Inc. All rights reserved. + Adapted to the new API, 2020 by Dominik Maier Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -35,11 +36,32 @@ #define UP4K(_i) ((((_i) >> 12) + 1) << 12) -const unsigned char *afl_postprocess(const unsigned char *in_buf, - unsigned int * len) { +typedef struct post_state { - static unsigned char *saved_buf; - static unsigned int saved_len; + unsigned char *buf; + size_t size; + +} post_state_t; + +void *afl_postprocess_init(void *afl) { + + post_state_t *state = malloc(sizeof(post_state_t)); + if (!state) { + + perror("malloc"); + return NULL; + + } + + state->buf = calloc(sizeof(unsigned char), 4096); + if (!state->buf) { return NULL; } + + return state; + +} + +size_t afl_postprocess(post_state_t *data, const unsigned char *in_buf, + unsigned int len, const unsigned char **out_buf) { unsigned char *new_buf = (unsigned char *)in_buf; unsigned int pos = 8; @@ -47,12 +69,17 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, /* Don't do anything if there's not enough room for the PNG header (8 bytes). */ - if (*len < 8) return in_buf; + if (len < 8) { + + *out_buf = in_buf; + return len; + + } /* Minimum size of a zero-length PNG chunk is 12 bytes; if we don't have that, we can bail out. */ - while (pos + 12 <= *len) { + while (pos + 12 <= len) { unsigned int chunk_len, real_cksum, file_cksum; @@ -62,7 +89,7 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, /* Bail out if chunk size is too big or goes past EOF. */ - if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > *len) break; + if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > len) break; /* Chunk checksum is calculated for chunk ID (dword) and the actual payload. */ @@ -82,17 +109,23 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, if (new_buf == in_buf) { - if (*len <= saved_len) { + if (len <= data->size) { - new_buf = saved_buf; + new_buf = data->buf; } else { - new_buf = realloc(saved_buf, UP4K(*len)); - if (!new_buf) return in_buf; - saved_buf = new_buf; - saved_len = UP4K(*len); - memcpy(new_buf, in_buf, *len); + new_buf = realloc(data->buf, UP4K(len)); + if (!new_buf) { + + *out_buf = in_buf; + return len; + + } + + data->buf = new_buf; + data->size = UP4K(len); + memcpy(new_buf, in_buf, len); } @@ -108,7 +141,15 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, } - return new_buf; + *out_buf = new_buf; + return len; } +/* Gets called afterwards */ +void afl_postprocess_deinit(post_state_t *data) { + + free(data->buf); + free(data); + +} diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 32eaf4af..5f9891bc 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -293,9 +293,18 @@ typedef struct py_mutator { void * afl_state; void * py_data; + u8 * fuzz_buf; + size_t fuzz_size; + u8 * pre_save_buf; size_t pre_save_size; + u8 * trim_buf; + size_t trim_size; + + u8 * havoc_buf; + size_t havoc_size; + } py_mutator_t; #endif @@ -544,7 +553,11 @@ typedef struct afl_state { struct extra_data *a_extras; /* Automatically selected extras */ u32 a_extras_cnt; /* Total number of tokens available */ - u8 *(*post_handler)(u8 *buf, u32 *len); + /* afl_postprocess API */ + void *(*post_init)(struct afl_state *afl); + size_t (*post_handler)(void *data, u8 *buf, u32 len, u8 **out_buf); + void *(*post_deinit)(void *data); + void *post_data; /* CmpLog */ @@ -643,10 +656,10 @@ struct custom_mutator { * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output. Negative on error will abort exeuction. */ - size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, u8 *add_buf, - size_t add_buf_size, size_t max_size); + size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf, + u8 *add_buf, size_t add_buf_size, size_t max_size); /** * A post-processing function to use right before AFL writes the test case to @@ -704,9 +717,9 @@ struct custom_mutator { * @param[out] out_buf Pointer to the buffer containing the trimmed test case. * External library should allocate memory for out_buf. AFL++ will release * the memory after saving the test case. - * @param[out] out_buf_size Pointer to the size of the trimmed test case + * @return the size of the trimmed test case */ - void (*afl_custom_trim)(void *data, u8 **out_buf, size_t *out_buf_size); + size_t (*afl_custom_trim)(void *data, u8 **out_buf); /** * This method is called after each trim operation to inform you if your @@ -728,16 +741,18 @@ struct custom_mutator { * * (Optional) * - * @param data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] data pointer returned in afl_custom_init for this fuzz case + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of input data + * @param[out] out_buf The new buffer. It's legal to reuse *buf if it's < + * buf_size. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output (out_size). */ - size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, size_t buf_size, - size_t max_size); + size_t (*afl_custom_havoc_mutation)(void *data, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size); /** * Return the probability (in percentage) that afl_custom_havoc_mutation @@ -803,8 +818,8 @@ void finalize_py_module(void *); size_t pre_save_py(void *, u8 *, size_t, u8 **); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); -void trim_py(void *, u8 **, size_t *); -size_t havoc_mutation_py(void *, u8 **, size_t, size_t); +size_t trim_py(void *, u8 **); +size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); u8 havoc_mutation_probability_py(void *); u8 queue_get_py(void *, const u8 *); void queue_new_entry_py(void *, const u8 *, const u8 *); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 6c6f05ac..7c398507 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -527,8 +527,13 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->post_handler) { - out_buf = afl->post_handler(out_buf, &len); - if (!out_buf || !len) return 0; + u8 *post_buf = NULL; + + size_t post_len = + afl->post_handler(afl->post_data, out_buf, len, &post_buf); + if (!post_buf || !post_len) return 0; + out_buf = post_buf; + len = post_len; } diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c index 3e573dd2..1d99e1fa 100644 --- a/src/afl-fuzz-globals.c +++ b/src/afl-fuzz-globals.c @@ -349,6 +349,8 @@ void read_afl_environment(afl_state_t *afl, char **envp) { void afl_state_deinit(afl_state_t *afl) { + if (afl->post_deinit) afl->post_deinit(afl->post_data); + free(afl->out_buf); free(afl->out_scratch_buf); free(afl->eff_buf); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a69c3b61..fe2be4d2 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -270,7 +270,9 @@ void setup_post(afl_state_t *afl) { void *dh; u8 * fn = afl->afl_env.afl_post_library; + u8 tbuf[6]; u32 tlen = 6; + strncpy(tbuf, "hello", tlen); if (!fn) return; @@ -281,10 +283,20 @@ void setup_post(afl_state_t *afl) { afl->post_handler = dlsym(dh, "afl_postprocess"); if (!afl->post_handler) FATAL("Symbol 'afl_postprocess' not found."); + afl->post_init = dlsym(dh, "afl_postprocess_init"); + if (!afl->post_init) FATAL("Symbol 'afl_postprocess_init' not found."); + afl->post_deinit = dlsym(dh, "afl_postprocess_deinit"); + if (!afl->post_deinit) FATAL("Symbol 'afl_postprocess_deinit' not found."); /* Do a quick test. It's better to segfault now than later =) */ - afl->post_handler("hello", &tlen); + u8 *post_buf = NULL; + afl->post_data = afl->post_init(afl); + if (!afl->post_data) FATAL("Could not initialize post handler."); + + size_t post_len = afl->post_handler(afl->post_data, tbuf, tlen, &post_buf); + if (!post_len || !post_buf) + SAYF("Empty return in test post handler for buf=\"hello\\0\"."); OKF("Postprocessor installed successfully."); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 41bc69c8..0692ebb0 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -7,6 +7,7 @@ Now maintained by Marc Heuse , Heiko Eißfeldt and Andrea Fioraldi + Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. Copyright 2019-2020 AFLplusplus Project. All rights reserved. @@ -192,7 +193,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (afl->mutator->afl_custom_init) - afl->mutator->data = afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + afl->mutator->data = + afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); } @@ -218,17 +220,18 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (afl->stage_cur < afl->stage_max) { + u8 *retbuf = NULL; + sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec)); u32 cksum; - u8 * retbuf = NULL; - size_t retlen = 0; - - afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf, &retlen); + size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf); - if (retlen > orig_len) + if (unlikely(retlen < 0 || !retbuf)) + FATAL("custom_trim failed (ret %zd)", retlen); + else if (unlikely(retlen > orig_len)) FATAL( "Trimmed data returned by custom mutator is larger than original " "data"); @@ -238,12 +241,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = run_target(afl, afl->fsrv.exec_tmout); ++afl->trim_execs; - if (afl->stop_soon || fault == FAULT_ERROR) { - - ck_free(retbuf); - goto abort_trimming; - - } + if (afl->stop_soon || fault == FAULT_ERROR) { goto abort_trimming; } cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); @@ -281,8 +279,6 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } - ck_free(retbuf); - /* Since this can be slow, update the screen every now and then. */ if (!(trim_exec++ % afl->stats_update_freq)) show_stats(afl); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 024b4665..8dfafb7b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1612,15 +1612,20 @@ custom_mutator_stage: ck_read(fd, new_buf, target->len, target->fname); close(fd); - // TODO: clean up this mess. + u8 *mutated_buf = NULL; + size_t mutated_size = afl->mutator->afl_custom_fuzz( - afl->mutator->data, &out_buf, len, new_buf, target->len, max_seed_size); + afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len, + max_seed_size); + + if (unlikely(mutated_size < 0)) + FATAL("custom_fuzz returned %zd", mutated_size); if (mutated_size > len) afl->out_size = mutated_size; if (mutated_size > 0) { - if (common_fuzz_stuff(afl, out_buf, (u32)mutated_size)) { + if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; @@ -1726,8 +1731,22 @@ havoc_stage: if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { - temp_len = afl->mutator->afl_custom_havoc_mutation( - afl->mutator->data, &out_buf, temp_len, MAX_FILE); + 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(new_len < 0)) + 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) { + + 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 6fbdb678..f9f71929 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -35,15 +35,22 @@ static void *unsupported(afl_state_t *afl, unsigned int seed) { } -size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, - size_t add_buf_size, size_t max_size) { +/* sorry for this makro... +it just filles in `&py_mutator->something_buf, &py_mutator->something_size`. */ +#define BUF_PARAMS(name) \ + (void **)&((py_mutator_t *)py_mutator)->name##_buf, \ + &((py_mutator_t *)py_mutator)->name##_size + +size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, + u8 *add_buf, size_t add_buf_size, size_t max_size) { size_t mutated_size; PyObject *py_args, *py_value; py_args = PyTuple_New(3); + py_mutator_t *py = (py_mutator_t *)py_mutator; /* buf */ - py_value = PyByteArray_FromStringAndSize(*buf, buf_size); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); @@ -79,17 +86,17 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, PyTuple_SetItem(py_args, 2, py_value); - py_value = PyObject_CallObject( - ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); + py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args); Py_DECREF(py_args); if (py_value != NULL) { mutated_size = PyByteArray_Size(py_value); - if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size); - memcpy(*buf, PyByteArray_AsString(py_value), mutated_size); + *out_buf = ck_maybe_grow(BUF_PARAMS(fuzz), mutated_size); + + memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); return mutated_size; @@ -364,14 +371,8 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { py_out_buf_size = PyByteArray_Size(py_value); - if (py_out_buf_size > py->pre_save_size) { - - /* Not enough space! - Let's resize our buf */ - py->pre_save_buf = ck_realloc(py->pre_save_buf, py_out_buf_size); - py->pre_save_size = py_out_buf_size; - - } + ck_maybe_grow((void **)&py->pre_save_buf, &py->pre_save_size, + py_out_buf_size); memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); @@ -465,9 +466,10 @@ u32 post_trim_py(void *py_mutator, u8 success) { } -void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { +size_t trim_py(void *py_mutator, u8 **out_buf) { PyObject *py_args, *py_value; + size_t ret; py_args = PyTuple_New(0); py_value = PyObject_CallObject( @@ -476,9 +478,9 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { if (py_value != NULL) { - *out_buf_size = PyByteArray_Size(py_value); - *out_buf = malloc(*out_buf_size); - memcpy(*out_buf, PyByteArray_AsString(py_value), *out_buf_size); + ret = PyByteArray_Size(py_value); + *out_buf = ck_maybe_grow(BUF_PARAMS(trim), ret); + memcpy(*out_buf, PyByteArray_AsString(py_value), ret); Py_DECREF(py_value); } else { @@ -488,17 +490,19 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { } + return ret; + } -size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, - size_t max_size) { +size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size) { size_t mutated_size; PyObject *py_args, *py_value; py_args = PyTuple_New(2); /* buf */ - py_value = PyByteArray_FromStringAndSize(*buf, buf_size); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); @@ -532,9 +536,19 @@ size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, if (py_value != NULL) { mutated_size = PyByteArray_Size(py_value); - if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size); + if (mutated_size <= buf_size) { + + /* We reuse the input buf here. */ + *out_buf = buf; + + } else { - memcpy(*buf, PyByteArray_AsString(py_value), mutated_size); + /* A new buf is needed... */ + *out_buf = ck_maybe_grow(BUF_PARAMS(havoc), mutated_size); + + } + + memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); return mutated_size; @@ -680,5 +694,7 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, } +#undef BUF_PARAMS + #endif /* USE_PYTHON */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index a43bfad2..9ba2c5f7 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -741,8 +741,13 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->post_handler) { - out_buf = afl->post_handler(out_buf, &len); - if (!out_buf || !len) return 0; + u8 *post_buf = NULL; + + size_t post_len = + afl->post_handler(afl->post_data, out_buf, len, &post_buf); + if (!post_buf || !post_len) return 0; + out_buf = post_buf; + len = post_len; } -- cgit 1.4.1 From 738a245c3eed6ad360591e58cce757c90fb3f490 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 28 Mar 2020 08:38:50 +0100 Subject: fix warning in afl-fuzz-run, tested with '-m32' also --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 9ba2c5f7..315539d1 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -222,7 +222,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { len, &new_buf); if (unlikely(new_size <= 0 || !new_buf)) - FATAL("Custom_pre_save failed (ret: %ld)", new_size); + FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size); /* everything as planned. use the new data. */ ck_write(fd, new_buf, new_size, afl->fsrv.out_file); -- cgit 1.4.1 From 23d9649aec7a7d74082debdb9f6fa2f5ffca7268 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 28 Mar 2020 09:31:30 +0100 Subject: making 'CFLAGS="-m32" make source-only tests' work --- gcc_plugin/Makefile | 12 +++++++++++- libdislocator/Makefile | 2 +- libtokencap/Makefile | 2 +- llvm_mode/LLVMInsTrim.so.cc | 2 +- llvm_mode/afl-llvm-pass.so.cc | 2 +- src/third_party/libradamsa/libradamsa.c | 2 +- test/test.sh | 2 +- 7 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 506d690d..df8bd9cb 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -29,7 +29,7 @@ MAN_PATH ?= $(PREFIX)/man/man8 VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) CFLAGS ?= -O3 -g -funroll-loops -CFLAGS += -Wall -I../include -D_FORTIFY_SOURCE=2 -Wno-pointer-sign \ +override CFLAGS = -Wall -I../include -D_FORTIFY_SOURCE=2 -Wno-pointer-sign \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ -Wno-unused-function @@ -40,6 +40,16 @@ CXXEFLAGS := $(CXXFLAGS) -Wall -D_FORTIFY_SOURCE=2 CC ?= gcc CXX ?= g++ +ifeq "clang" "$(CC)" + CC = gcc + CXX = g++ +endif + +ifeq "clang++" "$(CXX)" + CC = gcc + CXX = g++ +endif + PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include" HASH=\# diff --git a/libdislocator/Makefile b/libdislocator/Makefile index 07d98a0d..3ee37088 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -19,7 +19,7 @@ HELPER_PATH = $(PREFIX)/lib/afl VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) CFLAGS ?= -O3 -funroll-loops -CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign ifdef USEHUGEPAGE CFLAGS += -DUSEHUGEPAGE diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 4889479b..5fcd7731 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -21,7 +21,7 @@ MAN_PATH ?= $(PREFIX)/man/man8 VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) CFLAGS ?= -O3 -funroll-loops -CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign ifeq "$(shell uname)" "Linux" TARGETS = libtokencap.so diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index c4033523..8b23942c 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -509,7 +509,7 @@ struct InsTrim : public ModulePass { if (!be_quiet) { char modeline[100]; - snprintf(modeline, sizeof(modeline), "%s%s%s%s", + snprintf(modeline, sizeof(modeline), "%s%s%s%s%s", getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index f6ead9ec..3b0e1fda 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -587,7 +587,7 @@ bool AFLCoverage::runOnModule(Module &M) { else { char modeline[100]; - snprintf(modeline, sizeof(modeline), "%s%s%s%s", + snprintf(modeline, sizeof(modeline), "%s%s%s%s%s", getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", diff --git a/src/third_party/libradamsa/libradamsa.c b/src/third_party/libradamsa/libradamsa.c index f3677fa7..fe91594e 100644 --- a/src/third_party/libradamsa/libradamsa.c +++ b/src/third_party/libradamsa/libradamsa.c @@ -30815,7 +30815,7 @@ size_t copy_list(uint8_t *ptr, word lispval, size_t max) { lispval = G(lispval, 2); // list = cdr(list) } if (lispval != INULL && max == 0) { - printf("ERROR: lisp return value was not a proper list. Trailing %lu\n", lispval); + printf("ERROR: lisp return value was not a proper list. Trailing %lu\n", (unsigned long)lispval); } return n; } diff --git a/test/test.sh b/test/test.sh index 8434aaf1..ec4e71d0 100755 --- a/test/test.sh +++ b/test/test.sh @@ -580,7 +580,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { } $ECHO "$BLUE[*] Testing: shared library extensions" -cc -o test-compcov test-compcov.c > /dev/null 2>&1 +cc $CFLAGS -o test-compcov test-compcov.c > /dev/null 2>&1 test -e ../libtokencap.so && { AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so DYLD_INSERT_LIBRARIES=../libtokencap.so DYLD_FORCE_FLAT_NAMESPACE=1 ./test-compcov foobar > /dev/null 2>&1 grep -q BUGMENOT token.out > /dev/null 2>&1 && { -- cgit 1.4.1 From 1119a2e185498c83cdc672c4a4753494197314f2 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 28 Mar 2020 11:01:29 +0100 Subject: alloc-inl.h/ck_maybe_grow() back to size_t, reimplement overflow check --- include/alloc-inl.h | 12 ++++++------ src/afl-fuzz-python.c | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/include/alloc-inl.h b/include/alloc-inl.h index ae908162..11c1143a 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -771,10 +771,10 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, It will realloc *buf otherwise. *size will grow exponentially as per: https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ - Will FATAL if size_needed is <1 or *size is negative. + Will FATAL if size_needed is <1. @return For convenience, this function returns *buf. */ -static inline void *ck_maybe_grow(void **buf, ssize_t *size, +static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) { /* Oops. found a bug? */ @@ -782,14 +782,14 @@ static inline void *ck_maybe_grow(void **buf, ssize_t *size, /* No need to realloc */ if (likely(*size >= size_needed)) return *buf; - if (unlikely(*size < 0)) FATAL("Negative size detected!"); - /* No inital size was set */ + + /* No initial size was set */ if (*size == 0) *size = INITIAL_GROWTH_SIZE; while (*size < size_needed) { - *size *= 2; /* in case of overflow we'll realloc to size_needed */ - if ((*size) < 0) *size = size_needed; + if (2*(*size) < size_needed) *size = size_needed; + else *size *= 2; } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index f9f71929..6f8982c0 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -36,7 +36,7 @@ static void *unsupported(afl_state_t *afl, unsigned int seed) { } /* sorry for this makro... -it just filles in `&py_mutator->something_buf, &py_mutator->something_size`. */ +it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */ #define BUF_PARAMS(name) \ (void **)&((py_mutator_t *)py_mutator)->name##_buf, \ &((py_mutator_t *)py_mutator)->name##_size @@ -371,8 +371,7 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { py_out_buf_size = PyByteArray_Size(py_value); - ck_maybe_grow((void **)&py->pre_save_buf, &py->pre_save_size, - py_out_buf_size); + ck_maybe_grow(BUF_PARAMS(pre_save), py_out_buf_size); memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); -- cgit 1.4.1 From ab5e0703dab404a77cd4726f720db99bed1a0c71 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 11:55:10 +0100 Subject: tiny changes in custom mut api --- examples/custom_mutators/example.c | 46 ++++++++++++++++++++++++-------------- include/afl-fuzz.h | 6 +++-- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-one.c | 6 ++--- src/afl-fuzz-python.c | 2 +- src/afl-fuzz-run.c | 2 +- 6 files changed, 39 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 54fc9d47..9a62d1a7 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -29,16 +29,15 @@ typedef struct my_mutator { afl_t *afl; // any additional data here! - uint8_t *trim_buf; - size_t trim_buf_size; - int trimmming_steps; - int cur_step; + size_t trim_size_current; + int trimmming_steps; + int cur_step; // Reused buffers: BUF_VAR(u8, fuzz); BUF_VAR(u8, data); BUF_VAR(u8, havoc); - BUF_VAR(u8, trim_out); + BUF_VAR(u8, trim); BUF_VAR(u8, pre_save); } my_mutator_t; @@ -52,7 +51,7 @@ typedef struct my_mutator { * in the same way. * @return Pointer to the data object this custom mutator instance should use. * There may be multiple instances of this mutator in one afl-fuzz run! - * Returns NULL on error. + * Return NULL on error. */ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { @@ -80,11 +79,13 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Pointer to input data to be mutated * @param[in] buf_size Size of input data + * @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on + * error. * @param[in] add_buf Buffer containing the additional test case * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must not * produce data larger than max_size. - * @return Size of the mutated output. Negative return will abort fuzzing. + * @return Size of the mutated output. */ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 **out_buf, uint8_t *add_buf, @@ -100,7 +101,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (!mutated_out) { perror("custom mutator allocation (maybe_grow)"); - return -1; /* afl-fuzz will very likely error out after this. */ + return 0; /* afl-fuzz will very likely error out after this. */ } @@ -135,7 +136,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, * processing. External library should allocate memory for out_buf. * The buf pointer may be reused (up to the given buf_size); * @return Size of the output buffer after processing or the needed amount. - * A return smaller 1 indicates an error. + * A return of 0 indicates an error. */ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { @@ -146,7 +147,8 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (!data->pre_save_buf) { perror("custom mutator realloc failed."); - return -1; + *out_buf = NULL; + return 0; } @@ -195,8 +197,11 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { data->trimmming_steps = 1; data->cur_step = 0; - data->trim_buf = buf; - data->trim_buf_size = buf_size; + + maybe_grow(BUF_PARAMS(data, trim), buf_size); + memcpy(data->trim_buf, buf, buf_size); + + data->trim_size_current = buf_size; return data->trimmming_steps; @@ -218,15 +223,15 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * External library should allocate memory for out_buf. * AFL++ will not release the memory after saving the test case. * Keep a ref in *data. + * *out_buf = NULL is treated as error. * @return Pointer to the size of the trimmed test case */ size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { - size_t ret = data->trim_buf_size - 1; + *out_buf = data->trim_buf; - *out_buf = maybe_grow(BUF_PARAMS(data, trim_out), ret); // Remove the last byte of the trimming input - memcpy(*out_buf, data->trim_buf, ret); + return data->trim_size_current - 1; } @@ -266,7 +271,7 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * output * @param[in] buf_size Size of input data * @param[out] out_buf The output buffer. buf can be reused, if the content - * fits. + * fits. *out_buf = NULL is treated as error. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. * @return Size of the mutated output. @@ -277,6 +282,13 @@ size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size, if (buf_size == 0) { *out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1); + if (!*out_buf) { + + perror("custom havoc: maybe_grow"); + return 0; + + } + **out_buf = rand() % 256; buf_size = 1; @@ -354,7 +366,7 @@ void afl_custom_deinit(my_mutator_t *data) { free(data->havoc_buf); free(data->data_buf); free(data->fuzz_buf); - free(data->trim_out_buf); + free(data->trim_buf); free(data); } diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5f9891bc..79878cb6 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -649,14 +649,16 @@ struct custom_mutator { * (Optional for now. Required in the future) * * @param data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of the input/output data + * @param[out] out_buf the new buffer. We may reuse *buf if large enough. + * *out_buf = NULL is treated as FATAL. * @param[in] add_buf Buffer containing the additional test case * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. Negative on error will abort exeuction. + * @return Size of the mutated output. */ size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0692ebb0..f14a57bb 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -229,7 +229,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf); - if (unlikely(retlen < 0 || !retbuf)) + if (unlikely(!retbuf)) FATAL("custom_trim failed (ret %zd)", retlen); else if (unlikely(retlen > orig_len)) FATAL( diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 8dfafb7b..b1bbad0a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1618,8 +1618,8 @@ custom_mutator_stage: afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len, max_seed_size); - if (unlikely(mutated_size < 0)) - FATAL("custom_fuzz returned %zd", mutated_size); + if (unlikely(!mutated_buf)) + FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); if (mutated_size > len) afl->out_size = mutated_size; @@ -1734,7 +1734,7 @@ havoc_stage: 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(new_len < 0)) + if (unlikely(!custom_havoc_buf)) FATAL("Error in custom_havoc (return %zd)", new_len); if (likely(new_len > 0 && custom_havoc_buf)) { diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 6f8982c0..76b5ca80 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -103,7 +103,7 @@ size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, } else { PyErr_Print(); - FATAL("Call failed"); + FATAL("python custom fuzz: call failed"); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 315539d1..90cb2ed5 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -221,7 +221,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, len, &new_buf); - if (unlikely(new_size <= 0 || !new_buf)) + if (unlikely(!new_buf)) FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size); /* everything as planned. use the new data. */ -- cgit 1.4.1 From 81873d97f8a24a874a52f56aae5ca87745f1aaec Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 12:58:56 +0100 Subject: error handling for custom mutators --- examples/custom_mutators/custom_mutator_helpers.h | 49 ++++++++++++++--------- examples/custom_mutators/example.c | 15 ++++--- include/afl-fuzz.h | 13 +++--- include/alloc-inl.h | 6 +-- src/afl-fuzz-mutators.c | 3 +- src/afl-fuzz-python.c | 4 +- 6 files changed, 54 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index 0dc00d96..e5ce3569 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -277,37 +277,48 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } + +/* This function calculates the next power of 2 greater or equal its argument. + @return The rounded up power of 2 (if no overflow) or 0 on overflow. +*/ +static inline size_t next_pow2(size_t in) { + if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + size_t out = in - 1; + out |= out >> 1; + out |= out >> 2; + out |= out >> 4; + out |= out >> 8; + out |= out >> 16; + return out + 1; +} + /* This function makes sure *size is > size_needed after call. - It changes buf and size in-place, if needed. It will realloc *buf otherwise. *size will grow exponentially as per: https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ - Will return NULL if size_needed is <1 or *size is negative or malloc Failed. - @return For convenience, this function returns *buf. NULL on error. + Will return NULL and free *buf if size_needed is <1 or realloc failed. + @return For convenience, this function returns *buf. */ -static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { - - /* Oops. found a bug? */ - if (unlikely(size_needed < 1)) return NULL; +static inline void *maybe_grow(void **buf, size_t *size, + size_t size_needed) { /* No need to realloc */ - if (likely(*size >= size_needed)) return *buf; - if (unlikely(*size < 0)) return NULL; - /* No inital size was set */ - if (*size == 0) *size = INITIAL_GROWTH_SIZE; - while (*size < size_needed) { - - *size *= 2; - if ((*size) < 0) { + if (likely(size_needed && *size >= size_needed)) return *buf; - /* An overflow occurred. Fall back to size_needed */ - *size = size_needed; + /* No initial size was set */ + if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; - } + /* grow exponentially */ + size_t next_size = next_pow2(size_needed); + /* handle overflow */ + if (!next_size) { + next_size = size_needed; } - *buf = realloc(*buf, *size); + /* alloc */ + *buf = realloc(*buf, next_size); + *size = *buf ? next_size : 0; return *buf; diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 9a62d1a7..488ece81 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -100,6 +100,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), mutated_size); if (!mutated_out) { + *out_buf = NULL; perror("custom mutator allocation (maybe_grow)"); return 0; /* afl-fuzz will very likely error out after this. */ @@ -189,16 +190,20 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, * @param data pointer returned in afl_custom_init for this fuzz case * @param buf Buffer containing the test case * @param buf_size Size of the test case - * @return The amount of possible iteration steps to trim the input + * @return The amount of possible iteration steps to trim the input. + * negative on error. */ -int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { +int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { // We simply trim once data->trimmming_steps = 1; data->cur_step = 0; - maybe_grow(BUF_PARAMS(data, trim), buf_size); + if (!maybe_grow(BUF_PARAMS(data, trim), buf_size)) { + perror("init_trim grow"); + return -1; + } memcpy(data->trim_buf, buf, buf_size); data->trim_size_current = buf_size; @@ -245,9 +250,9 @@ size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param success Indicates if the last trim operation was successful. * @return The next trim iteration index (from 0 to the maximum amount of - * steps returned in init_trim) + * steps returned in init_trim). negative ret on failure. */ -int afl_custom_post_trim(my_mutator_t *data, int success) { +int32_t afl_custom_post_trim(my_mutator_t *data, int success) { if (success) { diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 79878cb6..a265c1a3 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -700,9 +700,10 @@ struct custom_mutator { * @param data pointer returned in afl_custom_init for this fuzz case * @param buf Buffer containing the test case * @param buf_size Size of the test case - * @return The amount of possible iteration steps to trim the input + * @return The amount of possible iteration steps to trim the input. + * Negative on error. */ - u32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size); + s32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size); /** * This method is called for each trimming operation. It doesn't have any @@ -733,9 +734,9 @@ struct custom_mutator { * @param data pointer returned in afl_custom_init for this fuzz case * @param success Indicates if the last trim operation was successful. * @return The next trim iteration index (from 0 to the maximum amount of - * steps returned in init_trim) + * steps returned in init_trim). Negative on error. */ - u32 (*afl_custom_post_trim)(void *data, u8 success); + s32 (*afl_custom_post_trim)(void *data, u8 success); /** * Perform a single custom mutation on a given input. @@ -818,8 +819,8 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); size_t pre_save_py(void *, u8 *, size_t, u8 **); -u32 init_trim_py(void *, u8 *, size_t); -u32 post_trim_py(void *, u8); +s32 init_trim_py(void *, u8 *, size_t); +s32 post_trim_py(void *, u8); size_t trim_py(void *, u8 **); size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); u8 havoc_mutation_probability_py(void *); diff --git a/include/alloc-inl.h b/include/alloc-inl.h index b8c83db4..91564932 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -767,10 +767,10 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, #endif /* _WANT_ORIGINAL_AFL_ALLOC */ -/* This function calculates the lowest power of 2 greater or equal its argument. +/* This function calculates the next power of 2 greater or equal its argument. @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ -static inline size_t powerOf2Ceil(size_t in) { +static inline size_t next_pow2(size_t in) { if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; @@ -801,7 +801,7 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; /* grow exponentially */ - size_t next_size = powerOf2Ceil(size_needed); + size_t next_size = next_pow2(size_needed); /* handle overflow */ if (!next_size) { diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index f14a57bb..90d7de40 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -213,7 +213,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { afl->stage_cur = 0; afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); - + if (unlikely(afl->stage_max) < 0) FATAL("custom_init_trim error ret: %d", afl->stage_max); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, q->len); @@ -273,6 +273,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); + if (unlikely(afl->stage_cur < 0)) FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 76b5ca80..91e5b084 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -388,7 +388,7 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { } -u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { +s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { PyObject *py_args, *py_value; @@ -426,7 +426,7 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { } -u32 post_trim_py(void *py_mutator, u8 success) { +s32 post_trim_py(void *py_mutator, u8 success) { PyObject *py_args, *py_value; -- cgit 1.4.1 From 98545f30aa52c1b82b88e54088848b90e178a929 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 12:59:41 +0100 Subject: code format --- examples/custom_mutators/custom_mutator_helpers.h | 13 ++++++------- examples/custom_mutators/example.c | 6 +++++- include/alloc-inl.h | 9 +++++---- src/afl-fuzz-mutators.c | 6 ++++-- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index e5ce3569..0848321f 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -277,12 +277,13 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } - /* This function calculates the next power of 2 greater or equal its argument. @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ static inline size_t next_pow2(size_t in) { - if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + + if (in == 0 || in > (size_t)-1) + return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; out |= out >> 2; @@ -290,6 +291,7 @@ static inline size_t next_pow2(size_t in) { out |= out >> 8; out |= out >> 16; return out + 1; + } /* This function makes sure *size is > size_needed after call. @@ -299,8 +301,7 @@ static inline size_t next_pow2(size_t in) { Will return NULL and free *buf if size_needed is <1 or realloc failed. @return For convenience, this function returns *buf. */ -static inline void *maybe_grow(void **buf, size_t *size, - size_t size_needed) { +static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { /* No need to realloc */ if (likely(size_needed && *size >= size_needed)) return *buf; @@ -312,9 +313,7 @@ static inline void *maybe_grow(void **buf, size_t *size, size_t next_size = next_pow2(size_needed); /* handle overflow */ - if (!next_size) { - next_size = size_needed; - } + if (!next_size) { next_size = size_needed; } /* alloc */ *buf = realloc(*buf, next_size); diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 488ece81..a9764f5b 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -193,7 +193,8 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, * @return The amount of possible iteration steps to trim the input. * negative on error. */ -int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { +int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, + size_t buf_size) { // We simply trim once data->trimmming_steps = 1; @@ -201,9 +202,12 @@ int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) data->cur_step = 0; if (!maybe_grow(BUF_PARAMS(data, trim), buf_size)) { + perror("init_trim grow"); return -1; + } + memcpy(data->trim_buf, buf, buf_size); data->trim_size_current = buf_size; diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 91564932..4211e398 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -771,7 +771,9 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ static inline size_t next_pow2(size_t in) { - if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + + if (in == 0 || in > (size_t)-1) + return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; out |= out >> 2; @@ -779,6 +781,7 @@ static inline size_t next_pow2(size_t in) { out |= out >> 8; out |= out >> 16; return out + 1; + } /* This function makes sure *size is > size_needed after call. @@ -804,9 +807,7 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, size_t next_size = next_pow2(size_needed); /* handle overflow */ - if (!next_size) { - next_size = size_needed; - } + if (!next_size) { next_size = size_needed; } /* alloc */ *buf = ck_realloc(*buf, next_size); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 90d7de40..754b2190 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -213,7 +213,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { afl->stage_cur = 0; afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); - if (unlikely(afl->stage_max) < 0) FATAL("custom_init_trim error ret: %d", afl->stage_max); + if (unlikely(afl->stage_max) < 0) + FATAL("custom_init_trim error ret: %d", afl->stage_max); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, q->len); @@ -273,7 +274,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); - if (unlikely(afl->stage_cur < 0)) FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); + if (unlikely(afl->stage_cur < 0)) + FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); -- cgit 1.4.1 From 452067ffca0de664fa4a11211c54f34c3842f20e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 30 Mar 2020 00:50:04 +0200 Subject: added read_timed --- docs/Changelog.md | 6 +++-- include/common.h | 50 ++++++++++++++++++++++++++++++++++++ include/types.h | 18 +++++++++++-- src/afl-forkserver.c | 24 ++++++------------ src/afl-fuzz-cmplog.c | 67 ++++++++++++++++++------------------------------- src/afl-fuzz-redqueen.c | 5 ++-- src/afl-fuzz-run.c | 23 ++++++----------- 7 files changed, 112 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index 198909d1..407a3324 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -16,12 +16,14 @@ sending a mail to . ! development and acceptance of PRs now happen only in the dev branch and only occasionally when everything is fine we PR to master - all: - - big code changes to make afl-fuzz thread-safe so afl-fuzz can spawn + - big code changes to make afl-fuzz thread-safe so afl-fuzz can spawn multiple fuzzing threads in the future or even become a library - afl basic tools now report on the environment variables picked up - more tools get environment variable usage info in the help output - force all output to stdout (some OK/SAY/WARN messages were sent to stdout, some to stderr) + - uninstrumented mode uses an internal forkserver ("fauxserver") + - reduced number of (de)allocations - afl-fuzz: - python mutator modules and custom mutator modules now use the same interface and hence the API changed @@ -38,7 +40,7 @@ sending a mail to . (https://github.com/adrianherrera/afl-ngram-pass/), activate by setting AFL_LLVM_NGRAM_SIZE - llvm_mode InsTrim mode: - - removed workaround for bug where paths were not instrumented and + - removed workaround for bug where paths were not instrumented and imported fix by author - made skipping 1 block functions an option and is disable by default, set AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 to re-enable this diff --git a/include/common.h b/include/common.h index 8b21b55f..e8558e24 100644 --- a/include/common.h +++ b/include/common.h @@ -29,6 +29,7 @@ #include #include +#include #include #include "types.h" #include "stdbool.h" @@ -390,5 +391,54 @@ static u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { } +/* Wrapper for select() and read(), reading exactly len bytes. + Returns the time passed to read. + If the wait times out, returns timeout_ms + 1; + Returns 0 if an error occurred (fd closed, signal, ...); */ +static inline u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { + + struct timeval timeout; + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + timeout.tv_sec = (timeout_ms / 1000); + timeout.tv_usec = (timeout_ms % 1000) * 1000; + + size_t read_total = 0; + size_t len_read = 0; + + while (len_read < len) { + + /* set exceptfds as well to return when a child exited/closed the pipe. */ + int sret = select(fd + 1, &readfds, NULL, NULL, &timeout); + + if (!sret) { + + // printf("Timeout in sret."); + return timeout_ms + 1; + + } else if (sret < 0) { + + // perror("sret malloc"); + // TODO: catch other (errno == EINTR) than ctrl+c? + return 0; + + } + + len_read = read(fd, buf + len_read, len - len_read); + if (!len_read) { return 0; } + read_total += len_read; + + } + + s32 exec_ms = + MIN(timeout_ms, + ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000))); + return exec_ms > 0 ? exec_ms + : 1; // at least 1 milli must have passed (0 is an error) + +} + #endif diff --git a/include/types.h b/include/types.h index ebc561f7..da95cb39 100644 --- a/include/types.h +++ b/include/types.h @@ -58,8 +58,22 @@ typedef int32_t s32; typedef int64_t s64; #ifndef MIN -#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a)) -#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) +#define MIN(a, b) \ + ({ \ + \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a < _b ? _a : _b; \ + \ + }) +#define MAX(a, b) \ + ({ \ + \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a > _b ? _a : _b; \ + \ + }) #endif /* !MIN */ #define SWAP16(_x) \ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 2dd7a9f0..01a606c3 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -164,10 +164,9 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) { - struct timeval timeout; - int st_pipe[2], ctl_pipe[2]; - int status; - s32 rlen; + int st_pipe[2], ctl_pipe[2]; + int status; + s32 rlen; if (fsrv->use_fauxsrv) ACTF("Using Fauxserver:"); @@ -318,24 +317,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) { rlen = 0; if (fsrv->exec_tmout) { - fd_set readfds; + rlen = 4; + u32 time = read_timed(fsrv->fsrv_st_fd, &status, rlen, + fsrv->exec_tmout * FORK_WAIT_MULT); - FD_ZERO(&readfds); - FD_SET(fsrv->fsrv_st_fd, &readfds); - timeout.tv_sec = ((fsrv->exec_tmout * FORK_WAIT_MULT) / 1000); - timeout.tv_usec = ((fsrv->exec_tmout * FORK_WAIT_MULT) % 1000) * 1000; - - int sret = select(fsrv->fsrv_st_fd + 1, &readfds, NULL, NULL, &timeout); - - if (sret == 0) { + if (!time) { fsrv->child_timed_out = 1; kill(fsrv->child_pid, SIGKILL); - } else { - - rlen = read(fsrv->fsrv_st_fd, &status, 4); - } } else { diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 7c398507..08ac15c7 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -31,10 +31,9 @@ void init_cmplog_forkserver(afl_state_t *afl) { - struct timeval timeout; - int st_pipe[2], ctl_pipe[2]; - int status; - s32 rlen; + int st_pipe[2], ctl_pipe[2]; + int status; + s32 rlen; ACTF("Spinning up the cmplog fork server..."); @@ -185,21 +184,19 @@ void init_cmplog_forkserver(afl_state_t *afl) { rlen = 0; if (afl->fsrv.exec_tmout) { - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(afl->cmplog_fsrv_st_fd, &readfds); - timeout.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000); - timeout.tv_usec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000; + rlen = 4; + u32 timeout_ms = afl->fsrv.exec_tmout * FORK_WAIT_MULT; + /* Reuse readfds as exceptfds to see when the child closed the pipe */ + u32 time_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, rlen, timeout_ms); - int sret = - select(afl->cmplog_fsrv_st_fd + 1, &readfds, NULL, NULL, &timeout); + if (!time_ms) { - if (sret == 0) { + PFATAL("Error in timed read"); - kill(afl->cmplog_fsrv_pid, SIGKILL); - - } else { + } else if (time_ms > timeout_ms) { + afl->fsrv.child_timed_out = 1; + kill(afl->cmplog_fsrv_pid, SIGKILL); rlen = read(afl->cmplog_fsrv_st_fd, &status, 4); } @@ -213,6 +210,11 @@ void init_cmplog_forkserver(afl_state_t *afl) { /* If we have a four-byte "hello" message from the server, we're all set. Otherwise, try to figure out what went wrong. */ + if (afl->fsrv.child_timed_out) + FATAL( + "Timeout while initializing cmplog fork server (adjusting -t may " + "help)"); + if (rlen == 4) { OKF("All right - fork server is up."); @@ -220,11 +222,6 @@ void init_cmplog_forkserver(afl_state_t *afl) { } - if (afl->fsrv.child_timed_out) - FATAL( - "Timeout while initializing cmplog fork server (adjusting -t may " - "help)"); - if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); @@ -379,16 +376,12 @@ void init_cmplog_forkserver(afl_state_t *afl) { u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { - struct timeval it; - int status = 0; - int sret; - u64 exec_ms; + int status = 0; + u64 exec_ms; u32 tb4; s32 res; - fd_set readfds; - afl->fsrv.child_timed_out = 0; /* After this memset, afl->fsrv.trace_bits[] are effectively volatile, so we @@ -423,18 +416,9 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { /* Configure timeout, as requested by user, then wait for child to terminate. */ + u32 time_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, 4, timeout); - it.tv_sec = (timeout / 1000); - it.tv_usec = (timeout % 1000) * 1000; - - FD_ZERO(&readfds); - FD_SET(afl->cmplog_fsrv_st_fd, &readfds); - it.tv_sec = ((timeout) / 1000); - it.tv_usec = ((timeout) % 1000) * 1000; - - sret = select(afl->cmplog_fsrv_st_fd + 1, &readfds, NULL, NULL, &it); - - if (sret == 0) { + if (time_ms > timeout) { /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ @@ -442,9 +426,12 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { kill(afl->cmplog_child_pid, SIGKILL); afl->fsrv.child_timed_out = 1; + /* After killing the child, the forkserver should tell us */ + if (!read(afl->cmplog_fsrv_st_fd, &status, 4)) time_ms = 0; + } - if ((res = read(afl->cmplog_fsrv_st_fd, &status, 4)) != 4) { + if (!time_ms) { // Something went wrong. if (afl->stop_soon) return 0; SAYF("\n" cLRD "[-] " cRST @@ -467,12 +454,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { if (!WIFSTOPPED(status)) afl->cmplog_child_pid = 0; - exec_ms = (u64)timeout - (it.tv_sec * 1000 + it.tv_usec / 1000); if (afl->slowest_exec_ms < exec_ms) afl->slowest_exec_ms = exec_ms; - it.tv_sec = 0; - it.tv_usec = 0; - ++afl->total_execs; /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index b069fa77..4acc204b 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -529,9 +529,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (!afl->shm.cmp_map->headers[k].hits) continue; if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) - afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_H); + afl->stage_max += MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_H); else - afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H); + afl->stage_max += + MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 90cb2ed5..f58e1a33 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -33,13 +33,10 @@ u8 run_target(afl_state_t *afl, u32 timeout) { s32 res; - int sret; + u32 time_ms; - fd_set readfds; - - struct timeval it; - int status = 0; - u32 tb4; + int status = 0; + u32 tb4; afl->fsrv.child_timed_out = 0; @@ -70,26 +67,20 @@ u8 run_target(afl_state_t *afl, u32 timeout) { if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - /* use select to monitor the forkserver for timeouts. */ - - FD_ZERO(&readfds); - FD_SET(afl->fsrv.fsrv_st_fd, &readfds); - it.tv_sec = ((timeout) / 1000); - it.tv_usec = ((timeout) % 1000) * 1000; - - sret = select(afl->fsrv.fsrv_st_fd + 1, &readfds, NULL, NULL, &it); + time_ms = read_timed(afl->fsrv.fsrv_st_fd, &status, 4, timeout); - if (sret == 0) { + if (time_ms > timeout) { /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ kill(afl->fsrv.child_pid, SIGKILL); afl->fsrv.child_timed_out = 1; + if (read(afl->fsrv.fsrv_st_fd, &status, 4) < 4) time_ms = 0; } - if ((res = read(afl->fsrv.fsrv_st_fd, &status, 4)) != 4) { + if (!time_ms) { if (afl->stop_soon) return 0; SAYF("\n" cLRD "[-] " cRST -- cgit 1.4.1 From 1e290542bb77f35d1e7bb340077f1c28c0b03b81 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 30 Mar 2020 16:46:50 +0200 Subject: rebase --- src/afl-fuzz-mutators.c | 4 ++-- test/test.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 754b2190..1a5528a2 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -193,8 +193,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (afl->mutator->afl_custom_init) - afl->mutator->data = - afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + afl->mutator->data = afl->mutator->afl_custom_init( + afl, rand_below(afl, 0xFFFFFFFF)); } diff --git a/test/test.sh b/test/test.sh index 725ae9e4..0d3c7199 100755 --- a/test/test.sh +++ b/test/test.sh @@ -895,12 +895,12 @@ test -d ../unicorn_mode/unicornafl && { $ECHO "$BLUE[*] Testing: custom mutator" unset AFL_CC # Line 474 sets AFL_CC to "gcc". We reset it to use the default compiler -CUSTOM_MUTATOR_PATH=../examples/custom_mutators +CUSTOM_MUTATOR_PATH=$( realpath ../examples/custom_mutators ) test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c && { # Compile the vulnerable program - ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c + ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1 # Compile the custom mutator - make -C ../examples/custom_mutators libexamplemutator.so + make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1 test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && { # Create input directory mkdir -p in -- cgit 1.4.1 From 0dd8ed9171cdbee3360f4b7f6a9fd91e7478a508 Mon Sep 17 00:00:00 2001 From: h1994st Date: Sat, 28 Mar 2020 00:52:29 -0400 Subject: Fix invalid memory access bug in `afl_custom_pre_save` of example.c --- examples/custom_mutators/example.c | 16 +++++++++------- src/afl-fuzz-python.c | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index a9764f5b..7d827029 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -157,15 +157,17 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, } - *out_buf = data->pre_save_buf; + uint8_t *pre_save_buf = data->pre_save_buf; - memcpy(*out_buf + 5, buf, buf_size); + memcpy(pre_save_buf + 5, buf, buf_size); size_t out_buf_size = buf_size + 5; - *out_buf[0] = 'A'; - *out_buf[1] = 'F'; - *out_buf[2] = 'L'; - *out_buf[3] = '+'; - *out_buf[4] = '+'; + pre_save_buf[0] = 'A'; + pre_save_buf[1] = 'F'; + pre_save_buf[2] = 'L'; + pre_save_buf[3] = '+'; + pre_save_buf[4] = '+'; + + *out_buf = pre_save_buf; return out_buf_size; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 91e5b084..01503d2c 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -133,8 +133,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (py_module != NULL) { u8 py_notrim = 0, py_idx; + /* init, required */ py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init"); - py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); py_functions[PY_FUNC_PRE_SAVE] = PyObject_GetAttrString(py_module, "pre_save"); @@ -151,6 +151,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); + py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { -- cgit 1.4.1 From 50fc7327f2556db588c65fe7941198b622ab50af Mon Sep 17 00:00:00 2001 From: h1994st Date: Sun, 29 Mar 2020 01:07:29 -0400 Subject: python mutator: fix nullptr for python mutator data --- include/afl-fuzz.h | 3 --- src/afl-fuzz-python.c | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index a265c1a3..fcbc09e5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -566,9 +566,6 @@ typedef struct afl_state { /* Custom mutators */ struct custom_mutator *mutator; -#ifdef USE_PYTHON - struct custom_mutator *py_mutator; -#endif /* cmplog forkserver ids */ s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 01503d2c..12c3a09d 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -303,6 +303,7 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { py_mutator_t *py_mutator; py_mutator = init_py_module(afl, module_name); + afl->mutator->data = py_mutator; if (!py_mutator) { FATAL("Failed to load python mutator."); } PyObject **py_functions = py_mutator->py_functions; -- cgit 1.4.1 From 61ea39861271fd54a193a14d3adbb72c072df75f Mon Sep 17 00:00:00 2001 From: h1994st Date: Mon, 30 Mar 2020 05:21:01 -0400 Subject: Fix heap allocation bug - Reason: `afl->out_size` is not consistent with the actual allocation of `afl->out_buf`. The deleted line in `src/afl-fuzz-one.c` may change `afl->out_size`, but `afl->out_buf` is not changed --- examples/custom_mutators/example.c | 12 ++++++------ src/afl-fuzz-one.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 7d827029..ec47104d 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -159,13 +159,13 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t *pre_save_buf = data->pre_save_buf; - memcpy(pre_save_buf + 5, buf, buf_size); + memcpy(pre_save_buf, buf, buf_size); size_t out_buf_size = buf_size + 5; - pre_save_buf[0] = 'A'; - pre_save_buf[1] = 'F'; - pre_save_buf[2] = 'L'; - pre_save_buf[3] = '+'; - pre_save_buf[4] = '+'; + pre_save_buf[buf_size + 0] = 'A'; + pre_save_buf[buf_size + 1] = 'F'; + pre_save_buf[buf_size + 2] = 'L'; + pre_save_buf[buf_size + 3] = '+'; + pre_save_buf[buf_size + 4] = '+'; *out_buf = pre_save_buf; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index b1bbad0a..29dd73ad 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1621,8 +1621,6 @@ custom_mutator_stage: if (unlikely(!mutated_buf)) FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); - if (mutated_size > len) afl->out_size = mutated_size; - if (mutated_size > 0) { if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { @@ -1650,6 +1648,8 @@ custom_mutator_stage: } out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + // ??? (h1994st): this line may be not necessary, as we do not modify the + // content of "out_buf". memcpy(out_buf, in_buf, len); } -- cgit 1.4.1 From e910c224da291300b229866ed3dea9ec47a277b3 Mon Sep 17 00:00:00 2001 From: h1994st Date: Mon, 30 Mar 2020 06:01:01 -0400 Subject: afl-fuzz-one.c: minor update --- src/afl-fuzz-one.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 29dd73ad..c61c9084 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1647,10 +1647,10 @@ custom_mutator_stage: } + /* `afl->out_buf` is actually not changed in the loop. Since `ck_maybe_grow` + is cheap, we still keep the following line but remove `memcpy`. */ out_buf = ck_maybe_grow(BUF_PARAMS(out), len); - // ??? (h1994st): this line may be not necessary, as we do not modify the - // content of "out_buf". - memcpy(out_buf, in_buf, len); + // memcpy(out_buf, in_buf, len); } -- cgit 1.4.1 From c36c34cf9e3c7f34466efbb191100b6ae699091c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 30 Mar 2020 16:38:51 +0200 Subject: fixed example --- examples/custom_mutators/example.c | 33 ++++++++++++--------------------- src/afl-fuzz-one.c | 6 ++---- 2 files changed, 14 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index ec47104d..c8200b26 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -142,34 +142,25 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { - if (data->pre_save_size < buf_size + 5) { + uint8_t *pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); + if (!pre_save_buf) { - data->pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); - if (!data->pre_save_buf) { - - perror("custom mutator realloc failed."); - *out_buf = NULL; - return 0; - - } - - data->pre_save_size = buf_size + 5; + perror("custom mutator realloc failed."); + *out_buf = NULL; + return 0; } - uint8_t *pre_save_buf = data->pre_save_buf; - - memcpy(pre_save_buf, buf, buf_size); - size_t out_buf_size = buf_size + 5; - pre_save_buf[buf_size + 0] = 'A'; - pre_save_buf[buf_size + 1] = 'F'; - pre_save_buf[buf_size + 2] = 'L'; - pre_save_buf[buf_size + 3] = '+'; - pre_save_buf[buf_size + 4] = '+'; + memcpy(pre_save_buf + 5, buf, buf_size); + pre_save_buf[0] = 'A'; + pre_save_buf[1] = 'F'; + pre_save_buf[2] = 'L'; + pre_save_buf[3] = '+'; + pre_save_buf[4] = '+'; *out_buf = pre_save_buf; - return out_buf_size; + return buf_size + 5; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c61c9084..2e49e19b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1647,10 +1647,8 @@ custom_mutator_stage: } - /* `afl->out_buf` is actually not changed in the loop. Since `ck_maybe_grow` - is cheap, we still keep the following line but remove `memcpy`. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); - // memcpy(out_buf, in_buf, len); + /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ + memcpy(out_buf, in_buf, len); } -- cgit 1.4.1 From 508230e91b5309ce7914ea0d0e274c3cc3533dd7 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 30 Mar 2020 18:38:39 +0200 Subject: code format --- src/afl-fuzz-mutators.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 1a5528a2..754b2190 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -193,8 +193,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (afl->mutator->afl_custom_init) - afl->mutator->data = afl->mutator->afl_custom_init( - afl, rand_below(afl, 0xFFFFFFFF)); + afl->mutator->data = + afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); } -- cgit 1.4.1 From 42ee300e92c0d3f7bba6f4f015353bd5ff6839c5 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 03:22:46 +0200 Subject: dropped make switches --- Makefile | 10 +- include/afl-fuzz.h | 2 +- include/common.h | 363 ++----------------------------------------------- include/list.h | 8 +- src/afl-common.c | 390 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-showmap.c | 20 --- 6 files changed, 411 insertions(+), 382 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index 6d8f857a..cbef4b7c 100644 --- a/Makefile +++ b/Makefile @@ -65,9 +65,9 @@ ifneq "$(shell uname -m)" "x86_64" endif CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -override CFLAGS += -Wall -g -Wno-pointer-sign -D_FORTIFY_SOURCE=2 -I include/ \ - -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ - -DDOC_PATH=\"$(DOC_PATH)\" -Wno-unused-function -fcommon +override CFLAGS += -Wall -g -Wno-pointer-sign -D_FORTIFY_SOURCE=2 \ + -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \ + -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) @@ -304,8 +304,8 @@ afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS) -afl-gotcpu: src/afl-gotcpu.c $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) +afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) # document all mutations and only do one run (use with only one input file!) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index fcbc09e5..e750d7c9 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -967,7 +967,7 @@ static inline u32 get_rand_seed(afl_state_t *afl) { /* Find first power of two greater or equal to val (assuming val under 2^63). */ -static u64 next_p2(u64 val) { +static inline u64 next_p2(u64 val) { u64 ret = 1; while (val > ret) diff --git a/include/common.h b/include/common.h index db102777..db92e32d 100644 --- a/include/common.h +++ b/include/common.h @@ -50,395 +50,54 @@ char * get_afl_env(char *env); /* Get unix time in milliseconds */ -static u64 get_cur_time(void) { - - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000); - -} +u64 get_cur_time(void); /* Get unix time in microseconds */ -static u64 get_cur_time_us(void) { - - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - return (tv.tv_sec * 1000000ULL) + tv.tv_usec; - -} +u64 get_cur_time_us(void); /* Describe integer. The buf should be at least 6 bytes to fit all ints we randomly see. Will return buf for convenience. */ -static u8 *stringify_int(u8 *buf, size_t len, u64 val) { -\ -#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ - do { \ - \ - if (val < (_divisor) * (_limit_mult)) { \ - \ - snprintf(buf, len, _fmt, ((_cast)val) / (_divisor)); \ - return buf; \ - \ - } \ - \ - } while (0) - - /* 0-9999 */ - CHK_FORMAT(1, 10000, "%llu", u64); - - /* 10.0k - 99.9k */ - CHK_FORMAT(1000, 99.95, "%0.01fk", double); - - /* 100k - 999k */ - CHK_FORMAT(1000, 1000, "%lluk", u64); - - /* 1.00M - 9.99M */ - CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double); - - /* 10.0M - 99.9M */ - CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double); - - /* 100M - 999M */ - CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64); - - /* 1.00G - 9.99G */ - CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double); - - /* 10.0G - 99.9G */ - CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double); - - /* 100G - 999G */ - CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64); - - /* 1.00T - 9.99G */ - CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double); - - /* 10.0T - 99.9T */ - CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double); - - /* 100T+ */ - strncpy(buf, "infty", len); - buf[len - 1] = '\0'; - - return buf; - -} +u8 *stringify_int(u8 *buf, size_t len, u64 val); /* Describe float. Similar as int. */ -static u8 *stringify_float(u8 *buf, size_t len, double val) { - - if (val < 99.995) { - - snprintf(buf, len, "%0.02f", val); - - } else if (val < 999.95) { - - snprintf(buf, len, "%0.01f", val); - - } else { - - stringify_int(buf, len, (u64)val); - - } - - return buf; - -} +u8 *stringify_float(u8 *buf, size_t len, double val); /* Describe integer as memory size. */ -static u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) { - - /* 0-9999 */ - CHK_FORMAT(1, 10000, "%llu B", u64); - - /* 10.0k - 99.9k */ - CHK_FORMAT(1024, 99.95, "%0.01f kB", double); - - /* 100k - 999k */ - CHK_FORMAT(1024, 1000, "%llu kB", u64); - - /* 1.00M - 9.99M */ - CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double); - - /* 10.0M - 99.9M */ - CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double); - - /* 100M - 999M */ - CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64); - - /* 1.00G - 9.99G */ - CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double); - - /* 10.0G - 99.9G */ - CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double); - - /* 100G - 999G */ - CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64); - - /* 1.00T - 9.99G */ - CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double); - - /* 10.0T - 99.9T */ - CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double); - -#undef CHK_FORMAT - - /* 100T+ */ - strncpy(buf, "infty", len - 1); - buf[len - 1] = '\0'; - - return buf; - -} +u8 *stringify_mem_size(u8 *buf, size_t len, u64 val); /* Describe time delta as string. Returns a pointer to buf for convenience. */ -static u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { - - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - - if (!event_ms) { - - snprintf(buf, len, "none seen yet"); - - } else { - - delta = cur_ms - event_ms; - - t_d = delta / 1000 / 60 / 60 / 24; - t_h = (delta / 1000 / 60 / 60) % 24; - t_m = (delta / 1000 / 60) % 60; - t_s = (delta / 1000) % 60; - - stringify_int(val_buf, sizeof(val_buf), t_d); - snprintf(buf, len, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, - t_s); - - } - - return buf; - -} +u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms); /* Unsafe Describe integer. The buf sizes are not checked. This is unsafe but fast. Will return buf for convenience. */ -static u8 *u_stringify_int(u8 *buf, u64 val) { -\ -#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ - do { \ - \ - if (val < (_divisor) * (_limit_mult)) { \ - \ - sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ - return buf; \ - \ - } \ - \ - } while (0) - - /* 0-9999 */ - CHK_FORMAT(1, 10000, "%llu", u64); - - /* 10.0k - 99.9k */ - CHK_FORMAT(1000, 99.95, "%0.01fk", double); - - /* 100k - 999k */ - CHK_FORMAT(1000, 1000, "%lluk", u64); - - /* 1.00M - 9.99M */ - CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double); - - /* 10.0M - 99.9M */ - CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double); - - /* 100M - 999M */ - CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64); - - /* 1.00G - 9.99G */ - CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double); - - /* 10.0G - 99.9G */ - CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double); - - /* 100G - 999G */ - CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64); - - /* 1.00T - 9.99G */ - CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double); - - /* 10.0T - 99.9T */ - CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double); - - /* 100T+ */ - strcpy(buf, "infty"); - - return buf; - -} +u8 *u_stringify_int(u8 *buf, u64 val); /* Unsafe describe float. Similar as unsafe int. */ -static u8 *u_stringify_float(u8 *buf, double val) { - - if (val < 99.995) { - - sprintf(buf, "%0.02f", val); - - } else if (val < 999.95) { - - sprintf(buf, "%0.01f", val); - - } else { - - return u_stringify_int(buf, (u64)val); - - } - - return buf; - -} +u8 *u_stringify_float(u8 *buf, double val); /* Unsafe describe integer as memory size. */ -static u8 *u_stringify_mem_size(u8 *buf, u64 val) { - - /* 0-9999 */ - CHK_FORMAT(1, 10000, "%llu B", u64); - - /* 10.0k - 99.9k */ - CHK_FORMAT(1024, 99.95, "%0.01f kB", double); - - /* 100k - 999k */ - CHK_FORMAT(1024, 1000, "%llu kB", u64); - - /* 1.00M - 9.99M */ - CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double); - - /* 10.0M - 99.9M */ - CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double); - - /* 100M - 999M */ - CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64); - - /* 1.00G - 9.99G */ - CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double); - - /* 10.0G - 99.9G */ - CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double); - - /* 100G - 999G */ - CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64); - - /* 1.00T - 9.99G */ - CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double); - - /* 10.0T - 99.9T */ - CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double); - -#undef CHK_FORMAT - - /* 100T+ */ - strcpy(buf, "infty"); - - return buf; - -} +u8 *u_stringify_mem_size(u8 *buf, u64 val); /* Unsafe describe time delta as string. Returns a pointer to buf for convenience. */ -static u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { - - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - - if (!event_ms) { - - sprintf(buf, "none seen yet"); - - } else { - - delta = cur_ms - event_ms; - - t_d = delta / 1000 / 60 / 60 / 24; - t_h = (delta / 1000 / 60 / 60) % 24; - t_m = (delta / 1000 / 60) % 60; - t_s = (delta / 1000) % 60; - - u_stringify_int(val_buf, t_d); - sprintf(buf, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, t_s); - - } - - return buf; - -} +u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms); /* Wrapper for select() and read(), reading exactly len bytes. Returns the time passed to read. If the wait times out, returns timeout_ms + 1; Returns 0 if an error occurred (fd closed, signal, ...); */ -static inline u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { - - struct timeval timeout; - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - - timeout.tv_sec = (timeout_ms / 1000); - timeout.tv_usec = (timeout_ms % 1000) * 1000; - - size_t read_total = 0; - size_t len_read = 0; - - while (len_read < len) { - - /* set exceptfds as well to return when a child exited/closed the pipe. */ - int sret = select(fd + 1, &readfds, NULL, NULL, &timeout); - - if (!sret) { - - // printf("Timeout in sret."); - return timeout_ms + 1; - - } else if (sret < 0) { - - // perror("sret malloc"); - // TODO: catch other (errno == EINTR) than ctrl+c? - return 0; - - } - - len_read = read(fd, ((u8 *)buf) + len_read, len - len_read); - if (!len_read) { return 0; } - read_total += len_read; - - } - - s32 exec_ms = - MIN(timeout_ms, - ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000))); - return exec_ms > 0 ? exec_ms - : 1; // at least 1 milli must have passed (0 is an error) - -} +u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms); #endif - diff --git a/include/list.h b/include/list.h index 25ee8282..c67b24b2 100644 --- a/include/list.h +++ b/include/list.h @@ -60,13 +60,13 @@ static inline element_t *get_head(list_t *list) { } -static void list_free_el(list_t *list, element_t *el) { +static inline void list_free_el(list_t *list, element_t *el) { PRE_FREE(el, list->element_prealloc_count); } -static void list_append(list_t *list, void *el) { +static inline void list_append(list_t *list, void *el) { element_t *head = get_head(list); if (!head->next) { @@ -143,7 +143,7 @@ static void list_append(list_t *list, void *el) { /* remove an item from the list */ -static void list_remove(list_t *list, void *remove_me) { +static inline void list_remove(list_t *list, void *remove_me) { LIST_FOREACH(list, void, { @@ -165,7 +165,7 @@ static void list_remove(list_t *list, void *remove_me) { /* Returns true if el is in list */ -static bool list_contains(list_t *list, void *contains_me) { +static inline bool list_contains(list_t *list, void *contains_me) { LIST_FOREACH(list, void, { diff --git a/src/afl-common.c b/src/afl-common.c index e10de6b3..785d7c4c 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -30,6 +30,7 @@ #include "debug.h" #include "alloc-inl.h" #include "envs.h" +#include "common.h" /* Detect @@ in args. */ #ifndef __glibc__ @@ -393,3 +394,392 @@ char *get_afl_env(char *env) { } +u64 get_cur_time(void) { + + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000); + +} + +/* Get unix time in microseconds */ + +u64 get_cur_time_us(void) { + + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return (tv.tv_sec * 1000000ULL) + tv.tv_usec; + +} + +/* Describe integer. The buf should be + at least 6 bytes to fit all ints we randomly see. + Will return buf for convenience. */ + +u8 *stringify_int(u8 *buf, size_t len, u64 val) { + +#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ + do { \ + \ + if (val < (_divisor) * (_limit_mult)) { \ + \ + snprintf(buf, len, _fmt, ((_cast)val) / (_divisor)); \ + return buf; \ + \ + } \ + \ + } while (0) + + /* 0-9999 */ + CHK_FORMAT(1, 10000, "%llu", u64); + + /* 10.0k - 99.9k */ + CHK_FORMAT(1000, 99.95, "%0.01fk", double); + + /* 100k - 999k */ + CHK_FORMAT(1000, 1000, "%lluk", u64); + + /* 1.00M - 9.99M */ + CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double); + + /* 10.0M - 99.9M */ + CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double); + + /* 100M - 999M */ + CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64); + + /* 1.00G - 9.99G */ + CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double); + + /* 10.0G - 99.9G */ + CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double); + + /* 100G - 999G */ + CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64); + + /* 1.00T - 9.99G */ + CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double); + + /* 10.0T - 99.9T */ + CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double); + + /* 100T+ */ + strncpy(buf, "infty", len); + buf[len - 1] = '\0'; + + return buf; + +} + +/* Describe float. Similar as int. */ + +u8 *stringify_float(u8 *buf, size_t len, double val) { + + if (val < 99.995) { + + snprintf(buf, len, "%0.02f", val); + + } else if (val < 999.95) { + + snprintf(buf, len, "%0.01f", val); + + } else { + + stringify_int(buf, len, (u64)val); + + } + + return buf; + +} + +/* Describe integer as memory size. */ + +u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) { + + /* 0-9999 */ + CHK_FORMAT(1, 10000, "%llu B", u64); + + /* 10.0k - 99.9k */ + CHK_FORMAT(1024, 99.95, "%0.01f kB", double); + + /* 100k - 999k */ + CHK_FORMAT(1024, 1000, "%llu kB", u64); + + /* 1.00M - 9.99M */ + CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double); + + /* 10.0M - 99.9M */ + CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double); + + /* 100M - 999M */ + CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64); + + /* 1.00G - 9.99G */ + CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double); + + /* 10.0G - 99.9G */ + CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double); + + /* 100G - 999G */ + CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64); + + /* 1.00T - 9.99G */ + CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double); + + /* 10.0T - 99.9T */ + CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double); + +#undef CHK_FORMAT + + /* 100T+ */ + strncpy(buf, "infty", len - 1); + buf[len - 1] = '\0'; + + return buf; + +} + +/* Describe time delta as string. + Returns a pointer to buf for convenience. */ + +u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { + + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + + if (!event_ms) { + + snprintf(buf, len, "none seen yet"); + + } else { + + delta = cur_ms - event_ms; + + t_d = delta / 1000 / 60 / 60 / 24; + t_h = (delta / 1000 / 60 / 60) % 24; + t_m = (delta / 1000 / 60) % 60; + t_s = (delta / 1000) % 60; + + stringify_int(val_buf, sizeof(val_buf), t_d); + snprintf(buf, len, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, + t_s); + + } + + return buf; + +} + +/* Unsafe Describe integer. The buf sizes are not checked. + This is unsafe but fast. + Will return buf for convenience. */ + +u8 *u_stringify_int(u8 *buf, u64 val) { + +#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ + do { \ + \ + if (val < (_divisor) * (_limit_mult)) { \ + \ + sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ + return buf; \ + \ + } \ + \ + } while (0) + + /* 0-9999 */ + CHK_FORMAT(1, 10000, "%llu", u64); + + /* 10.0k - 99.9k */ + CHK_FORMAT(1000, 99.95, "%0.01fk", double); + + /* 100k - 999k */ + CHK_FORMAT(1000, 1000, "%lluk", u64); + + /* 1.00M - 9.99M */ + CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double); + + /* 10.0M - 99.9M */ + CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double); + + /* 100M - 999M */ + CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64); + + /* 1.00G - 9.99G */ + CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double); + + /* 10.0G - 99.9G */ + CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double); + + /* 100G - 999G */ + CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64); + + /* 1.00T - 9.99G */ + CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double); + + /* 10.0T - 99.9T */ + CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double); + + /* 100T+ */ + strcpy(buf, "infty"); + + return buf; + +} + +/* Unsafe describe float. Similar as unsafe int. */ + +u8 *u_stringify_float(u8 *buf, double val) { + + if (val < 99.995) { + + sprintf(buf, "%0.02f", val); + + } else if (val < 999.95) { + + sprintf(buf, "%0.01f", val); + + } else { + + return u_stringify_int(buf, (u64)val); + + } + + return buf; + +} + +/* Unsafe describe integer as memory size. */ + +u8 *u_stringify_mem_size(u8 *buf, u64 val) { + + /* 0-9999 */ + CHK_FORMAT(1, 10000, "%llu B", u64); + + /* 10.0k - 99.9k */ + CHK_FORMAT(1024, 99.95, "%0.01f kB", double); + + /* 100k - 999k */ + CHK_FORMAT(1024, 1000, "%llu kB", u64); + + /* 1.00M - 9.99M */ + CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double); + + /* 10.0M - 99.9M */ + CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double); + + /* 100M - 999M */ + CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64); + + /* 1.00G - 9.99G */ + CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double); + + /* 10.0G - 99.9G */ + CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double); + + /* 100G - 999G */ + CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64); + + /* 1.00T - 9.99G */ + CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double); + + /* 10.0T - 99.9T */ + CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double); + +#undef CHK_FORMAT + + /* 100T+ */ + strcpy(buf, "infty"); + + return buf; + +} + +/* Unsafe describe time delta as string. + Returns a pointer to buf for convenience. */ + +u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { + + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + + if (!event_ms) { + + sprintf(buf, "none seen yet"); + + } else { + + delta = cur_ms - event_ms; + + t_d = delta / 1000 / 60 / 60 / 24; + t_h = (delta / 1000 / 60 / 60) % 24; + t_m = (delta / 1000 / 60) % 60; + t_s = (delta / 1000) % 60; + + u_stringify_int(val_buf, t_d); + sprintf(buf, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, t_s); + + } + + return buf; + +} + +/* Wrapper for select() and read(), reading exactly len bytes. + Returns the time passed to read. + If the wait times out, returns timeout_ms + 1; + Returns 0 if an error occurred (fd closed, signal, ...); */ +u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { + + struct timeval timeout; + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + timeout.tv_sec = (timeout_ms / 1000); + timeout.tv_usec = (timeout_ms % 1000) * 1000; + + size_t read_total = 0; + size_t len_read = 0; + + while (len_read < len) { + + /* set exceptfds as well to return when a child exited/closed the pipe. */ + int sret = select(fd + 1, &readfds, NULL, NULL, &timeout); + + if (!sret) { + + // printf("Timeout in sret."); + return timeout_ms + 1; + + } else if (sret < 0) { + + // perror("sret malloc"); + // TODO: catch other (errno == EINTR) than ctrl+c? + return 0; + + } + + len_read = read(fd, ((u8 *)buf) + len_read, len - len_read); + if (!len_read) { return 0; } + read_total += len_read; + + } + + s32 exec_ms = + MIN(timeout_ms, + ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000))); + return exec_ms > 0 ? exec_ms + : 1; // at least 1 milli must have passed (0 is an error) + +} diff --git a/src/afl-showmap.c b/src/afl-showmap.c index caacefe4..eaab5c31 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -224,26 +224,6 @@ static u32 write_results(afl_forkserver_t *fsrv) { } -/* Write output file. */ - -static s32 write_to_file(u8 *path, u8 *mem, u32 len) { - - s32 ret; - - unlink(path); /* Ignore errors */ - - ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600); - - if (ret < 0) PFATAL("Unable to create '%s'", path); - - ck_write(ret, mem, len, path); - - lseek(ret, 0, SEEK_SET); - - return ret; - -} - /* Write modified data to file for testing. If use_stdin is clear, the old file is unlinked and a new one is created. Otherwise, out_fd is rewound and truncated. */ -- cgit 1.4.1 From 5bc6dccbbd6167b556af751755f0ae02c1ca2a8f Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 03:41:51 +0200 Subject: src doku is now markdown --- Makefile | 2 +- docs/Changelog.md | 5 +- include/common.h | 1 + qbdi_mode/build.sh | 2 +- src/README.md | 24 ++++ src/README.src | 22 --- src/afl-common.c | 5 +- src/afl-fuzz-globals.c | 364 ------------------------------------------------- src/afl-fuzz-state.c | 364 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 397 insertions(+), 392 deletions(-) create mode 100644 src/README.md delete mode 100644 src/README.src delete mode 100644 src/afl-fuzz-globals.c create mode 100644 src/afl-fuzz-state.c (limited to 'src') diff --git a/Makefile b/Makefile index cbef4b7c..b45cf9d3 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ endif CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) override CFLAGS += -Wall -g -Wno-pointer-sign -D_FORTIFY_SOURCE=2 \ - -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \ + -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) diff --git a/docs/Changelog.md b/docs/Changelog.md index 407a3324..1b97812c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -23,7 +23,8 @@ sending a mail to . - force all output to stdout (some OK/SAY/WARN messages were sent to stdout, some to stderr) - uninstrumented mode uses an internal forkserver ("fauxserver") - - reduced number of (de)allocations + - now builds with `-D_FORTIFY_SOURCE=2` + - drastically reduced number of (de)allocations during fuzzing - afl-fuzz: - python mutator modules and custom mutator modules now use the same interface and hence the API changed @@ -205,7 +206,7 @@ sending a mail to . - big code refactoring: * all includes are now in include/ - * all afl sources are now in src/ - see src/README.src + * all afl sources are now in src/ - see src/README.md * afl-fuzz was splitted up in various individual files for including functionality in other programs (e.g. forkserver, memory map, etc.) for better readability. diff --git a/include/common.h b/include/common.h index db92e32d..c26740ed 100644 --- a/include/common.h +++ b/include/common.h @@ -101,3 +101,4 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms); u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms); #endif + diff --git a/qbdi_mode/build.sh b/qbdi_mode/build.sh index c2912e94..e3786f40 100755 --- a/qbdi_mode/build.sh +++ b/qbdi_mode/build.sh @@ -52,6 +52,6 @@ ${compiler_prefix}${CC} -shared -o libdemo.so demo-so.c -w -g echo "[+] Building afl-fuzz for Android" # build afl-fuzz cd .. -${compiler_prefix}${CC} -DANDROID_DISABLE_FANCY=1 -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I include/ -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DDOC_PATH=\"/usr/local/share/doc/afl\" -Wno-unused-function src/afl-fuzz-misc.c src/afl-fuzz-extras.c src/afl-fuzz-queue.c src/afl-fuzz-one.c src/afl-fuzz-python.c src/afl-fuzz-stats.c src/afl-fuzz-init.c src/afl-fuzz.c src/afl-fuzz-bitmap.c src/afl-fuzz-run.c src/afl-fuzz-globals.c src/afl-common.c src/afl-sharedmem.c src/afl-forkserver.c -o qbdi_mode/afl-fuzz -ldl -w +${compiler_prefix}${CC} -DANDROID_DISABLE_FANCY=1 -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I include/ -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DDOC_PATH=\"/usr/local/share/doc/afl\" -Wno-unused-function src/afl-fuzz-misc.c src/afl-fuzz-extras.c src/afl-fuzz-queue.c src/afl-fuzz-one.c src/afl-fuzz-python.c src/afl-fuzz-stats.c src/afl-fuzz-init.c src/afl-fuzz.c src/afl-fuzz-bitmap.c src/afl-fuzz-run.c src/afl-fuzz-state.c src/afl-common.c src/afl-sharedmem.c src/afl-forkserver.c -o qbdi_mode/afl-fuzz -ldl -w echo "[+] All done. Enjoy!" diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..6da534c3 --- /dev/null +++ b/src/README.md @@ -0,0 +1,24 @@ +# Source Folder + +Quick explanation about the files here: + +- `afl-analyze.c` - afl-analyze binary tool +- `afl-as.c` - afl-as binary tool +- `afl-gotcpu.c` - afl-gotcpu binary tool +- `afl-showmap.c` - afl-showmap binary tool +- `afl-tmin.c` - afl-tmin binary tool +- `afl-fuzz.c` - afl-fuzz binary tool (just main() and usage()) +- `afl-fuzz-bitmap.c` - afl-fuzz bitmap handling +- `afl-fuzz-extras.c` - afl-fuzz the *extra* function calls +- `afl-fuzz-state.c` - afl-fuzz state and globals +- `afl-fuzz-init.c` - afl-fuzz initialization +- `afl-fuzz-misc.c` - afl-fuzz misc functions +- `afl-fuzz-one.c` - afl-fuzz fuzzer_one big loop, this is where the mutation is happening +- `afl-fuzz-python.c` - afl-fuzz the python mutator extension +- `afl-fuzz-queue.c` - afl-fuzz handling the queue +- `afl-fuzz-run.c` - afl-fuzz running the target +- `afl-fuzz-stats.c` - afl-fuzz writing the statistics file +- `afl-gcc.c` - afl-gcc binary tool (deprecated) +- `afl-common.c` - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin +- `afl-forkserver.c` - forkserver implementation, used by afl-fuzz and afl-tmin +afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin diff --git a/src/README.src b/src/README.src deleted file mode 100644 index 244f5ddd..00000000 --- a/src/README.src +++ /dev/null @@ -1,22 +0,0 @@ -Quick explanation about the files here: - -afl-analyze.c - afl-analyze binary tool -afl-as.c - afl-as binary tool -afl-gotcpu.c - afl-gotcpu binary tool -afl-showmap.c - afl-showmap binary tool -afl-tmin.c - afl-tmin binary tool -afl-fuzz.c - afl-fuzz binary tool (just main() and usage()) -afl-fuzz-bitmap.c - afl-fuzz bitmap handling -afl-fuzz-extras.c - afl-fuzz the *extra* function calls -afl-fuzz-globals.c - afl-fuzz global variables -afl-fuzz-init.c - afl-fuzz initialization -afl-fuzz-misc.c - afl-fuzz misc functions -afl-fuzz-one.c - afl-fuzz fuzzer_one big loop, this is where the mutation is happening -afl-fuzz-python.c - afl-fuzz the python mutator extension -afl-fuzz-queue.c - afl-fuzz handling the queue -afl-fuzz-run.c - afl-fuzz running the target -afl-fuzz-stats.c - afl-fuzz writing the statistics file -afl-gcc.c - afl-gcc binary tool (deprecated) -afl-common.c - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin -afl-forkserver.c - forkserver implementation, used by afl-fuzz and afl-tmin -afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin diff --git a/src/afl-common.c b/src/afl-common.c index 785d7c4c..c73d8725 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -423,7 +423,7 @@ u64 get_cur_time_us(void) { Will return buf for convenience. */ u8 *stringify_int(u8 *buf, size_t len, u64 val) { - +\ #define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ do { \ \ @@ -583,7 +583,7 @@ u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { Will return buf for convenience. */ u8 *u_stringify_int(u8 *buf, u64 val) { - +\ #define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ do { \ \ @@ -783,3 +783,4 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { : 1; // at least 1 milli must have passed (0 is an error) } + diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c deleted file mode 100644 index 1d99e1fa..00000000 --- a/src/afl-fuzz-globals.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - american fuzzy lop++ - globals declarations - ------------------------------------------- - - Originally written by Michal Zalewski - - Now maintained by Marc Heuse , - Heiko Eißfeldt and - Andrea Fioraldi - - Copyright 2016, 2017 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 is the real deal: the program takes an instrumented binary and - attempts a variety of basic fuzzing tricks, paying close attention to - how they affect the execution path. - - */ - -#include "afl-fuzz.h" -#include "envs.h" - -s8 interesting_8[] = {INTERESTING_8}; -s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; -s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; - -char *power_names[POWER_SCHEDULES_NUM] = { - - "explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"}; - -u8 *doc_path = NULL; /* gath to documentation dir */ - -/* Initialize MOpt "globals" for this afl state */ - -static void init_mopt_globals(afl_state_t *afl) { - - MOpt_globals_t *core = &afl->mopt_globals_core; - core->finds = afl->core_operator_finds_puppet; - core->finds_v2 = afl->core_operator_finds_puppet_v2; - core->cycles = afl->core_operator_cycles_puppet; - core->cycles_v2 = afl->core_operator_cycles_puppet_v2; - core->cycles_v3 = afl->core_operator_cycles_puppet_v3; - core->is_pilot_mode = 0; - core->pTime = &afl->tmp_core_time; - core->period = period_core; - core->havoc_stagename = "MOpt-core-havoc"; - core->splice_stageformat = "MOpt-core-splice %u"; - core->havoc_stagenameshort = "MOpt_core_havoc"; - core->splice_stagenameshort = "MOpt_core_splice"; - - MOpt_globals_t *pilot = &afl->mopt_globals_pilot; - pilot->finds = afl->stage_finds_puppet[0]; - pilot->finds_v2 = afl->stage_finds_puppet_v2[0]; - pilot->cycles = afl->stage_cycles_puppet[0]; - pilot->cycles_v2 = afl->stage_cycles_puppet_v2[0]; - pilot->cycles_v3 = afl->stage_cycles_puppet_v3[0]; - pilot->is_pilot_mode = 1; - pilot->pTime = &afl->tmp_pilot_time; - pilot->period = period_pilot; - pilot->havoc_stagename = "MOpt-havoc"; - pilot->splice_stageformat = "MOpt-splice %u"; - pilot->havoc_stagenameshort = "MOpt_havoc"; - pilot->splice_stagenameshort = "MOpt_splice"; - -} - -/* A global pointer to all instances is needed (for now) for signals to arrive - */ - -list_t afl_states = {.element_prealloc_count = 0}; - -/* Initializes an afl_state_t. */ - -void afl_state_init(afl_state_t *afl) { - - /* thanks to this memset, growing vars like out_buf - and out_size are NULL/0 by default. */ - memset(afl, 0, sizeof(afl_state_t)); - - afl->w_init = 0.9; - afl->w_end = 0.3; - afl->g_max = 5000; - afl->period_pilot_tmp = 5000.0; - afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ - afl->havoc_max_mult = HAVOC_MAX_MULT; - - afl->clear_screen = 1; /* Window resized? */ - afl->havoc_div = 1; /* Cycle count divisor for havoc */ - afl->stage_name = "init"; /* Name of the current fuzz stage */ - afl->splicing_with = -1; /* Splicing with which test case? */ - -#ifdef HAVE_AFFINITY - afl->cpu_aff = -1; /* Selected CPU core */ -#endif /* HAVE_AFFINITY */ - - afl->fsrv.use_stdin = 1; - - afl->cal_cycles = CAL_CYCLES; - afl->cal_cycles_long = CAL_CYCLES_LONG; - - afl->fsrv.exec_tmout = EXEC_TIMEOUT; - afl->hang_tmout = EXEC_TIMEOUT; - - afl->fsrv.mem_limit = MEM_LIMIT; - - afl->stats_update_freq = 1; - -#ifndef HAVE_ARC4RANDOM - afl->fsrv.dev_urandom_fd = -1; -#endif - afl->fsrv.dev_null_fd = -1; - - afl->fsrv.child_pid = -1; - afl->fsrv.out_dir_fd = -1; - - afl->cmplog_prev_timed_out = 0; - - /* statis file */ - afl->last_bitmap_cvg = 0; - afl->last_stability = 0; - afl->last_eps = 0; - - /* plot file saves from last run */ - afl->plot_prev_qp = 0; - afl->plot_prev_pf = 0; - afl->plot_prev_pnf = 0; - afl->plot_prev_ce = 0; - afl->plot_prev_md = 0; - afl->plot_prev_qc = 0; - afl->plot_prev_uc = 0; - afl->plot_prev_uh = 0; - - afl->stats_last_stats_ms = 0; - afl->stats_last_plot_ms = 0; - afl->stats_last_ms = 0; - afl->stats_last_execs = 0; - afl->stats_avg_exec = -1; - - init_mopt_globals(afl); - - list_append(&afl_states, afl); - -} - -/*This sets up the environment variables for afl-fuzz into the afl_state - * struct*/ - -void read_afl_environment(afl_state_t *afl, char **envp) { - - int index = 0, found = 0; - char *env; - while ((env = envp[index++]) != NULL) { - - if (strncmp(env, "ALF_", 4) == 0) { - - WARNF("Potentially mistyped AFL environment variable: %s", env); - found++; - - } else if (strncmp(env, "AFL_", 4) == 0) { - - int i = 0, match = 0; - while (match == 0 && afl_environment_variables[i] != NULL) { - - size_t afl_environment_variable_len = - strlen(afl_environment_variables[i]); - if (strncmp(env, afl_environment_variables[i], - afl_environment_variable_len) == 0 && - env[afl_environment_variable_len] == '=') { - - match = 1; - if (!strncmp(env, "AFL_SKIP_CPUFREQ", afl_environment_variable_len)) { - - afl->afl_env.afl_skip_cpufreq = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_EXIT_WHEN_DONE", - - afl_environment_variable_len)) { - - afl->afl_env.afl_exit_when_done = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_NO_AFFINITY", - - afl_environment_variable_len)) { - - afl->afl_env.afl_no_affinity = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_SKIP_CRASHES", - - afl_environment_variable_len)) { - - afl->afl_env.afl_skip_crashes = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_HANG_TMOUT", - - afl_environment_variable_len)) { - - afl->afl_env.afl_hang_tmout = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_SKIP_BIN_CHECK", - - afl_environment_variable_len)) { - - afl->afl_env.afl_skip_bin_check = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_DUMB_FORKSRV", - - afl_environment_variable_len)) { - - afl->afl_env.afl_dumb_forksrv = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_IMPORT_FIRST", - - afl_environment_variable_len)) { - - afl->afl_env.afl_import_first = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY", - - afl_environment_variable_len)) { - - afl->afl_env.afl_custom_mutator_only = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_NO_UI", afl_environment_variable_len)) { - - afl->afl_env.afl_no_ui = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_FORCE_UI", - - afl_environment_variable_len)) { - - afl->afl_env.afl_force_ui = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", - - afl_environment_variable_len)) { - - afl->afl_env.afl_i_dont_care_about_missing_crashes = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_BENCH_JUST_ONE", - - afl_environment_variable_len)) { - - afl->afl_env.afl_bench_just_one = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_BENCH_UNTIL_CRASH", - - afl_environment_variable_len)) { - - afl->afl_env.afl_bench_until_crash = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", - - afl_environment_variable_len)) { - - afl->afl_env.afl_debug_child_output = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_AUTORESUME", - - afl_environment_variable_len)) { - - afl->afl_env.afl_autoresume = - get_afl_env(afl_environment_variables[i]) ? 1 : 0; - - } else if (!strncmp(env, "AFL_TMPDIR", - - afl_environment_variable_len)) { - - afl->afl_env.afl_tmpdir = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_POST_LIBRARY", - - afl_environment_variable_len)) { - - afl->afl_env.afl_post_library = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LIBRARY", - - afl_environment_variable_len)) { - - afl->afl_env.afl_custom_mutator_library = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_PYTHON_MODULE", - - afl_environment_variable_len)) { - - afl->afl_env.afl_python_module = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_PATH", afl_environment_variable_len)) { - - afl->afl_env.afl_path = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } else if (!strncmp(env, "AFL_PRELOAD", - - afl_environment_variable_len)) { - - afl->afl_env.afl_preload = - (u8 *)get_afl_env(afl_environment_variables[i]); - - } - - } else - - i++; - - } - - if (match == 0) { - - WARNF("Mistyped AFL environment variable: %s", env); - found++; - - } - - } - - } - - if (found) sleep(2); - -} - -/* Removes this afl_state instance and frees it. */ - -void afl_state_deinit(afl_state_t *afl) { - - if (afl->post_deinit) afl->post_deinit(afl->post_data); - - free(afl->out_buf); - free(afl->out_scratch_buf); - free(afl->eff_buf); - free(afl->in_buf); - free(afl->in_scratch_buf); - free(afl->ex_buf); - - list_remove(&afl_states, afl); - -} - diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c new file mode 100644 index 00000000..1d99e1fa --- /dev/null +++ b/src/afl-fuzz-state.c @@ -0,0 +1,364 @@ +/* + american fuzzy lop++ - globals declarations + ------------------------------------------- + + Originally written by Michal Zalewski + + Now maintained by Marc Heuse , + Heiko Eißfeldt and + Andrea Fioraldi + + Copyright 2016, 2017 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 is the real deal: the program takes an instrumented binary and + attempts a variety of basic fuzzing tricks, paying close attention to + how they affect the execution path. + + */ + +#include "afl-fuzz.h" +#include "envs.h" + +s8 interesting_8[] = {INTERESTING_8}; +s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; +s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; + +char *power_names[POWER_SCHEDULES_NUM] = { + + "explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"}; + +u8 *doc_path = NULL; /* gath to documentation dir */ + +/* Initialize MOpt "globals" for this afl state */ + +static void init_mopt_globals(afl_state_t *afl) { + + MOpt_globals_t *core = &afl->mopt_globals_core; + core->finds = afl->core_operator_finds_puppet; + core->finds_v2 = afl->core_operator_finds_puppet_v2; + core->cycles = afl->core_operator_cycles_puppet; + core->cycles_v2 = afl->core_operator_cycles_puppet_v2; + core->cycles_v3 = afl->core_operator_cycles_puppet_v3; + core->is_pilot_mode = 0; + core->pTime = &afl->tmp_core_time; + core->period = period_core; + core->havoc_stagename = "MOpt-core-havoc"; + core->splice_stageformat = "MOpt-core-splice %u"; + core->havoc_stagenameshort = "MOpt_core_havoc"; + core->splice_stagenameshort = "MOpt_core_splice"; + + MOpt_globals_t *pilot = &afl->mopt_globals_pilot; + pilot->finds = afl->stage_finds_puppet[0]; + pilot->finds_v2 = afl->stage_finds_puppet_v2[0]; + pilot->cycles = afl->stage_cycles_puppet[0]; + pilot->cycles_v2 = afl->stage_cycles_puppet_v2[0]; + pilot->cycles_v3 = afl->stage_cycles_puppet_v3[0]; + pilot->is_pilot_mode = 1; + pilot->pTime = &afl->tmp_pilot_time; + pilot->period = period_pilot; + pilot->havoc_stagename = "MOpt-havoc"; + pilot->splice_stageformat = "MOpt-splice %u"; + pilot->havoc_stagenameshort = "MOpt_havoc"; + pilot->splice_stagenameshort = "MOpt_splice"; + +} + +/* A global pointer to all instances is needed (for now) for signals to arrive + */ + +list_t afl_states = {.element_prealloc_count = 0}; + +/* Initializes an afl_state_t. */ + +void afl_state_init(afl_state_t *afl) { + + /* thanks to this memset, growing vars like out_buf + and out_size are NULL/0 by default. */ + memset(afl, 0, sizeof(afl_state_t)); + + afl->w_init = 0.9; + afl->w_end = 0.3; + afl->g_max = 5000; + afl->period_pilot_tmp = 5000.0; + afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ + afl->havoc_max_mult = HAVOC_MAX_MULT; + + afl->clear_screen = 1; /* Window resized? */ + afl->havoc_div = 1; /* Cycle count divisor for havoc */ + afl->stage_name = "init"; /* Name of the current fuzz stage */ + afl->splicing_with = -1; /* Splicing with which test case? */ + +#ifdef HAVE_AFFINITY + afl->cpu_aff = -1; /* Selected CPU core */ +#endif /* HAVE_AFFINITY */ + + afl->fsrv.use_stdin = 1; + + afl->cal_cycles = CAL_CYCLES; + afl->cal_cycles_long = CAL_CYCLES_LONG; + + afl->fsrv.exec_tmout = EXEC_TIMEOUT; + afl->hang_tmout = EXEC_TIMEOUT; + + afl->fsrv.mem_limit = MEM_LIMIT; + + afl->stats_update_freq = 1; + +#ifndef HAVE_ARC4RANDOM + afl->fsrv.dev_urandom_fd = -1; +#endif + afl->fsrv.dev_null_fd = -1; + + afl->fsrv.child_pid = -1; + afl->fsrv.out_dir_fd = -1; + + afl->cmplog_prev_timed_out = 0; + + /* statis file */ + afl->last_bitmap_cvg = 0; + afl->last_stability = 0; + afl->last_eps = 0; + + /* plot file saves from last run */ + afl->plot_prev_qp = 0; + afl->plot_prev_pf = 0; + afl->plot_prev_pnf = 0; + afl->plot_prev_ce = 0; + afl->plot_prev_md = 0; + afl->plot_prev_qc = 0; + afl->plot_prev_uc = 0; + afl->plot_prev_uh = 0; + + afl->stats_last_stats_ms = 0; + afl->stats_last_plot_ms = 0; + afl->stats_last_ms = 0; + afl->stats_last_execs = 0; + afl->stats_avg_exec = -1; + + init_mopt_globals(afl); + + list_append(&afl_states, afl); + +} + +/*This sets up the environment variables for afl-fuzz into the afl_state + * struct*/ + +void read_afl_environment(afl_state_t *afl, char **envp) { + + int index = 0, found = 0; + char *env; + while ((env = envp[index++]) != NULL) { + + if (strncmp(env, "ALF_", 4) == 0) { + + WARNF("Potentially mistyped AFL environment variable: %s", env); + found++; + + } else if (strncmp(env, "AFL_", 4) == 0) { + + int i = 0, match = 0; + while (match == 0 && afl_environment_variables[i] != NULL) { + + size_t afl_environment_variable_len = + strlen(afl_environment_variables[i]); + if (strncmp(env, afl_environment_variables[i], + afl_environment_variable_len) == 0 && + env[afl_environment_variable_len] == '=') { + + match = 1; + if (!strncmp(env, "AFL_SKIP_CPUFREQ", afl_environment_variable_len)) { + + afl->afl_env.afl_skip_cpufreq = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_EXIT_WHEN_DONE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_exit_when_done = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_NO_AFFINITY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_no_affinity = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_SKIP_CRASHES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_skip_crashes = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_HANG_TMOUT", + + afl_environment_variable_len)) { + + afl->afl_env.afl_hang_tmout = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_SKIP_BIN_CHECK", + + afl_environment_variable_len)) { + + afl->afl_env.afl_skip_bin_check = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_DUMB_FORKSRV", + + afl_environment_variable_len)) { + + afl->afl_env.afl_dumb_forksrv = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_IMPORT_FIRST", + + afl_environment_variable_len)) { + + afl->afl_env.afl_import_first = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_custom_mutator_only = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_NO_UI", afl_environment_variable_len)) { + + afl->afl_env.afl_no_ui = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_FORCE_UI", + + afl_environment_variable_len)) { + + afl->afl_env.afl_force_ui = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_i_dont_care_about_missing_crashes = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_BENCH_JUST_ONE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_bench_just_one = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_BENCH_UNTIL_CRASH", + + afl_environment_variable_len)) { + + afl->afl_env.afl_bench_until_crash = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", + + afl_environment_variable_len)) { + + afl->afl_env.afl_debug_child_output = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_AUTORESUME", + + afl_environment_variable_len)) { + + afl->afl_env.afl_autoresume = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + + } else if (!strncmp(env, "AFL_TMPDIR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_tmpdir = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_POST_LIBRARY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_post_library = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LIBRARY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_custom_mutator_library = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_PYTHON_MODULE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_python_module = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_PATH", afl_environment_variable_len)) { + + afl->afl_env.afl_path = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_PRELOAD", + + afl_environment_variable_len)) { + + afl->afl_env.afl_preload = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } + + } else + + i++; + + } + + if (match == 0) { + + WARNF("Mistyped AFL environment variable: %s", env); + found++; + + } + + } + + } + + if (found) sleep(2); + +} + +/* Removes this afl_state instance and frees it. */ + +void afl_state_deinit(afl_state_t *afl) { + + if (afl->post_deinit) afl->post_deinit(afl->post_data); + + free(afl->out_buf); + free(afl->out_scratch_buf); + free(afl->eff_buf); + free(afl->in_buf); + free(afl->in_scratch_buf); + free(afl->ex_buf); + + list_remove(&afl_states, afl); + +} + -- cgit 1.4.1 From 5a4d4ad7360875fea9efb330a55afe4771e1a428 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 04:22:22 +0200 Subject: fixed bug in cmplog --- include/afl-fuzz.h | 14 +++++++------- src/afl-fuzz-cmplog.c | 16 ++++++++-------- src/afl-fuzz-run.c | 10 +++++----- src/afl-fuzz-stats.c | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e750d7c9..47aad5af 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -484,11 +484,6 @@ typedef struct afl_state { unique_tmouts, /* Timeouts with unique signatures */ unique_hangs, /* Hangs with unique signatures */ total_execs, /* Total execve() calls */ - slowest_exec_ms, /* Slowest testcase non hang in ms */ - start_time, /* Unix start time (ms) */ - last_path_time, /* Time for most recent path (ms) */ - last_crash_time, /* Time for most recent crash (ms) */ - last_hang_time, /* Time for most recent hang (ms) */ last_crash_execs, /* Exec counter at last crash */ queue_cycle, /* Queue round counter */ cycles_wo_finds, /* Cycles without any new paths */ @@ -496,9 +491,14 @@ typedef struct afl_state { bytes_trim_in, /* Bytes coming into the trimmer */ bytes_trim_out, /* Bytes coming outa the trimmer */ blocks_eff_total, /* Blocks subject to effector maps */ - blocks_eff_select; /* Blocks selected as fuzzable */ + blocks_eff_select, /* Blocks selected as fuzzable */ + start_time, /* Unix start time (ms) */ + last_path_time, /* Time for most recent path (ms) */ + last_crash_time, /* Time for most recent crash (ms) */ + last_hang_time; /* Time for most recent hang (ms) */ - u32 subseq_tmouts; /* Number of timeouts in a row */ + u32 slowest_exec_ms, /* Slowest testcase non hang in ms */ + subseq_tmouts; /* Number of timeouts in a row */ u8 *stage_name, /* Name of the current fuzz stage */ *stage_short, /* Short stage name */ diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 08ac15c7..f932f33b 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -187,13 +187,13 @@ void init_cmplog_forkserver(afl_state_t *afl) { rlen = 4; u32 timeout_ms = afl->fsrv.exec_tmout * FORK_WAIT_MULT; /* Reuse readfds as exceptfds to see when the child closed the pipe */ - u32 time_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, rlen, timeout_ms); + u32 exec_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, rlen, timeout_ms); - if (!time_ms) { + if (!exec_ms) { PFATAL("Error in timed read"); - } else if (time_ms > timeout_ms) { + } else if (exec_ms > timeout_ms) { afl->fsrv.child_timed_out = 1; kill(afl->cmplog_fsrv_pid, SIGKILL); @@ -377,7 +377,7 @@ void init_cmplog_forkserver(afl_state_t *afl) { u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { int status = 0; - u64 exec_ms; + u32 exec_ms; u32 tb4; s32 res; @@ -416,9 +416,9 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { /* Configure timeout, as requested by user, then wait for child to terminate. */ - u32 time_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, 4, timeout); + exec_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, 4, timeout); - if (time_ms > timeout) { + if (exec_ms > timeout) { /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ @@ -427,11 +427,11 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) { afl->fsrv.child_timed_out = 1; /* After killing the child, the forkserver should tell us */ - if (!read(afl->cmplog_fsrv_st_fd, &status, 4)) time_ms = 0; + if (!read(afl->cmplog_fsrv_st_fd, &status, 4)) exec_ms = 0; } - if (!time_ms) { // Something went wrong. + if (!exec_ms) { // Something went wrong. if (afl->stop_soon) return 0; SAYF("\n" cLRD "[-] " cRST diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index f58e1a33..8cef78b9 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -33,7 +33,7 @@ u8 run_target(afl_state_t *afl, u32 timeout) { s32 res; - u32 time_ms; + u32 exec_ms; int status = 0; u32 tb4; @@ -67,20 +67,20 @@ u8 run_target(afl_state_t *afl, u32 timeout) { if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - time_ms = read_timed(afl->fsrv.fsrv_st_fd, &status, 4, timeout); + exec_ms = read_timed(afl->fsrv.fsrv_st_fd, &status, 4, timeout); - if (time_ms > timeout) { + if (exec_ms > timeout) { /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ kill(afl->fsrv.child_pid, SIGKILL); afl->fsrv.child_timed_out = 1; - if (read(afl->fsrv.fsrv_st_fd, &status, 4) < 4) time_ms = 0; + if (read(afl->fsrv.fsrv_st_fd, &status, 4) < 4) exec_ms = 0; } - if (!time_ms) { + if (!exec_ms) { if (afl->stop_soon) return 0; SAYF("\n" cLRD "[-] " cRST diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 7fde2fdc..98a97a34 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -95,7 +95,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "last_hang : %llu\n" "execs_since_crash : %llu\n" "exec_timeout : %u\n" - "slowest_exec_ms : %llu\n" + "slowest_exec_ms : %u\n" "peak_rss_mb : %lu\n" "afl_banner : %s\n" "afl_version : " VERSION -- cgit 1.4.1 From b83a2c1a00f6c9e45d6803e2b54dc3a82ffa49fc Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 04:51:38 +0200 Subject: make travis happy --- include/afl-fuzz.h | 2 -- include/common.h | 3 +++ src/afl-analyze.c | 7 +++---- src/afl-common.c | 6 ++++-- src/afl-forkserver.c | 2 -- src/afl-fuzz-state.c | 2 -- src/afl-fuzz.c | 2 -- src/afl-showmap.c | 5 +---- src/afl-tmin.c | 6 ++---- 9 files changed, 13 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 47aad5af..357cd854 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -239,8 +239,6 @@ enum { }; -extern u8 *doc_path; /* gath to documentation dir */ - /* Python stuff */ #ifdef USE_PYTHON diff --git a/include/common.h b/include/common.h index c26740ed..c9436e81 100644 --- a/include/common.h +++ b/include/common.h @@ -48,6 +48,9 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv); char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv); char * get_afl_env(char *env); +extern u8 be_quiet; +extern u8 *doc_path; /* path to documentation dir */ + /* Get unix time in milliseconds */ u64 get_cur_time(void); diff --git a/src/afl-analyze.c b/src/afl-analyze.c index d509c43e..473a257d 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -60,10 +60,9 @@ static s32 child_pid; /* PID of the tested program */ u8 *trace_bits; /* SHM with instrumentation bitmap */ static u8 *in_file, /* Analyzer input test case */ - *prog_in, /* Targeted program input file */ - *doc_path; /* Path to docs */ + *prog_in; /* Targeted program input file */ -static u8 *in_data; /* Input data for analysis */ + static u8 *in_data; /* Input data for analysis */ static u32 in_len, /* Input data length */ orig_cksum, /* Original checksum */ @@ -77,7 +76,7 @@ static s32 dev_null_fd = -1; /* FD to /dev/null */ u8 edges_only, /* Ignore hit counts? */ use_hex_offsets, /* Show hex offsets? */ - be_quiet, use_stdin = 1; /* Use stdin for program input? */ + use_stdin = 1; /* Use stdin for program input? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_timed_out; /* Child timed out? */ diff --git a/src/afl-common.c b/src/afl-common.c index c73d8725..920c7dfd 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -38,8 +38,10 @@ #endif #include -extern u8 be_quiet; -char * afl_environment_variables[] = { +u8 be_quiet = 0; +u8 *doc_path = ""; + +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", diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 01a606c3..962ca86d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -49,8 +49,6 @@ /* Describe integer as memory size. */ -extern u8 *doc_path; - list_t fsrv_list = {.element_prealloc_count = 0}; /* Initializes the struct */ diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 1d99e1fa..80176a10 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -34,8 +34,6 @@ char *power_names[POWER_SCHEDULES_NUM] = { "explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"}; -u8 *doc_path = NULL; /* gath to documentation dir */ - /* Initialize MOpt "globals" for this afl state */ static void init_mopt_globals(afl_state_t *afl) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ba56ff67..617a42ec 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -25,8 +25,6 @@ #include "afl-fuzz.h" -u8 be_quiet = 0; - static u8 *get_libradamsa_path(u8 *own_loc) { u8 *tmp, *cp, *rsl, *own_copy; diff --git a/src/afl-showmap.c b/src/afl-showmap.c index eaab5c31..f8a38c36 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -59,13 +59,10 @@ #include #include -u8 be_quiet; - char *stdin_file; /* stdin file */ u8 *in_dir, /* input folder */ - *doc_path, /* Path to docs */ - *at_file = NULL; /* Substitution string for @@ */ + *at_file = NULL; /* Substitution string for @@ */ static u8 *in_data; /* Input data */ diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 2275aef5..8a5e3eef 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -61,8 +61,7 @@ static u8 *mask_bitmap; /* Mask for trace bits (-B) */ u8 *in_file, /* Minimizer input test case */ - *output_file, /* Minimizer output file */ - *doc_path; /* Path to docs */ + *output_file; /* Minimizer output file */ static u8 *in_data; /* Input data for trimming */ @@ -77,8 +76,7 @@ u8 crash_mode, /* Crash-centric mode? */ hang_mode, /* Minimize as long as it hangs */ exit_crash, /* Treat non-zero exit as crash? */ edges_only, /* Ignore hit counts? */ - exact_mode, /* Require path match for crashes? */ - be_quiet; + exact_mode; /* Require path match for crashes? */ static volatile u8 stop_soon; /* Ctrl-C pressed? */ -- cgit 1.4.1 From c8bdf0790f7d19078d9ec5705fc04eefd8615988 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 14:01:22 +0200 Subject: reenabled custom mutator report --- examples/custom_mutators/Makefile | 2 +- llvm_mode/afl-clang-fast.c | 1 - src/afl-fuzz-one.c | 1 + test/test.sh | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 463cefb1..9849f3f4 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,7 +1,7 @@ all: libexamplemutator.so libexamplemutator.so: - $(CC) $(CFLAGS) -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so clean: rm -rf libexamplemutator.so diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 99bc8d03..de8d3410 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -48,7 +48,6 @@ static u8 debug; static u8 cwd[4096]; static u8 cmplog_mode; u8 use_stdin = 0; /* dummy */ -u8 be_quiet = 0; u8 *getthecwd() { diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 2e49e19b..b20bde90 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1648,6 +1648,7 @@ custom_mutator_stage: } /* `(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); } diff --git a/test/test.sh b/test/test.sh index 0dc58cc8..a04df384 100755 --- a/test/test.sh +++ b/test/test.sh @@ -961,7 +961,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS CODE=1 } - test "$CODE" = 1 && { $ECHO "$YELLOW[!] custom mutator tests currently will not fail travis" ; CODE=0 ; } + #test "$CODE" = 1 && { $ECHO "$YELLOW[!] custom mutator tests currently will not fail travis" ; CODE=0 ; } make -C ../examples/custom_mutators clean > /dev/null 2>&1 rm -f test-custom-mutator -- cgit 1.4.1 From a0693d466cdb298e2990e6f343745afc95ea4149 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 01:24:44 +0200 Subject: try to fix forkserver --- Makefile | 4 ++-- src/afl-forkserver.c | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index aaeb136c..f615c7dd 100644 --- a/Makefile +++ b/Makefile @@ -153,8 +153,8 @@ endif ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) - CFLAGS+=-fsanitize=address - LDFLAGS+=-fsanitize=address + CFLAGS+=-fsanitize=address -fstack-protector-strong + LDFLAGS+=-fsanitize=address -fstack-protector-strong endif ifdef PROFILING diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 962ca86d..a863efcc 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -319,10 +319,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) { u32 time = read_timed(fsrv->fsrv_st_fd, &status, rlen, fsrv->exec_tmout * FORK_WAIT_MULT); - if (!time) { + if (time > fsrv->exec_tmout * FORK_WAIT_MULT) { fsrv->child_timed_out = 1; - kill(fsrv->child_pid, SIGKILL); + kill(fsrv->fsrv_pid, SIGKILL); + + } + if (!time) { + + kill(fsrv->fsrv_pid, SIGKILL); } -- cgit 1.4.1 From eca55be4fb961bc65cf8c3531fe2e2eb2b7ca614 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 01:55:13 +0200 Subject: minor changes --- afl-whatsup | 4 ++-- src/afl-fuzz-init.c | 2 +- test/unittests/unit_maybe_alloc.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/afl-whatsup b/afl-whatsup index c3017689..1a276964 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -171,8 +171,8 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do TOTAL_CRASHES=$((TOTAL_CRASHES + unique_crashes)) TOTAL_PENDING=$((TOTAL_PENDING + pending_total)) TOTAL_PFAV=$((TOTAL_PFAV + pending_favs)) - - if [ "$last_path" -gt "$TOTAL_LAST_PATH" ]; then + + if [ "$last_path" -gt "$TOTAL_LAST_PATH" ]; then TOTAL_LAST_PATH=$last_path fi diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index fe2be4d2..e2495524 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -391,7 +391,7 @@ void read_testcases(afl_state_t *afl) { if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { - free(fn2); + ck_free(fn2); continue; } diff --git a/test/unittests/unit_maybe_alloc.c b/test/unittests/unit_maybe_alloc.c index 93f10889..25b41d46 100644 --- a/test/unittests/unit_maybe_alloc.c +++ b/test/unittests/unit_maybe_alloc.c @@ -137,4 +137,4 @@ int main(int argc, char **argv) { return cmocka_run_group_tests (tests, setup, teardown); -} \ No newline at end of file +} -- cgit 1.4.1 From 74b4096570f564c8f48880c9c19e3d2876405687 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 01:58:34 +0200 Subject: one less alloc --- src/afl-fuzz-run.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8cef78b9..08d8b615 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -168,19 +168,15 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { #ifdef _AFL_DOCUMENT_MUTATIONS s32 doc_fd; - char *fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir, + char fn[PATH_MAX]; + snprintf(fn, PATH_MAX, ("%s/mutations/%09u:%s", afl->out_dir, afl->document_counter++, describe_op(afl, 0)); - if (fn != NULL) { - if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { + if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { - if (write(doc_fd, mem, len) != len) - PFATAL("write to mutation file failed: %s", fn); - close(doc_fd); - - } - - ck_free(fn); + if (write(doc_fd, mem, len) != len) + PFATAL("write to mutation file failed: %s", fn); + close(doc_fd); } -- cgit 1.4.1 From 25d6d216176ab83e43f3c924327b5f366e1ebe9c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 02:00:03 +0200 Subject: code format --- src/afl-analyze.c | 2 +- src/afl-forkserver.c | 5 +---- src/afl-fuzz-run.c | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 473a257d..427fbe6d 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -62,7 +62,7 @@ u8 *trace_bits; /* SHM with instrumentation bitmap */ static u8 *in_file, /* Analyzer input test case */ *prog_in; /* Targeted program input file */ - static u8 *in_data; /* Input data for analysis */ +static u8 *in_data; /* Input data for analysis */ static u32 in_len, /* Input data length */ orig_cksum, /* Original checksum */ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a863efcc..11b359da 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -325,11 +325,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) { kill(fsrv->fsrv_pid, SIGKILL); } - if (!time) { - kill(fsrv->fsrv_pid, SIGKILL); - - } + if (!time) { kill(fsrv->fsrv_pid, SIGKILL); } } else { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 08d8b615..2caea123 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -167,7 +167,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { s32 fd = afl->fsrv.out_fd; #ifdef _AFL_DOCUMENT_MUTATIONS - s32 doc_fd; + s32 doc_fd; char fn[PATH_MAX]; snprintf(fn, PATH_MAX, ("%s/mutations/%09u:%s", afl->out_dir, afl->document_counter++, describe_op(afl, 0)); -- cgit 1.4.1 From d611e7d50e8efa3940a878d43c02382486c26d8c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 02:03:46 +0200 Subject: next_p2 replaced by next_pow2 --- src/afl-fuzz-queue.c | 6 +++--- src/afl-fuzz-run.c | 4 ++-- src/afl-tmin.c | 15 ++------------- 3 files changed, 7 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 4f1bd041..61bf62f5 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -184,7 +184,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u32 i; u64 fav_factor; - u64 fuzz_p2 = next_p2(q->n_fuzz); + u64 fuzz_p2 = next_pow2(q->n_fuzz); if (afl->schedule == MMOPT || afl->schedule == RARE) fav_factor = q->len << 2; @@ -201,7 +201,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { /* Faster-executing or smaller test cases are favored. */ u64 top_rated_fav_factor; - u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz); + u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); if (afl->schedule == MMOPT || afl->schedule == RARE) top_rated_fav_factor = afl->top_rated[i]->len << 2; @@ -440,7 +440,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { if (q->fuzz_level < 16) factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz); else - factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_p2(fuzz)); + factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz)); break; case LIN: factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz); break; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 2caea123..5875eb68 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -608,7 +608,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Select initial chunk len, starting with large steps. */ - len_p2 = next_p2(q->len); + len_p2 = next_pow2(q->len); remove_len = MAX(len_p2 / TRIM_START_STEPS, TRIM_MIN_BYTES); @@ -653,7 +653,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 move_tail = q->len - remove_pos - trim_avail; q->len -= trim_avail; - len_p2 = next_p2(q->len); + len_p2 = next_pow2(q->len); memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, move_tail); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 8a5e3eef..30e76d42 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -404,17 +404,6 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, } -/* Find first power of two greater or equal to val. */ - -static u32 next_p2(u32 val) { - - u32 ret = 1; - while (val > ret) - ret <<= 1; - return ret; - -} - /* Actually minimize! */ static void minimize(afl_forkserver_t *fsrv, char **argv) { @@ -432,7 +421,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) { * BLOCK NORMALIZATION * ***********************/ - set_len = next_p2(in_len / TMIN_SET_STEPS); + set_len = next_pow2(in_len / TMIN_SET_STEPS); set_pos = 0; if (set_len < TMIN_SET_MIN_SIZE) set_len = TMIN_SET_MIN_SIZE; @@ -482,7 +471,7 @@ next_pass: * BLOCK DELETION * ******************/ - del_len = next_p2(in_len / TRIM_START_STEPS); + del_len = next_pow2(in_len / TRIM_START_STEPS); stage_o_len = in_len; ACTF(cBRI "Stage #1: " cRST "Removing blocks of data..."); -- cgit 1.4.1 From 24b9eddc7edd7beb81cfa2bc445b8e8d6a05b184 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Apr 2020 12:19:54 +0200 Subject: disable memory limits for ASAN build --- Makefile | 2 +- src/afl-fuzz.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/Makefile b/Makefile index f615c7dd..5023a72f 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ endif ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) - CFLAGS+=-fsanitize=address -fstack-protector-strong + CFLAGS+=-fsanitize=address -fstack-protector-strong -D_ASAN_BUILD=1 LDFLAGS+=-fsanitize=address -fstack-protector-strong endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 617a42ec..64644b64 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -721,6 +721,13 @@ int main(int argc, char **argv_orig, char **envp) { } +#ifdef _ASAN_BUILD + if (!afl->fsrv.mem_limit) { + WARNF("in the ASAN build we disable all memory limits"); + afl->fsrv.mem_limit = 0; + } +#endif + setup_signal_handlers(); check_asan_opts(); -- cgit 1.4.1 From 29b1e30126a40d86d1e349aa213cdca6728f7666 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 12:43:26 +0200 Subject: fixed asan mem limit --- Makefile | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index 5023a72f..f615c7dd 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ endif ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) - CFLAGS+=-fsanitize=address -fstack-protector-strong -D_ASAN_BUILD=1 + CFLAGS+=-fsanitize=address -fstack-protector-strong LDFLAGS+=-fsanitize=address -fstack-protector-strong endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 64644b64..68392b05 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -721,7 +721,7 @@ int main(int argc, char **argv_orig, char **envp) { } -#ifdef _ASAN_BUILD +#if defined(__SANITIZE_ADDRESS__) if (!afl->fsrv.mem_limit) { WARNF("in the ASAN build we disable all memory limits"); afl->fsrv.mem_limit = 0; -- cgit 1.4.1 From e95ac10ff766cd053ba545b1efafbc698fe4fc18 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Apr 2020 12:52:54 +0200 Subject: fix ASAN check --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 68392b05..6e86285d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -722,7 +722,7 @@ int main(int argc, char **argv_orig, char **envp) { } #if defined(__SANITIZE_ADDRESS__) - if (!afl->fsrv.mem_limit) { + if (afl->fsrv.mem_limit) { WARNF("in the ASAN build we disable all memory limits"); afl->fsrv.mem_limit = 0; } -- cgit 1.4.1 From 0565fe4213b96a778895799eb61743166be35a0d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 12:24:39 +0200 Subject: rename all 'Makefile' to 'GNUmakefile', use -Werror for -flto checks --- GNUmakefile | 477 +++++++++++++++++++++++++++ Makefile | 479 +--------------------------- examples/argv_fuzzing/GNUmakefile | 51 +++ examples/argv_fuzzing/Makefile | 53 +-- examples/custom_mutators/GNUmakefile | 7 + examples/custom_mutators/Makefile | 9 +- examples/socket_fuzzing/GNUmakefile | 48 +++ examples/socket_fuzzing/Makefile | 50 +-- gcc_plugin/GNUmakefile | 160 ++++++++++ gcc_plugin/Makefile | 162 +--------- libdislocator/GNUmakefile | 44 +++ libdislocator/Makefile | 46 +-- libtokencap/GNUmakefile | 63 ++++ libtokencap/Makefile | 65 +--- llvm_mode/GNUmakefile | 375 ++++++++++++++++++++++ llvm_mode/Makefile | 377 +--------------------- qemu_mode/libcompcov/GNUmakefile | 44 +++ qemu_mode/libcompcov/Makefile | 46 +-- qemu_mode/unsigaction/GNUmakefile | 34 ++ qemu_mode/unsigaction/Makefile | 34 +- src/third_party/libradamsa/GNUmakefile | 26 ++ src/third_party/libradamsa/Makefile | 28 +- unicorn_mode/samples/c/GNUmakefile | 42 +++ unicorn_mode/samples/c/Makefile | 44 +-- unicorn_mode/samples/persistent/GNUmakefile | 42 +++ unicorn_mode/samples/persistent/Makefile | 44 +-- 26 files changed, 1438 insertions(+), 1412 deletions(-) create mode 100644 GNUmakefile create mode 100644 examples/argv_fuzzing/GNUmakefile create mode 100644 examples/custom_mutators/GNUmakefile create mode 100644 examples/socket_fuzzing/GNUmakefile create mode 100644 gcc_plugin/GNUmakefile create mode 100644 libdislocator/GNUmakefile create mode 100644 libtokencap/GNUmakefile create mode 100644 llvm_mode/GNUmakefile create mode 100644 qemu_mode/libcompcov/GNUmakefile create mode 100644 qemu_mode/unsigaction/GNUmakefile create mode 100644 src/third_party/libradamsa/GNUmakefile create mode 100644 unicorn_mode/samples/c/GNUmakefile create mode 100644 unicorn_mode/samples/persistent/GNUmakefile (limited to 'src') diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 00000000..8e0f0d97 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,477 @@ +# +# american fuzzy lop++ - makefile +# ----------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. 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 +# + +# For Heiko: +#TEST_MMAP=1 +# the hash character is treated differently in different make versions +# so use a variable for '#' +HASH=\# + +PREFIX ?= /usr/local +BIN_PATH = $(PREFIX)/bin +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH = $(PREFIX)/share/doc/afl +MISC_PATH = $(PREFIX)/share/afl +MAN_PATH = $(PREFIX)/man/man8 + +PROGNAME = afl +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +# PROGS intentionally omit afl-as, which gets installed elsewhere. + +PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze +SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config +MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8 +ASAN_OPTIONS=detect_leaks=0 + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto=full +else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto=thin + else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto + endif + endif +endif + +ifneq "$(shell uname)" "Darwin" + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_OPT = -march=native + endif +endif + +ifneq "$(shell uname -m)" "x86_64" + ifneq "$(shell uname -m)" "i386" + ifneq "$(shell uname -m)" "amd64" + ifneq "$(shell uname -m)" "i86pc" + AFL_NO_X86=1 + endif + endif + endif +endif + +CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 +override CFLAGS += -Wall -g -Wno-pointer-sign \ + -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ + -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" + +AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) + +ifneq "$(shell type python3m 2>/dev/null)" "" + ifneq "$(shell type python3m-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python3m-config --includes) + PYTHON_VERSION ?= $(strip $(shell python3m --version 2>&1)) + # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. + ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" + PYTHON_LIB ?= $(shell python3m-config --libs --embed) + else + PYTHON_LIB ?= $(shell python3m-config --ldflags) + endif + endif +endif + +ifneq "$(shell type python3 2>/dev/null)" "" + ifneq "$(shell type python3-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python3-config --includes) + PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1)) + # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. + ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" + PYTHON_LIB ?= $(shell python3-config --libs --embed) + else + PYTHON_LIB ?= $(shell python3-config --ldflags) + endif + endif +endif + +ifneq "$(shell type python 2>/dev/null)" "" + ifneq "$(shell type python-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python-config --includes) + PYTHON_LIB ?= $(shell python-config --ldflags) + PYTHON_VERSION ?= $(strip $(shell python --version 2>&1)) + endif +endif + +ifdef SOURCE_DATE_EPOCH + BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d") +else + BUILD_DATE ?= $(shell date "+%Y-%m-%d") +endif + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +ifneq "$(findstring FreeBSD, $(shell uname))" "" + CFLAGS += -pthread + LDFLAGS += -lpthread +endif + +ifneq "$(findstring NetBSD, $(shell uname))" "" + CFLAGS += -pthread + LDFLAGS += -lpthread +endif + +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + TEST_CC = afl-gcc +else + TEST_CC = afl-clang +endif + +COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h + +ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + PYTHON_OK=1 + PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\"" +else + PYTHON_OK=0 + PYFLAGS= +endif + +ifdef STATIC + $(info Compiling static version of binaries) + # Disable python for static compilation to simplify things + PYTHON_OK=0 + PYFLAGS= + + CFLAGS += -static + LDFLAGS += -lm -lpthread -lz -lutil +endif + +ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer +ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer + +ifdef ASAN_BUILD + $(info Compiling ASAN version of binaries) + CFLAGS+=$(ASAN_CFLAGS) + LDFLAGS+=$(ASAN_LDFLAGS) +endif + +ifdef PROFILING + $(info Compiling profiling version of binaries) + CFLAGS+=-pg + LDFLAGS+=-pg +endif + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS+=-Wno-deprecated-declarations +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS+=-Wno-deprecated-declarations +endif + +all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done + +man: $(MANPAGES) + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + +tests: source-only + @cd test ; ./test.sh + @rm -f test/errors + +performance-tests: performance-test +test-performance: performance-test + +performance-test: source-only + @cd test ; ./test-performance.sh + + +help: + @echo "HELP --- the following make targets exist:" + @echo "==========================================" + @echo "all: just the main afl++ binaries" + @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa" + @echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa" + @echo "distrib: everything (for both binary-only and source code fuzzing)" + @echo "man: creates simple man pages from the help option of the programs" + @echo "install: installs everything you have compiled with the build option above" + @echo "clean: cleans everything. for qemu_mode it means it deletes all downloads as well" + @echo "code-format: format the code, do this before you commit and send a PR please!" + @echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem" + @echo "unit: perform unit tests (based on cmocka)" + @echo "document: creates afl-fuzz-document which will only do one run and save all manipulated inputs into out/queue/mutations" + @echo "help: shows these build options :-)" + @echo "==========================================" + @echo "Recommended: \"distrib\" or \"source-only\", then \"install\"" + @echo + @echo Known build environment options: + @echo "==========================================" + @echo STATIC - compile AFL++ static + @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes + @echo PROFILING - compile afl-fuzz with profiling information + @echo AFL_NO_X86 - if compiling on non-intel/amd platforms + @echo "==========================================" + @echo e.g.: make ASAN_BUILD=1 + +ifndef AFL_NO_X86 + +test_x86: + @echo "[*] Checking for the default compiler cc..." + @type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC='."; echo; exit 1 ) + @echo "[*] Checking for the ability to compile x86 code..." + @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) + @rm -f .test1 + +else + +test_x86: + @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." + +endif + + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + + +ifeq "$(PYTHON_OK)" "1" + +test_python: + @rm -f .test 2> /dev/null + @echo "[+] $(PYTHON_VERSION) support seems to be working." + +else + +test_python: + @echo "[-] You seem to need to install the package python3-dev or python2-dev (and perhaps python[23]-apt), but it is optional so we continue" + +endif + + +ready: + @echo "[+] Everything seems to be working, ready to compile." + +afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) + set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done + +afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) + ln -sf afl-as as + +src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o + +src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o + +src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o + +radamsa: src/third_party/libradamsa/libradamsa.so + cp src/third_party/libradamsa/libradamsa.so . + +src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h + $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" + +afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) + +afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) + +afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) + +afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS) + +afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) + + +# document all mutations and only do one run (use with only one input file!) +document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 + $(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS) + +test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o + +test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o + +unit_maybe_alloc: test/unittests/unit_maybe_alloc.o + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_maybe_alloc + +test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o + +unit_list: test/unittests/unit_list.o + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_list + +test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o + +unit_preallocable: test/unittests/unit_preallocable.o + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_preallocable + +unit: unit_maybe_alloc unit_preallocable unit_list + +code-format: + ./.custom-format.py -i src/*.c + ./.custom-format.py -i include/*.h + ./.custom-format.py -i libdislocator/*.c + ./.custom-format.py -i libtokencap/*.c + ./.custom-format.py -i llvm_mode/*.c + ./.custom-format.py -i llvm_mode/*.h + ./.custom-format.py -i llvm_mode/*.cc + ./.custom-format.py -i gcc_plugin/*.c + #./.custom-format.py -i gcc_plugin/*.h + ./.custom-format.py -i gcc_plugin/*.cc + ./.custom-format.py -i examples/*/*.c + ./.custom-format.py -i examples/*/*.h + ./.custom-format.py -i qemu_mode/patches/*.h + ./.custom-format.py -i qemu_mode/libcompcov/*.c + ./.custom-format.py -i qemu_mode/libcompcov/*.cc + ./.custom-format.py -i qemu_mode/libcompcov/*.h + ./.custom-format.py -i qbdi_mode/*.c + ./.custom-format.py -i qbdi_mode/*.cpp + ./.custom-format.py -i *.h + ./.custom-format.py -i *.c + + +ifndef AFL_NO_X86 + +test_build: afl-gcc afl-as afl-showmap + @echo "[*] Testing the CC wrapper and instrumentation output..." + @unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 ) + ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null + echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr + @rm -f test-instr + @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi + @echo "[+] All right, the instrumentation seems to be working!" + +else + +test_build: afl-gcc afl-as afl-showmap + @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." + +endif + + +all_done: test_build + @if [ ! "`type clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.md for a faster alternative to afl-gcc."; fi + @echo "[+] All done! Be sure to review the README.md - it's pretty short and useful." + @if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi + @! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null + +.NOTPARALLEL: clean + +clean: + rm -f $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable + rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM + -$(MAKE) -C llvm_mode clean + -$(MAKE) -C gcc_plugin clean + $(MAKE) -C libdislocator clean + $(MAKE) -C libtokencap clean + $(MAKE) -C examples/socket_fuzzing clean + $(MAKE) -C examples/argv_fuzzing clean + $(MAKE) -C qemu_mode/unsigaction clean + $(MAKE) -C qemu_mode/libcompcov clean + $(MAKE) -C src/third_party/libradamsa/ clean + -rm -rf unicorn_mode/unicornafl + +distrib: all radamsa + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing + cd qemu_mode && sh ./build_qemu_support.sh + cd unicorn_mode && sh ./build_unicorn_support.sh + +binary-only: all radamsa + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing + cd qemu_mode && sh ./build_qemu_support.sh + cd unicorn_mode && sh ./build_unicorn_support.sh + +source-only: all radamsa + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + +%.8: % + @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ + @echo .SH NAME >> $@ + @echo .B $* >> $@ + @echo >> $@ + @echo .SH SYNOPSIS >> $@ + @./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@ + @echo >> $@ + @echo .SH OPTIONS >> $@ + @echo .nf >> $@ + @./$* -hh 2>&1 | tail -n +4 >> $@ + @echo >> $@ + @echo .SH AUTHOR >> $@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ + @echo >> $@ + @echo .SH LICENSE >> $@ + @echo Apache License Version 2.0, January 2004 >> $@ + +install: all $(MANPAGES) + install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) + rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh + install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) + rm -f $${DESTDIR}$(BIN_PATH)/afl-as + if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi + if [ -f afl-gcc-fast ]; then set e; install -m 755 afl-gcc-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-gcc-fast $${DESTDIR}$(BIN_PATH)/afl-g++-fast; install -m 755 afl-gcc-pass.so afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH); fi + $(MAKE) -C llvm_mode install + if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi + $(MAKE) -C examples/socket_fuzzing install + $(MAKE) -C examples/argv_fuzzing install + + set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ + set -e; if [ -f afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi + + mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH) + install -m0644 *.8 ${DESTDIR}$(MAN_PATH) + + install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) + ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as + install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) + cp -r testcases/ $${DESTDIR}$(MISC_PATH) + cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) diff --git a/Makefile b/Makefile index cb4bc653..0b306dde 100644 --- a/Makefile +++ b/Makefile @@ -1,477 +1,2 @@ -# -# american fuzzy lop++ - makefile -# ----------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. 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 -# - -# For Heiko: -#TEST_MMAP=1 -# the hash character is treated differently in different make versions -# so use a variable for '#' -HASH=\# - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH = $(PREFIX)/share/doc/afl -MISC_PATH = $(PREFIX)/share/afl -MAN_PATH = $(PREFIX)/man/man8 - -PROGNAME = afl -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -# PROGS intentionally omit afl-as, which gets installed elsewhere. - -PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze -SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config -MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8 -ASAN_OPTIONS=detect_leaks=0 - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto=full -else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto=thin - else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto - endif - endif -endif - -ifneq "$(shell uname)" "Darwin" - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_OPT = -march=native - endif -endif - -ifneq "$(shell uname -m)" "x86_64" - ifneq "$(shell uname -m)" "i386" - ifneq "$(shell uname -m)" "amd64" - ifneq "$(shell uname -m)" "i86pc" - AFL_NO_X86=1 - endif - endif - endif -endif - -CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 -override CFLAGS += -Wall -g -Wno-pointer-sign \ - -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ - -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" - -AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) - -ifneq "$(shell type python3m 2>/dev/null)" "" - ifneq "$(shell type python3m-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python3m-config --includes) - PYTHON_VERSION ?= $(strip $(shell python3m --version 2>&1)) - # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. - ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" - PYTHON_LIB ?= $(shell python3m-config --libs --embed) - else - PYTHON_LIB ?= $(shell python3m-config --ldflags) - endif - endif -endif - -ifneq "$(shell type python3 2>/dev/null)" "" - ifneq "$(shell type python3-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python3-config --includes) - PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1)) - # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. - ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" - PYTHON_LIB ?= $(shell python3-config --libs --embed) - else - PYTHON_LIB ?= $(shell python3-config --ldflags) - endif - endif -endif - -ifneq "$(shell type python 2>/dev/null)" "" - ifneq "$(shell type python-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python-config --includes) - PYTHON_LIB ?= $(shell python-config --ldflags) - PYTHON_VERSION ?= $(strip $(shell python --version 2>&1)) - endif -endif - -ifdef SOURCE_DATE_EPOCH - BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d") -else - BUILD_DATE ?= $(shell date "+%Y-%m-%d") -endif - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -ifneq "$(findstring FreeBSD, $(shell uname))" "" - CFLAGS += -pthread - LDFLAGS += -lpthread -endif - -ifneq "$(findstring NetBSD, $(shell uname))" "" - CFLAGS += -pthread - LDFLAGS += -lpthread -endif - -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - TEST_CC = afl-gcc -else - TEST_CC = afl-clang -endif - -COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h - -ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - PYTHON_OK=1 - PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\"" -else - PYTHON_OK=0 - PYFLAGS= -endif - -ifdef STATIC - $(info Compiling static version of binaries) - # Disable python for static compilation to simplify things - PYTHON_OK=0 - PYFLAGS= - - CFLAGS += -static - LDFLAGS += -lm -lpthread -lz -lutil -endif - -ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer -ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer - -ifdef ASAN_BUILD - $(info Compiling ASAN version of binaries) - CFLAGS+=$(ASAN_CFLAGS) - LDFLAGS+=$(ASAN_LDFLAGS) -endif - -ifdef PROFILING - $(info Compiling profiling version of binaries) - CFLAGS+=-pg - LDFLAGS+=-pg -endif - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS+=-Wno-deprecated-declarations -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS+=-Wno-deprecated-declarations -endif - -all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done - -man: $(MANPAGES) - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - -tests: source-only - @cd test ; ./test.sh - @rm -f test/errors - -performance-tests: performance-test -test-performance: performance-test - -performance-test: source-only - @cd test ; ./test-performance.sh - - -help: - @echo "HELP --- the following make targets exist:" - @echo "==========================================" - @echo "all: just the main afl++ binaries" - @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa" - @echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa" - @echo "distrib: everything (for both binary-only and source code fuzzing)" - @echo "man: creates simple man pages from the help option of the programs" - @echo "install: installs everything you have compiled with the build option above" - @echo "clean: cleans everything. for qemu_mode it means it deletes all downloads as well" - @echo "code-format: format the code, do this before you commit and send a PR please!" - @echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem" - @echo "unit: perform unit tests (based on cmocka)" - @echo "document: creates afl-fuzz-document which will only do one run and save all manipulated inputs into out/queue/mutations" - @echo "help: shows these build options :-)" - @echo "==========================================" - @echo "Recommended: \"distrib\" or \"source-only\", then \"install\"" - @echo - @echo Known build environment options: - @echo "==========================================" - @echo STATIC - compile AFL++ static - @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes - @echo PROFILING - compile afl-fuzz with profiling information - @echo AFL_NO_X86 - if compiling on non-intel/amd platforms - @echo "==========================================" - @echo e.g.: make ASAN_BUILD=1 - -ifndef AFL_NO_X86 - -test_x86: - @echo "[*] Checking for the default compiler cc..." - @type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC='."; echo; exit 1 ) - @echo "[*] Checking for the ability to compile x86 code..." - @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) - @rm -f .test1 - -else - -test_x86: - @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." - -endif - - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - - -ifeq "$(PYTHON_OK)" "1" - -test_python: - @rm -f .test 2> /dev/null - @echo "[+] $(PYTHON_VERSION) support seems to be working." - -else - -test_python: - @echo "[-] You seem to need to install the package python3-dev or python2-dev (and perhaps python[23]-apt), but it is optional so we continue" - -endif - - -ready: - @echo "[+] Everything seems to be working, ready to compile." - -afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) - set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done - -afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) - ln -sf afl-as as - -src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o - -src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o - -src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o - -radamsa: src/third_party/libradamsa/libradamsa.so - cp src/third_party/libradamsa/libradamsa.so . - -src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h - $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" - -afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) - -afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) - -afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) - -afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS) - -afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) - - -# document all mutations and only do one run (use with only one input file!) -document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 - $(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS) - -test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o - -test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o - -unit_maybe_alloc: test/unittests/unit_maybe_alloc.o - $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_maybe_alloc - -test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o - -unit_list: test/unittests/unit_list.o - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_list - -test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o - -unit_preallocable: test/unittests/unit_preallocable.o - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_preallocable - -unit: unit_maybe_alloc unit_preallocable unit_list - -code-format: - ./.custom-format.py -i src/*.c - ./.custom-format.py -i include/*.h - ./.custom-format.py -i libdislocator/*.c - ./.custom-format.py -i libtokencap/*.c - ./.custom-format.py -i llvm_mode/*.c - ./.custom-format.py -i llvm_mode/*.h - ./.custom-format.py -i llvm_mode/*.cc - ./.custom-format.py -i gcc_plugin/*.c - #./.custom-format.py -i gcc_plugin/*.h - ./.custom-format.py -i gcc_plugin/*.cc - ./.custom-format.py -i examples/*/*.c - ./.custom-format.py -i examples/*/*.h - ./.custom-format.py -i qemu_mode/patches/*.h - ./.custom-format.py -i qemu_mode/libcompcov/*.c - ./.custom-format.py -i qemu_mode/libcompcov/*.cc - ./.custom-format.py -i qemu_mode/libcompcov/*.h - ./.custom-format.py -i qbdi_mode/*.c - ./.custom-format.py -i qbdi_mode/*.cpp - ./.custom-format.py -i *.h - ./.custom-format.py -i *.c - - -ifndef AFL_NO_X86 - -test_build: afl-gcc afl-as afl-showmap - @echo "[*] Testing the CC wrapper and instrumentation output..." - @unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 ) - ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null - echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr - @rm -f test-instr - @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi - @echo "[+] All right, the instrumentation seems to be working!" - -else - -test_build: afl-gcc afl-as afl-showmap - @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." - -endif - - -all_done: test_build - @if [ ! "`type clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.md for a faster alternative to afl-gcc."; fi - @echo "[+] All done! Be sure to review the README.md - it's pretty short and useful." - @if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi - @! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null - -.NOTPARALLEL: clean - -clean: - rm -f $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable - rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM - -$(MAKE) -C llvm_mode clean - -$(MAKE) -C gcc_plugin clean - $(MAKE) -C libdislocator clean - $(MAKE) -C libtokencap clean - $(MAKE) -C examples/socket_fuzzing clean - $(MAKE) -C examples/argv_fuzzing clean - $(MAKE) -C qemu_mode/unsigaction clean - $(MAKE) -C qemu_mode/libcompcov clean - $(MAKE) -C src/third_party/libradamsa/ clean - -rm -rf unicorn_mode/unicornafl - -distrib: all radamsa - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - $(MAKE) -C examples/socket_fuzzing - $(MAKE) -C examples/argv_fuzzing - cd qemu_mode && sh ./build_qemu_support.sh - cd unicorn_mode && sh ./build_unicorn_support.sh - -binary-only: all radamsa - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - $(MAKE) -C examples/socket_fuzzing - $(MAKE) -C examples/argv_fuzzing - cd qemu_mode && sh ./build_qemu_support.sh - cd unicorn_mode && sh ./build_unicorn_support.sh - -source-only: all radamsa - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - -%.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ - @echo .SH NAME >> $@ - @echo .B $* >> $@ - @echo >> $@ - @echo .SH SYNOPSIS >> $@ - @./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@ - @echo >> $@ - @echo .SH OPTIONS >> $@ - @echo .nf >> $@ - @./$* -hh 2>&1 | tail -n +4 >> $@ - @echo >> $@ - @echo .SH AUTHOR >> $@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ - @echo >> $@ - @echo .SH LICENSE >> $@ - @echo Apache License Version 2.0, January 2004 >> $@ - -install: all $(MANPAGES) - install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) - rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh - install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) - rm -f $${DESTDIR}$(BIN_PATH)/afl-as - if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi - if [ -f afl-gcc-fast ]; then set e; install -m 755 afl-gcc-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-gcc-fast $${DESTDIR}$(BIN_PATH)/afl-g++-fast; install -m 755 afl-gcc-pass.so afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH); fi - $(MAKE) -C llvm_mode install - if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi - $(MAKE) -C examples/socket_fuzzing install - $(MAKE) -C examples/argv_fuzzing install - - set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ - set -e; if [ -f afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi - - mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH) - install -m0644 *.8 ${DESTDIR}$(MAN_PATH) - - install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) - ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as - install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) - cp -r testcases/ $${DESTDIR}$(MISC_PATH) - cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) +all: + @echo please use GNU make, thanks! diff --git a/examples/argv_fuzzing/GNUmakefile b/examples/argv_fuzzing/GNUmakefile new file mode 100644 index 00000000..34192e39 --- /dev/null +++ b/examples/argv_fuzzing/GNUmakefile @@ -0,0 +1,51 @@ +# +# american fuzzy lop++ - argvfuzz +# -------------------------------- +# +# Copyright 2019-2020 Kjell Braden +# +# 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 + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) + M32FLAG = -mbe32 + endif +endif + + +all: argvfuzz32.so argvfuzz64.so + +argvfuzz32.so: argvfuzz.c + -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)" + +argvfuzz64.so: argvfuzz.c + -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz64 build failure (that's fine)" + +install: argvfuzz32.so argvfuzz64.so + install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ + if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi + if [ -f argvfuzz64.so ]; then set -e; install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi + +clean: + rm -f argvfuzz32.so argvfuzz64.so diff --git a/examples/argv_fuzzing/Makefile b/examples/argv_fuzzing/Makefile index 34192e39..0b306dde 100644 --- a/examples/argv_fuzzing/Makefile +++ b/examples/argv_fuzzing/Makefile @@ -1,51 +1,2 @@ -# -# american fuzzy lop++ - argvfuzz -# -------------------------------- -# -# Copyright 2019-2020 Kjell Braden -# -# 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 - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) - M32FLAG = -mbe32 - endif -endif - - -all: argvfuzz32.so argvfuzz64.so - -argvfuzz32.so: argvfuzz.c - -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)" - -argvfuzz64.so: argvfuzz.c - -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz64 build failure (that's fine)" - -install: argvfuzz32.so argvfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f argvfuzz64.so ]; then set -e; install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f argvfuzz32.so argvfuzz64.so +all: + @echo please use GNU make, thanks! diff --git a/examples/custom_mutators/GNUmakefile b/examples/custom_mutators/GNUmakefile new file mode 100644 index 00000000..9849f3f4 --- /dev/null +++ b/examples/custom_mutators/GNUmakefile @@ -0,0 +1,7 @@ +all: libexamplemutator.so + +libexamplemutator.so: + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + +clean: + rm -rf libexamplemutator.so diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 9849f3f4..0b306dde 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,7 +1,2 @@ -all: libexamplemutator.so - -libexamplemutator.so: - $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so - -clean: - rm -rf libexamplemutator.so +all: + @echo please use GNU make, thanks! diff --git a/examples/socket_fuzzing/GNUmakefile b/examples/socket_fuzzing/GNUmakefile new file mode 100644 index 00000000..ad921664 --- /dev/null +++ b/examples/socket_fuzzing/GNUmakefile @@ -0,0 +1,48 @@ +# +# american fuzzy lop++ - socket_fuzz +# ---------------------------------- +# +# 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 + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) + M32FLAG = -mbe32 + endif +endif + +all: socketfuzz32.so socketfuzz64.so + +socketfuzz32.so: socketfuzz.c + -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)" + +socketfuzz64.so: socketfuzz.c + -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz64 build failure (that's fine)" + +install: socketfuzz32.so socketfuzz64.so + install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ + if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi + if [ -f socketfuzz64.so ]; then set -e; install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi + +clean: + rm -f socketfuzz32.so socketfuzz64.so diff --git a/examples/socket_fuzzing/Makefile b/examples/socket_fuzzing/Makefile index ad921664..0b306dde 100644 --- a/examples/socket_fuzzing/Makefile +++ b/examples/socket_fuzzing/Makefile @@ -1,48 +1,2 @@ -# -# american fuzzy lop++ - socket_fuzz -# ---------------------------------- -# -# 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 - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) - M32FLAG = -mbe32 - endif -endif - -all: socketfuzz32.so socketfuzz64.so - -socketfuzz32.so: socketfuzz.c - -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)" - -socketfuzz64.so: socketfuzz.c - -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz64 build failure (that's fine)" - -install: socketfuzz32.so socketfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f socketfuzz64.so ]; then set -e; install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f socketfuzz32.so socketfuzz64.so +all: + @echo please use GNU make, thanks! diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile new file mode 100644 index 00000000..4c7a0313 --- /dev/null +++ b/gcc_plugin/GNUmakefile @@ -0,0 +1,160 @@ +# +# american fuzzy lop++ - GCC plugin instrumentation +# ----------------------------------------------- +# +# Written by Austin Seipp and +# Laszlo Szekeres and +# Michal Zalewski and +# Heiko Eißfeldt +# +# GCC integration design is based on the LLVM design, which comes +# from Laszlo Szekeres. +# +# Copyright 2015 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 +# + +PREFIX ?= /usr/local +HELPER_PATH ?= $(PREFIX)/lib/afl +BIN_PATH ?= $(PREFIX)/bin +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 +override CFLAGS = -Wall -I../include -Wno-pointer-sign \ + -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ + -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ + -Wno-unused-function + +CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 +CXXEFLAGS := $(CXXFLAGS) -Wall + +CC ?= gcc +CXX ?= g++ + +ifeq "clang" "$(CC)" + CC = gcc + CXX = g++ +endif + +ifeq "clang++" "$(CXX)" + CC = gcc + CXX = g++ +endif + +PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include" +HASH=\# + +GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}') +GCCBINDIR = $(shell dirname `command -v $(CC)` 2>/dev/null ) + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +PROGS = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o + + +all: test_shm test_deps $(PROGS) afl-gcc-fast.8 test_build all_done + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + + +test_deps: + @echo "[*] Checking for working '$(CC)'..." + @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) +# @echo "[*] Checking for gcc for plugin support..." +# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) + @echo "[*] Checking for gcc plugin development header files..." + @test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 ) + @echo "[*] Checking for '../afl-showmap'..." + @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) + @echo "[+] All set and ready to build." + +afl-common.o: ../src/afl-common.c + $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) + +../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps + $(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) + ln -sf afl-gcc-fast ../afl-g++-fast + +../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps + $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ + +../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +test_build: $(PROGS) + @echo "[*] Testing the CC wrapper and instrumentation output..." + unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) +# unset AFL_USE_ASAN AFL_USE_MSAN; AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) + ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr ../$@ + @echo .SH NAME >> ../$@ + @echo .B $* >> ../$@ + @echo >> ../$@ + @echo .SH SYNOPSIS >> ../$@ + @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ + @echo >> ../$@ + @echo .SH OPTIONS >> ../$@ + @echo .nf >> ../$@ + @../$* -h 2>&1 | tail -n +4 >> ../$@ + @echo >> ../$@ + @echo .SH AUTHOR >> ../$@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ + @echo >> ../$@ + @echo .SH LICENSE >> ../$@ + @echo Apache License Version 2.0, January 2004 >> ../$@ + ln -sf afl-gcc-fast.8 ../afl-g++-fast.8 + +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 + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 + rm -f $(PROGS) afl-common.o ../afl-g++-fast ../afl-g*-fast.8 diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 4c7a0313..0b306dde 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -1,160 +1,2 @@ -# -# american fuzzy lop++ - GCC plugin instrumentation -# ----------------------------------------------- -# -# Written by Austin Seipp and -# Laszlo Szekeres and -# Michal Zalewski and -# Heiko Eißfeldt -# -# GCC integration design is based on the LLVM design, which comes -# from Laszlo Szekeres. -# -# Copyright 2015 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 -# - -PREFIX ?= /usr/local -HELPER_PATH ?= $(PREFIX)/lib/afl -BIN_PATH ?= $(PREFIX)/bin -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 -override CFLAGS = -Wall -I../include -Wno-pointer-sign \ - -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ - -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ - -Wno-unused-function - -CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 -CXXEFLAGS := $(CXXFLAGS) -Wall - -CC ?= gcc -CXX ?= g++ - -ifeq "clang" "$(CC)" - CC = gcc - CXX = g++ -endif - -ifeq "clang++" "$(CXX)" - CC = gcc - CXX = g++ -endif - -PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include" -HASH=\# - -GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}') -GCCBINDIR = $(shell dirname `command -v $(CC)` 2>/dev/null ) - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -PROGS = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o - - -all: test_shm test_deps $(PROGS) afl-gcc-fast.8 test_build all_done - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - - -test_deps: - @echo "[*] Checking for working '$(CC)'..." - @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) -# @echo "[*] Checking for gcc for plugin support..." -# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) - @echo "[*] Checking for gcc plugin development header files..." - @test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 ) - @echo "[*] Checking for '../afl-showmap'..." - @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) - @echo "[+] All set and ready to build." - -afl-common.o: ../src/afl-common.c - $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) - -../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps - $(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) - ln -sf afl-gcc-fast ../afl-g++-fast - -../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps - $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ - -../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps - $(CC) $(CFLAGS) -fPIC -c $< -o $@ - -test_build: $(PROGS) - @echo "[*] Testing the CC wrapper and instrumentation output..." - unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) -# unset AFL_USE_ASAN AFL_USE_MSAN; AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) - ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr ../$@ - @echo .SH NAME >> ../$@ - @echo .B $* >> ../$@ - @echo >> ../$@ - @echo .SH SYNOPSIS >> ../$@ - @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ - @echo >> ../$@ - @echo .SH OPTIONS >> ../$@ - @echo .nf >> ../$@ - @../$* -h 2>&1 | tail -n +4 >> ../$@ - @echo >> ../$@ - @echo .SH AUTHOR >> ../$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ - @echo >> ../$@ - @echo .SH LICENSE >> ../$@ - @echo Apache License Version 2.0, January 2004 >> ../$@ - ln -sf afl-gcc-fast.8 ../afl-g++-fast.8 - -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 - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 - rm -f $(PROGS) afl-common.o ../afl-g++-fast ../afl-g*-fast.8 +all: + @echo please use GNU make, thanks! diff --git a/libdislocator/GNUmakefile b/libdislocator/GNUmakefile new file mode 100644 index 00000000..3ee37088 --- /dev/null +++ b/libdislocator/GNUmakefile @@ -0,0 +1,44 @@ +# +# american fuzzy lop++ - libdislocator +# ---------------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2016 Google Inc. 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 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +ifdef USEHUGEPAGE + CFLAGS += -DUSEHUGEPAGE +endif + +all: libdislocator.so + +VPATH = .. +libdislocator.so: libdislocator.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../libdislocator.so + +install: all + install -m 755 -d $${DESTDIR}$(HELPER_PATH) + install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH) + install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH) + diff --git a/libdislocator/Makefile b/libdislocator/Makefile index 3ee37088..0b306dde 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -1,44 +1,2 @@ -# -# american fuzzy lop++ - libdislocator -# ---------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2016 Google Inc. 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 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign - -ifdef USEHUGEPAGE - CFLAGS += -DUSEHUGEPAGE -endif - -all: libdislocator.so - -VPATH = .. -libdislocator.so: libdislocator.so.c ../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../libdislocator.so - -install: all - install -m 755 -d $${DESTDIR}$(HELPER_PATH) - install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH) - install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH) - +all: + @echo please use GNU make, thanks! diff --git a/libtokencap/GNUmakefile b/libtokencap/GNUmakefile new file mode 100644 index 00000000..5fcd7731 --- /dev/null +++ b/libtokencap/GNUmakefile @@ -0,0 +1,63 @@ +# +# american fuzzy lop++ - libtokencap +# -------------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2016 Google Inc. 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 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +ifeq "$(shell uname)" "Linux" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +ifeq "$(shell uname)" "Darwin" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +ifeq "$(shell uname)" "FreeBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "OpenBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "NetBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "DragonFly" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +all: $(TARGETS) + +VPATH = .. +libtokencap.so: libtokencap.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../libtokencap.so + +install: all + install -m 755 -d $${DESTDIR}$(HELPER_PATH) + install -m 755 ../libtokencap.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.tokencap.md + diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 5fcd7731..0b306dde 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -1,63 +1,2 @@ -# -# american fuzzy lop++ - libtokencap -# -------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2016 Google Inc. 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 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign - -ifeq "$(shell uname)" "Linux" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -ifeq "$(shell uname)" "Darwin" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -ifeq "$(shell uname)" "FreeBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "OpenBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "NetBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "DragonFly" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -all: $(TARGETS) - -VPATH = .. -libtokencap.so: libtokencap.so.c ../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../libtokencap.so - -install: all - install -m 755 -d $${DESTDIR}$(HELPER_PATH) - install -m 755 ../libtokencap.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.tokencap.md - +all: + @echo please use GNU make, thanks! diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile new file mode 100644 index 00000000..006d115d --- /dev/null +++ b/llvm_mode/GNUmakefile @@ -0,0 +1,375 @@ +# +# american fuzzy lop++ - LLVM instrumentation +# ----------------------------------------- +# +# Written by Laszlo Szekeres and +# Michal Zalewski +# +# LLVM integration design comes from Laszlo Szekeres. +# +# Copyright 2015, 2016 Google Inc. 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 +# + +# For Heiko: +#TEST_MMAP=1 +HASH=\# + +PREFIX ?= /usr/local +HELPER_PATH ?= $(PREFIX)/lib/afl +BIN_PATH ?= $(PREFIX)/bin +DOC_PATH ?= $(PREFIX)/share/doc/afl +MISC_PATH ?= $(PREFIX)/share/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +ifeq "$(shell uname)" "OpenBSD" + LLVM_CONFIG ?= $(BIN_PATH)/llvm-config + HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1) + ifeq "$(HAS_OPT)" "1" + $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9") + endif +else + LLVM_CONFIG ?= llvm-config +endif + +LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null ) +LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 ) +LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) +LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//') +LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) +LLVM_STDCXX = gnu++11 +LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0) +LLVM_LTO = 0 + +ifeq "$(LLVMVER)" "" + $(warning [!] llvm_mode needs llvm-config, which was not found) +endif + +ifeq "$(LLVM_UNSUPPORTED)" "1" + $(warning llvm_mode only supports llvm versions 3.8.0 up to 11) +endif + +ifeq "$(LLVM_MAJOR)" "9" + $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation) + $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) + LLVM_LTO = 1 +endif + +ifeq "$(LLVM_NEW_API)" "1" + $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14) + $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) + LLVM_STDCXX = c++14 + LLVM_LTO = 1 +endif + +ifeq "$(LLVM_LTO)" "0" + $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.) +endif + +ifeq "$(LLVM_APPLE)" "1" + $(warning llvm_mode will not compile with Xcode clang...) +endif + +# We were using llvm-config --bindir to get the location of clang, but +# this seems to be busted on some distros, so using the one in $PATH is +# probably better. + +CC = $(LLVM_BINDIR)/clang +CXX = $(LLVM_BINDIR)/clang++ + +ifeq "$(shell test -e $(CC) || echo 1 )" "1" + # llvm-config --bindir may not providing a valid path, so ... + ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1" + # we found one in the local install directory, lets use these + CC = $(BIN_DIR)/clang + CXX = $(BIN_DIR)/clang++ + else + # hope for the best + $(warning we have trouble finding clang/clang++ - llvm-config is not helping us) + CC = clang + CXX = clang++ + endif +endif + +# sanity check. +# Are versions of clang --version and llvm-config --version equal? +CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p') + +ifneq "$(CLANGVER)" "$(LLVMVER)" + CC = $(shell $(LLVM_CONFIG) --bindir)/clang + CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++ +endif + +# After we set CC/CXX we can start makefile magic tests + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_OPT = -march=native +endif + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto=full +else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto=thin + else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto + endif + endif +endif + +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(AFL_REAL_LD)" "" + AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null) + ifeq "$(AFL_REAL_LD)" "" + AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null) + endif +endif +endif + +CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 +override CFLAGS = -Wall \ + -g -Wno-pointer-sign -I ../include/ \ + -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ + -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ + -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ + -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function +ifdef AFL_TRACE_PC + CFLAGS += -DUSE_TRACE_PC=1 +endif + +CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 +override CXXFLAGS += -Wall -g -I ../include/ \ + -DVERSION=\"$(VERSION)\" -Wno-variadic-macros + +CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS) +CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) + + +# User teor2345 reports that this is required to make things work on MacOS X. +ifeq "$(shell uname)" "Darwin" + CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress +endif + +ifeq "$(shell uname)" "OpenBSD" + CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so +endif + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS += -DAFL_CLANG_FUSELD=1 +endif + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifndef AFL_TRACE_PC + PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.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 +else + PROGS = ../afl-clang-fast ../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 +endif + +# If prerequisites are not given, warn, do not build anything, and exit with code 0 +ifeq "$(LLVMVER)" "" + NO_BUILD = 1 +endif + +ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00" + NO_BUILD = 1 +endif + +ifeq "$(NO_BUILD)" "1" + TARGETS = no_build +else + TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done +endif + +LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?) + +all: $(TARGETS) + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + +no_build: + @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m" + +test_deps: +ifndef AFL_TRACE_PC + @echo "[*] Checking for working 'llvm-config'..." + ifneq "$(LLVM_APPLE)" "1" + @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 ) + endif +else + @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)." +endif + @echo "[*] Checking for working '$(CC)'..." + @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) + @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'" +ifneq "$(CLANGVER)" "$(LLVMVER)" + @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)" + @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang" +else + @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good." +endif + @echo "[*] Checking for '../afl-showmap'..." + @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) + @echo "[+] All set and ready to build." + +afl-common.o: ../src/afl-common.c + $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) + +../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps + $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" + ln -sf afl-clang-fast ../afl-clang-fast++ +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + ln -sf afl-clang-fast ../afl-clang-lto + ln -sf afl-clang-fast ../afl-clang-lto++ +endif +endif + +../afl-ld: afl-ld.c +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + ln -sf afl-ld ../ld + @rm -f .test-instr + @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto" + @rm -f .test-instr +endif +endif +../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps + -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) + +../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps +ifeq "$(LLVM_MIN_4_0_1)" "0" + $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) +endif + $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) + +../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc +ifeq "$(LLVM_LTO)" "1" + $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) +endif + +../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc +ifeq "$(LLVM_LTO)" "1" + $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) +endif + +# laf +../split-switches-pass.so: split-switches-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +../split-compares-pass.so: split-compares-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +# /laf + +../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) + +../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) + +../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps + @printf "[*] Building 32-bit variant of the runtime (-m32)... " + @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + +../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps + @printf "[*] Building 64-bit variant of the runtime (-m64)... " + @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + +test_build: $(PROGS) + @echo "[*] Testing the CC wrapper and instrumentation output..." + unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) + ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null + echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr + @rm -f test-instr + @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi + @echo "[+] All right, the instrumentation seems to be working!" + +all_done: test_build + @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs." + +.NOTPARALLEL: clean + +install: all + install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) +ifndef AFL_TRACE_PC + 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 -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi +else + if [ -f ../afl-clang-fast -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 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi +endif + 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 + if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi + set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi + install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/ + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md + +vpath % .. +%.8: % + @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@ + @echo .SH NAME >> ../$@ + @echo .B $* >> ../$@ + @echo >> ../$@ + @echo .SH SYNOPSIS >> ../$@ + @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ + @echo >> ../$@ + @echo .SH OPTIONS >> ../$@ + @echo .nf >> ../$@ + @../$* -h 2>&1 | tail -n +4 >> ../$@ + @echo >> ../$@ + @echo .SH AUTHOR >> ../$@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ + @echo >> ../$@ + @echo .SH LICENSE >> ../$@ + @echo Apache License Version 2.0, January 2004 >> ../$@ + ln -sf afl-clang-fast.8 ../afl-clang-fast++.8 +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + ln -sf afl-clang-fast.8 ../afl-clang-lto.8 + ln -sf afl-clang-fast.8 ../afl-clang-lto++.8 +endif +endif + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo + rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile index 006d115d..0b306dde 100644 --- a/llvm_mode/Makefile +++ b/llvm_mode/Makefile @@ -1,375 +1,2 @@ -# -# american fuzzy lop++ - LLVM instrumentation -# ----------------------------------------- -# -# Written by Laszlo Szekeres and -# Michal Zalewski -# -# LLVM integration design comes from Laszlo Szekeres. -# -# Copyright 2015, 2016 Google Inc. 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 -# - -# For Heiko: -#TEST_MMAP=1 -HASH=\# - -PREFIX ?= /usr/local -HELPER_PATH ?= $(PREFIX)/lib/afl -BIN_PATH ?= $(PREFIX)/bin -DOC_PATH ?= $(PREFIX)/share/doc/afl -MISC_PATH ?= $(PREFIX)/share/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -ifeq "$(shell uname)" "OpenBSD" - LLVM_CONFIG ?= $(BIN_PATH)/llvm-config - HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1) - ifeq "$(HAS_OPT)" "1" - $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9") - endif -else - LLVM_CONFIG ?= llvm-config -endif - -LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null ) -LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 ) -LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) -LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//') -LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) -LLVM_STDCXX = gnu++11 -LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0) -LLVM_LTO = 0 - -ifeq "$(LLVMVER)" "" - $(warning [!] llvm_mode needs llvm-config, which was not found) -endif - -ifeq "$(LLVM_UNSUPPORTED)" "1" - $(warning llvm_mode only supports llvm versions 3.8.0 up to 11) -endif - -ifeq "$(LLVM_MAJOR)" "9" - $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation) - $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) - LLVM_LTO = 1 -endif - -ifeq "$(LLVM_NEW_API)" "1" - $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14) - $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) - LLVM_STDCXX = c++14 - LLVM_LTO = 1 -endif - -ifeq "$(LLVM_LTO)" "0" - $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.) -endif - -ifeq "$(LLVM_APPLE)" "1" - $(warning llvm_mode will not compile with Xcode clang...) -endif - -# We were using llvm-config --bindir to get the location of clang, but -# this seems to be busted on some distros, so using the one in $PATH is -# probably better. - -CC = $(LLVM_BINDIR)/clang -CXX = $(LLVM_BINDIR)/clang++ - -ifeq "$(shell test -e $(CC) || echo 1 )" "1" - # llvm-config --bindir may not providing a valid path, so ... - ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1" - # we found one in the local install directory, lets use these - CC = $(BIN_DIR)/clang - CXX = $(BIN_DIR)/clang++ - else - # hope for the best - $(warning we have trouble finding clang/clang++ - llvm-config is not helping us) - CC = clang - CXX = clang++ - endif -endif - -# sanity check. -# Are versions of clang --version and llvm-config --version equal? -CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p') - -ifneq "$(CLANGVER)" "$(LLVMVER)" - CC = $(shell $(LLVM_CONFIG) --bindir)/clang - CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++ -endif - -# After we set CC/CXX we can start makefile magic tests - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_OPT = -march=native -endif - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto=full -else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto=thin - else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto - endif - endif -endif - -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(AFL_REAL_LD)" "" - AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null) - ifeq "$(AFL_REAL_LD)" "" - AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null) - endif -endif -endif - -CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 -override CFLAGS = -Wall \ - -g -Wno-pointer-sign -I ../include/ \ - -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ - -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ - -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ - -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function -ifdef AFL_TRACE_PC - CFLAGS += -DUSE_TRACE_PC=1 -endif - -CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 -override CXXFLAGS += -Wall -g -I ../include/ \ - -DVERSION=\"$(VERSION)\" -Wno-variadic-macros - -CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS) -CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) - - -# User teor2345 reports that this is required to make things work on MacOS X. -ifeq "$(shell uname)" "Darwin" - CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress -endif - -ifeq "$(shell uname)" "OpenBSD" - CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so -endif - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS += -DAFL_CLANG_FUSELD=1 -endif - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifndef AFL_TRACE_PC - PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.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 -else - PROGS = ../afl-clang-fast ../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 -endif - -# If prerequisites are not given, warn, do not build anything, and exit with code 0 -ifeq "$(LLVMVER)" "" - NO_BUILD = 1 -endif - -ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00" - NO_BUILD = 1 -endif - -ifeq "$(NO_BUILD)" "1" - TARGETS = no_build -else - TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done -endif - -LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?) - -all: $(TARGETS) - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - -no_build: - @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m" - -test_deps: -ifndef AFL_TRACE_PC - @echo "[*] Checking for working 'llvm-config'..." - ifneq "$(LLVM_APPLE)" "1" - @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 ) - endif -else - @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)." -endif - @echo "[*] Checking for working '$(CC)'..." - @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) - @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'" -ifneq "$(CLANGVER)" "$(LLVMVER)" - @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)" - @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang" -else - @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good." -endif - @echo "[*] Checking for '../afl-showmap'..." - @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) - @echo "[+] All set and ready to build." - -afl-common.o: ../src/afl-common.c - $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) - -../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps - $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" - ln -sf afl-clang-fast ../afl-clang-fast++ -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - ln -sf afl-clang-fast ../afl-clang-lto - ln -sf afl-clang-fast ../afl-clang-lto++ -endif -endif - -../afl-ld: afl-ld.c -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) - ln -sf afl-ld ../ld - @rm -f .test-instr - @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto" - @rm -f .test-instr -endif -endif -../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps - -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) - -../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps -ifeq "$(LLVM_MIN_4_0_1)" "0" - $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) -endif - $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) - -../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc -ifeq "$(LLVM_LTO)" "1" - $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -endif - -../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc -ifeq "$(LLVM_LTO)" "1" - $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) -endif - -# laf -../split-switches-pass.so: split-switches-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -../split-compares-pass.so: split-compares-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -# /laf - -../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) - -../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) - -../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps - $(CC) $(CFLAGS) -fPIC -c $< -o $@ - -../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps - @printf "[*] Building 32-bit variant of the runtime (-m32)... " - @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - -../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps - @printf "[*] Building 64-bit variant of the runtime (-m64)... " - @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - -test_build: $(PROGS) - @echo "[*] Testing the CC wrapper and instrumentation output..." - unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) - ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null - echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr - @rm -f test-instr - @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi - @echo "[+] All right, the instrumentation seems to be working!" - -all_done: test_build - @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs." - -.NOTPARALLEL: clean - -install: all - install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) -ifndef AFL_TRACE_PC - 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 -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi -else - if [ -f ../afl-clang-fast -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 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi -endif - 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 - if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi - set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi - install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/ - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md - -vpath % .. -%.8: % - @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@ - @echo .SH NAME >> ../$@ - @echo .B $* >> ../$@ - @echo >> ../$@ - @echo .SH SYNOPSIS >> ../$@ - @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ - @echo >> ../$@ - @echo .SH OPTIONS >> ../$@ - @echo .nf >> ../$@ - @../$* -h 2>&1 | tail -n +4 >> ../$@ - @echo >> ../$@ - @echo .SH AUTHOR >> ../$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ - @echo >> ../$@ - @echo .SH LICENSE >> ../$@ - @echo Apache License Version 2.0, January 2004 >> ../$@ - ln -sf afl-clang-fast.8 ../afl-clang-fast++.8 -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - ln -sf afl-clang-fast.8 ../afl-clang-lto.8 - ln -sf afl-clang-fast.8 ../afl-clang-lto++.8 -endif -endif - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo - rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld +all: + @echo please use GNU make, thanks! diff --git a/qemu_mode/libcompcov/GNUmakefile b/qemu_mode/libcompcov/GNUmakefile new file mode 100644 index 00000000..f06ac2af --- /dev/null +++ b/qemu_mode/libcompcov/GNUmakefile @@ -0,0 +1,44 @@ +# +# american fuzzy lop++ - libcompcov +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. 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 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops -I ../../include/ +CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +LDFLAGS += -ldl + +all: libcompcov.so + +libcompcov.so: libcompcov.so.c ../../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../../libcompcov.so compcovtest + +compcovtest: compcovtest.cc + $(CXX) -std=c++11 $< -o $@ + +install: all + install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md + diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index f06ac2af..0b306dde 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -1,44 +1,2 @@ -# -# american fuzzy lop++ - libcompcov -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. 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 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -I ../../include/ -CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -LDFLAGS += -ldl - -all: libcompcov.so - -libcompcov.so: libcompcov.so.c ../../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../../libcompcov.so compcovtest - -compcovtest: compcovtest.cc - $(CXX) -std=c++11 $< -o $@ - -install: all - install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md - +all: + @echo please use GNU make, thanks! diff --git a/qemu_mode/unsigaction/GNUmakefile b/qemu_mode/unsigaction/GNUmakefile new file mode 100644 index 00000000..31fa8c55 --- /dev/null +++ b/qemu_mode/unsigaction/GNUmakefile @@ -0,0 +1,34 @@ +# +# american fuzzy lop++ - unsigaction +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. 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 +# + +ifndef AFL_NO_X86 + +all: lib_i386 lib_amd64 + +lib_i386: + @$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so 2>/dev/null ; if [ "$$?" = "0" ]; then echo "unsigaction32 build success"; else echo "unsigaction32 build failure (that's fine)"; fi + +lib_amd64: + $(CC) -fPIC -shared unsigaction.c -o unsigaction64.so + +clean: + rm -f unsigaction32.so unsigaction64.so + +else + +all: + @echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)." + +endif diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile index 31fa8c55..0b306dde 100644 --- a/qemu_mode/unsigaction/Makefile +++ b/qemu_mode/unsigaction/Makefile @@ -1,34 +1,2 @@ -# -# american fuzzy lop++ - unsigaction -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. 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 -# - -ifndef AFL_NO_X86 - -all: lib_i386 lib_amd64 - -lib_i386: - @$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so 2>/dev/null ; if [ "$$?" = "0" ]; then echo "unsigaction32 build success"; else echo "unsigaction32 build failure (that's fine)"; fi - -lib_amd64: - $(CC) -fPIC -shared unsigaction.c -o unsigaction64.so - -clean: - rm -f unsigaction32.so unsigaction64.so - -else - all: - @echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)." - -endif + @echo please use GNU make, thanks! diff --git a/src/third_party/libradamsa/GNUmakefile b/src/third_party/libradamsa/GNUmakefile new file mode 100644 index 00000000..c5a78ead --- /dev/null +++ b/src/third_party/libradamsa/GNUmakefile @@ -0,0 +1,26 @@ +CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +all: libradamsa.so + +# These can be overriden: +CFLAGS ?= -march=native $(CFLAGS_FLTO) + +# These are required: (otherwise radamsa gets very very slooooow) +CFLAGS += -O3 -funroll-loops + +libradamsa.so: libradamsa.a + $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so + +libradamsa.a: libradamsa.c radamsa.h + @echo " ***************************************************************" + @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" + @echo " ***************************************************************" + $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c + +test: libradamsa.a libradamsa-test.c + $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a + ./libradamsa-test libradamsa-test.c | grep "library test passed" + rm /tmp/libradamsa-*.fuzz + +clean: + rm -f libradamsa.a libradamsa.so libradamsa-test diff --git a/src/third_party/libradamsa/Makefile b/src/third_party/libradamsa/Makefile index c5a78ead..0b306dde 100644 --- a/src/third_party/libradamsa/Makefile +++ b/src/third_party/libradamsa/Makefile @@ -1,26 +1,2 @@ -CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) - -all: libradamsa.so - -# These can be overriden: -CFLAGS ?= -march=native $(CFLAGS_FLTO) - -# These are required: (otherwise radamsa gets very very slooooow) -CFLAGS += -O3 -funroll-loops - -libradamsa.so: libradamsa.a - $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so - -libradamsa.a: libradamsa.c radamsa.h - @echo " ***************************************************************" - @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" - @echo " ***************************************************************" - $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c - -test: libradamsa.a libradamsa-test.c - $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a - ./libradamsa-test libradamsa-test.c | grep "library test passed" - rm /tmp/libradamsa-*.fuzz - -clean: - rm -f libradamsa.a libradamsa.so libradamsa-test +all: + @echo please use GNU make, thanks! diff --git a/unicorn_mode/samples/c/GNUmakefile b/unicorn_mode/samples/c/GNUmakefile new file mode 100644 index 00000000..fe100490 --- /dev/null +++ b/unicorn_mode/samples/c/GNUmakefile @@ -0,0 +1,42 @@ +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 + +UNAME_S := $(shell uname -s) + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm +ifeq ($(UNAME_S), Linux) +LDFLAGS += -lrt +endif + +ifneq ($(CROSS),) +CC = $(CROSS)gcc +endif + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -O3 -c $< + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -g -c $< -o $@ + +harness: harness.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug diff --git a/unicorn_mode/samples/c/Makefile b/unicorn_mode/samples/c/Makefile index fe100490..0b306dde 100644 --- a/unicorn_mode/samples/c/Makefile +++ b/unicorn_mode/samples/c/Makefile @@ -1,42 +1,2 @@ -# UnicornAFL Usage -# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 -# Adapted for AFL++ by domenukk , 2020 - -UNAME_S := $(shell uname -s) - -LIBDIR = ../../unicornafl -BIN_EXT = -AR_EXT = a - -# Verbose output? -V ?= 0 - -CFLAGS += -Wall -Werror -I../../unicornafl/include - -LDFLAGS += -L$(LIBDIR) -lpthread -lm -ifeq ($(UNAME_S), Linux) -LDFLAGS += -lrt -endif - -ifneq ($(CROSS),) -CC = $(CROSS)gcc -endif - -.PHONY: all clean - -all: harness - -clean: - rm -rf *.o harness harness-debug - -harness.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -O3 -c $< - -harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -g -c $< -o $@ - -harness: harness.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ - -debug: harness-debug.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug +all: + @echo please use GNU make, thanks! diff --git a/unicorn_mode/samples/persistent/GNUmakefile b/unicorn_mode/samples/persistent/GNUmakefile new file mode 100644 index 00000000..fe100490 --- /dev/null +++ b/unicorn_mode/samples/persistent/GNUmakefile @@ -0,0 +1,42 @@ +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 + +UNAME_S := $(shell uname -s) + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm +ifeq ($(UNAME_S), Linux) +LDFLAGS += -lrt +endif + +ifneq ($(CROSS),) +CC = $(CROSS)gcc +endif + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -O3 -c $< + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -g -c $< -o $@ + +harness: harness.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile index fe100490..0b306dde 100644 --- a/unicorn_mode/samples/persistent/Makefile +++ b/unicorn_mode/samples/persistent/Makefile @@ -1,42 +1,2 @@ -# UnicornAFL Usage -# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 -# Adapted for AFL++ by domenukk , 2020 - -UNAME_S := $(shell uname -s) - -LIBDIR = ../../unicornafl -BIN_EXT = -AR_EXT = a - -# Verbose output? -V ?= 0 - -CFLAGS += -Wall -Werror -I../../unicornafl/include - -LDFLAGS += -L$(LIBDIR) -lpthread -lm -ifeq ($(UNAME_S), Linux) -LDFLAGS += -lrt -endif - -ifneq ($(CROSS),) -CC = $(CROSS)gcc -endif - -.PHONY: all clean - -all: harness - -clean: - rm -rf *.o harness harness-debug - -harness.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -O3 -c $< - -harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -g -c $< -o $@ - -harness: harness.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ - -debug: harness-debug.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug +all: + @echo please use GNU make, thanks! -- cgit 1.4.1 From 7114663f52f095d549e438e7e1b091b172c6627f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 16:41:33 +0200 Subject: small enhancements and code-format --- include/afl-fuzz.h | 6 +++--- include/list.h | 35 +++++++++++++++++------------------ src/afl-fuzz-stats.c | 26 +++++++++++++++----------- src/afl-fuzz.c | 6 +++++- 4 files changed, 40 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index a9165064..56135d0e 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -935,13 +935,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, static inline u32 rand_below(afl_state_t *afl, u32 limit) { #ifdef HAVE_ARC4RANDOM - if (afl->fixed_seed) { return random() % limit; } + if (unlikely(afl->fixed_seed)) { return random() % limit; } /* The boundary not being necessarily a power of 2, we need to ensure the result uniformity. */ return arc4random_uniform(limit); #else - if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) { + if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) { ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom"); @@ -957,7 +957,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) { static inline u32 get_rand_seed(afl_state_t *afl) { - if (afl->fixed_seed) return (u32)afl->init_seed; + if (unlikely(afl->fixed_seed)) return (u32)afl->init_seed; return afl->rand_seed[0]; } diff --git a/include/list.h b/include/list.h index d9cd9d34..e93b4e8f 100644 --- a/include/list.h +++ b/include/list.h @@ -98,24 +98,23 @@ static inline void list_append(list_t *list, void *el) { A return from this block will return from calling func. */ -#define LIST_FOREACH(list, type, block) \ - do { \ - \ - list_t * li = (list); \ - element_t *head = get_head((li)); \ - element_t *el_box = (head)->next; \ - if (!el_box) FATAL("foreach over uninitialized list"); \ - while (el_box != head) { \ - \ - __attribute__((unused)) \ - type *el = (type *)((el_box)->data); \ - /* get next so el_box can be unlinked */ \ - element_t *next = el_box->next; \ - {block}; \ - el_box = next; \ - \ - } \ - \ +#define LIST_FOREACH(list, type, block) \ + do { \ + \ + list_t * li = (list); \ + element_t *head = get_head((li)); \ + element_t *el_box = (head)->next; \ + if (!el_box) FATAL("foreach over uninitialized list"); \ + while (el_box != head) { \ + \ + __attribute__((unused)) type *el = (type *)((el_box)->data); \ + /* get next so el_box can be unlinked */ \ + element_t *next = el_box->next; \ + {block}; \ + el_box = next; \ + \ + } \ + \ } while (0); /* In foreach: remove the current el from the list */ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 98a97a34..169dbf2a 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -36,6 +36,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, u8 fn[PATH_MAX]; s32 fd; FILE * f; + uint32_t t_bytes = count_non_255_bytes(afl->virgin_bits); snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); @@ -97,6 +98,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "exec_timeout : %u\n" "slowest_exec_ms : %u\n" "peak_rss_mb : %lu\n" + "var_byte_count : %u\n" + "found_edges : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -119,9 +122,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else (unsigned long int)(rus.ru_maxrss >> 10), #endif - afl->use_banner, afl->unicorn_mode ? "unicorn" : "", - afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "", - afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", + afl->var_byte_count, t_bytes, afl->use_banner, + afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "", + afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "", + afl->crash_mode ? "crash " : "", afl->persistent_mode ? "persistent " : "", afl->deferred_mode ? "deferred " : "", (afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode || @@ -257,7 +261,7 @@ void show_stats(afl_state_t *afl) { t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE; if (t_bytes) - stab_ratio = 100 - ((double)afl->var_byte_count) * 100 / t_bytes; + stab_ratio = 100 - (((double)afl->var_byte_count) * 100) / t_bytes; else stab_ratio = 100; @@ -361,9 +365,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -445,9 +449,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -476,9 +480,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -552,7 +556,7 @@ void show_stats(afl_state_t *afl) { /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6e86285d..ad4f5b6b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -691,6 +691,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fixed_seed) OKF("Running with fixed seed: %u", (u32)afl->init_seed); srandom((u32)afl->init_seed); + srand((u32)afl->init_seed); // in case it is a different implementation if (afl->use_radamsa) { @@ -721,11 +722,14 @@ int main(int argc, char **argv_orig, char **envp) { } -#if defined(__SANITIZE_ADDRESS__) +#if defined(__SANITIZE_ADDRESS__) if (afl->fsrv.mem_limit) { + WARNF("in the ASAN build we disable all memory limits"); afl->fsrv.mem_limit = 0; + } + #endif setup_signal_handlers(); -- cgit 1.4.1 From 2ae0208d3be8ffba76f6cf370c99efa05429ad69 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 16:46:31 +0200 Subject: fix UI bug for bit flip yields --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 169dbf2a..77bbe023 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -571,7 +571,7 @@ void show_stats(afl_state_t *afl) { u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]), u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]), u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]), - u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP4]), u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); } -- cgit 1.4.1 From cc65e91eeba541aa9e3b42e81df3d752814eff21 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 17:00:35 +0200 Subject: restore portable Makefiles --- examples/custom_mutators/GNUmakefile | 7 ------ examples/custom_mutators/Makefile | 9 +++++-- qemu_mode/libcompcov/GNUmakefile | 44 -------------------------------- qemu_mode/libcompcov/Makefile | 46 ++++++++++++++++++++++++++++++++-- src/third_party/libradamsa/GNUmakefile | 26 ------------------- src/third_party/libradamsa/Makefile | 28 +++++++++++++++++++-- 6 files changed, 77 insertions(+), 83 deletions(-) delete mode 100644 examples/custom_mutators/GNUmakefile delete mode 100644 qemu_mode/libcompcov/GNUmakefile delete mode 100644 src/third_party/libradamsa/GNUmakefile (limited to 'src') diff --git a/examples/custom_mutators/GNUmakefile b/examples/custom_mutators/GNUmakefile deleted file mode 100644 index 9849f3f4..00000000 --- a/examples/custom_mutators/GNUmakefile +++ /dev/null @@ -1,7 +0,0 @@ -all: libexamplemutator.so - -libexamplemutator.so: - $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so - -clean: - rm -rf libexamplemutator.so diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 0b306dde..9849f3f4 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,2 +1,7 @@ -all: - @echo please use GNU make, thanks! +all: libexamplemutator.so + +libexamplemutator.so: + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + +clean: + rm -rf libexamplemutator.so diff --git a/qemu_mode/libcompcov/GNUmakefile b/qemu_mode/libcompcov/GNUmakefile deleted file mode 100644 index f06ac2af..00000000 --- a/qemu_mode/libcompcov/GNUmakefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# american fuzzy lop++ - libcompcov -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. 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 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -I ../../include/ -CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -LDFLAGS += -ldl - -all: libcompcov.so - -libcompcov.so: libcompcov.so.c ../../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../../libcompcov.so compcovtest - -compcovtest: compcovtest.cc - $(CXX) -std=c++11 $< -o $@ - -install: all - install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md - diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index 0b306dde..f06ac2af 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -1,2 +1,44 @@ -all: - @echo please use GNU make, thanks! +# +# american fuzzy lop++ - libcompcov +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. 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 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops -I ../../include/ +CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +LDFLAGS += -ldl + +all: libcompcov.so + +libcompcov.so: libcompcov.so.c ../../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../../libcompcov.so compcovtest + +compcovtest: compcovtest.cc + $(CXX) -std=c++11 $< -o $@ + +install: all + install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md + diff --git a/src/third_party/libradamsa/GNUmakefile b/src/third_party/libradamsa/GNUmakefile deleted file mode 100644 index c5a78ead..00000000 --- a/src/third_party/libradamsa/GNUmakefile +++ /dev/null @@ -1,26 +0,0 @@ -CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) - -all: libradamsa.so - -# These can be overriden: -CFLAGS ?= -march=native $(CFLAGS_FLTO) - -# These are required: (otherwise radamsa gets very very slooooow) -CFLAGS += -O3 -funroll-loops - -libradamsa.so: libradamsa.a - $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so - -libradamsa.a: libradamsa.c radamsa.h - @echo " ***************************************************************" - @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" - @echo " ***************************************************************" - $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c - -test: libradamsa.a libradamsa-test.c - $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a - ./libradamsa-test libradamsa-test.c | grep "library test passed" - rm /tmp/libradamsa-*.fuzz - -clean: - rm -f libradamsa.a libradamsa.so libradamsa-test diff --git a/src/third_party/libradamsa/Makefile b/src/third_party/libradamsa/Makefile index 0b306dde..c5a78ead 100644 --- a/src/third_party/libradamsa/Makefile +++ b/src/third_party/libradamsa/Makefile @@ -1,2 +1,26 @@ -all: - @echo please use GNU make, thanks! +CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +all: libradamsa.so + +# These can be overriden: +CFLAGS ?= -march=native $(CFLAGS_FLTO) + +# These are required: (otherwise radamsa gets very very slooooow) +CFLAGS += -O3 -funroll-loops + +libradamsa.so: libradamsa.a + $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so + +libradamsa.a: libradamsa.c radamsa.h + @echo " ***************************************************************" + @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" + @echo " ***************************************************************" + $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c + +test: libradamsa.a libradamsa-test.c + $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a + ./libradamsa-test libradamsa-test.c | grep "library test passed" + rm /tmp/libradamsa-*.fuzz + +clean: + rm -f libradamsa.a libradamsa.so libradamsa-test -- cgit 1.4.1 From 97cae2df9975589eb05a543f92c6ba232242fd7b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 23:33:55 +0200 Subject: no random timing for -s fixed_seed --- src/afl-fuzz-queue.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 61bf62f5..92cbab6f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -186,7 +186,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2 = next_pow2(q->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE) + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) fav_factor = q->len << 2; else fav_factor = q->exec_us * q->len; @@ -203,7 +203,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE) + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) top_rated_fav_factor = afl->top_rated[i]->len << 2; else top_rated_fav_factor = @@ -214,8 +214,17 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { else if (fuzz_p2 == top_rated_fuzz_p2) if (fav_factor > top_rated_fav_factor) continue; - if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) - continue; + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) { + + if (fav_factor > afl->top_rated[i]->len << 2) + continue; + + } else { + + if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) + continue; + + } /* Looks like we're going to win. Decrease ref count for the previous winner, discard its afl->fsrv.trace_bits[] if necessary. */ @@ -330,7 +339,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Longer execution time means longer work on the input, the deeper in // coverage, the better the fuzzing, right? -mh - if (afl->schedule != MMOPT && afl->schedule != RARE) { + if (afl->schedule != MMOPT && afl->schedule != RARE && likely(!afl->fixed_seed)) { if (q->exec_us * 0.1 > avg_exec_us) perf_score = 10; -- cgit 1.4.1