diff options
author | van Hauser <vh@thc.org> | 2023-03-17 12:47:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-17 12:47:33 +0100 |
commit | 24503fba5fd2580559223ec3c6ee408dfa15e080 (patch) | |
tree | 95826d4a61f3c423d0e70eb7f1da568dc793204b /src | |
parent | 2ff0ff7a903c57f9df5ed1e97370c187ec45a31e (diff) | |
parent | d80cedcf02f56351bb08e7520ddcd76b0ff3f84e (diff) | |
download | afl++-24503fba5fd2580559223ec3c6ee408dfa15e080.tar.gz |
Merge pull request #1668 from AFLplusplus/dev
push to stable
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-analyze.c | 4 | ||||
-rw-r--r-- | src/afl-common.c | 75 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 42 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 19 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 22 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 31 | ||||
-rw-r--r-- | src/afl-fuzz.c | 5 | ||||
-rw-r--r-- | src/afl-showmap.c | 4 | ||||
-rw-r--r-- | src/afl-tmin.c | 4 |
10 files changed, 148 insertions, 60 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c index d4a9aa91..548956d8 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -725,7 +725,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-common.c b/src/afl-common.c index d83130b4..86226c9f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -58,6 +58,25 @@ u8 last_intr = 0; #define AFL_PATH "/usr/local/lib/afl/" #endif +void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, + size_t needlelen) { + + if (unlikely(needlelen > haystacklen)) { return NULL; } + + for (u32 i = 0; i <= haystacklen - needlelen; ++i) { + + if (unlikely(memcmp(haystack + i, needle, needlelen) == 0)) { + + return (void *)(haystack + i); + + } + + } + + return (void *)NULL; + +} + void set_sanitizer_defaults() { /* Set sane defaults for ASAN if nothing else is specified. */ @@ -66,23 +85,44 @@ void set_sanitizer_defaults() { u8 *have_msan_options = getenv("MSAN_OPTIONS"); u8 *have_lsan_options = getenv("LSAN_OPTIONS"); u8 have_san_options = 0; + u8 default_options[1024] = + "detect_odr_violation=0:abort_on_error=1:symbolize=0:allocator_may_" + "return_null=1:handle_segv=0:handle_sigbus=0:handle_abort=0:handle_" + "sigfpe=0:handle_sigill=0:"; + if (have_asan_options || have_ubsan_options || have_msan_options || - have_lsan_options) + have_lsan_options) { + have_san_options = 1; - u8 default_options[1024] = - "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_" - "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:" - "handle_abort=0:handle_sigfpe=0:handle_sigill=0:"; - if (!have_lsan_options) strcat(default_options, "detect_leaks=0:"); + } + + /* LSAN does not support abort_on_error=1. (is this still true??) */ + + if (!have_lsan_options) { + + u8 buf[2048] = ""; + if (!have_san_options) { strcpy(buf, default_options); } + strcat(buf, "exitcode=" STRINGIFY(LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:detect_leaks=1:malloc_context_size=30:"); + setenv("LSAN_OPTIONS", buf, 1); + + } + + /* for everything not LSAN we disable detect_leaks */ + + if (!have_lsan_options) { + + strcat(default_options, "detect_leaks=0:malloc_context_size=0:"); + + } /* Set sane defaults for ASAN if nothing else is specified. */ - if (!have_san_options) setenv("ASAN_OPTIONS", default_options, 1); + if (!have_san_options) { setenv("ASAN_OPTIONS", default_options, 1); } /* Set sane defaults for UBSAN if nothing else is specified. */ - if (!have_san_options) setenv("UBSAN_OPTIONS", default_options, 1); + if (!have_san_options) { setenv("UBSAN_OPTIONS", default_options, 1); } /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ @@ -90,25 +130,12 @@ void set_sanitizer_defaults() { if (!have_msan_options) { u8 buf[2048] = ""; - if (!have_san_options) strcpy(buf, default_options); + if (!have_san_options) { strcpy(buf, default_options); } strcat(buf, "exit_code=" STRINGIFY(MSAN_ERROR) ":msan_track_origins=0:"); setenv("MSAN_OPTIONS", buf, 1); } - /* LSAN, too, does not support abort_on_error=1. (is this still true??) */ - - if (!have_lsan_options) { - - u8 buf[2048] = ""; - if (!have_san_options) strcpy(buf, default_options); - strcat(buf, - "exitcode=" STRINGIFY( - LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:"); - setenv("LSAN_OPTIONS", buf, 1); - - } - /* Envs for QASan */ setenv("QASAN_MAX_CALL_STACK", "0", 0); setenv("QASAN_SYMBOLIZE", "0", 0); @@ -126,7 +153,7 @@ u32 check_binary_signatures(u8 *fn) { if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); } close(fd); - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { + if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); } setenv(PERSIST_ENV_VAR, "1", 1); @@ -151,7 +178,7 @@ u32 check_binary_signatures(u8 *fn) { } - if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + if (afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); } setenv(DEFER_ENV_VAR, "1", 1); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index b4e9537e..c65dd641 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -475,10 +475,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { only be used for special schedules */ if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { + classify_counts(&afl->fsrv); + classified = 1; + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); /* Saturated increment */ - if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF) + if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)) afl->n_fuzz[cksum % N_FUZZ_SIZE]++; } @@ -488,7 +491,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* Keep only if there are new bits in the map, add to queue for future fuzzing, etc. */ - new_bits = has_new_bits_unclassified(afl, afl->virgin_bits); + if (likely(classified)) { + + new_bits = has_new_bits(afl, afl->virgin_bits); + + } else { + + new_bits = has_new_bits_unclassified(afl, afl->virgin_bits); + + } if (likely(!new_bits)) { @@ -497,8 +508,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } - classified = new_bits; - save_to_queue: #ifndef SIMPLE_FILES @@ -556,21 +565,21 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } - /* AFLFast schedule? update the new queue entry */ - if (cksum) { + if (unlikely(!classified && new_bits)) { - afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; - afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; + /* due to classify counts we have to recalculate the checksum */ + afl->queue_top->exec_cksum = + hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + classified = 1; } - /* due to classify counts we have to recalculate the checksum */ - afl->queue_top->exec_cksum = - hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + /* For AFLFast schedules we update the new queue entry */ + afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; /* Try to calibrate inline; this also calls update_bitmap_score() when successful. */ - res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0); if (unlikely(res == FSRV_RUN_ERROR)) { @@ -604,7 +613,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (likely(!afl->non_instrumented_mode)) { - if (!classified) { + if (unlikely(!classified)) { classify_counts(&afl->fsrv); classified = 1; @@ -729,7 +738,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (likely(!afl->non_instrumented_mode)) { - if (!classified) { classify_counts(&afl->fsrv); } + if (unlikely(!classified)) { + + classify_counts(&afl->fsrv); + classified = 1; + + } simplify_trace(afl, afl->fsrv.trace_bits); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index c20965b4..01d1e82e 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -24,7 +24,9 @@ */ #include "afl-fuzz.h" +#include "common.h" #include <limits.h> +#include <string.h> #include "cmplog.h" #ifdef HAVE_AFFINITY @@ -2786,7 +2788,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { !afl->fsrv.nyx_mode && #endif !afl->fsrv.cs_mode && !afl->non_instrumented_mode && - !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { + !afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { SAYF("\n" cLRD "[-] " cRST "Looks like the target binary is not instrumented! The fuzzer depends " @@ -2817,7 +2819,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) && - memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { + afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { SAYF("\n" cLRD "[-] " cRST "This program appears to be instrumented with afl-gcc, but is being " @@ -2830,9 +2832,9 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (memmem(f_data, f_len, "__asan_init", 11) || - memmem(f_data, f_len, "__msan_init", 11) || - memmem(f_data, f_len, "__lsan_init", 11)) { + if (afl_memmem(f_data, f_len, "__asan_init", 11) || + afl_memmem(f_data, f_len, "__msan_init", 11) || + afl_memmem(f_data, f_len, "__lsan_init", 11)) { afl->fsrv.uses_asan = 1; @@ -2840,7 +2842,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { /* Detect persistent & deferred init signatures in the binary. */ - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { + if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { OKF(cPIN "Persistent mode binary detected."); setenv(PERSIST_ENV_VAR, "1", 1); @@ -2867,7 +2869,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if (afl->fsrv.frida_mode || - memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { OKF(cPIN "Deferred forkserver binary detected."); setenv(DEFER_ENV_VAR, "1", 1); @@ -2923,8 +2925,11 @@ void setup_signal_handlers(void) { struct sigaction sa; + memset((void *)&sa, 0, sizeof(sa)); sa.sa_handler = NULL; +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 65446799..4eb55bb3 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -67,7 +67,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { u32 hits = afl->n_fuzz[q->n_fuzz_entry]; - if (likely(hits)) { weight *= (log10(hits) + 1); } + if (likely(hits)) { weight /= (log10(hits) + 1); } } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 6d8c8758..f9aa5cfe 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -24,6 +24,7 @@ */ #include <signal.h> +#include <limits.h> #include "afl-fuzz.h" #include "envs.h" @@ -100,6 +101,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->hang_tmout = EXEC_TIMEOUT; afl->exit_on_time = 0; afl->stats_update_freq = 1; + afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000; afl->stats_avg_exec = 0; afl->skip_deterministic = 1; afl->sync_time = SYNC_TIME; @@ -565,6 +567,26 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } + } else if (!strncmp(env, "AFL_FUZZER_STATS_UPDATE_INTERVAL", + + afl_environment_variable_len)) { + + u64 stats_update_freq_sec = + strtoull(get_afl_env(afl_environment_variables[i]), NULL, 0); + if (stats_update_freq_sec >= UINT_MAX || + 0 == stats_update_freq_sec) { + + WARNF( + "Incorrect value given to AFL_FUZZER_STATS_UPDATE_INTERVAL, " + "using default of %d seconds\n", + STATS_UPDATE_SEC); + + } else { + + afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000; + + } + } } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bfd30845..f53fd610 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -62,7 +62,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { if (memchr(argv[i], '\'', strlen(argv[i]))) { #else - if (index(argv[i], '\'')) { + if (strchr(argv[i], '\'')) { #endif @@ -611,9 +611,10 @@ void show_stats_normal(afl_state_t *afl) { /* Roughly every minute, update fuzzer stats and save auto tokens. */ - if (unlikely(!afl->non_instrumented_mode && - (afl->force_ui_update || - cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) { + if (unlikely( + !afl->non_instrumented_mode && + (afl->force_ui_update || cur_ms - afl->stats_last_stats_ms > + afl->stats_file_update_freq_msecs))) { afl->stats_last_stats_ms = cur_ms; write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio, @@ -669,9 +670,14 @@ void show_stats_normal(afl_state_t *afl) { /* AFL_EXIT_ON_TIME. */ - if (unlikely(afl->last_find_time && !afl->non_instrumented_mode && - afl->afl_env.afl_exit_on_time && - (cur_ms - afl->last_find_time) > afl->exit_on_time)) { + /* If no coverage was found yet, check whether run time is greater than + * exit_on_time. */ + + if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time && + ((afl->last_find_time && + (cur_ms - afl->last_find_time) > afl->exit_on_time) || + (!afl->last_find_time && + (cur_ms - afl->start_time) > afl->exit_on_time)))) { afl->stop_soon = 2; @@ -1470,12 +1476,11 @@ void show_stats_pizza(afl_state_t *afl) { /* If no coverage was found yet, check whether run time is greater than * exit_on_time. */ - if (unlikely( - !afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time && - ((afl->last_find_time && - (cur_ms - afl->last_find_time) > afl->exit_on_time) || - (!afl->last_find_time && (afl->prev_run_time + cur_ms - - afl->start_time) > afl->exit_on_time)))) { + if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time && + ((afl->last_find_time && + (cur_ms - afl->last_find_time) > afl->exit_on_time) || + (!afl->last_find_time && + (cur_ms - afl->start_time) > afl->exit_on_time)))) { afl->stop_soon = 2; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 4914ce0b..d7708fdf 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -210,7 +210,8 @@ static void usage(u8 *argv0, int more_help) { " -b cpu_id - bind the fuzzing process to the specified CPU core " "(0-...)\n" " -e ext - file extension for the fuzz test input file (if " - "needed)\n\n", + "needed)\n" + "\n", argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); if (more_help > 1) { @@ -312,6 +313,8 @@ static void usage(u8 *argv0, int more_help) { " afl-clang-lto/afl-gcc-fast target\n" "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n" "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n" + "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, " + "(default: 60, minimum: 1)\n" "\n" ); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 1e281d08..29abeb13 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -654,7 +654,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 12c5e0c9..c0087f5f 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -743,7 +743,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); |