aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c4
-rw-r--r--src/afl-common.c75
-rw-r--r--src/afl-fuzz-bitmap.c42
-rw-r--r--src/afl-fuzz-init.c19
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-state.c22
-rw-r--r--src/afl-fuzz-stats.c31
-rw-r--r--src/afl-fuzz.c5
-rw-r--r--src/afl-showmap.c4
-rw-r--r--src/afl-tmin.c4
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);