diff options
Diffstat (limited to 'src/afl-fuzz-mutators.c')
-rw-r--r-- | src/afl-fuzz-mutators.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 9fc77ffe..850266c2 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -168,7 +168,8 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_deinit", optional for backward compatibility */ mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); - if (!mutator->afl_custom_deinit) FATAL("Symbol 'afl_custom_init' not found."); + if (!mutator->afl_custom_deinit) + FATAL("Symbol 'afl_custom_deinit' not found."); /* "afl_custom_post_process", optional */ mutator->afl_custom_post_process = dlsym(dh, "afl_custom_post_process"); @@ -282,9 +283,32 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else if (unlikely(retlen > orig_len)) { - FATAL( - "Trimmed data returned by custom mutator is larger than original " - "data"); + /* Do not exit the fuzzer, even if the trimmed data returned by the custom + mutator is larger than the original data. For some use cases, like the + grammar mutator, the definition of "size" may have different meanings. + For example, the trimming function in a grammar mutator aims at + reducing the objects in a grammar structure, but does not guarantee to + generate a smaller binary buffer. + + Thus, we allow the custom mutator to generate the trimmed data that is + larger than the original data. */ + + if (afl->not_on_tty && afl->debug) { + + WARNF( + "Trimmed data returned by custom mutator is larger than original " + "data"); + + } + + } else if (unlikely(retlen == 0)) { + + /* Do not run the empty test case on the target. To keep the custom + trimming function running, we simply treat the empty test case as an + unsuccessful trimming and skip it, instead of aborting the trimming. */ + + ++afl->trim_execs; + goto unsuccessful_trimming; } @@ -325,6 +349,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else { + unsuccessful_trimming: + /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); if (unlikely(afl->stage_cur < 0)) { |