aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c14
-rw-r--r--src/afl-common.c8
-rw-r--r--src/afl-forkserver.c98
-rw-r--r--src/afl-fuzz-bitmap.c42
-rw-r--r--src/afl-fuzz-cmplog.c235
-rw-r--r--src/afl-fuzz-extras.c23
-rw-r--r--src/afl-fuzz-globals.c30
-rw-r--r--src/afl-fuzz-init.c33
-rw-r--r--src/afl-fuzz-misc.c186
-rw-r--r--src/afl-fuzz-mutators.c95
-rw-r--r--src/afl-fuzz-one.c324
-rw-r--r--src/afl-fuzz-python.c240
-rw-r--r--src/afl-fuzz-queue.c51
-rw-r--r--src/afl-fuzz-redqueen.c2
-rw-r--r--src/afl-fuzz-run.c52
-rw-r--r--src/afl-fuzz-stats.c303
-rw-r--r--src/afl-fuzz.c25
-rw-r--r--src/afl-gotcpu.c2
-rw-r--r--src/afl-showmap.c12
-rw-r--r--src/afl-tmin.c157
20 files changed, 777 insertions, 1155 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 2148cdf0..d509c43e 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -207,15 +207,6 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
}
-/* Handle timeout signal. */
-
-static void handle_timeout(int sig) {
-
- child_timed_out = 1;
- if (child_pid > 0) kill(child_pid, SIGKILL);
-
-}
-
/* Execute target application. Returns exec checksum, or 0 if program
times out. */
@@ -770,11 +761,6 @@ static void setup_signal_handlers(void) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- /* Exec timeout notifications. */
-
- sa.sa_handler = handle_timeout;
- sigaction(SIGALRM, &sa, NULL);
-
}
/* Display usage hints. */
diff --git a/src/afl-common.c b/src/afl-common.c
index 1aa15442..8c4d53e8 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -57,10 +57,10 @@ char * afl_environment_variables[] = {
"AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
"AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
"AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES",
- "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NOT_ZERO",
- "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID",
- "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
- "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI",
+ "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
+ "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY",
+ "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH",
+ "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI",
"AFL_NO_X86", // not really an env but we dont want to warn on it
"AFL_PATH", "AFL_PERFORMANCE_FILE",
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c7a3475f..2dd7a9f0 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -51,91 +51,8 @@
extern u8 *doc_path;
-u8 *forkserver_DMS(u64 val) {
-
- static u8 tmp[12][16];
- static u8 cur;
-
-#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
- do { \
- \
- if (val < (_divisor) * (_limit_mult)) { \
- \
- sprintf(tmp[cur], _fmt, ((_cast)val) / (_divisor)); \
- return tmp[cur]; \
- \
- } \
- \
- } while (0)
-
- cur = (cur + 1) % 12;
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu B", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1024, 1000, "%llu kB", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
-
-#undef CHK_FORMAT
-
- /* 100T+ */
- strcpy(tmp[cur], "infty");
- return tmp[cur];
-
-}
-
list_t fsrv_list = {.element_prealloc_count = 0};
-/* the timeout handler */
-
-void handle_timeout(int sig) {
-
- LIST_FOREACH(&fsrv_list, afl_forkserver_t, {
-
- // TODO: We need a proper timer to handle multiple timeouts
- if (el->child_pid > 0) {
-
- el->child_timed_out = 1;
- kill(el->child_pid, SIGKILL);
-
- } else if (el->child_pid == -1 && el->fsrv_pid > 0) {
-
- el->child_timed_out = 1;
- kill(el->fsrv_pid, SIGKILL);
-
- }
-
- });
-
-}
-
/* Initializes the struct */
void afl_fsrv_init(afl_forkserver_t *fsrv) {
@@ -156,6 +73,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->out_dir_fd = -1;
fsrv->use_fauxsrv = 0;
+ fsrv->prev_timed_out = 0;
list_append(&fsrv_list, fsrv);
@@ -166,8 +84,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
- static unsigned char tmp[4] = {0};
- pid_t child_pid = -1;
+ unsigned char tmp[4] = {0};
+ pid_t child_pid = -1;
/* Phone home and tell the parent that we're OK. If parent isn't there,
assume we're not running in forkserver mode and just execute program. */
@@ -476,6 +394,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
} else {
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, "
"before receiving any input\n"
@@ -508,7 +428,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
"options\n"
" fail, poke <afl-users@googlegroups.com> for troubleshooting "
"tips.\n",
- forkserver_DMS(fsrv->mem_limit << 20), fsrv->mem_limit - 1);
+ stringify_mem_size(val_buf, sizeof(val_buf), fsrv->mem_limit << 20),
+ fsrv->mem_limit - 1);
}
@@ -543,6 +464,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
} else {
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
SAYF(
"\n" cLRD "[-] " cRST
"Hmm, looks like the target binary terminated "
@@ -574,7 +497,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
"never\n"
" reached before the program terminates.\n\n"
: "",
- forkserver_DMS(fsrv->mem_limit << 20), fsrv->mem_limit - 1);
+ stringify_int(val_buf, sizeof(val_buf), fsrv->mem_limit << 20),
+ fsrv->mem_limit - 1);
}
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 7e2d3212..0d5b542d 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -138,7 +138,8 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
}
- if (ret && virgin_map == afl->virgin_bits) afl->bitmap_changed = 1;
+ if (unlikely(ret) && unlikely(virgin_map == afl->virgin_bits))
+ afl->bitmap_changed = 1;
return ret;
@@ -413,13 +414,13 @@ void minimize_bits(u8 *dst, u8 *src) {
#ifndef SIMPLE_FILES
/* Construct a file name for a new test case, capturing the operation
- that led to its discovery. Uses a static buffer. */
+ that led to its discovery. Returns a ptr to afl->describe_op_buf_256. */
u8 *describe_op(afl_state_t *afl, u8 hnb) {
u8 *ret = afl->describe_op_buf_256;
- if (afl->syncing_party) {
+ if (unlikely(afl->syncing_party)) {
sprintf(ret, "sync:%s,src:%06u", afl->syncing_party, afl->syncing_case);
@@ -465,16 +466,18 @@ static void write_crash_readme(afl_state_t *afl) {
s32 fd;
FILE *f;
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
ck_free(fn);
/* Do not die on errors here - that would be impolite. */
- if (fd < 0) return;
+ if (unlikely(fd < 0)) return;
f = fdopen(fd, "w");
- if (!f) {
+ if (unlikely(!f)) {
close(fd);
return;
@@ -501,7 +504,9 @@ static void write_crash_readme(afl_state_t *afl) {
" https://github.com/AFLplusplus/AFLplusplus\n\n",
- afl->orig_cmdline, DMS(afl->fsrv.mem_limit << 20)); /* ignore errors */
+ afl->orig_cmdline,
+ stringify_mem_size(val_buf, sizeof(val_buf),
+ afl->fsrv.mem_limit << 20)); /* ignore errors */
fclose(f);
@@ -513,7 +518,7 @@ static void write_crash_readme(afl_state_t *afl) {
u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
- if (len == 0) return 0;
+ if (unlikely(len == 0)) return 0;
u8 *fn = "";
u8 hnb;
@@ -537,14 +542,14 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
- if (fault == afl->crash_mode) {
+ if (unlikely(fault == afl->crash_mode)) {
/* Keep only if there are new bits in the map, add to queue for
future fuzzing, etc. */
if (!(hnb = has_new_bits(afl, afl->virgin_bits))) {
- if (afl->crash_mode) ++afl->total_crashes;
+ if (unlikely(afl->crash_mode)) ++afl->total_crashes;
return 0;
}
@@ -576,10 +581,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
- if (res == FAULT_ERROR) FATAL("Unable to execute target application");
+ if (unlikely(res == FAULT_ERROR))
+ FATAL("Unable to execute target application");
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (fd < 0) PFATAL("Unable to create '%s'", fn);
+ if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", fn);
ck_write(fd, mem, len, fn);
close(fd);
@@ -600,7 +606,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (afl->unique_hangs >= KEEP_UNIQUE_HANG) return keeping;
- if (!afl->dumb_mode) {
+ if (likely(!afl->dumb_mode)) {
#ifdef WORD_SIZE_64
simplify_trace((u64 *)afl->fsrv.trace_bits);
@@ -663,7 +669,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (afl->unique_crashes >= KEEP_UNIQUE_CRASH) return keeping;
- if (!afl->dumb_mode) {
+ if (likely(!afl->dumb_mode)) {
#ifdef WORD_SIZE_64
simplify_trace((u64 *)afl->fsrv.trace_bits);
@@ -675,7 +681,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
- if (!afl->unique_crashes) write_crash_readme(afl);
+ if (unlikely(!afl->unique_crashes)) write_crash_readme(afl);
#ifndef SIMPLE_FILES
@@ -691,10 +697,10 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#endif /* ^!SIMPLE_FILES */
++afl->unique_crashes;
- if (afl->infoexec) { // if the user wants to be informed on new crashes -
- // do
+ if (unlikely(afl->infoexec)) {
+
+ // if the user wants to be informed on new crashes - do that
#if !TARGET_OS_IPHONE
- // that
if (system(afl->infoexec) == -1)
hnb += 0; // we dont care if system errors, but we dont want a
// compiler warning either
@@ -719,7 +725,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
test case, too. */
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (fd < 0) PFATAL("Unable to create '%s'", fn);
+ if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", fn);
ck_write(fd, mem, len, fn);
close(fd);
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 1600af53..6c6f05ac 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -31,10 +31,10 @@
void init_cmplog_forkserver(afl_state_t *afl) {
- static struct timeval timeout;
- int st_pipe[2], ctl_pipe[2];
- int status;
- s32 rlen;
+ struct timeval timeout;
+ int st_pipe[2], ctl_pipe[2];
+ int status;
+ s32 rlen;
ACTF("Spinning up the cmplog fork server...");
@@ -264,6 +264,8 @@ void init_cmplog_forkserver(afl_state_t *afl) {
} else {
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, "
"before receiving any input\n"
@@ -296,7 +298,9 @@ void init_cmplog_forkserver(afl_state_t *afl) {
"options\n"
" fail, poke <afl-users@googlegroups.com> for troubleshooting "
"tips.\n",
- DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1);
+ stringify_mem_size(val_buf, sizeof(val_buf),
+ afl->fsrv.mem_limit << 20),
+ afl->fsrv.mem_limit - 1);
}
@@ -331,6 +335,8 @@ void init_cmplog_forkserver(afl_state_t *afl) {
} else {
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
SAYF(
"\n" cLRD "[-] " cRST
"Hmm, looks like the target binary terminated "
@@ -362,7 +368,8 @@ void init_cmplog_forkserver(afl_state_t *afl) {
"never\n"
" reached before the program terminates.\n\n"
: "",
- DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1);
+ stringify_mem_size(val_buf, sizeof(val_buf), afl->fsrv.mem_limit << 20),
+ afl->fsrv.mem_limit - 1);
}
@@ -372,12 +379,15 @@ void init_cmplog_forkserver(afl_state_t *afl) {
u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
- static struct itimerval it;
- static u32 prev_timed_out = 0;
- static u64 exec_ms = 0;
+ struct timeval it;
+ int status = 0;
+ int sret;
+ u64 exec_ms;
- int status = 0;
u32 tb4;
+ s32 res;
+
+ fd_set readfds;
afl->fsrv.child_timed_out = 0;
@@ -388,185 +398,80 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
memset(afl->fsrv.trace_bits, 0, MAP_SIZE);
MEM_BARRIER();
- /* If we're running in "dumb" mode, we can't rely on the fork server
- logic compiled into the target program, so we will just keep calling
- execve(). There is a bit of code duplication between here and
- init_forkserver(), but c'est la vie. */
-
- if (afl->dumb_mode == 1 || afl->no_forkserver) {
-
- afl->cmplog_child_pid = fork();
-
- if (afl->cmplog_child_pid < 0) PFATAL("fork() failed");
-
- if (!afl->cmplog_child_pid) {
-
- struct rlimit r;
-
- if (afl->fsrv.mem_limit) {
-
- r.rlim_max = r.rlim_cur = ((rlim_t)afl->fsrv.mem_limit) << 20;
-
-#ifdef RLIMIT_AS
-
- setrlimit(RLIMIT_AS, &r); /* Ignore errors */
-
-#else
-
- setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
+ /* Since we always have a forkserver (or a fauxserver) running, we can simply
+ tell them to have at it and read back the pid from it.*/
-#endif /* ^RLIMIT_AS */
-
- }
-
- r.rlim_max = r.rlim_cur = 0;
-
- setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
-
- /* Isolate the process and configure standard descriptors. If
- afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
- afl->fsrv.out_fd is cloned instead. */
-
- setsid();
-
- dup2(afl->fsrv.dev_null_fd, 1);
- dup2(afl->fsrv.dev_null_fd, 2);
-
- if (afl->fsrv.out_file) {
-
- dup2(afl->fsrv.dev_null_fd, 0);
-
- } else {
+ if ((res = write(afl->cmplog_fsrv_ctl_fd, &afl->cmplog_prev_timed_out, 4)) !=
+ 4) {
- dup2(afl->fsrv.out_fd, 0);
- close(afl->fsrv.out_fd);
+ if (afl->stop_soon) return 0;
+ RPFATAL(res,
+ "Unable to request new process from cmplog fork server (OOM?)");
- }
-
- /* On Linux, would be faster to use O_CLOEXEC. Maybe TODO. */
-
- close(afl->fsrv.dev_null_fd);
- close(afl->fsrv.out_dir_fd);
-#ifndef HAVE_ARC4RANDOM
- close(afl->fsrv.dev_urandom_fd);
-#endif
- close(fileno(afl->fsrv.plot_file));
-
- /* Set sane defaults for ASAN if nothing else specified. */
-
- setenv("ASAN_OPTIONS",
- "abort_on_error=1:"
- "detect_leaks=0:"
- "symbolize=0:"
- "allocator_may_return_null=1",
- 0);
-
- setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
- "symbolize=0:"
- "msan_track_origins=0", 0);
-
- setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
-
- if (!afl->qemu_mode && afl->argv[0] != afl->cmplog_binary) {
-
- ck_free(afl->argv[0]);
- afl->argv[0] = afl->cmplog_binary;
-
- }
-
- execv(afl->argv[0], afl->argv);
-
- /* Use a distinctive bitmap value to tell the parent about execv()
- falling through. */
-
- *(u32 *)afl->fsrv.trace_bits = EXEC_FAIL_SIG;
- exit(0);
-
- }
-
- } else {
-
- s32 res;
-
- /* In non-dumb mode, we have the fork server up and running, so simply
- tell it to have at it, and then read back PID. */
-
- if ((res = write(afl->cmplog_fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
-
- if (afl->stop_soon) return 0;
- RPFATAL(res,
- "Unable to request new process from cmplog fork server (OOM?)");
-
- }
-
- if ((res = read(afl->cmplog_fsrv_st_fd, &afl->cmplog_child_pid, 4)) != 4) {
-
- if (afl->stop_soon) return 0;
- RPFATAL(res,
- "Unable to request new process from cmplog fork server (OOM?)");
+ }
- }
+ if ((res = read(afl->cmplog_fsrv_st_fd, &afl->cmplog_child_pid, 4)) != 4) {
- if (afl->cmplog_child_pid <= 0)
- FATAL("Cmplog fork server is misbehaving (OOM?)");
+ if (afl->stop_soon) return 0;
+ RPFATAL(res,
+ "Unable to request new process from cmplog fork server (OOM?)");
}
+ if (afl->cmplog_child_pid <= 0)
+ FATAL("Cmplog fork server is misbehaving (OOM?)");
+
/* Configure timeout, as requested by user, then wait for child to terminate.
*/
- it.it_value.tv_sec = (timeout / 1000);
- it.it_value.tv_usec = (timeout % 1000) * 1000;
+ it.tv_sec = (timeout / 1000);
+ it.tv_usec = (timeout % 1000) * 1000;
- setitimer(ITIMER_REAL, &it, NULL);
+ FD_ZERO(&readfds);
+ FD_SET(afl->cmplog_fsrv_st_fd, &readfds);
+ it.tv_sec = ((timeout) / 1000);
+ it.tv_usec = ((timeout) % 1000) * 1000;
- /* The SIGALRM handler simply kills the afl->cmplog_child_pid and sets
- * afl->fsrv.child_timed_out. */
+ sret = select(afl->cmplog_fsrv_st_fd + 1, &readfds, NULL, NULL, &it);
- if (afl->dumb_mode == 1 || afl->no_forkserver) {
+ if (sret == 0) {
- if (waitpid(afl->cmplog_child_pid, &status, 0) <= 0)
- PFATAL("waitpid() failed");
+ /* If there was no response from forkserver after timeout seconds,
+ we kill the child. The forkserver should inform us afterwards */
- } else {
+ kill(afl->cmplog_child_pid, SIGKILL);
+ afl->fsrv.child_timed_out = 1;
- s32 res;
-
- if ((res = read(afl->cmplog_fsrv_st_fd, &status, 4)) != 4) {
-
- if (afl->stop_soon) return 0;
- SAYF(
- "\n" cLRD "[-] " cRST
- "Unable to communicate with fork server. Some possible reasons:\n\n"
- " - You've run out of memory. Use -m to increase the the memory "
- "limit\n"
- " to something higher than %lld.\n"
- " - The binary or one of the libraries it uses manages to create\n"
- " threads before the forkserver initializes.\n"
- " - The binary, at least in some circumstances, exits in a way "
- "that\n"
- " also kills the parent process - raise() could be the "
- "culprit.\n\n"
- "If all else fails you can disable the fork server via "
- "AFL_NO_FORKSRV=1.\n",
- afl->fsrv.mem_limit);
- RPFATAL(res, "Unable to communicate with fork server");
+ }
- }
+ if ((res = read(afl->cmplog_fsrv_st_fd, &status, 4)) != 4) {
+
+ if (afl->stop_soon) return 0;
+ SAYF("\n" cLRD "[-] " cRST
+ "Unable to communicate with fork server. Some possible reasons:\n\n"
+ " - You've run out of memory. Use -m to increase the the memory "
+ "limit\n"
+ " to something higher than %lld.\n"
+ " - The binary or one of the libraries it uses manages to create\n"
+ " threads before the forkserver initializes.\n"
+ " - The binary, at least in some circumstances, exits in a way "
+ "that\n"
+ " also kills the parent process - raise() could be the "
+ "culprit.\n\n"
+ "If all else fails you can disable the fork server via "
+ "AFL_NO_FORKSRV=1.\n",
+ afl->fsrv.mem_limit);
+ RPFATAL(res, "Unable to communicate with fork server");
}
if (!WIFSTOPPED(status)) afl->cmplog_child_pid = 0;
- getitimer(ITIMER_REAL, &it);
- exec_ms =
- (u64)timeout - (it.it_value.tv_sec * 1000 + it.it_value.tv_usec / 1000);
+ exec_ms = (u64)timeout - (it.tv_sec * 1000 + it.tv_usec / 1000);
if (afl->slowest_exec_ms < exec_ms) afl->slowest_exec_ms = exec_ms;
- it.it_value.tv_sec = 0;
- it.it_value.tv_usec = 0;
-
- setitimer(ITIMER_REAL, &it, NULL);
+ it.tv_sec = 0;
+ it.tv_usec = 0;
++afl->total_execs;
@@ -584,7 +489,7 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
classify_counts((u32 *)afl->fsrv.trace_bits);
#endif /* ^WORD_SIZE_64 */
- prev_timed_out = afl->fsrv.child_timed_out;
+ afl->cmplog_prev_timed_out = afl->fsrv.child_timed_out;
/* Report outcome to caller. */
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index ff4c0ae2..4dd1647c 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -55,6 +55,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
u8 * lptr;
u32 cur_line = 0;
+ u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
+
f = fopen(fname, "r");
if (!f) PFATAL("Unable to open '%s'", fname);
@@ -170,8 +172,10 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
afl->extras[afl->extras_cnt].len = klen;
if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE)
- FATAL("Keyword too big in line %u (%s, limit is %s)", cur_line, DMS(klen),
- DMS(MAX_DICT_FILE));
+ FATAL(
+ "Keyword too big in line %u (%s, limit is %s)", cur_line,
+ stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen),
+ stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
if (*min_len > klen) *min_len = klen;
if (*max_len < klen) *max_len = klen;
@@ -193,6 +197,8 @@ void load_extras(afl_state_t *afl, u8 *dir) {
u32 min_len = MAX_DICT_FILE, max_len = 0, dict_level = 0;
u8 * x;
+ u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
+
/* If the name ends with @, extract level and continue. */
if ((x = strchr(dir, '@'))) {
@@ -238,8 +244,10 @@ void load_extras(afl_state_t *afl, u8 *dir) {
}
if (st.st_size > MAX_DICT_FILE)
- FATAL("Extra '%s' is too big (%s, limit is %s)", fn, DMS(st.st_size),
- DMS(MAX_DICT_FILE));
+ FATAL(
+ "Extra '%s' is too big (%s, limit is %s)", fn,
+ stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
+ stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
if (min_len > st.st_size) min_len = st.st_size;
if (max_len < st.st_size) max_len = st.st_size;
@@ -273,11 +281,12 @@ check_and_sort:
compare_extras_len);
OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt,
- DMS(min_len), DMS(max_len));
+ stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len),
+ stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len));
if (max_len > 32)
WARNF("Some tokens are relatively large (%s) - consider trimming.",
- DMS(max_len));
+ stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len));
if (afl->extras_cnt > MAX_DET_EXTRAS)
WARNF("More than %d tokens - will use them probabilistically.",
@@ -378,7 +387,7 @@ void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) {
} else {
- i = MAX_AUTO_EXTRAS / 2 + UR(afl, (MAX_AUTO_EXTRAS + 1) / 2);
+ i = MAX_AUTO_EXTRAS / 2 + rand_below(afl, (MAX_AUTO_EXTRAS + 1) / 2);
ck_free(afl->a_extras[i].data);
diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c
index efffa749..88633a1b 100644
--- a/src/afl-fuzz-globals.c
+++ b/src/afl-fuzz-globals.c
@@ -30,8 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
-char *power_names[POWER_SCHEDULES_NUM] = {"explore", "fast", "coe", "lin",
- "quad", "exploit", "mmopt"};
+char *power_names[POWER_SCHEDULES_NUM] = {
+
+ "explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
u8 *doc_path = NULL; /* gath to documentation dir */
@@ -78,6 +79,8 @@ list_t afl_states = {.element_prealloc_count = 0};
void afl_state_init(afl_state_t *afl) {
+ memset(afl, 0, sizeof(afl_state_t));
+
afl->w_init = 0.9;
afl->w_end = 0.3;
afl->g_max = 5000;
@@ -114,6 +117,29 @@ void afl_state_init(afl_state_t *afl) {
afl->fsrv.child_pid = -1;
afl->fsrv.out_dir_fd = -1;
+ afl->cmplog_prev_timed_out = 0;
+
+ /* statis file */
+ afl->last_bitmap_cvg = 0;
+ afl->last_stability = 0;
+ afl->last_eps = 0;
+
+ /* plot file saves from last run */
+ afl->plot_prev_qp = 0;
+ afl->plot_prev_pf = 0;
+ afl->plot_prev_pnf = 0;
+ afl->plot_prev_ce = 0;
+ afl->plot_prev_md = 0;
+ afl->plot_prev_qc = 0;
+ afl->plot_prev_uc = 0;
+ afl->plot_prev_uh = 0;
+
+ afl->stats_last_stats_ms = 0;
+ afl->stats_last_plot_ms = 0;
+ afl->stats_last_ms = 0;
+ afl->stats_last_execs = 0;
+ afl->stats_avg_exec = -1;
+
init_mopt_globals(afl);
list_append(&afl_states, afl);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 6b5fa24f..038c4393 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -304,7 +304,7 @@ static void shuffle_ptrs(afl_state_t *afl, void **ptrs, u32 cnt) {
for (i = 0; i < cnt - 2; ++i) {
- u32 j = i + UR(afl, cnt - i);
+ u32 j = i + rand_below(afl, cnt - i);
void *s = ptrs[i];
ptrs[i] = ptrs[j];
ptrs[j] = s;
@@ -323,6 +323,8 @@ void read_testcases(afl_state_t *afl) {
u32 i;
u8 * fn1;
+ u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
+
/* Auto-detect non-in-place resumption attempts. */
fn1 = alloc_printf("%s/queue", afl->in_dir);
@@ -389,8 +391,9 @@ void read_testcases(afl_state_t *afl) {
}
if (st.st_size > MAX_FILE)
- FATAL("Test case '%s' is too big (%s, limit is %s)", fn2, DMS(st.st_size),
- DMS(MAX_FILE));
+ FATAL("Test case '%s' is too big (%s, limit is %s)", fn2,
+ stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
+ stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
/* Check for metadata that indicates that deterministic fuzzing
is complete for this entry. We don't want to repeat deterministic
@@ -553,6 +556,8 @@ void perform_dry_run(afl_state_t *afl) {
if (afl->fsrv.mem_limit) {
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
SAYF("\n" cLRD "[-] " cRST
"Oops, the program crashed with one of the test cases provided. "
"There are\n"
@@ -593,8 +598,9 @@ void perform_dry_run(afl_state_t *afl) {
"other options\n"
" fail, poke <afl-users@googlegroups.com> for "
"troubleshooting tips.\n",
- DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1,
- doc_path);
+ stringify_mem_size(val_buf, sizeof(val_buf),
+ afl->fsrv.mem_limit << 20),
+ afl->fsrv.mem_limit - 1, doc_path);
} else {
@@ -797,7 +803,7 @@ void pivot_inputs(afl_state_t *afl) {
u32 find_start_position(afl_state_t *afl) {
- static u8 tmp[4096]; /* Ought to be enough for anybody. */
+ u8 tmp[4096] = {0}; /* Ought to be enough for anybody. */
u8 *fn, *off;
s32 fd, i;
@@ -834,7 +840,7 @@ u32 find_start_position(afl_state_t *afl) {
void find_timeout(afl_state_t *afl) {
- static u8 tmp[4096]; /* Ought to be enough for anybody. */
+ u8 tmp[4096] = {0}; /* Ought to be enough for anybody. */
u8 *fn, *off;
s32 fd, i;
@@ -902,7 +908,7 @@ static u8 delete_files(u8 *path, u8 *prefix) {
double get_runnable_processes(void) {
- static double res;
+ double res = 0;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__NetBSD__) || defined(__DragonFly__)
@@ -1049,7 +1055,7 @@ static void handle_existing_out_dir(afl_state_t *afl) {
/* Let's see how much work is at stake. */
- if (!afl->in_place_resume &&
+ if (!afl->in_place_resume && last_update > start_time2 &&
last_update - start_time2 > OUTPUT_GRACE * 60) {
SAYF("\n" cLRD "[-] " cRST
@@ -1787,7 +1793,7 @@ void fix_up_sync(afl_state_t *afl) {
static void handle_resize(int sig) {
- LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen; });
+ LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen = 1; });
}
@@ -2008,7 +2014,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
}
- if (memmem(f_data, f_len, "libasan.so", 10) ||
+ if (memmem(f_data, f_len, "__asan_init", 11) ||
memmem(f_data, f_len, "__msan_init", 11))
afl->fsrv.uses_asan = 1;
@@ -2125,11 +2131,6 @@ void setup_signal_handlers(void) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- /* Exec timeout notifications. */
-
- sa.sa_handler = handle_timeout;
- sigaction(SIGALRM, &sa, NULL);
-
/* Window resize */
sa.sa_handler = handle_resize;
diff --git a/src/afl-fuzz-misc.c b/src/afl-fuzz-misc.c
deleted file mode 100644
index 29e8bd82..00000000
--- a/src/afl-fuzz-misc.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- american fuzzy lop++ - misc stuffs from Mordor
- ----------------------------------------------
-
- Originally written by Michal Zalewski
-
- Now maintained by Marc Heuse <mh@mh-sec.de>,
- Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
- Andrea Fioraldi <andreafioraldi@gmail.com>
-
- Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at:
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- This is the real deal: the program takes an instrumented binary and
- attempts a variety of basic fuzzing tricks, paying close attention to
- how they affect the execution path.
-
- */
-
-#include "afl-fuzz.h"
-
-/* Describe integer. Uses 12 cyclic static buffers for return values. The value
- returned should be five characters or less for all the integers we reasonably
- expect to see. */
-
-u8 *DI(u64 val) {
-
- static u8 tmp[12][16];
- static u8 cur;
-
- cur = (cur + 1) % 12;
-
-#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
- do { \
- \
- if (val < (_divisor) * (_limit_mult)) { \
- \
- sprintf(tmp[cur], _fmt, ((_cast)val) / (_divisor)); \
- return tmp[cur]; \
- \
- } \
- \
- } while (0)
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1000, 99.95, "%0.01fk", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1000, 1000, "%lluk", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double);
-
- /* 100T+ */
- strcpy(tmp[cur], "infty");
- return tmp[cur];
-
-}
-
-/* Describe float. Similar to the above, except with a single
- static buffer. */
-
-u8 *DF(double val) {
-
- static u8 tmp[16];
-
- if (val < 99.995) {
-
- sprintf(tmp, "%0.02f", val);
- return tmp;
-
- }
-
- if (val < 999.95) {
-
- sprintf(tmp, "%0.01f", val);
- return tmp;
-
- }
-
- return DI((u64)val);
-
-}
-
-/* Describe integer as memory size. */
-
-u8 *DMS(u64 val) {
-
- static u8 tmp[12][16];
- static u8 cur;
-
- cur = (cur + 1) % 12;
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu B", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1024, 1000, "%llu kB", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
-
-#undef CHK_FORMAT
-
- /* 100T+ */
- strcpy(tmp[cur], "infty");
- return tmp[cur];
-
-}
-
-/* Describe time delta. Returns one static buffer, 34 chars of less. */
-
-u8 *DTD(u64 cur_ms, u64 event_ms) {
-
- static u8 tmp[64];
- u64 delta;
- s32 t_d, t_h, t_m, t_s;
-
- if (!event_ms) return "none seen yet";
-
- delta = cur_ms - event_ms;
-
- t_d = delta / 1000 / 60 / 60 / 24;
- t_h = (delta / 1000 / 60 / 60) % 24;
- t_m = (delta / 1000 / 60) % 60;
- t_s = (delta / 1000) % 60;
-
- sprintf(tmp, "%s days, %d hrs, %d min, %d sec", DI(t_d), t_h, t_m, t_s);
- return tmp;
-
-}
-
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 9071404d..0ded4ba1 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -27,7 +27,7 @@
void load_custom_mutator(afl_state_t *, const char *);
#ifdef USE_PYTHON
-void load_custom_mutator_py(afl_state_t *, const char *);
+void load_custom_mutator_py(afl_state_t *, char *);
#endif
void setup_custom_mutator(afl_state_t *afl) {
@@ -59,10 +59,7 @@ void setup_custom_mutator(afl_state_t *afl) {
FATAL(
"MOpt and Python mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators "
- "(custom/radamsa/redquenn/...).");
-
- if (init_py_module(afl, module_name))
- FATAL("Failed to initialize Python module");
+ "(custom/radamsa/redqueen/...).");
load_custom_mutator_py(afl, module_name);
@@ -79,18 +76,13 @@ void destroy_custom_mutator(afl_state_t *afl) {
if (afl->mutator) {
+ afl->mutator->afl_custom_deinit(afl->mutator->data);
+
if (afl->mutator->dh)
dlclose(afl->mutator->dh);
- else {
-
- /* Python mutator */
-#ifdef USE_PYTHON
- finalize_py_module(afl);
-#endif
-
- }
ck_free(afl->mutator);
+ afl->mutator = NULL;
}
@@ -109,10 +101,13 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
afl->mutator->dh = dh;
/* Mutator */
- /* "afl_custom_init", optional for backward compatibility */
+ /* "afl_custom_init", required */
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
- if (!afl->mutator->afl_custom_init)
- WARNF("Symbol 'afl_custom_init' not found.");
+ if (!afl->mutator->afl_custom_init) FATAL("Symbol 'afl_custom_init' not found.");
+
+ /* "afl_custom_deinit", required */
+ afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
+ if (!afl->mutator->afl_custom_deinit) FATAL("Symbol 'afl_custom_deinit' not found.");
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
@@ -186,25 +181,24 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Initialize the custom mutator */
if (afl->mutator->afl_custom_init)
- afl->mutator->afl_custom_init(afl, UR(afl, 0xFFFFFFFF));
+ afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
}
u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
- static u8 tmp[64];
- static u8 clean_trace[MAP_SIZE];
-
u8 needs_write = 0, fault = 0;
u32 trim_exec = 0;
u32 orig_len = q->len;
- afl->stage_name = tmp;
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
+ afl->stage_name = afl->stage_name_buf;
afl->bytes_trim_in += q->len;
/* Initialize trimming in the custom mutator */
afl->stage_cur = 0;
- afl->stage_max = afl->mutator->afl_custom_init_trim(afl, in_buf, q->len);
+ afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
if (afl->not_on_tty && afl->debug)
SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max,
@@ -212,7 +206,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
while (afl->stage_cur < afl->stage_max) {
- sprintf(tmp, "ptrim %s", DI(trim_exec));
+ sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec));
u32 cksum;
@@ -251,7 +245,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
if (!needs_write) {
needs_write = 1;
- memcpy(clean_trace, afl->fsrv.trace_bits, MAP_SIZE);
+ memcpy(afl->clean_trace_custom, afl->fsrv.trace_bits, MAP_SIZE);
}
@@ -299,7 +293,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
ck_write(fd, in_buf, q->len, q->fname);
close(fd);
- memcpy(afl->fsrv.trace_bits, clean_trace, MAP_SIZE);
+ memcpy(afl->fsrv.trace_bits, afl->clean_trace_custom, MAP_SIZE);
update_bitmap_score(afl, q);
}
@@ -310,54 +304,3 @@ abort_trimming:
return fault;
}
-
-#ifdef USE_PYTHON
-void load_custom_mutator_py(afl_state_t *afl, const char *module_name) {
-
- PyObject **py_functions = afl->py_functions;
-
- afl->mutator = ck_alloc(sizeof(struct custom_mutator));
-
- afl->mutator->name = module_name;
- ACTF("Loading Python mutator library from '%s'...", module_name);
-
- if (py_functions[PY_FUNC_INIT]) afl->mutator->afl_custom_init = init_py;
-
- /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
- is quite different from the custom mutator. */
- afl->mutator->afl_custom_fuzz = fuzz_py;
-
- if (py_functions[PY_FUNC_PRE_SAVE])
- afl->mutator->afl_custom_pre_save = pre_save_py;
-
- if (py_functions[PY_FUNC_INIT_TRIM])
- afl->mutator->afl_custom_init_trim = init_trim_py;
-
- if (py_functions[PY_FUNC_POST_TRIM])
- afl->mutator->afl_custom_post_trim = post_trim_py;
-
- if (py_functions[PY_FUNC_TRIM]) afl->mutator->afl_custom_trim = trim_py;
-
- if (py_functions[PY_FUNC_HAVOC_MUTATION])
- afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
-
- if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY])
- afl->mutator->afl_custom_havoc_mutation_probability =
- havoc_mutation_probability_py;
-
- if (py_functions[PY_FUNC_QUEUE_GET])
- afl->mutator->afl_custom_queue_get = queue_get_py;
-
- if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY])
- afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py;
-
- OKF("Python mutator '%s' installed successfully.", module_name);
-
- /* Initialize the custom mutator */
- if (afl->mutator->afl_custom_init)
- afl->mutator->afl_custom_init(afl, UR(afl, 0xFFFFFFFF));
-
-}
-
-#endif
-
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 92210c8b..cc150cfe 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -31,7 +31,7 @@ int select_algorithm(afl_state_t *afl) {
int i_puppet, j_puppet;
- double sele = ((double)(UR(afl, 10000)) * 0.0001);
+ double sele = ((double)(rand_below(afl, 10000)) * 0.0001);
j_puppet = 0;
for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
@@ -67,9 +67,9 @@ static u32 choose_block_len(afl_state_t *afl, u32 limit) {
u32 min_value, max_value;
u32 rlim = MIN(afl->queue_cycle, 3);
- if (!afl->run_over10m) rlim = 1;
+ if (unlikely(!afl->run_over10m)) rlim = 1;
- switch (UR(afl, rlim)) {
+ switch (rand_below(afl, rlim)) {
case 0:
min_value = 1;
@@ -83,7 +83,7 @@ static u32 choose_block_len(afl_state_t *afl, u32 limit) {
default:
- if (UR(afl, 10)) {
+ if (rand_below(afl, 10)) {
min_value = HAVOC_BLK_MEDIUM;
max_value = HAVOC_BLK_LARGE;
@@ -99,7 +99,7 @@ static u32 choose_block_len(afl_state_t *afl, u32 limit) {
if (min_value >= limit) min_value = 1;
- return min_value + UR(afl, MIN(max_value, limit) - min_value + 1);
+ return min_value + rand_below(afl, MIN(max_value, limit) - min_value + 1);
}
@@ -356,7 +356,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
#else
- if (afl->mutator && afl->mutator->afl_custom_queue_get) {
+ if (unlikely(afl->mutator) && unlikely(afl->mutator->afl_custom_queue_get)) {
/* The custom mutator will decide to skip this test case or not. */
@@ -365,7 +365,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
- if (afl->pending_favored) {
+ if (likely(afl->pending_favored)) {
/* If we have any favored, non-fuzzed new arrivals in the queue,
possibly skip to them at the expense of already-fuzzed or non-favored
@@ -373,7 +373,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (((afl->queue_cur->was_fuzzed > 0 || afl->queue_cur->fuzz_level > 0) ||
!afl->queue_cur->favored) &&
- UR(afl, 100) < SKIP_TO_NEW_PROB)
+ rand_below(afl, 100) < SKIP_TO_NEW_PROB)
return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored &&
@@ -387,11 +387,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->queue_cycle > 1 &&
(afl->queue_cur->fuzz_level == 0 || afl->queue_cur->was_fuzzed)) {
- if (UR(afl, 100) < SKIP_NFAV_NEW_PROB) return 1;
+ if (rand_below(afl, 100) < SKIP_NFAV_NEW_PROB) return 1;
} else {
- if (UR(afl, 100) < SKIP_NFAV_OLD_PROB) return 1;
+ if (rand_below(afl, 100) < SKIP_NFAV_OLD_PROB) return 1;
}
@@ -399,7 +399,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
#endif /* ^IGNORE_FINDS */
- if (afl->not_on_tty) {
+ if (unlikely(afl->not_on_tty)) {
ACTF("Fuzzing test case #%u (%u total, %llu uniq crashes found)...",
afl->current_entry, afl->queued_paths, afl->unique_crashes);
@@ -411,13 +411,13 @@ u8 fuzz_one_original(afl_state_t *afl) {
fd = open(afl->queue_cur->fname, O_RDONLY);
- if (fd < 0) PFATAL("Unable to open '%s'", afl->queue_cur->fname);
+ if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", afl->queue_cur->fname);
len = afl->queue_cur->len;
orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
- if (orig_in == MAP_FAILED)
+ if (unlikely(orig_in == MAP_FAILED))
PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len);
close(fd);
@@ -436,7 +436,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
* CALIBRATION (only if failed earlier on) *
*******************************************/
- if (afl->queue_cur->cal_failed) {
+ if (unlikely(afl->queue_cur->cal_failed)) {
u8 res = FAULT_TMOUT;
@@ -445,11 +445,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
- if (res == FAULT_ERROR) FATAL("Unable to execute target application");
+ if (unlikely(res == FAULT_ERROR))
+ FATAL("Unable to execute target application");
}
- if (afl->stop_soon || res != afl->crash_mode) {
+ if (unlikely(afl->stop_soon) || res != afl->crash_mode) {
++afl->cur_skipped_paths;
goto abandon_entry;
@@ -466,9 +467,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
u8 res = trim_case(afl, afl->queue_cur, in_buf);
- if (res == FAULT_ERROR) FATAL("Unable to execute target application");
+ if (unlikely(res == FAULT_ERROR))
+ FATAL("Unable to execute target application");
- if (afl->stop_soon) {
+ if (unlikely(afl->stop_soon)) {
++afl->cur_skipped_paths;
goto abandon_entry;
@@ -491,9 +493,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
- if (perf_score == 0) goto abandon_entry;
+ if (unlikely(perf_score == 0)) goto abandon_entry;
- if (afl->use_radamsa > 1) goto radamsa_stage;
+ if (unlikely(afl->use_radamsa > 1)) goto radamsa_stage;
if (afl->shm.cmplog_mode) {
@@ -1401,7 +1403,7 @@ skip_interest:
map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS &&
- UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
+ rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1,
@@ -1549,8 +1551,8 @@ custom_mutator_stage:
* CUSTOM MUTATORS *
*******************/
- if (!afl->mutator) goto havoc_stage;
- if (!afl->mutator->afl_custom_fuzz) goto havoc_stage;
+ if (likely(!afl->mutator)) goto havoc_stage;
+ if (likely(!afl->mutator->afl_custom_fuzz)) goto havoc_stage;
afl->stage_name = "custom mutator";
afl->stage_short = "custom";
@@ -1573,7 +1575,7 @@ custom_mutator_stage:
/* Pick a random other queue entry for passing to external API */
do {
- tid = UR(afl, afl->queued_paths);
+ tid = rand_below(afl, afl->queued_paths);
} while (tid == afl->current_entry && afl->queued_paths > 1);
@@ -1603,7 +1605,7 @@ custom_mutator_stage:
/* Read the additional testcase into a new buffer. */
fd = open(target->fname, O_RDONLY);
- if (fd < 0) PFATAL("Unable to open '%s'", target->fname);
+ if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname);
new_buf = ck_alloc_nozero(target->len);
ck_read(fd, new_buf, target->len, target->fname);
close(fd);
@@ -1649,7 +1651,7 @@ custom_mutator_stage:
afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_CUSTOM_MUTATOR] += afl->stage_max;
- if (afl->custom_only) {
+ if (likely(afl->custom_only)) {
/* Skip other stages */
ret_val = 0;
@@ -1679,8 +1681,8 @@ havoc_stage:
perf_score = orig_perf;
- snprintf(afl->stage_name_buf64, 64, "splice %u", splice_cycle);
- afl->stage_name = afl->stage_name_buf64;
+ snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle);
+ afl->stage_name = afl->stage_name_buf;
afl->stage_short = "splice";
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@@ -1713,34 +1715,35 @@ havoc_stage:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
- u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2));
+ u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
afl->stage_cur_val = use_stacking;
for (i = 0; i < use_stacking; ++i) {
- if (stacked_custom && UR(afl, 100) < stacked_custom_prob) {
+ if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) {
temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf,
temp_len, MAX_FILE);
}
- switch (UR(afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
+ switch (rand_below(
+ afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
case 0:
/* Flip a single bit somewhere. Spooky! */
- FLIP_BIT(out_buf, UR(afl, temp_len << 3));
+ FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
break;
case 1:
/* Set byte to interesting value. */
- out_buf[UR(afl, temp_len)] =
- interesting_8[UR(afl, sizeof(interesting_8))];
+ out_buf[rand_below(afl, temp_len)] =
+ interesting_8[rand_below(afl, sizeof(interesting_8))];
break;
case 2:
@@ -1749,15 +1752,15 @@ havoc_stage:
if (temp_len < 2) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- *(u16 *)(out_buf + UR(afl, temp_len - 1)) =
- interesting_16[UR(afl, sizeof(interesting_16) >> 1)];
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
+ interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)];
} else {
- *(u16 *)(out_buf + UR(afl, temp_len - 1)) =
- SWAP16(interesting_16[UR(afl, sizeof(interesting_16) >> 1)]);
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16(
+ interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]);
}
@@ -1769,15 +1772,15 @@ havoc_stage:
if (temp_len < 4) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- *(u32 *)(out_buf + UR(afl, temp_len - 3)) =
- interesting_32[UR(afl, sizeof(interesting_32) >> 2)];
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
+ interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)];
} else {
- *(u32 *)(out_buf + UR(afl, temp_len - 3)) =
- SWAP32(interesting_32[UR(afl, sizeof(interesting_32) >> 2)]);
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32(
+ interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]);
}
@@ -1787,14 +1790,14 @@ havoc_stage:
/* Randomly subtract from byte. */
- out_buf[UR(afl, temp_len)] -= 1 + UR(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX);
break;
case 5:
/* Randomly add to byte. */
- out_buf[UR(afl, temp_len)] += 1 + UR(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX);
break;
case 6:
@@ -1803,16 +1806,16 @@ havoc_stage:
if (temp_len < 2) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 1);
+ u32 pos = rand_below(afl, temp_len - 1);
- *(u16 *)(out_buf + pos) -= 1 + UR(afl, ARITH_MAX);
+ *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 1);
- u16 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
*(u16 *)(out_buf + pos) =
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
@@ -1827,16 +1830,16 @@ havoc_stage:
if (temp_len < 2) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 1);
+ u32 pos = rand_below(afl, temp_len - 1);
- *(u16 *)(out_buf + pos) += 1 + UR(afl, ARITH_MAX);
+ *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 1);
- u16 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
*(u16 *)(out_buf + pos) =
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
@@ -1851,16 +1854,16 @@ havoc_stage:
if (temp_len < 4) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 3);
+ u32 pos = rand_below(afl, temp_len - 3);
- *(u32 *)(out_buf + pos) -= 1 + UR(afl, ARITH_MAX);
+ *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 3);
- u32 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
*(u32 *)(out_buf + pos) =
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
@@ -1875,16 +1878,16 @@ havoc_stage:
if (temp_len < 4) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 3);
+ u32 pos = rand_below(afl, temp_len - 3);
- *(u32 *)(out_buf + pos) += 1 + UR(afl, ARITH_MAX);
+ *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 3);
- u32 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
*(u32 *)(out_buf + pos) =
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
@@ -1899,7 +1902,7 @@ havoc_stage:
why not. We use XOR with 1-255 to eliminate the
possibility of a no-op. */
- out_buf[UR(afl, temp_len)] ^= 1 + UR(afl, 255);
+ out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
break;
case 11 ... 12: {
@@ -1916,7 +1919,7 @@ havoc_stage:
del_len = choose_block_len(afl, temp_len - 1);
- del_from = UR(afl, temp_len - del_len + 1);
+ del_from = rand_below(afl, temp_len - del_len + 1);
memmove(out_buf + del_from, out_buf + del_from + del_len,
temp_len - del_from - del_len);
@@ -1933,14 +1936,14 @@ havoc_stage:
/* Clone bytes (75%) or insert a block of constant bytes (25%). */
- u8 actually_clone = UR(afl, 4);
+ u8 actually_clone = rand_below(afl, 4);
u32 clone_from, clone_to, clone_len;
u8 *new_buf;
if (actually_clone) {
clone_len = choose_block_len(afl, temp_len);
- clone_from = UR(afl, temp_len - clone_len + 1);
+ clone_from = rand_below(afl, temp_len - clone_len + 1);
} else {
@@ -1949,7 +1952,7 @@ havoc_stage:
}
- clone_to = UR(afl, temp_len);
+ clone_to = rand_below(afl, temp_len);
new_buf = ck_alloc_nozero(temp_len + clone_len);
@@ -1963,7 +1966,8 @@ havoc_stage:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else
memset(new_buf + clone_to,
- UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
+ rand_below(afl, 2) ? rand_below(afl, 256)
+ : out_buf[rand_below(afl, temp_len)],
clone_len);
/* Tail */
@@ -1989,10 +1993,10 @@ havoc_stage:
copy_len = choose_block_len(afl, temp_len - 1);
- copy_from = UR(afl, temp_len - copy_len + 1);
- copy_to = UR(afl, temp_len - copy_len + 1);
+ copy_from = rand_below(afl, temp_len - copy_len + 1);
+ copy_to = rand_below(afl, temp_len - copy_len + 1);
- if (UR(afl, 4)) {
+ if (rand_below(afl, 4)) {
if (copy_from != copy_to)
memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
@@ -2000,7 +2004,8 @@ havoc_stage:
} else
memset(out_buf + copy_to,
- UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
+ rand_below(afl, 2) ? rand_below(afl, 256)
+ : out_buf[rand_below(afl, temp_len)],
copy_len);
break;
@@ -2014,18 +2019,18 @@ havoc_stage:
/* Overwrite bytes with an extra. */
- if (!afl->extras_cnt || (afl->a_extras_cnt && UR(afl, 2))) {
+ if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
/* No user-specified extras or odds in our favor. Let's use an
auto-detected one. */
- u32 use_extra = UR(afl, afl->a_extras_cnt);
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
u32 insert_at;
if (extra_len > temp_len) break;
- insert_at = UR(afl, temp_len - extra_len + 1);
+ insert_at = rand_below(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
@@ -2033,13 +2038,13 @@ havoc_stage:
/* No auto extras or odds in our favor. Use the dictionary. */
- u32 use_extra = UR(afl, afl->extras_cnt);
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
u32 insert_at;
if (extra_len > temp_len) break;
- insert_at = UR(afl, temp_len - extra_len + 1);
+ insert_at = rand_below(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len);
}
@@ -2050,15 +2055,15 @@ havoc_stage:
case 16: {
- u32 use_extra, extra_len, insert_at = UR(afl, temp_len + 1);
+ u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1);
u8 *new_buf;
/* Insert an extra. Do the same dice-rolling stuff as for the
previous case. */
- if (!afl->extras_cnt || (afl->a_extras_cnt && UR(afl, 2))) {
+ if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
- use_extra = UR(afl, afl->a_extras_cnt);
+ use_extra = rand_below(afl, afl->a_extras_cnt);
extra_len = afl->a_extras[use_extra].len;
if (temp_len + extra_len >= MAX_FILE) break;
@@ -2074,7 +2079,7 @@ havoc_stage:
} else {
- use_extra = UR(afl, afl->extras_cnt);
+ use_extra = rand_below(afl, afl->extras_cnt);
extra_len = afl->extras[use_extra].len;
if (temp_len + extra_len >= MAX_FILE) break;
@@ -2182,7 +2187,7 @@ retry_splicing:
do {
- tid = UR(afl, afl->queued_paths);
+ tid = rand_below(afl, afl->queued_paths);
} while (tid == afl->current_entry);
@@ -2214,7 +2219,7 @@ retry_splicing:
fd = open(target->fname, O_RDONLY);
- if (fd < 0) PFATAL("Unable to open '%s'", target->fname);
+ if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname);
new_buf = ck_alloc_nozero(target->len);
@@ -2237,7 +2242,7 @@ retry_splicing:
/* Split somewhere between the first and last differing byte. */
- split_at = f_diff + UR(afl, l_diff - f_diff);
+ split_at = f_diff + rand_below(afl, l_diff - f_diff);
/* Do the thing. */
@@ -2263,7 +2268,7 @@ retry_splicing:
radamsa_stage:
- if (!afl->use_radamsa || !afl->radamsa_mutate_ptr) goto abandon_entry;
+ if (likely(!afl->use_radamsa || !afl->radamsa_mutate_ptr)) goto abandon_entry;
afl->stage_name = "radamsa";
afl->stage_short = "radamsa";
@@ -2391,7 +2396,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
cases. */
if ((afl->queue_cur->was_fuzzed || !afl->queue_cur->favored) &&
- UR(afl, 100) < SKIP_TO_NEW_PROB)
+ rand_below(afl, 100) < SKIP_TO_NEW_PROB)
return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored &&
@@ -2404,11 +2409,11 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->queue_cycle > 1 && !afl->queue_cur->was_fuzzed) {
- if (UR(afl, 100) < SKIP_NFAV_NEW_PROB) return 1;
+ if (rand_below(afl, 100) < SKIP_NFAV_NEW_PROB) return 1;
} else {
- if (UR(afl, 100) < SKIP_NFAV_OLD_PROB) return 1;
+ if (rand_below(afl, 100) < SKIP_NFAV_OLD_PROB) return 1;
}
@@ -3407,7 +3412,7 @@ skip_interest:
map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS &&
- UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
+ rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1,
@@ -3573,9 +3578,9 @@ pacemaker_fuzzing:
perf_score = orig_perf;
- snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
- splice_cycle);
- afl->stage_name = afl->stage_name_buf64;
+ snprintf(afl->stage_name_buf, STAGE_BUF_SIZE,
+ MOpt_globals.splice_stageformat, splice_cycle);
+ afl->stage_name = afl->stage_name_buf;
afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@@ -3594,7 +3599,8 @@ pacemaker_fuzzing:
afl->orig_hit_cnt_puppet = afl->queued_paths + afl->unique_crashes;
afl->last_limit_time_start = get_cur_time();
afl->SPLICE_CYCLES_puppet =
- (UR(afl, SPLICE_CYCLES_puppet_up - SPLICE_CYCLES_puppet_low + 1) +
+ (rand_below(
+ afl, SPLICE_CYCLES_puppet_up - SPLICE_CYCLES_puppet_low + 1) +
SPLICE_CYCLES_puppet_low);
}
@@ -3623,9 +3629,9 @@ pacemaker_fuzzing:
} else {
perf_score = orig_perf;
- snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
- splice_cycle);
- afl->stage_name = afl->stage_name_buf64;
+ snprintf(afl->stage_name_buf, STAGE_BUF_SIZE,
+ MOpt_globals.splice_stageformat, splice_cycle);
+ afl->stage_name = afl->stage_name_buf;
afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@@ -3642,7 +3648,7 @@ pacemaker_fuzzing:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
++afl->stage_cur) {
- u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2));
+ u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
afl->stage_cur_val = use_stacking;
@@ -3658,13 +3664,13 @@ pacemaker_fuzzing:
case 0:
/* Flip a single bit somewhere. Spooky! */
- FLIP_BIT(out_buf, UR(afl, temp_len << 3));
+ FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
MOpt_globals.cycles_v2[STAGE_FLIP1] += 1;
break;
case 1:
if (temp_len < 2) break;
- temp_len_puppet = UR(afl, (temp_len << 3) - 1);
+ temp_len_puppet = rand_below(afl, (temp_len << 3) - 1);
FLIP_BIT(out_buf, temp_len_puppet);
FLIP_BIT(out_buf, temp_len_puppet + 1);
MOpt_globals.cycles_v2[STAGE_FLIP2] += 1;
@@ -3672,7 +3678,7 @@ pacemaker_fuzzing:
case 2:
if (temp_len < 2) break;
- temp_len_puppet = UR(afl, (temp_len << 3) - 3);
+ temp_len_puppet = rand_below(afl, (temp_len << 3) - 3);
FLIP_BIT(out_buf, temp_len_puppet);
FLIP_BIT(out_buf, temp_len_puppet + 1);
FLIP_BIT(out_buf, temp_len_puppet + 2);
@@ -3682,55 +3688,57 @@ pacemaker_fuzzing:
case 3:
if (temp_len < 4) break;
- out_buf[UR(afl, temp_len)] ^= 0xFF;
+ out_buf[rand_below(afl, temp_len)] ^= 0xFF;
MOpt_globals.cycles_v2[STAGE_FLIP8] += 1;
break;
case 4:
if (temp_len < 8) break;
- *(u16 *)(out_buf + UR(afl, temp_len - 1)) ^= 0xFFFF;
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) ^= 0xFFFF;
MOpt_globals.cycles_v2[STAGE_FLIP16] += 1;
break;
case 5:
if (temp_len < 8) break;
- *(u32 *)(out_buf + UR(afl, temp_len - 3)) ^= 0xFFFFFFFF;
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) ^= 0xFFFFFFFF;
MOpt_globals.cycles_v2[STAGE_FLIP32] += 1;
break;
case 6:
- out_buf[UR(afl, temp_len)] -= 1 + UR(afl, ARITH_MAX);
- out_buf[UR(afl, temp_len)] += 1 + UR(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] -=
+ 1 + rand_below(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] +=
+ 1 + rand_below(afl, ARITH_MAX);
MOpt_globals.cycles_v2[STAGE_ARITH8] += 1;
break;
case 7:
/* Randomly subtract from word, random endian. */
if (temp_len < 8) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 1);
- *(u16 *)(out_buf + pos) -= 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 1);
- u16 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
*(u16 *)(out_buf + pos) =
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
}
/* Randomly add to word, random endian. */
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 1);
- *(u16 *)(out_buf + pos) += 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 1);
- u16 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
*(u16 *)(out_buf + pos) =
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
@@ -3742,15 +3750,15 @@ pacemaker_fuzzing:
case 8:
/* Randomly subtract from dword, random endian. */
if (temp_len < 8) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 3);
- *(u32 *)(out_buf + pos) -= 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 3);
- u32 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
*(u32 *)(out_buf + pos) =
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
@@ -3758,15 +3766,15 @@ pacemaker_fuzzing:
/* Randomly add to dword, random endian. */
// if (temp_len < 4) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- u32 pos = UR(afl, temp_len - 3);
- *(u32 *)(out_buf + pos) += 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
} else {
- u32 pos = UR(afl, temp_len - 3);
- u32 num = 1 + UR(afl, ARITH_MAX);
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
*(u32 *)(out_buf + pos) =
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
@@ -3778,23 +3786,25 @@ pacemaker_fuzzing:
case 9:
/* Set byte to interesting value. */
if (temp_len < 4) break;
- out_buf[UR(afl, temp_len)] =
- interesting_8[UR(afl, sizeof(interesting_8))];
+ out_buf[rand_below(afl, temp_len)] =
+ interesting_8[rand_below(afl, sizeof(interesting_8))];
MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1;
break;
case 10:
/* Set word to interesting value, randomly choosing endian. */
if (temp_len < 8) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- *(u16 *)(out_buf + UR(afl, temp_len - 1)) =
- interesting_16[UR(afl, sizeof(interesting_16) >> 1)];
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
+ interesting_16[rand_below(afl,
+ sizeof(interesting_16) >> 1)];
} else {
- *(u16 *)(out_buf + UR(afl, temp_len - 1)) = SWAP16(
- interesting_16[UR(afl, sizeof(interesting_16) >> 1)]);
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
+ SWAP16(interesting_16[rand_below(
+ afl, sizeof(interesting_16) >> 1)]);
}
@@ -3806,15 +3816,17 @@ pacemaker_fuzzing:
if (temp_len < 8) break;
- if (UR(afl, 2)) {
+ if (rand_below(afl, 2)) {
- *(u32 *)(out_buf + UR(afl, temp_len - 3)) =
- interesting_32[UR(afl, sizeof(interesting_32) >> 2)];
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
+ interesting_32[rand_below(afl,
+ sizeof(interesting_32) >> 2)];
} else {
- *(u32 *)(out_buf + UR(afl, temp_len - 3)) = SWAP32(
- interesting_32[UR(afl, sizeof(interesting_32) >> 2)]);
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
+ SWAP32(interesting_32[rand_below(
+ afl, sizeof(interesting_32) >> 2)]);
}
@@ -3827,7 +3839,7 @@ pacemaker_fuzzing:
why not. We use XOR with 1-255 to eliminate the
possibility of a no-op. */
- out_buf[UR(afl, temp_len)] ^= 1 + UR(afl, 255);
+ out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
MOpt_globals.cycles_v2[STAGE_RANDOMBYTE] += 1;
break;
@@ -3845,7 +3857,7 @@ pacemaker_fuzzing:
del_len = choose_block_len(afl, temp_len - 1);
- del_from = UR(afl, temp_len - del_len + 1);
+ del_from = rand_below(afl, temp_len - del_len + 1);
memmove(out_buf + del_from, out_buf + del_from + del_len,
temp_len - del_from - del_len);
@@ -3863,14 +3875,14 @@ pacemaker_fuzzing:
/* Clone bytes (75%) or insert a block of constant bytes (25%).
*/
- u8 actually_clone = UR(afl, 4);
+ u8 actually_clone = rand_below(afl, 4);
u32 clone_from, clone_to, clone_len;
u8 *new_buf;
if (actually_clone) {
clone_len = choose_block_len(afl, temp_len);
- clone_from = UR(afl, temp_len - clone_len + 1);
+ clone_from = rand_below(afl, temp_len - clone_len + 1);
} else {
@@ -3879,7 +3891,7 @@ pacemaker_fuzzing:
}
- clone_to = UR(afl, temp_len);
+ clone_to = rand_below(afl, temp_len);
new_buf = ck_alloc_nozero(temp_len + clone_len);
@@ -3893,7 +3905,9 @@ pacemaker_fuzzing:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else
memset(new_buf + clone_to,
- UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
+ rand_below(afl, 2)
+ ? rand_below(afl, 256)
+ : out_buf[rand_below(afl, temp_len)],
clone_len);
/* Tail */
@@ -3920,10 +3934,10 @@ pacemaker_fuzzing:
copy_len = choose_block_len(afl, temp_len - 1);
- copy_from = UR(afl, temp_len - copy_len + 1);
- copy_to = UR(afl, temp_len - copy_len + 1);
+ copy_from = rand_below(afl, temp_len - copy_len + 1);
+ copy_to = rand_below(afl, temp_len - copy_len + 1);
- if (UR(afl, 4)) {
+ if (rand_below(afl, 4)) {
if (copy_from != copy_to)
memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
@@ -3931,7 +3945,8 @@ pacemaker_fuzzing:
} else
memset(out_buf + copy_to,
- UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
+ rand_below(afl, 2) ? rand_below(afl, 256)
+ : out_buf[rand_below(afl, temp_len)],
copy_len);
MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1;
break;
@@ -4041,7 +4056,7 @@ pacemaker_fuzzing:
do {
- tid = UR(afl, afl->queued_paths);
+ tid = rand_below(afl, afl->queued_paths);
} while (tid == afl->current_entry);
@@ -4096,7 +4111,7 @@ pacemaker_fuzzing:
/* Split somewhere between the first and last differing byte. */
- split_at = f_diff + UR(afl, l_diff - f_diff);
+ split_at = f_diff + rand_below(afl, l_diff - f_diff);
/* Do the thing. */
@@ -4120,7 +4135,8 @@ pacemaker_fuzzing:
if (splice_cycle >= afl->SPLICE_CYCLES_puppet)
afl->SPLICE_CYCLES_puppet =
- (UR(afl, SPLICE_CYCLES_puppet_up - SPLICE_CYCLES_puppet_low + 1) +
+ (rand_below(
+ afl, SPLICE_CYCLES_puppet_up - SPLICE_CYCLES_puppet_low + 1) +
SPLICE_CYCLES_puppet_low);
afl->splicing_with = -1;
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 595c1ed0..d3027d2b 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -28,9 +28,84 @@
/* Python stuff */
#ifdef USE_PYTHON
-int init_py_module(afl_state_t *afl, u8 *module_name) {
+static void *unsupported(afl_state_t *afl, unsigned int seed) {
+ FATAL("Python Mutator cannot be called twice yet");
+ return NULL;
+}
+
+size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf,
+ size_t add_buf_size, size_t max_size) {
+
+ size_t mutated_size;
+ PyObject *py_args, *py_value;
+ py_args = PyTuple_New(3);
+
+ /* buf */
+ py_value = PyByteArray_FromStringAndSize(*buf, buf_size);
+ if (!py_value) {
+
+ Py_DECREF(py_args);
+ FATAL("Failed to convert arguments");
+
+ }
+
+ PyTuple_SetItem(py_args, 0, py_value);
+
+ /* add_buf */
+ py_value = PyByteArray_FromStringAndSize(add_buf, add_buf_size);
+ if (!py_value) {
+
+ Py_DECREF(py_args);
+ FATAL("Failed to convert arguments");
+
+ }
+
+ PyTuple_SetItem(py_args, 1, py_value);
+
+ /* max_size */
+#if PY_MAJOR_VERSION >= 3
+ py_value = PyLong_FromLong(max_size);
+#else
+ py_value = PyInt_FromLong(max_size);
+#endif
+ if (!py_value) {
+
+ Py_DECREF(py_args);
+ FATAL("Failed to convert arguments");
+
+ }
+
+ PyTuple_SetItem(py_args, 2, py_value);
+
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args);
+
+ Py_DECREF(py_args);
+
+ if (py_value != NULL) {
+
+ mutated_size = PyByteArray_Size(py_value);
+ if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size);
+
+ memcpy(*buf, PyByteArray_AsString(py_value), mutated_size);
+ Py_DECREF(py_value);
+ return mutated_size;
+
+ } else {
+
+ PyErr_Print();
+ FATAL("Call failed");
+
+ }
+
+}
- if (!module_name) return 1;
+
+static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
+
+ if (!module_name) return NULL;
+
+ py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
+ if (!py) PFATAL("Could not allocate memory for python mutator!");
Py_Initialize();
@@ -40,17 +115,18 @@ int init_py_module(afl_state_t *afl, u8 *module_name) {
PyObject *py_name = PyString_FromString(module_name);
#endif
- afl->py_module = PyImport_Import(py_name);
+ py->py_module = PyImport_Import(py_name);
Py_DECREF(py_name);
- PyObject * py_module = afl->py_module;
- PyObject **py_functions = afl->py_functions;
+ PyObject * py_module = py->py_module;
+ PyObject **py_functions = py->py_functions;
- if (afl->py_module != NULL) {
+ if (py_module != NULL) {
u8 py_notrim = 0, py_idx;
- py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(afl->py_module, "init");
- py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(afl->py_module, "fuzz");
+ py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init");
+ py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
+ py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
py_functions[PY_FUNC_PRE_SAVE] =
PyObject_GetAttrString(py_module, "pre_save");
py_functions[PY_FUNC_INIT_TRIM] =
@@ -96,7 +172,7 @@ int init_py_module(afl_state_t *afl, u8 *module_name) {
"Cannot find/call function with index %d in external "
"Python module.\n",
py_idx);
- return 1;
+ return NULL;
}
@@ -119,23 +195,27 @@ int init_py_module(afl_state_t *afl, u8 *module_name) {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", module_name);
- return 1;
+ return NULL;
}
- return 0;
+ return py;
}
-void finalize_py_module(afl_state_t *afl) {
+void finalize_py_module(void *py_mutator) {
+
+ py_mutator_t *py = (py_mutator_t *)py_mutator;
- if (afl->py_module != NULL) {
+ if (py->py_module != NULL) {
+
+ deinit_py(py_mutator);
u32 i;
for (i = 0; i < PY_FUNC_COUNT; ++i)
- Py_XDECREF(afl->py_functions[i]);
+ Py_XDECREF(py->py_functions[i]);
- Py_DECREF(afl->py_module);
+ Py_DECREF(py->py_module);
}
@@ -143,7 +223,7 @@ void finalize_py_module(afl_state_t *afl) {
}
-void init_py(afl_state_t *afl, unsigned int seed) {
+static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int seed) {
PyObject *py_args, *py_value;
@@ -158,14 +238,13 @@ void init_py(afl_state_t *afl, unsigned int seed) {
if (!py_value) {
Py_DECREF(py_args);
- fprintf(stderr, "Cannot convert argument\n");
- return;
+ FATAL("Cannot convert argument in python init.");
}
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_INIT], py_args);
+ py_value = PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
Py_DECREF(py_args);
@@ -173,79 +252,90 @@ void init_py(afl_state_t *afl, unsigned int seed) {
PyErr_Print();
fprintf(stderr, "Call failed\n");
- return;
+ FATAL("Custom py mutator INIT failed.");
}
}
-size_t fuzz_py(afl_state_t *afl, u8 **buf, size_t buf_size, u8 *add_buf,
- size_t add_buf_size, size_t max_size) {
+void deinit_py(void *py_mutator) {
- size_t mutated_size;
PyObject *py_args, *py_value;
- py_args = PyTuple_New(3);
- /* buf */
- py_value = PyByteArray_FromStringAndSize(*buf, buf_size);
- if (!py_value) {
+ py_args = PyTuple_New(0);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DEINIT], py_args);
+ Py_DECREF(py_args);
- Py_DECREF(py_args);
- FATAL("Failed to convert arguments");
+ if (py_value != NULL) {
+
+ Py_DECREF(py_value);
+
+ } else {
+
+ PyErr_Print();
+ FATAL("Call failed");
}
- PyTuple_SetItem(py_args, 0, py_value);
+}
- /* add_buf */
- py_value = PyByteArray_FromStringAndSize(add_buf, add_buf_size);
- if (!py_value) {
+void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
- Py_DECREF(py_args);
- FATAL("Failed to convert arguments");
+ afl->mutator = ck_alloc(sizeof(struct custom_mutator));
+ afl->mutator->name = module_name;
+ ACTF("Loading Python mutator library from '%s'...", module_name);
+
+ py_mutator_t *py_mutator;
+ py_mutator = init_py_module(afl, module_name);
+ if (!py_mutator) {
+ FATAL("Failed to load python mutator.");
}
- PyTuple_SetItem(py_args, 1, py_value);
+ PyObject **py_functions = py_mutator->py_functions;
- /* max_size */
-#if PY_MAJOR_VERSION >= 3
- py_value = PyLong_FromLong(max_size);
-#else
- py_value = PyInt_FromLong(max_size);
-#endif
- if (!py_value) {
+ if (py_functions[PY_FUNC_INIT]) afl->mutator->afl_custom_init = unsupported;
- Py_DECREF(py_args);
- FATAL("Failed to convert arguments");
+ if (py_functions[PY_FUNC_DEINIT]) afl->mutator->afl_custom_deinit = deinit_py;
- }
+ /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
+ is quite different from the custom mutator. */
+ afl->mutator->afl_custom_fuzz = fuzz_py;
- PyTuple_SetItem(py_args, 2, py_value);
+ if (py_functions[PY_FUNC_PRE_SAVE])
+ afl->mutator->afl_custom_pre_save = pre_save_py;
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_FUZZ], py_args);
+ if (py_functions[PY_FUNC_INIT_TRIM])
+ afl->mutator->afl_custom_init_trim = init_trim_py;
- Py_DECREF(py_args);
+ if (py_functions[PY_FUNC_POST_TRIM])
+ afl->mutator->afl_custom_post_trim = post_trim_py;
- if (py_value != NULL) {
+ if (py_functions[PY_FUNC_TRIM]) afl->mutator->afl_custom_trim = trim_py;
- mutated_size = PyByteArray_Size(py_value);
- if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size);
+ if (py_functions[PY_FUNC_HAVOC_MUTATION])
+ afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
- memcpy(*buf, PyByteArray_AsString(py_value), mutated_size);
- Py_DECREF(py_value);
- return mutated_size;
+ if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY])
+ afl->mutator->afl_custom_havoc_mutation_probability =
+ havoc_mutation_probability_py;
- } else {
+ if (py_functions[PY_FUNC_QUEUE_GET])
+ afl->mutator->afl_custom_queue_get = queue_get_py;
- PyErr_Print();
- FATAL("Call failed");
+ if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY])
+ afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py;
- }
+ OKF("Python mutator '%s' installed successfully.", module_name);
+
+ /* Initialize the custom mutator */
+ init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
}
-size_t pre_save_py(afl_state_t *afl, u8 *buf, size_t buf_size, u8 **out_buf) {
+
+size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) {
size_t out_buf_size;
PyObject *py_args, *py_value;
@@ -260,7 +350,7 @@ size_t pre_save_py(afl_state_t *afl, u8 *buf, size_t buf_size, u8 **out_buf) {
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_PRE_SAVE], py_args);
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args);
Py_DECREF(py_args);
@@ -281,7 +371,7 @@ size_t pre_save_py(afl_state_t *afl, u8 *buf, size_t buf_size, u8 **out_buf) {
}
-u32 init_trim_py(afl_state_t *afl, u8 *buf, size_t buf_size) {
+u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
PyObject *py_args, *py_value;
@@ -296,7 +386,7 @@ u32 init_trim_py(afl_state_t *afl, u8 *buf, size_t buf_size) {
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_INIT_TRIM], py_args);
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -318,7 +408,7 @@ u32 init_trim_py(afl_state_t *afl, u8 *buf, size_t buf_size) {
}
-u32 post_trim_py(afl_state_t *afl, u8 success) {
+u32 post_trim_py(void *py_mutator, u8 success) {
PyObject *py_args, *py_value;
@@ -334,7 +424,7 @@ u32 post_trim_py(afl_state_t *afl, u8 success) {
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_POST_TRIM], py_args);
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -356,12 +446,12 @@ u32 post_trim_py(afl_state_t *afl, u8 success) {
}
-void trim_py(afl_state_t *afl, u8 **out_buf, size_t *out_buf_size) {
+void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) {
PyObject *py_args, *py_value;
py_args = PyTuple_New(0);
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_TRIM], py_args);
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -380,7 +470,7 @@ void trim_py(afl_state_t *afl, u8 **out_buf, size_t *out_buf_size) {
}
-size_t havoc_mutation_py(afl_state_t *afl, u8 **buf, size_t buf_size,
+size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size,
size_t max_size) {
size_t mutated_size;
@@ -414,7 +504,7 @@ size_t havoc_mutation_py(afl_state_t *afl, u8 **buf, size_t buf_size,
PyTuple_SetItem(py_args, 1, py_value);
py_value =
- PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION], py_args);
+ PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], py_args);
Py_DECREF(py_args);
@@ -437,13 +527,13 @@ size_t havoc_mutation_py(afl_state_t *afl, u8 **buf, size_t buf_size,
}
-u8 havoc_mutation_probability_py(afl_state_t *afl) {
+u8 havoc_mutation_probability_py(void *py_mutator) {
PyObject *py_args, *py_value;
py_args = PyTuple_New(0);
py_value = PyObject_CallObject(
- afl->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args);
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -461,7 +551,7 @@ u8 havoc_mutation_probability_py(afl_state_t *afl) {
}
-u8 queue_get_py(afl_state_t *afl, const u8 *filename) {
+u8 queue_get_py(void *py_mutator, const u8 *filename) {
PyObject *py_args, *py_value;
@@ -483,7 +573,7 @@ u8 queue_get_py(afl_state_t *afl, const u8 *filename) {
PyTuple_SetItem(py_args, 0, py_value);
// Call Python function
- py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_GET], py_args);
+ py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -509,7 +599,7 @@ u8 queue_get_py(afl_state_t *afl, const u8 *filename) {
}
-void queue_new_entry_py(afl_state_t *afl, const u8 *filename_new_queue,
+void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
const u8 *filename_orig_queue) {
PyObject *py_args, *py_value;
@@ -553,7 +643,7 @@ void queue_new_entry_py(afl_state_t *afl, const u8 *filename_new_queue,
// Call
py_value =
- PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args);
+ PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args);
Py_DECREF(py_args);
if (py_value == NULL) {
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index cfeab798..f49e1f1e 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -185,12 +185,16 @@ void destroy_queue(afl_state_t *afl) {
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u32 i;
- u64 fav_factor = q->exec_us * q->len;
+ u64 fav_factor;
u64 fuzz_p2 = next_p2(q->n_fuzz);
+ if (afl->schedule == MMOPT || afl->schedule == RARE)
+ fav_factor = q->len << 2;
+ else
+ fav_factor = q->exec_us * q->len;
+
/* 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 < MAP_SIZE; ++i)
if (afl->fsrv.trace_bits[i]) {
@@ -198,20 +202,20 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
if (afl->top_rated[i]) {
/* Faster-executing or smaller test cases are favored. */
+ u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
- u64 top_rated_fav_factor =
- afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
- if (fuzz_p2 > top_rated_fuzz_p2) {
+ if (afl->schedule == MMOPT || afl->schedule == RARE)
+ 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 (fuzz_p2 > top_rated_fuzz_p2)
continue;
-
- } else if (fuzz_p2 == top_rated_fuzz_p2) {
-
+ else if (fuzz_p2 == top_rated_fuzz_p2)
if (fav_factor > top_rated_fav_factor) continue;
- }
-
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
continue;
@@ -254,7 +258,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
void cull_queue(afl_state_t *afl) {
struct queue_entry *q;
- static u8 temp_v[MAP_SIZE >> 3];
+ u8 temp_v[MAP_SIZE >> 3];
u32 i;
if (afl->dumb_mode || !afl->score_changed) return;
@@ -328,7 +332,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh
- if (afl->schedule != MMOPT) {
+ if (afl->schedule != MMOPT && afl->schedule != RARE) {
if (q->exec_us * 0.1 > avg_exec_us)
perf_score = 10;
@@ -448,8 +452,29 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
break;
case MMOPT:
+ /* -- this was a more complex setup, which is good, but competed with
+ -- rare. the simpler algo however is good when rare is not.
+ // the newer the entry, the higher the pref_score
+ perf_score *= (1 + (double)((double)q->depth /
+ (double)afl->queued_paths));
+ // with special focus on the last 8 entries
+ if (afl->max_depth - q->depth < 8) perf_score *= (1 + ((8 -
+ (afl->max_depth - q->depth)) / 5));
+ */
+ // put focus on the last 5 entries
+ if (afl->max_depth - q->depth < 5) perf_score *= 2;
+
+ break;
+
+ case RARE:
- if (afl->max_depth - q->depth < 5) perf_score *= 1.5;
+ // increase the score for every bitmap byte for which this entry
+ // is the top contender
+ perf_score += (q->tc_ref * 10);
+ // the more often fuzz result paths are equal to this queue entry,
+ // reduce its value
+ perf_score *=
+ (1 - (double)((double)q->n_fuzz / (double)afl->total_execs));
break;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index c910e75e..b069fa77 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -97,7 +97,7 @@ static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
u32 i;
for (i = 0; i < len; ++i)
- buf[i] = UR(afl, 256);
+ buf[i] = rand_below(afl, 256);
}
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index cdec75e8..8c4b5941 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -28,14 +28,7 @@
#include <signal.h>
/* Execute target application, monitoring for timeouts. Return status
- information. The called program will update afl->fsrv.trace_bits[]. */
-
-void timeout_handle(union sigval timer_data) {
-
- pid_t child_pid = timer_data.sival_int;
- if (child_pid > 0) kill(child_pid, SIGKILL);
-
-}
+ information. The called program will update afl->fsrv.trace_bits. */
u8 run_target(afl_state_t *afl, u32 timeout) {
@@ -44,11 +37,9 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
fd_set readfds;
- static struct timeval it;
- static u32 prev_timed_out = 0;
-
- int status = 0;
- u32 tb4;
+ struct timeval it;
+ int status = 0;
+ u32 tb4;
afl->fsrv.child_timed_out = 0;
@@ -63,7 +54,7 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
/* we have the fork server (or faux server) up and running, so simply
tell it to have at it, and then read back PID. */
- if ((res = write(afl->fsrv.fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
+ if ((res = write(afl->fsrv.fsrv_ctl_fd, &afl->fsrv.prev_timed_out, 4)) != 4) {
if (afl->stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
@@ -144,7 +135,7 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
classify_counts((u32 *)afl->fsrv.trace_bits);
#endif /* ^WORD_SIZE_64 */
- prev_timed_out = afl->fsrv.child_timed_out;
+ afl->fsrv.prev_timed_out = afl->fsrv.child_timed_out;
/* Report outcome to caller. */
@@ -299,8 +290,6 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
u32 handicap, u8 from_queue) {
- static u8 first_trace[MAP_SIZE];
-
u8 fault = 0, new_bits = 0, var_detected = 0,
first_run = (q->exec_cksum == 0);
@@ -331,7 +320,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
afl->shm.cmplog_mode)
init_cmplog_forkserver(afl);
- if (q->exec_cksum) memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE);
+ if (q->exec_cksum) memcpy(afl->first_trace, afl->fsrv.trace_bits, MAP_SIZE);
start_us = get_cur_time_us();
@@ -372,7 +361,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
for (i = 0; i < MAP_SIZE; ++i) {
- if (!afl->var_bytes[i] && first_trace[i] != afl->fsrv.trace_bits[i]) {
+ if (!afl->var_bytes[i] &&
+ afl->first_trace[i] != afl->fsrv.trace_bits[i]) {
afl->var_bytes[i] = 1;
afl->stage_max = CAL_CYCLES_LONG;
@@ -386,7 +376,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
} else {
q->exec_cksum = cksum;
- memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE);
+ memcpy(afl->first_trace, afl->fsrv.trace_bits, MAP_SIZE);
}
@@ -471,8 +461,6 @@ void sync_fuzzers(afl_state_t *afl) {
while ((sd_ent = readdir(sd))) {
- static u8 stage_tmp[128];
-
DIR * qd;
struct dirent *qd_ent;
u8 * qd_path, *qd_synced_path;
@@ -511,8 +499,9 @@ void sync_fuzzers(afl_state_t *afl) {
/* Show stats */
- sprintf(stage_tmp, "sync %u", ++sync_cnt);
- afl->stage_name = stage_tmp;
+ snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt);
+
+ afl->stage_name = afl->stage_name_buf;
afl->stage_cur = 0;
afl->stage_max = 0;
@@ -608,21 +597,20 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
if (afl->mutator && afl->mutator->afl_custom_trim)
return trim_case_custom(afl, q, in_buf);
- static u8 tmp[64];
- static u8 clean_trace[MAP_SIZE];
-
u8 needs_write = 0, fault = 0;
u32 trim_exec = 0;
u32 remove_len;
u32 len_p2;
+ u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
+
/* Although the trimmer will be less useful when variable behavior is
detected, it will still work to some extent, so we don't check for
this. */
if (q->len < 5) return 0;
- afl->stage_name = tmp;
+ afl->stage_name = afl->stage_name_buf;
afl->bytes_trim_in += q->len;
/* Select initial chunk len, starting with large steps. */
@@ -638,7 +626,9 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
u32 remove_pos = remove_len;
- sprintf(tmp, "trim %s/%s", DI(remove_len), DI(remove_len));
+ sprintf(afl->stage_name_buf, "trim %s/%s",
+ u_stringify_int(val_bufs[0], remove_len),
+ u_stringify_int(val_bufs[1], remove_len));
afl->stage_cur = 0;
afl->stage_max = q->len / remove_len;
@@ -680,7 +670,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
if (!needs_write) {
needs_write = 1;
- memcpy(clean_trace, afl->fsrv.trace_bits, MAP_SIZE);
+ memcpy(afl->clean_trace, afl->fsrv.trace_bits, MAP_SIZE);
}
@@ -722,7 +712,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
ck_write(fd, in_buf, q->len, q->fname);
close(fd);
- memcpy(afl->fsrv.trace_bits, clean_trace, MAP_SIZE);
+ memcpy(afl->fsrv.trace_bits, afl->clean_trace, MAP_SIZE);
update_bitmap_score(afl, q);
}
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 63cca14d..dc16df8f 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -30,12 +30,12 @@
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
double eps) {
- static double last_bcvg, last_stab, last_eps;
- static struct rusage rus;
+ struct rusage rus;
- u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
- s32 fd;
- FILE *f;
+ unsigned long long int cur_time = get_cur_time();
+ u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
+ s32 fd;
+ FILE * f;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
@@ -52,15 +52,15 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
if (!bitmap_cvg && !stability && !eps) {
- bitmap_cvg = last_bcvg;
- stability = last_stab;
- eps = last_eps;
+ bitmap_cvg = afl->last_bitmap_cvg;
+ stability = afl->last_stability;
+ eps = afl->last_eps;
} else {
- last_bcvg = bitmap_cvg;
- last_stab = stability;
- last_eps = eps;
+ afl->last_bitmap_cvg = bitmap_cvg;
+ afl->last_stability = stability;
+ afl->last_eps = eps;
}
@@ -70,8 +70,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
f,
"start_time : %llu\n"
"last_update : %llu\n"
+ "run_time : %llu\n"
"fuzzer_pid : %d\n"
"cycles_done : %llu\n"
+ "cycles_wo_finds : %llu\n"
"execs_done : %llu\n"
"execs_per_sec : %0.02f\n"
// "real_execs_per_sec: %0.02f\n" // damn the name is too long
@@ -100,10 +102,11 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"\n"
"target_mode : %s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
- afl->start_time / 1000, get_cur_time() / 1000, getpid(),
- afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
- /*eps,*/ afl->total_execs /
- ((double)(get_cur_time() - afl->start_time) / 1000),
+ afl->start_time / 1000, cur_time / 1000,
+ (cur_time - afl->start_time) / 1000, getpid(),
+ afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
+ afl->total_execs,
+ afl->total_execs / ((double)(get_cur_time() - afl->start_time) / 1000),
afl->queued_paths, afl->queued_favored, afl->queued_discovered,
afl->queued_imported, afl->max_depth, afl->current_entry,
afl->pending_favored, afl->pending_not_fuzzed, afl->queued_variable,
@@ -137,23 +140,24 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
- static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md;
- static u64 prev_qc, prev_uc, prev_uh;
-
- if (prev_qp == afl->queued_paths && prev_pf == afl->pending_favored &&
- prev_pnf == afl->pending_not_fuzzed && prev_ce == afl->current_entry &&
- prev_qc == afl->queue_cycle && prev_uc == afl->unique_crashes &&
- prev_uh == afl->unique_hangs && prev_md == afl->max_depth)
+ if (afl->plot_prev_qp == afl->queued_paths &&
+ afl->plot_prev_pf == afl->pending_favored &&
+ afl->plot_prev_pnf == afl->pending_not_fuzzed &&
+ afl->plot_prev_ce == afl->current_entry &&
+ afl->plot_prev_qc == afl->queue_cycle &&
+ afl->plot_prev_uc == afl->unique_crashes &&
+ afl->plot_prev_uh == afl->unique_hangs &&
+ afl->plot_prev_md == afl->max_depth)
return;
- prev_qp = afl->queued_paths;
- prev_pf = afl->pending_favored;
- prev_pnf = afl->pending_not_fuzzed;
- prev_ce = afl->current_entry;
- prev_qc = afl->queue_cycle;
- prev_uc = afl->unique_crashes;
- prev_uh = afl->unique_hangs;
- prev_md = afl->max_depth;
+ afl->plot_prev_qp = afl->queued_paths;
+ afl->plot_prev_pf = afl->pending_favored;
+ afl->plot_prev_pnf = afl->pending_not_fuzzed;
+ afl->plot_prev_ce = afl->current_entry;
+ afl->plot_prev_qc = afl->queue_cycle;
+ afl->plot_prev_uc = afl->unique_crashes;
+ afl->plot_prev_uh = afl->unique_hangs;
+ afl->plot_prev_md = afl->max_depth;
/* Fields in the file:
@@ -192,21 +196,25 @@ static void check_term_size(afl_state_t *afl) {
void show_stats(afl_state_t *afl) {
- static u64 last_stats_ms, last_plot_ms, last_ms, last_execs;
- static double avg_exec;
- double t_byte_ratio, stab_ratio;
+ double t_byte_ratio, stab_ratio;
u64 cur_ms;
u32 t_bytes, t_bits;
u32 banner_len, banner_pad;
u8 tmp[256];
+ u8 time_tmp[64];
+
+ u8 val_buf[8][STRINGIFY_VAL_SIZE_MAX];
+#define IB(i) (val_buf[(i)])
cur_ms = get_cur_time();
/* If not enough time has passed since last UI update, bail out. */
- if (cur_ms - last_ms < 1000 / UI_TARGET_HZ && !afl->force_ui_update) return;
+ if (cur_ms - afl->stats_last_ms < 1000 / UI_TARGET_HZ &&
+ !afl->force_ui_update)
+ return;
/* Check if we're past the 10 minute mark. */
@@ -214,31 +222,33 @@ void show_stats(afl_state_t *afl) {
/* Calculate smoothed exec speed stats. */
- if (!last_execs) {
+ if (!afl->stats_last_execs) {
- avg_exec = ((double)afl->total_execs) * 1000 / (cur_ms - afl->start_time);
+ afl->stats_avg_exec =
+ ((double)afl->total_execs) * 1000 / (cur_ms - afl->start_time);
} else {
- double cur_avg =
- ((double)(afl->total_execs - last_execs)) * 1000 / (cur_ms - last_ms);
+ double cur_avg = ((double)(afl->total_execs - afl->stats_last_execs)) *
+ 1000 / (cur_ms - afl->stats_last_ms);
/* If there is a dramatic (5x+) jump in speed, reset the indicator
more quickly. */
- if (cur_avg * 5 < avg_exec || cur_avg / 5 > avg_exec) avg_exec = cur_avg;
+ if (cur_avg * 5 < afl->stats_avg_exec || cur_avg / 5 > afl->stats_avg_exec)
+ afl->stats_avg_exec = cur_avg;
- avg_exec = avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
- cur_avg * (1.0 / AVG_SMOOTHING);
+ afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
+ cur_avg * (1.0 / AVG_SMOOTHING);
}
- last_ms = cur_ms;
- last_execs = afl->total_execs;
+ afl->stats_last_ms = cur_ms;
+ afl->stats_last_execs = afl->total_execs;
/* Tell the callers when to contact us (as measured in execs). */
- afl->stats_update_freq = avg_exec / (UI_TARGET_HZ * 10);
+ afl->stats_update_freq = afl->stats_avg_exec / (UI_TARGET_HZ * 10);
if (!afl->stats_update_freq) afl->stats_update_freq = 1;
/* Do some bitmap stats. */
@@ -253,10 +263,10 @@ void show_stats(afl_state_t *afl) {
/* Roughly every minute, update fuzzer stats and save auto tokens. */
- if (cur_ms - last_stats_ms > STATS_UPDATE_SEC * 1000) {
+ if (cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000) {
- last_stats_ms = cur_ms;
- write_stats_file(afl, t_byte_ratio, stab_ratio, avg_exec);
+ afl->stats_last_stats_ms = cur_ms;
+ write_stats_file(afl, t_byte_ratio, stab_ratio, afl->stats_avg_exec);
save_auto(afl);
write_bitmap(afl);
@@ -264,10 +274,10 @@ void show_stats(afl_state_t *afl) {
/* Every now and then, write plot data. */
- if (cur_ms - last_plot_ms > PLOT_UPDATE_SEC * 1000) {
+ if (cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000) {
- last_plot_ms = cur_ms;
- maybe_update_plot_file(afl, t_byte_ratio, avg_exec);
+ afl->stats_last_plot_ms = cur_ms;
+ maybe_update_plot_file(afl, t_byte_ratio, afl->stats_avg_exec);
}
@@ -384,9 +394,10 @@ void show_stats(afl_state_t *afl) {
}
+ u_stringify_time_diff(time_tmp, cur_ms, afl->start_time);
SAYF(bV bSTOP " run time : " cRST "%-33s " bSTG bV bSTOP
" cycles done : %s%-5s " bSTG bV "\n",
- DTD(cur_ms, afl->start_time), tmp, DI(afl->queue_cycle - 1));
+ time_tmp, tmp, u_stringify_int(IB(0), afl->queue_cycle - 1));
/* We want to warn people about not seeing new paths after a full cycle,
except when resuming fuzzing or running in non-instrumented mode. */
@@ -395,8 +406,9 @@ void show_stats(afl_state_t *afl) {
(afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
afl->in_bitmap || afl->crash_mode)) {
- SAYF(bV bSTOP " last new path : " cRST "%-33s ",
- DTD(cur_ms, afl->last_path_time));
+ u_stringify_time_diff(time_tmp, cur_ms,
+ afl->last_path_time);
+ SAYF(bV bSTOP " last new path : " cRST "%-33s ", time_tmp);
} else {
@@ -413,25 +425,26 @@ void show_stats(afl_state_t *afl) {
}
SAYF(bSTG bV bSTOP " total paths : " cRST "%-5s " bSTG bV "\n",
- DI(afl->queued_paths));
+ u_stringify_int(IB(0), afl->queued_paths));
/* Highlight crashes in red if found, denote going over the KEEP_UNIQUE_CRASH
limit with a '+' appended to the count. */
- sprintf(tmp, "%s%s", DI(afl->unique_crashes),
+ sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->unique_crashes),
(afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
+ u_stringify_time_diff(time_tmp, cur_ms, afl->last_crash_time);
SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP
" uniq crashes : %s%-6s" bSTG bV "\n",
- DTD(cur_ms, afl->last_crash_time), afl->unique_crashes ? cLRD : cRST,
- tmp);
+ time_tmp, afl->unique_crashes ? cLRD : cRST, tmp);
- sprintf(tmp, "%s%s", DI(afl->unique_hangs),
+ sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->unique_hangs),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
+ u_stringify_time_diff(time_tmp, cur_ms, afl->last_hang_time);
SAYF(bV bSTOP " last uniq hang : " cRST "%-33s " bSTG bV bSTOP
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
- DTD(cur_ms, afl->last_hang_time), tmp);
+ time_tmp, tmp);
SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
@@ -441,7 +454,7 @@ void show_stats(afl_state_t *afl) {
together, but then cram them into a fixed-width field - so we need to
put them in a temporary buffer first. */
- sprintf(tmp, "%s%s%u (%0.01f%%)", DI(afl->current_entry),
+ sprintf(tmp, "%s%s%u (%0.01f%%)", u_stringify_int(IB(0), afl->current_entry),
afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level,
((double)afl->current_entry * 100) / afl->queued_paths);
@@ -455,7 +468,7 @@ void show_stats(afl_state_t *afl) {
: ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST),
tmp);
- sprintf(tmp, "%s (%0.02f%%)", DI(afl->cur_skipped_paths),
+ sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths),
((double)afl->cur_skipped_paths * 100) / afl->queued_paths);
SAYF(bV bSTOP " paths timed out : " cRST "%-16s " bSTG bV, tmp);
@@ -468,7 +481,7 @@ void show_stats(afl_state_t *afl) {
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
- sprintf(tmp, "%s (%0.02f%%)", DI(afl->queued_favored),
+ sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
((double)afl->queued_favored) * 100 / afl->queued_paths);
/* Yeah... it's still going on... halp? */
@@ -479,59 +492,65 @@ void show_stats(afl_state_t *afl) {
if (!afl->stage_max) {
- sprintf(tmp, "%s/-", DI(afl->stage_cur));
+ sprintf(tmp, "%s/-", u_stringify_int(IB(0), afl->stage_cur));
} else {
- sprintf(tmp, "%s/%s (%0.02f%%)", DI(afl->stage_cur), DI(afl->stage_max),
+ sprintf(tmp, "%s/%s (%0.02f%%)", u_stringify_int(IB(0), afl->stage_cur),
+ u_stringify_int(IB(1), afl->stage_max),
((double)afl->stage_cur) * 100 / afl->stage_max);
}
SAYF(bV bSTOP " stage execs : " cRST "%-21s" bSTG bV bSTOP, tmp);
- sprintf(tmp, "%s (%0.02f%%)", DI(afl->queued_with_cov),
+ sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov),
((double)afl->queued_with_cov) * 100 / afl->queued_paths);
SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp);
- sprintf(tmp, "%s (%s%s unique)", DI(afl->total_crashes),
- DI(afl->unique_crashes),
+ sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_crashes),
+ u_stringify_int(IB(1), afl->unique_crashes),
(afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
if (afl->crash_mode) {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" new crashes : %s%-22s" bSTG bV "\n",
- DI(afl->total_execs), afl->unique_crashes ? cLRD : cRST, tmp);
+ u_stringify_int(IB(0), afl->total_execs),
+ afl->unique_crashes ? cLRD : cRST, tmp);
} else {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" total crashes : %s%-22s" bSTG bV "\n",
- DI(afl->total_execs), afl->unique_crashes ? cLRD : cRST, tmp);
+ u_stringify_int(IB(0), afl->total_execs),
+ afl->unique_crashes ? cLRD : cRST, tmp);
}
/* Show a warning about slow execution. */
- if (avg_exec < 100) {
+ if (afl->stats_avg_exec < 100) {
- sprintf(tmp, "%s/sec (%s)", DF(avg_exec),
- avg_exec < 20 ? "zzzz..." : "slow!");
+ sprintf(tmp, "%s/sec (%s)",
+ u_stringify_float(IB(0), afl->stats_avg_exec),
+ afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp);
} else {
- sprintf(tmp, "%s/sec", DF(avg_exec));
+ sprintf(tmp, "%s/sec",
+ u_stringify_float(IB(0), afl->stats_avg_exec));
SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp);
}
- sprintf(tmp, "%s (%s%s unique)", DI(afl->total_tmouts),
- DI(afl->unique_tmouts),
- (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
+ sprintf(tmp, "%s (%s%s unique)",
+ u_stringify_int(IB(0), afl->total_tmouts),
+ u_stringify_int(IB(1), afl->unique_tmouts),
+ (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
@@ -547,70 +566,80 @@ void show_stats(afl_state_t *afl) {
} else {
- sprintf(
- tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP1]),
- DI(afl->stage_cycles[STAGE_FLIP1]), DI(afl->stage_finds[STAGE_FLIP2]),
- DI(afl->stage_cycles[STAGE_FLIP2]), DI(afl->stage_finds[STAGE_FLIP4]),
- DI(afl->stage_cycles[STAGE_FLIP4]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]),
+ u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4]));
}
SAYF(bV bSTOP " bit flips : " cRST "%-36s " bSTG bV bSTOP
" levels : " cRST "%-10s" bSTG bV "\n",
- tmp, DI(afl->max_depth));
+ tmp, u_stringify_int(IB(0), afl->max_depth));
if (!afl->skip_deterministic)
- sprintf(
- tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP8]),
- DI(afl->stage_cycles[STAGE_FLIP8]), DI(afl->stage_finds[STAGE_FLIP16]),
- DI(afl->stage_cycles[STAGE_FLIP16]), DI(afl->stage_finds[STAGE_FLIP32]),
- DI(afl->stage_cycles[STAGE_FLIP32]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP
" pending : " cRST "%-10s" bSTG bV "\n",
- tmp, DI(afl->pending_not_fuzzed));
+ tmp, u_stringify_int(IB(0), afl->pending_not_fuzzed));
if (!afl->skip_deterministic)
- sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_ARITH8]),
- DI(afl->stage_cycles[STAGE_ARITH8]),
- DI(afl->stage_finds[STAGE_ARITH16]),
- DI(afl->stage_cycles[STAGE_ARITH16]),
- DI(afl->stage_finds[STAGE_ARITH32]),
- DI(afl->stage_cycles[STAGE_ARITH32]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
" pend fav : " cRST "%-10s" bSTG bV "\n",
- tmp, DI(afl->pending_favored));
+ tmp, u_stringify_int(IB(0), afl->pending_favored));
if (!afl->skip_deterministic)
- sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_INTEREST8]),
- DI(afl->stage_cycles[STAGE_INTEREST8]),
- DI(afl->stage_finds[STAGE_INTEREST16]),
- DI(afl->stage_cycles[STAGE_INTEREST16]),
- DI(afl->stage_finds[STAGE_INTEREST32]),
- DI(afl->stage_cycles[STAGE_INTEREST32]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_INTEREST8]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_INTEREST8]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_INTEREST16]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_INTEREST16]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_INTEREST32]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_INTEREST32]));
SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP
" own finds : " cRST "%-10s" bSTG bV "\n",
- tmp, DI(afl->queued_discovered));
+ tmp, u_stringify_int(IB(0), afl->queued_discovered));
if (!afl->skip_deterministic)
- sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_EXTRAS_UO]),
- DI(afl->stage_cycles[STAGE_EXTRAS_UO]),
- DI(afl->stage_finds[STAGE_EXTRAS_UI]),
- DI(afl->stage_cycles[STAGE_EXTRAS_UI]),
- DI(afl->stage_finds[STAGE_EXTRAS_AO]),
- DI(afl->stage_cycles[STAGE_EXTRAS_AO]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
" imported : " cRST "%-10s" bSTG bV "\n",
- tmp, afl->sync_id ? DI(afl->queued_imported) : (u8 *)"n/a");
+ tmp,
+ afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) : (u8 *)"n/a");
- sprintf(
- tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_HAVOC]),
- DI(afl->stage_cycles[STAGE_HAVOC]), DI(afl->stage_finds[STAGE_SPLICE]),
- DI(afl->stage_cycles[STAGE_SPLICE]), DI(afl->stage_finds[STAGE_RADAMSA]),
- DI(afl->stage_cycles[STAGE_RADAMSA]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
+ u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
+ u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
+ u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]),
+ u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
+ u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
@@ -631,23 +660,25 @@ void show_stats(afl_state_t *afl) {
if (afl->shm.cmplog_mode) {
sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
- DI(afl->stage_finds[STAGE_PYTHON]),
- DI(afl->stage_cycles[STAGE_PYTHON]),
- DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
- DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
- DI(afl->stage_finds[STAGE_COLORIZATION]),
- DI(afl->stage_cycles[STAGE_COLORIZATION]),
- DI(afl->stage_finds[STAGE_ITS]), DI(afl->stage_cycles[STAGE_ITS]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]),
+ u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]),
+ u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS]));
SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp);
} else {
- sprintf(tmp, "%s/%s, %s/%s", DI(afl->stage_finds[STAGE_PYTHON]),
- DI(afl->stage_cycles[STAGE_PYTHON]),
- DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
- DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
+ sprintf(tmp, "%s/%s, %s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp);
@@ -663,7 +694,7 @@ void show_stats(afl_state_t *afl) {
sprintf(tmp, "%0.02f%%/%s, ",
((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 /
afl->bytes_trim_in,
- DI(afl->trim_execs));
+ u_stringify_int(IB(0), afl->trim_execs));
}
@@ -688,8 +719,9 @@ void show_stats(afl_state_t *afl) {
if (afl->mutator) {
- sprintf(tmp, "%s/%s", DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
- DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
+ sprintf(tmp, "%s/%s",
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
} else {
@@ -744,6 +776,8 @@ void show_stats(afl_state_t *afl) {
/* Last line */
SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
+#undef IB
+
/* Hallelujah! */
fflush(0);
@@ -762,6 +796,9 @@ void show_init_stats(afl_state_t *afl) {
u64 avg_us = 0;
u32 max_len = 0;
+ u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX];
+#define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)])
+
if (afl->total_cal_cycles) avg_us = afl->total_cal_us / afl->total_cal_cycles;
while (q) {
@@ -797,10 +834,10 @@ void show_init_stats(afl_state_t *afl) {
if (max_len > 50 * 1024)
WARNF(cLRD "Some test cases are huge (%s) - see %s/perf_tips.md!",
- DMS(max_len), doc_path);
+ stringify_mem_size(IB(0), max_len), doc_path);
else if (max_len > 10 * 1024)
- WARNF("Some test cases are big (%s) - see %s/perf_tips.md.", DMS(max_len),
- doc_path);
+ WARNF("Some test cases are big (%s) - see %s/perf_tips.md.",
+ stringify_mem_size(IB(0), max_len), doc_path);
if (afl->useless_at_start && !afl->in_bitmap)
WARNF(cLRD "Some test cases look useless. Consider using a smaller set.");
@@ -824,7 +861,8 @@ void show_init_stats(afl_state_t *afl) {
max_bits,
((double)afl->total_bitmap_size) /
(afl->total_bitmap_entries ? afl->total_bitmap_entries : 1),
- DI(min_us), DI(max_us), DI(avg_us));
+ stringify_int(IB(0), min_us), stringify_int(IB(1), max_us),
+ stringify_int(IB(2), avg_us));
if (!afl->timeout_given) {
@@ -868,6 +906,7 @@ void show_init_stats(afl_state_t *afl) {
afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
OKF("All set and ready to roll!");
+#undef IB
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 10fee76c..ba56ff67 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -96,8 +96,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"Execution control settings:\n"
" -p schedule - power schedules recompute a seed's performance "
"score.\n"
- " <explore (default), fast, coe, lin, quad, exploit, "
- "mmopt>\n"
+ " <explore(default), fast, coe, lin, quad, exploit, "
+ "mmopt, rare>\n"
" see docs/power_schedules.md\n"
" -f file - location read by the fuzzed program (stdin)\n"
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
@@ -230,8 +230,7 @@ int main(int argc, char **argv_orig, char **envp) {
u64 prev_queued = 0;
u32 sync_interval_cnt = 0, seek_to, show_help = 0;
u8 * extras_dir = 0;
- u8 mem_limit_given = 0;
- u8 exit_1 = !!get_afl_env("AFL_BENCH_JUST_ONE");
+ u8 mem_limit_given = 0, exit_1 = 0;
char **use_argv;
struct timeval tv;
@@ -246,11 +245,12 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_init(&afl->fsrv);
read_afl_environment(afl, envp);
+ exit_1 = !!afl->afl_env.afl_bench_just_one;
SAYF(cCYA "afl-fuzz" VERSION cRST
" based on afl by Michal Zalewski and a big online community\n");
- doc_path = access(DOC_PATH, F_OK) ? (u8 *)"docs" : doc_path;
+ doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz);
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@@ -304,6 +304,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->schedule = MMOPT;
+ } else if (!stricmp(optarg, "rare")) {
+
+ afl->schedule = RARE;
+
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
@@ -760,8 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
case LIN: OKF("Using linear power schedule (LIN)"); break;
case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
case MMOPT: OKF("Using modified MOpt power schedule (MMOPT)"); break;
+ case RARE: OKF("Using rare edge focus power schedule (RARE)"); break;
case EXPLORE:
- OKF("Using exploration-based constant power schedule (EXPLORE)");
+ OKF("Using exploration-based constant power schedule (EXPLORE, default)");
break;
default: FATAL("Unknown power schedule"); break;
@@ -1046,9 +1051,9 @@ int main(int argc, char **argv_orig, char **envp) {
}
- show_stats(afl);
+ // show_stats(afl);
- if (afl->not_on_tty) {
+ if (unlikely(afl->not_on_tty)) {
ACTF("Entering queue cycle %llu.", afl->queue_cycle);
fflush(stdout);
@@ -1119,7 +1124,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (afl->queue_cur) show_stats(afl);
+ // if (afl->queue_cur) show_stats(afl);
/*
* ATTENTION - the following 10 lines were copied from a PR to Google's afl
@@ -1144,12 +1149,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
write_bitmap(afl);
- write_stats_file(afl, 0, 0, 0);
maybe_update_plot_file(afl, 0, 0);
save_auto(afl);
stop_fuzzing:
+ write_stats_file(afl, 0, 0, 0);
afl->force_ui_update = 1; // ensure the screen is reprinted
show_stats(afl); // print the screen one last time
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index 70ed4dbc..6c2fa147 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -90,7 +90,7 @@ static u64 get_cpu_usage_us(void) {
static u32 measure_preemption(u32 target_ms) {
- static volatile u32 v1, v2;
+ volatile u32 v1, v2 = 0;
u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;
s32 loop_repeats = 0;
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 0051bbec..caacefe4 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -263,9 +263,8 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
static u8 run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
u32 len) {
- static struct itimerval it;
- static u32 prev_timed_out = 0;
- int status = 0;
+ struct itimerval it;
+ int status = 0;
memset(fsrv->trace_bits, 0, MAP_SIZE);
MEM_BARRIER();
@@ -277,7 +276,7 @@ static u8 run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
/* we have the fork server up and running, so simply
tell it to have at it, and then read back PID. */
- if ((res = write(fsrv->fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
+ if ((res = write(fsrv->fsrv_ctl_fd, &fsrv->prev_timed_out, 4)) != 4) {
if (stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
@@ -579,11 +578,6 @@ static void setup_signal_handlers(void) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- /* Exec timeout notifications. */
-
- sa.sa_handler = handle_timeout;
- sigaction(SIGALRM, &sa, NULL);
-
}
/* Show banner. */
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 17e9af5a..2275aef5 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -247,160 +247,14 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
}
-/* Handle timeout signal. */
-/*
-static void handle_timeout(int sig) {
-
- if (child_pid > 0) {
-
- child_timed_out = 1;
- kill(child_pid, SIGKILL);
-
- } else if (child_pid == -1 && forksrv_pid > 0) {
-
- child_timed_out = 1;
- kill(forksrv_pid, SIGKILL);
-
- }
-
-}
-
-*/
-
-/* start the app and it's forkserver */
-/*
-static void init_forkserver(char **argv) {
-
- static struct itimerval it;
- int st_pipe[2], ctl_pipe[2];
- int status = 0;
- s32 rlen;
-
- ACTF("Spinning up the fork server...");
- if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL("pipe() failed");
-
- forksrv_pid = fork();
-
- if (forksrv_pid < 0) PFATAL("fork() failed");
-
- if (!forksrv_pid) {
-
- struct rlimit r;
-
- if (dup2(use_stdin ? out_fd : dev_null_fd, 0) < 0 ||
- dup2(dev_null_fd, 1) < 0 ||
- dup2(dev_null_fd, 2) < 0) {
-
- *(u32*)trace_bits = EXEC_FAIL_SIG;
- PFATAL("dup2() failed");
-
- }
-
- close(dev_null_fd);
- close(out_fd);
-
- setsid();
-
- if (mem_limit) {
-
- r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;
-
-#ifdef RLIMIT_AS
-
- setrlimit(RLIMIT_AS, &r); // Ignore errors
-
-#else
-
- setrlimit(RLIMIT_DATA, &r); // Ignore errors
-
-#endif // ^RLIMIT_AS
-
- }
-
- r.rlim_max = r.rlim_cur = 0;
- setrlimit(RLIMIT_CORE, &r); // Ignore errors
-
- // Set up control and status pipes, close the unneeded original fds.
-
- if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) PFATAL("dup2() failed");
- if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) PFATAL("dup2() failed");
-
- close(ctl_pipe[0]);
- close(ctl_pipe[1]);
- close(st_pipe[0]);
- close(st_pipe[1]);
-
- execv(fsrv->target_path, argv);
-
- *(u32*)trace_bits = EXEC_FAIL_SIG;
- exit(0);
-
- }
-
- // Close the unneeded endpoints.
-
- close(ctl_pipe[0]);
- close(st_pipe[1]);
-
- fsrv_ctl_fd = ctl_pipe[1];
- fsrv_st_fd = st_pipe[0];
-
- // Configure timeout, wait for child, cancel timeout.
-
- if (exec_tmout) {
-
- child_timed_out = 0;
- it.it_value.tv_sec = (exec_tmout * FORK_WAIT_MULT / 1000);
- it.it_value.tv_usec = ((exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;
-
- }
-
- setitimer(ITIMER_REAL, &it, NULL);
-
- rlen = read(fsrv_st_fd, &status, 4);
-
- it.it_value.tv_sec = 0;
- it.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &it, NULL);
-
- // If we have a four-byte "hello" message from the server, we're all set.
- // Otherwise, try to figure out what went wrong.
-
- if (rlen == 4) {
-
- ACTF("All right - fork server is up.");
- return;
-
- }
-
- if (waitpid(forksrv_pid, &status, 0) <= 0)
- PFATAL("waitpid() failed");
-
- u8 child_crashed;
-
- if (WIFSIGNALED(status))
- child_crashed = 1;
-
- if (child_timed_out)
- SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
- else if (stop_soon)
- SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
- else if (child_crashed)
- SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST, WTERMSIG(status));
-
-}
-
-*/
-
/* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */
static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
u8 first_run) {
- static struct itimerval it;
- static u32 prev_timed_out = 0;
- int status = 0;
+ struct itimerval it;
+ int status = 0;
u32 cksum;
@@ -416,7 +270,7 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
/* we have the fork server up and running, so simply
tell it to have at it, and then read back PID. */
- if ((res = write(fsrv->fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
+ if ((res = write(fsrv->fsrv_ctl_fd, &fsrv->prev_timed_out, 4)) != 4) {
if (stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
@@ -962,11 +816,6 @@ static void setup_signal_handlers(void) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- /* Exec timeout notifications. */
-
- sa.sa_handler = handle_timeout;
- sigaction(SIGALRM, &sa, NULL);
-
}
/* Display usage hints. */