From 190f3024dad3713a1b2d3a42b5b99c662dd2cf58 Mon Sep 17 00:00:00 2001 From: Rishi Ranjan <43873720+rish9101@users.noreply.github.com> Date: Fri, 8 May 2020 23:38:27 +0530 Subject: Support multiple custom mutators (#282) * Make a list of custom mutators using env variable * Set up multiple custom mutators * Add destroy custom mutator and changes to load_custom_mutator * Use array instead of list, make changes to afl-fuzz-one for multiple mutators * Make change to fuzz-one custom_queue_get to support multiple mutators * Modify custom python mutator support * Fix bug * Fix missing afl->mutator->data * Revert to list with max count * Change custom_pre_save hook and code format * Free custom_mutator struct in the list * Add testcase for multiple custom mutators * Resolve merge conflict --- test/test-multiple-mutators.c | 24 ++++++++++++++++++++++++ test/test.sh | 32 +++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 test/test-multiple-mutators.c (limited to 'test') diff --git a/test/test-multiple-mutators.c b/test/test-multiple-mutators.c new file mode 100644 index 00000000..35e0407b --- /dev/null +++ b/test/test-multiple-mutators.c @@ -0,0 +1,24 @@ +/** + * Test-Case for multiple custom mutators in C + * Reference: + * https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c + */ + +#include +#include +#include +#include + +int main(int argc, char ** argv) +{ + int a=0; + char s[16]; + memset(s, 0, 16); + read(0, s, 0xa0); + + if ( s[17] != '\x00') { + abort(); + } + + return 0; +} diff --git a/test/test.sh b/test/test.sh index 90633a9f..1caa9985 100755 --- a/test/test.sh +++ b/test/test.sh @@ -949,7 +949,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { } test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.py && { unset AFL_CC - # Compile the vulnerable program + # Compile the vulnerable program for single mutator test -e ../afl-clang-fast && { ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1 } || { @@ -959,6 +959,16 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { ../afl-gcc -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1 } } + # Compile the vulnerable program for multiple mutators + test -e ../afl-clang-fast && { + ../afl-clang-fast -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1 + } || { + test -e ../afl-gcc-fast && { + ../afl-gcc-fast -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1 + } || { + ../afl-gcc -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1 + } + } # Compile the custom mutator make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1 test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && { @@ -986,6 +996,25 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { # Clean rm -rf out errors + #Run afl-fuzz w/ multiple C mutators + $ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds" + { + AFL_CUSTOM_MUTATOR_LIBRARY="${CUSTOM_MUTATOR_PATH}/libexamplemutator.so;${CUSTOM_MUTATOR_PATH}/libexamplemutator.so" ../afl-fuzz -V20 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1 + } >>errors 2>&1 + + test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here + $ECHO "$GREEN[+] afl-fuzz is working correctly with multiple C mutators" + } || { + echo CUT------------------------------------------------------------------CUT + cat errors + echo CUT------------------------------------------------------------------CUT + $ECHO "$RED[!] afl-fuzz is not working correctly with multiple C mutators" + CODE=1 + } + + # Clean + rm -rf out errors + # Run afl-fuzz w/ the Python mutator $ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds" { @@ -1021,6 +1050,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { make -C ../examples/custom_mutators clean > /dev/null 2>&1 rm -f test-custom-mutator + rm -f test-custom-mutators } || { $ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test" INCOMPLETE=1 -- cgit 1.4.1 From fa84e52af0cf1869a8abbff2f48a9c55e2d447d4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 9 May 2020 11:35:54 +0200 Subject: custom mutator code enhancements and code-format --- include/afl-fuzz.h | 16 ++++++------- src/afl-fuzz-mutators.c | 56 ++++++++++++++++++++++++------------------- src/afl-fuzz-one.c | 48 +++++++++++++++++++++---------------- src/afl-fuzz-python.c | 19 ++++----------- src/afl-fuzz-queue.c | 6 +++-- src/afl-fuzz-run.c | 22 ++++++++--------- test/test-multiple-mutators.c | 20 ++++++++-------- 7 files changed, 98 insertions(+), 89 deletions(-) (limited to 'test') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index d6a19c5d..7aed41d6 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -605,9 +605,9 @@ typedef struct afl_state { u8 * in_scratch_buf; size_t in_scratch_size; - u8 * ex_buf; - size_t ex_size; - u32 custom_mutators_count; + u8 * ex_buf; + size_t ex_size; + u32 custom_mutators_count; list_t custom_mutator_list; @@ -623,8 +623,7 @@ struct custom_mutator { void * dh; u8 * pre_save_buf; size_t pre_save_size; - u8 stacked_custom_prob, - stacked_custom; + u8 stacked_custom_prob, stacked_custom; void *data; /* custom mutator data ptr */ @@ -815,13 +814,14 @@ void read_afl_environment(afl_state_t *, char **); /* Custom mutators */ void setup_custom_mutators(afl_state_t *); void destroy_custom_mutators(afl_state_t *); -u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf, struct custom_mutator * mutator); +u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf, + struct custom_mutator *mutator); /* Python */ #ifdef USE_PYTHON -struct custom_mutator * load_custom_mutator_py(afl_state_t *, char *); -void finalize_py_module(void *); +struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *); +void finalize_py_module(void *); size_t pre_save_py(void *, u8 *, size_t, u8 **); s32 init_trim_py(void *, u8 *, size_t); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 23f15945..027add49 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -28,15 +28,15 @@ struct custom_mutator *load_custom_mutator(afl_state_t *, const char *); #ifdef USE_PYTHON -struct custom_mutator * load_custom_mutator_py(afl_state_t *, char *); +struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *); #endif void setup_custom_mutators(afl_state_t *afl) { /* Try mutator library first */ - struct custom_mutator * mutator; - u8 * fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); - u32 prev_mutator_count = 0; + struct custom_mutator *mutator; + u8 * fn = afl->afl_env.afl_custom_mutator_library; + u32 prev_mutator_count = 0; if (fn) { @@ -44,9 +44,9 @@ void setup_custom_mutators(afl_state_t *afl) { FATAL( "MOpt and custom mutator are mutually exclusive. We accept pull " "requests that integrates MOpt with the optional mutators " - "(custom/radamsa/redquenn/...)."); + "(custom/radamsa/redqueen/...)."); - u8 *fn_token = (u8 *)strsep((char **)&fn, ";"); + u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,"); if (likely(!fn_token)) { @@ -58,14 +58,22 @@ void setup_custom_mutators(afl_state_t *afl) { while (fn_token) { - prev_mutator_count = afl->custom_mutators_count; - mutator = load_custom_mutator(afl, fn_token); - list_append(&afl->custom_mutator_list, mutator); - afl->custom_mutators_count++; - if (prev_mutator_count > afl->custom_mutators_count) FATAL("Maximum Custom Mutator count reached."); - fn_token = (u8 *)strsep((char **)&fn, ";"); + if (*fn_token) { // strsep can be empty if ";;" + + if (afl->not_on_tty && afl->debug) + SAYF("[Custom] Processing: %s\n", fn_token); + prev_mutator_count = afl->custom_mutators_count; + mutator = load_custom_mutator(afl, fn_token); + list_append(&afl->custom_mutator_list, mutator); + afl->custom_mutators_count++; + if (prev_mutator_count > afl->custom_mutators_count) + FATAL("Maximum Custom Mutator count reached."); + fn_token = (u8 *)strsep((char **)&fn, ";:,"); + + } } + } } @@ -85,7 +93,7 @@ void setup_custom_mutators(afl_state_t *afl) { } - struct custom_mutator * mutator = load_custom_mutator_py(afl, module_name); + struct custom_mutator *mutator = load_custom_mutator_py(afl, module_name); afl->custom_mutators_count++; list_append(&afl->custom_mutator_list, mutator); @@ -113,14 +121,16 @@ void destroy_custom_mutators(afl_state_t *afl) { if (el->dh) dlclose(el->dh); if (el->pre_save_buf) { + ck_free(el->pre_save_buf); el->pre_save_buf = NULL; el->pre_save_size = 0; + } ck_free(el); - } ); + }); } @@ -212,17 +222,18 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (mutator->afl_custom_init) - mutator->data = - mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation); - mutator->stacked_custom_prob = 6; // like one of the default mutations in havoc + mutator->stacked_custom_prob = + 6; // like one of the default mutations in havoc return mutator; } -u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct custom_mutator *mutator) { +u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, + struct custom_mutator *mutator) { u8 needs_write = 0, fault = 0; u32 trim_exec = 0; @@ -235,8 +246,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct /* Initialize trimming in the custom mutator */ afl->stage_cur = 0; - afl->stage_max = - mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); + afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); if (unlikely(afl->stage_max) < 0) { FATAL("custom_init_trim error ret: %d", afl->stage_max); @@ -299,8 +309,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct } /* Tell the custom mutator that the trimming was successful */ - afl->stage_cur = - mutator->afl_custom_post_trim(mutator->data, 1); + afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 1); if (afl->not_on_tty && afl->debug) { @@ -312,8 +321,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct } else { /* Tell the custom mutator that the trimming was unsuccessful */ - afl->stage_cur = - mutator->afl_custom_post_trim(mutator->data, 0); + afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); if (unlikely(afl->stage_cur < 0)) { FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index dff1606a..ddd15c84 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -384,17 +384,21 @@ u8 fuzz_one_original(afl_state_t *afl) { #else - if (unlikely(afl->custom_mutators_count )) { + if (unlikely(afl->custom_mutators_count)) { /* The custom mutator will decide to skip this test case or not. */ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - if (el->afl_custom_queue_get && !el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) { + if (el->afl_custom_queue_get && + !el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) { + return 1; + } - } ); + }); + } if (likely(afl->pending_favored)) { @@ -1660,13 +1664,14 @@ custom_mutator_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - LIST_FOREACH (&afl->custom_mutator_list, struct custom_mutator, { + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - if ( el->afl_custom_fuzz ) { + if (el->afl_custom_fuzz) { has_custom_fuzz = true; - for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; + ++afl->stage_cur) { struct queue_entry *target; u32 tid; @@ -1698,7 +1703,7 @@ custom_mutator_stage: /* Make sure that the target has a reasonable length. */ while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 1) { + afl->queued_paths > 1) { target = target->next; ++afl->splicing_with; @@ -1717,9 +1722,9 @@ custom_mutator_stage: u8 *mutated_buf = NULL; - size_t mutated_size = el->afl_custom_fuzz( - el->data, out_buf, len, &mutated_buf, new_buf, target->len, - max_seed_size); + size_t mutated_size = + el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, + target->len, max_seed_size); if (unlikely(!mutated_buf)) { @@ -1754,15 +1759,15 @@ 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. */ + /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. + */ memcpy(out_buf, in_buf, len); } } - - } ); + }); if (!has_custom_fuzz) goto havoc_stage; @@ -1827,14 +1832,15 @@ havoc_stage: if (el->stacked_custom_prob > 100) { FATAL( - "The probability returned by afl_custom_havoc_mutation_propability " + "The probability returned by " + "afl_custom_havoc_mutation_propability " "has to be in the range 0-100."); } } - - } ); + + }); } @@ -1850,10 +1856,11 @@ havoc_stage: for (i = 0; i < use_stacking; ++i) { if (afl->custom_mutators_count) { - + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - if (el->stacked_custom && rand_below(afl, 100) < el->stacked_custom_prob) { + if (el->stacked_custom && + rand_below(afl, 100) < el->stacked_custom_prob) { u8 * custom_havoc_buf = NULL; size_t new_len = el->afl_custom_havoc_mutation( @@ -1877,8 +1884,9 @@ havoc_stage: } } - - } ); + + }); + } switch (rand_below( diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index a65add55..e90d91d1 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -295,9 +295,10 @@ void deinit_py(void *py_mutator) { } -struct custom_mutator * load_custom_mutator_py(afl_state_t *afl, char *module_name) { +struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, + char * module_name) { - struct custom_mutator * mutator; + struct custom_mutator *mutator; mutator = ck_alloc(sizeof(struct custom_mutator)); mutator->pre_save_buf = NULL; @@ -313,17 +314,9 @@ struct custom_mutator * load_custom_mutator_py(afl_state_t *afl, char *module_na PyObject **py_functions = py_mutator->py_functions; - if (py_functions[PY_FUNC_INIT]) { + if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; } - mutator->afl_custom_init = unsupported; - - } - - if (py_functions[PY_FUNC_DEINIT]) { - - mutator->afl_custom_deinit = deinit_py; - - } + if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; } /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator is quite different from the custom mutator. */ @@ -374,8 +367,6 @@ struct custom_mutator * load_custom_mutator_py(afl_state_t *afl, char *module_na } - - OKF("Python mutator '%s' installed successfully.", module_name); /* Initialize the custom mutator */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index c33751d9..cfeb6c5e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -144,16 +144,18 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - if ( el->afl_custom_queue_new_entry) { + if (el->afl_custom_queue_new_entry) { + u8 *fname_orig = NULL; /* At the initialization stage, queue_cur is NULL */ if (afl->queue_cur) fname_orig = afl->queue_cur->fname; el->afl_custom_queue_new_entry(el->data, fname, fname_orig); + } - } ); + }); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 3876dec7..4a22dad6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -91,22 +91,22 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (unlikely(afl->custom_mutators_count)) { - u8 *new_buf = NULL; + u8 * new_buf = NULL; ssize_t new_size = len; - void * new_mem = mem; + void * new_mem = mem; LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_pre_save) { - new_size = el->afl_custom_pre_save( - el->data, new_mem, new_size, &new_buf - ); + + new_size = + el->afl_custom_pre_save(el->data, new_mem, new_size, &new_buf); } new_mem = new_buf; - } ); + }); if (unlikely(!new_buf && (new_size <= 0))) { @@ -124,7 +124,6 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { } - } else { /* boring uncustom. */ @@ -535,21 +534,22 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Custom mutator trimmer */ if (afl->custom_mutators_count) { - u8 trimmed_case = 0; + u8 trimmed_case = 0; bool custom_trimmed = false; LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_trim) { - + trimmed_case = trim_case_custom(afl, q, in_buf, el); custom_trimmed = true; + } - } ); + }); if (custom_trimmed) return trimmed_case; - + } u8 needs_write = 0, fault = 0; diff --git a/test/test-multiple-mutators.c b/test/test-multiple-mutators.c index 35e0407b..0f6f5c64 100644 --- a/test/test-multiple-mutators.c +++ b/test/test-multiple-mutators.c @@ -9,16 +9,16 @@ #include #include -int main(int argc, char ** argv) -{ - int a=0; - char s[16]; - memset(s, 0, 16); - read(0, s, 0xa0); +int main(int argc, char **argv) { - if ( s[17] != '\x00') { - abort(); - } + int a = 0; + char s[16]; + memset(s, 0, 16); + read(0, s, 0xa0); + + if (s[17] != '\x00') { abort(); } + + return 0; - return 0; } + -- cgit 1.4.1 From 26fe7a9d669448ed8711c575aecd452ce0fcb00a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 10 May 2020 15:53:47 +0200 Subject: final code-format fixes, remove test-multiple-mutators when done --- include/alloc-inl.h | 84 +++++++++++++++++++++++++---------------------------- test/test.sh | 1 + 2 files changed, 40 insertions(+), 45 deletions(-) (limited to 'test') diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 7279c323..a8483a9e 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -249,23 +249,21 @@ static inline u8 *DFL_ck_memdup_str(u8 *mem, u32 size) { /* Macro to enforce allocation limits as a last-resort defense against integer overflows. */ -#define ALLOC_CHECK_SIZE(_s) \ - do { \ - \ - if ((_s) > MAX_ALLOC) ABORT("Bad alloc request: %u bytes", (_s)); - -} - -while (0) +#define ALLOC_CHECK_SIZE(_s) \ + do { \ + \ + if ((_s) > MAX_ALLOC) ABORT("Bad alloc request: %u bytes", (_s)); \ + \ + } while (0) /* Macro to check malloc() failures and the like. */ -#define ALLOC_CHECK_RESULT(_r, _s) \ - do { \ - \ - if (!(_r)) ABORT("Out of memory: can't allocate %u bytes", (_s)); - -} +#define ALLOC_CHECK_RESULT(_r, _s) \ + do { \ + \ + if (!(_r)) ABORT("Out of memory: can't allocate %u bytes", (_s)); \ + \ + } while (0) @@ -290,38 +288,34 @@ while (0) /* Sanity-checking macros for pointers. */ -#define CHECK_PTR(_p) \ - do { \ - \ - if (_p) { \ - \ - if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) { \ - \ - if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \ - ABORT("Use after free."); \ - else \ - ABORT("Corrupted head alloc canary."); - -} - -if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) ABORT("Corrupted tail alloc canary."); - -} - -} - -while (0) - -#define CHECK_PTR_EXPR(_p) \ - ({ \ - \ - \ - \ - typeof(_p) _tmp = (_p); \ - CHECK_PTR(_tmp); \ - _tmp; +#define CHECK_PTR(_p) \ + do { \ + \ + if (_p) { \ + \ + if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) { \ + \ + if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \ + ABORT("Use after free."); \ + else \ + ABORT("Corrupted head alloc canary."); \ + \ + } \ + if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \ + ABORT("Corrupted tail alloc canary."); \ + \ + } \ + \ + } while (0) -}) +#define CHECK_PTR_EXPR(_p) \ + ({ \ + \ + typeof(_p) _tmp = (_p); \ + CHECK_PTR(_tmp); \ + _tmp; \ + \ + }) /* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized requests. */ diff --git a/test/test.sh b/test/test.sh index 1caa9985..919d7a9c 100755 --- a/test/test.sh +++ b/test/test.sh @@ -1039,6 +1039,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { # Clean rm -rf in out errors rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/ + rm -f test-multiple-mutators } || { ls . ls ${CUSTOM_MUTATOR_PATH} -- cgit 1.4.1