diff options
author | van Hauser <vh@thc.org> | 2020-08-14 13:23:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-14 13:23:14 +0200 |
commit | a7537b5511ad767d2240cf2dc6d3e261daa676f9 (patch) | |
tree | 2cd8418efff844e634425e050ef716301adfd84b /src/afl-fuzz-run.c | |
parent | 15e799f7ae666418e75c6a79db833c5316b21f97 (diff) | |
parent | 83281503b3f1d4109c6f7a6af62a2133d55f1150 (diff) | |
download | afl++-a7537b5511ad767d2240cf2dc6d3e261daa676f9.tar.gz |
Merge branch 'debug' into dev
Diffstat (limited to 'src/afl-fuzz-run.c')
-rw-r--r-- | src/afl-fuzz-run.c | 99 |
1 files changed, 70 insertions, 29 deletions
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d3f823c9..5381723d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -350,7 +350,9 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - if (q->exec_cksum) { + if (unlikely(afl->taint_mode)) + q->exec_cksum = 0; + else if (q->exec_cksum) { memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); hnb = has_new_bits(afl, afl->virgin_bits); @@ -753,56 +755,65 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (remove_pos < q->len) { u32 trim_avail = MIN(remove_len, q->len - remove_pos); - u64 cksum; - write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); + if (likely((!q->taint_bytes_highest) || + (q->len - trim_avail > q->taint_bytes_highest))) { - fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; + u64 cksum; - if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); - /* Note that we don't keep track of crashes or hangs here; maybe TODO? - */ + fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + ++afl->trim_execs; + + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ + + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + + /* If the deletion had no impact on the trace, make it permanent. This + isn't perfect for variable-path inputs, but we're just making a + best-effort pass, so it's not a big deal if we end up with false + negatives every now and then. */ + + if (cksum == q->exec_cksum) { - cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + u32 move_tail = q->len - remove_pos - trim_avail; - /* If the deletion had no impact on the trace, make it permanent. This - isn't perfect for variable-path inputs, but we're just making a - best-effort pass, so it's not a big deal if we end up with false - negatives every now and then. */ + q->len -= trim_avail; + len_p2 = next_pow2(q->len); - if (cksum == q->exec_cksum) { + memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, + move_tail); - u32 move_tail = q->len - remove_pos - trim_avail; + /* Let's save a clean trace, which will be needed by + update_bitmap_score once we're done with the trimming stuff. */ - q->len -= trim_avail; - len_p2 = next_pow2(q->len); + if (!needs_write) { - memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, - move_tail); + needs_write = 1; + memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); - /* Let's save a clean trace, which will be needed by - update_bitmap_score once we're done with the trimming stuff. */ + } - if (!needs_write) { + } else { - needs_write = 1; - memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); + remove_pos += remove_len; } + /* Since this can be slow, update the screen every now and then. */ + if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } + ++afl->stage_cur; + } else { remove_pos += remove_len; } - /* Since this can be slow, update the screen every now and then. */ - - if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } - ++afl->stage_cur; - } remove_len >>= 1; @@ -855,6 +866,8 @@ abort_trimming: } +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + /* Write a modified test case, run program, process results. Handle error conditions, returning 1 if it's time to bail out. This is a helper function for fuzz_one(). */ @@ -864,6 +877,32 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; + if (unlikely(afl->taint_needs_splode)) { + + s32 new_len = afl->queue_cur->len + len - afl->taint_len; + if (new_len < 4) + new_len = 4; + else if (new_len > MAX_FILE) + new_len = MAX_FILE; + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), new_len); + + u32 i, taint = 0; + for (i = 0; i < (u32)new_len; i++) { + + if (i >= afl->taint_len || i >= afl->queue_cur->len || afl->taint_map[i]) + new_buf[i] = out_buf[taint++]; + else + new_buf[i] = afl->taint_src[i]; + + } + + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + + out_buf = new_buf; + len = new_len; + + } + write_to_testcase(afl, out_buf, len); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -911,3 +950,5 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { } +#undef BUF_PARAMS + |