From 4ff2673895c85ac6ac15dffc999e05a43d8d1521 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 9 Apr 2025 14:21:42 +0200 Subject: [PATCH] fix update_bitmap_score when no current trace is present --- docs/Changelog.md | 1 + include/afl-fuzz.h | 2 +- src/afl-fuzz-bitmap.c | 6 +-- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-queue.c | 104 +++++++++++++++++++++------------------- src/afl-fuzz-run.c | 4 +- src/afl-fuzz.c | 4 +- src/afl-showmap.c | 3 +- 8 files changed, 65 insertions(+), 61 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 0c616d4f..f34d5437 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,6 +11,7 @@ - memory leak fixes by @kcwu - thanks! - some more nits and small memory saves thanks to @kcwu - remove deprecated files from queue/.state + - fix bitmap update function if no current trace is present - frida_mode: - fixes for new MacOS + M4 hardware diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index f21f2dda..f475498a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1186,7 +1186,7 @@ void deinit_py(void *); void mark_as_det_done(afl_state_t *, struct queue_entry *); void add_to_queue(afl_state_t *, u8 *, u32, u8); void destroy_queue(afl_state_t *); -void update_bitmap_score(afl_state_t *, struct queue_entry *); +void update_bitmap_score(afl_state_t *, struct queue_entry *, bool); void cull_queue(afl_state_t *); u32 calculate_score(afl_state_t *, struct queue_entry *); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index dce672a3..0d3a1609 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -490,8 +490,7 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem, u8 fn[PATH_MAX]; u8 *queue_fn = ""; - u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0, - need_hash = 1; + u8 new_bits = 0, keeping = 0, res, is_timeout = 0, need_hash = 1; s32 fd; u64 cksum = 0; u32 cksum_simplified = 0, cksum_unique = 0; @@ -508,7 +507,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem, if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { classify_counts(&afl->fsrv); - classified = 1; need_hash = 0; cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); @@ -632,7 +630,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem, afl->san_case_status |= NON_COV_INCREASE_BUG; fault = san_fault; - classified = new_bits; goto may_save_fault; } @@ -640,7 +637,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem, } fault = san_fault; - classified = new_bits; save_to_queue: diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index dbc23ac6..7c7a4b9f 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -636,7 +636,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, q->len = out_len; memcpy(afl->fsrv.trace_bits, afl->clean_trace_custom, afl->fsrv.map_size); - update_bitmap_score(afl, q); + update_bitmap_score(afl, q, true); } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 3adbc83d..ea6d902a 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -794,7 +794,8 @@ void destroy_queue(afl_state_t *afl) { previous contender, or if the contender has a more favorable speed x size factor. */ -void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { +void update_bitmap_score(afl_state_t *afl, struct queue_entry *q, + bool have_trace) { u32 i; u64 fav_factor; @@ -824,75 +825,80 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { } - /* For every byte set in afl->fsrv.trace_bits[], see if there is a previous - winner, and how it compares to us. */ - for (i = 0; i < afl->fsrv.map_size; ++i) { + if (have_trace) { - if (afl->fsrv.trace_bits[i]) { + /* For every byte set in afl->fsrv.trace_bits[], see if there is a previous + winner, and how it compares to us. */ + for (i = 0; i < afl->fsrv.map_size; ++i) { - if (afl->top_rated[i]) { + if (afl->fsrv.trace_bits[i]) { - /* Faster-executing or smaller test cases are favored. */ - u64 top_rated_fav_factor; - u64 top_rated_fuzz_p2; + if (afl->top_rated[i]) { - if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { + /* Faster-executing or smaller test cases are favored. */ + u64 top_rated_fav_factor; + u64 top_rated_fuzz_p2; - top_rated_fuzz_p2 = 0; // Skip the fuzz_p2 comparison + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { - } else if (unlikely(afl->schedule == RARE)) { + top_rated_fuzz_p2 = 0; // Skip the fuzz_p2 comparison - top_rated_fuzz_p2 = - next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]); + } else if (unlikely(afl->schedule == RARE)) { - } else { + top_rated_fuzz_p2 = + next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]); - top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; + } else { + + top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; + + } + + if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) { + + top_rated_fav_factor = afl->top_rated[i]->len << 2; + + } else { + + top_rated_fav_factor = + afl->top_rated[i]->exec_us * afl->top_rated[i]->len; + + } + + if (likely(fuzz_p2 > top_rated_fuzz_p2)) { continue; } + + if (likely(fav_factor > top_rated_fav_factor)) { continue; } + + /* Looks like we're going to win. Decrease ref count for the + previous winner, discard its afl->fsrv.trace_bits[] if necessary. + */ + + if (!--afl->top_rated[i]->tc_ref) { + + ck_free(afl->top_rated[i]->trace_mini); + afl->top_rated[i]->trace_mini = NULL; + + } } - if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) { + /* Insert ourselves as the new winner. */ - top_rated_fav_factor = afl->top_rated[i]->len << 2; + afl->top_rated[i] = q; + ++q->tc_ref; - } else { + if (!q->trace_mini) { - top_rated_fav_factor = - afl->top_rated[i]->exec_us * afl->top_rated[i]->len; + u32 len = ((afl->fsrv.map_size + 7) >> 3); + q->trace_mini = (u8 *)ck_alloc(len); + minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits); } - if (likely(fuzz_p2 > top_rated_fuzz_p2)) { continue; } - - if (likely(fav_factor > top_rated_fav_factor)) { continue; } - - /* Looks like we're going to win. Decrease ref count for the - previous winner, discard its afl->fsrv.trace_bits[] if necessary. */ - - if (!--afl->top_rated[i]->tc_ref) { - - ck_free(afl->top_rated[i]->trace_mini); - afl->top_rated[i]->trace_mini = NULL; - - } + afl->score_changed = 1; } - /* Insert ourselves as the new winner. */ - - afl->top_rated[i] = q; - ++q->tc_ref; - - if (!q->trace_mini) { - - u32 len = ((afl->fsrv.map_size + 7) >> 3); - q->trace_mini = (u8 *)ck_alloc(len); - minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits); - - } - - afl->score_changed = 1; - } } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index dc39db06..7dfa7a30 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -652,7 +652,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, afl->total_bitmap_size += q->bitmap_size; ++afl->total_bitmap_entries; - update_bitmap_score(afl, q); + update_bitmap_score(afl, q, true); /* If this case didn't result in new output from the instrumentation, tell parent. This is a non-critical problem, but something to warn the user @@ -1161,7 +1161,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { queue_testcase_retake_mem(afl, q, in_buf, q->len, orig_len); memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); - update_bitmap_score(afl, q); + update_bitmap_score(afl, q, true); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7d796467..584b664e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2857,7 +2857,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->total_bitmap_size += q->bitmap_size; ++afl->total_bitmap_entries; - update_bitmap_score(afl, q); + update_bitmap_score(afl, q, false); if (q->was_fuzzed) { --afl->pending_not_fuzzed; } @@ -3231,7 +3231,7 @@ int main(int argc, char **argv_orig, char **envp) { if (likely(!afl->queue_buf[i]->disabled)) { - update_bitmap_score(afl, afl->queue_buf[i]); + update_bitmap_score(afl, afl->queue_buf[i], false); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 6cd89779..77765fba 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -159,10 +159,11 @@ void show_stats(afl_state_t *afl) { } -void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { +void update_bitmap_score(afl_state_t *afl, struct queue_entry *q, bool x) { (void)afl; (void)q; + (void)x; }