diff options
-rw-r--r-- | include/afl-fuzz.h | 6 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 35 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 54 | ||||
-rw-r--r-- | src/afl-fuzz.c | 6 |
4 files changed, 76 insertions, 25 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 620f5062..4e2deaa3 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -316,6 +316,10 @@ typedef struct afl_env_vars { } afl_env_vars_t; +struct afl_pass_stat { + u8 total; u8 faileds; +}; + typedef struct afl_state { /* Position of this state in the global states list */ @@ -540,6 +544,8 @@ typedef struct afl_state { /* cmplog forkserver ids */ s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; + + struct afl_pass_stat* pass_stats; u8 describe_op_buf_256[256]; /* describe_op will use this to return a string up to 256 */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 92210c8b..c4d49ec1 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -495,7 +495,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->use_radamsa > 1) goto radamsa_stage; - if (afl->shm.cmplog_mode) { + if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { if (input_to_state_stage(afl, in_buf, out_buf, len, afl->queue_cur->exec_cksum)) @@ -2508,20 +2508,15 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - /* Skip right away if -d is given, if we have done deterministic fuzzing on - this entry ourselves (was_fuzzed), or if it has gone through deterministic - testing in earlier, resumed runs (passed_det). */ + if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { - if (afl->skip_deterministic || afl->queue_cur->was_fuzzed || - afl->queue_cur->passed_det) - goto havoc_stage; + if (input_to_state_stage(afl, in_buf, out_buf, len, + afl->queue_cur->exec_cksum)) + goto abandon_entry; - /* Skip deterministic fuzzing if exec path checksum puts this out of scope - for this master instance. */ + } - if (afl->master_max && - (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) - goto havoc_stage; + /* Go to pacemker fuzzing if MOpt is doing well */ cur_ms_lv = get_cur_time(); if (!(afl->key_puppet == 0 && @@ -2534,6 +2529,22 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { goto pacemaker_fuzzing; } + + /* Skip right away if -d is given, if we have done deterministic fuzzing on + this entry ourselves (was_fuzzed), or if it has gone through deterministic + testing in earlier, resumed runs (passed_det). */ + + if (afl->skip_deterministic || afl->queue_cur->was_fuzzed || + afl->queue_cur->passed_det) + goto havoc_stage; + + /* Skip deterministic fuzzing if exec path checksum puts this out of scope + for this master instance. */ + + if (afl->master_max && + (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) + goto havoc_stage; + doing_det = 1; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index c910e75e..c8d54ce2 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -127,9 +127,14 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) { rand_replace(afl, buf + rng->start, s); u32 cksum; + u64 start_us = get_cur_time_us(); if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) goto checksum_fail; + u64 stop_us = get_cur_time_us(); - if (cksum != exec_cksum) { + /* Discard if the mutations change the paths or if it is too decremental + in speed */ + if (cksum != exec_cksum || + (stop_us - start_us > 2 * afl->queue_cur->exec_us)) { ranges = add_range(ranges, rng->start, rng->start + s / 2); ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); @@ -365,9 +370,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u8 status; // opt not in the paper - u32 fails = 0; + u32 fails; + u8 found_one = 0; for (i = 0; i < loggeds; ++i) { + + fails = 0; struct cmp_operands *o = &afl->shm.cmp_map->log[key][i]; @@ -396,12 +404,17 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { break; } + + if (status == 1) + found_one = 1; // If failed, add to dictionary if (fails == 8) { - try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); - try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); + if (afl->pass_stats[key].total == 0) { + try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); + try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); + } } @@ -409,6 +422,11 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { afl->stage_cur++; } + + if (!found_one && afl->pass_stats[key].faileds < 0xff) { + afl->pass_stats[key].faileds++; + } + if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++; return 0; @@ -450,9 +468,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u8 status; // opt not in the paper - u32 fails = 0; + u32 fails; + u8 found_one = 0; for (i = 0; i < loggeds; ++i) { + + fails = 0; struct cmpfn_operands *o = &((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i]; @@ -482,12 +503,17 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { break; } + + if (status == 1) + found_one = 1; // If failed, add to dictionary if (fails == 8) { - maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape)); - maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape)); + if (afl->pass_stats[key].total == 0) { + maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape)); + maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape)); + } } @@ -495,6 +521,11 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { afl->stage_cur++; } + + if (!found_one && afl->pass_stats[key].faileds < 0xff) { + afl->pass_stats[key].faileds++; + } + if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++; return 0; @@ -507,6 +538,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, u32 exec_cksum) { u8 r = 1; + + if (afl->pass_stats == NULL) + afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W); if (unlikely(colorization(afl, buf, len, exec_cksum))) return 1; @@ -528,6 +562,12 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, for (k = 0; k < CMP_MAP_W; ++k) { if (!afl->shm.cmp_map->headers[k].hits) continue; + + if (afl->pass_stats[k].total && + (UR(afl, afl->pass_stats[k].total) < afl->pass_stats[k].faileds || + afl->pass_stats[k].total == 0xff)) + afl->shm.cmp_map->headers[k].hits = 0; + 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); else diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 10fee76c..b89bccb4 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -966,12 +966,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->cmplog_binary) { - if (afl->limit_time_sig) - FATAL( - "MOpt and CmpLog are mutually exclusive. We accept pull requests " - "that integrates MOpt with the optional mutators " - "(custom/radamsa/redquenn/...)."); - if (afl->unicorn_mode) FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry"); if (!afl->qemu_mode) check_binary(afl, afl->cmplog_binary); |