From 56ac3fcdc511d124ad058412021ead21bbbcf4bf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 14 Oct 2020 15:30:30 +0200 Subject: configurable testcache with malloc (#581) * cache item number to cache memory size * reload testcase if trimming changed the size * fix splicing selection * slim splicing * import sync fix * write testcache stats to fuzzer_stats * fix new seed selection algo * malloc+read instead of mmap * fix * testcache is configurable now and no reference counts * fixes compilation, test script * fixes * switch TEST_CC to afl-cc in makefile * code format * fix * fix crash * fix crash * fix env help output * remove unnecessary pointer resets * fix endless loop bug * actually use the cache if set * one more fix * increase default cache entries, add default cache size value to config.h Co-authored-by: hexcoder- --- src/afl-fuzz-run.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/afl-fuzz-run.c') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ee22b0f6..ab870319 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -692,6 +692,8 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { + u32 orig_len = q->len; + /* Custom mutator trimmer */ if (afl->custom_mutators_count) { @@ -709,6 +711,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { }); + if (orig_len != q->len) { queue_testcase_retake(afl, q, orig_len); } + if (custom_trimmed) return trimmed_case; } @@ -842,6 +846,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { close(fd); + if (orig_len != q->len) queue_testcase_retake(afl, q, orig_len); + memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); update_bitmap_score(afl, q); -- cgit 1.4.1 From f41aafa4f7aa446c3cb1cbe6d77364cf32a6c6cb Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 15:48:39 +0200 Subject: retake from mem if possible --- include/afl-fuzz.h | 4 ++++ src/afl-fuzz-queue.c | 39 ++++++++++++++++++++++++++++++++++----- src/afl-fuzz-run.c | 8 ++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) (limited to 'src/afl-fuzz-run.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index acded98f..6204c81b 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1165,6 +1165,10 @@ u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q); void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, u32 old_len); +/* If trimming changes the testcase size we have to replace it */ +void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, u8 *in, + u32 len, u32 old_len); + #if TESTCASE_CACHE == 1 #error define of TESTCASE_CACHE must be zero or larger than 1 #endif diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 095a391f..92b722f6 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -870,8 +870,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } -void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, - u32 old_len) { +/* after a custom trim we need to reload the testcase from disk */ + +inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, + u32 old_len) { if (likely(q->testcase_buf)) { @@ -879,9 +881,9 @@ void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (len != old_len) { - afl->q_testcase_cache_size = - afl->q_testcase_cache_size + q->len - old_len; + afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; q->testcase_buf = realloc(q->testcase_buf, len); + if (unlikely(!q->testcase_buf)) { PFATAL("Unable to malloc '%s' with len %d", q->fname, len); @@ -901,8 +903,35 @@ void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, } +/* after a normal trim we need to replace the testcase with the new data */ + +inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, + u8 *in, u32 len, u32 old_len) { + + if (likely(q->testcase_buf)) { + + if (len != old_len) { + + afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; + q->testcase_buf = realloc(q->testcase_buf, len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to malloc '%s' with len %d", q->fname, len); + + } + + } + + memcpy(q->testcase_buf, in, len); + + } + +} + /* Returns the testcase buf from the file behind this queue entry. Increases the refcount. */ + inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { u32 len = q->len; @@ -913,7 +942,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { u8 *buf; - if (q == afl->queue_cur) { + if (unlikely(q == afl->queue_cur)) { buf = afl_realloc((void **)&afl->testcase_buf, len); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ab870319..dfd3abfb 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -711,7 +711,11 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { }); - if (orig_len != q->len) { queue_testcase_retake(afl, q, orig_len); } + if (orig_len != q->len || custom_trimmed) { + + queue_testcase_retake(afl, q, orig_len); + + } if (custom_trimmed) return trimmed_case; @@ -846,7 +850,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { close(fd); - if (orig_len != q->len) queue_testcase_retake(afl, q, orig_len); + 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); -- cgit 1.4.1