aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-common.c62
-rw-r--r--src/afl-forkserver.c111
-rw-r--r--src/afl-fuzz-bitmap.c8
-rw-r--r--src/afl-fuzz-init.c73
-rw-r--r--src/afl-fuzz-one.c37
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-run.c40
-rw-r--r--src/afl-fuzz-stats.c56
-rw-r--r--src/afl-fuzz.c68
-rw-r--r--src/afl-sharedmem.c25
10 files changed, 277 insertions, 205 deletions
diff --git a/src/afl-common.c b/src/afl-common.c
index 1bb58a60..2802cda3 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -61,8 +61,9 @@ char *afl_environment_variables[] = {
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IMPORT_FIRST",
"AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY",
"AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER",
- "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM",
- "AFL_LLVM_CTX", "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD",
+ "AFL_LD_PASSTHROUGH", "AFL_REAL_LD", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE",
+ "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX",
+ "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD",
"AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY",
"AFL_LLVM_SKIPSINGLEBLOCK", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
"AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
@@ -253,7 +254,8 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
"binaries that are\n"
" instrumented at compile time with afl-gcc. It is also possible to "
"use it as a\n"
- " traditional \"dumb\" fuzzer by specifying '-n' in the command "
+ " traditional non-instrumented fuzzer by specifying '-n' in the "
+ "command "
"line.\n");
FATAL("Failed to locate 'afl-qemu-trace'.");
@@ -353,7 +355,8 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
"binaries that are\n"
" instrumented at compile time with afl-gcc. It is also possible to "
"use it as a\n"
- " traditional \"dumb\" fuzzer by specifying '-n' in the command "
+ " traditional non-instrumented fuzzer by specifying '-n' in the "
+ "command "
"line.\n",
ncp);
@@ -869,56 +872,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
}
-/* Wrapper for select() and read(), reading exactly len bytes.
- Returns the time passed to read.
- If the wait times out, returns timeout_ms + 1;
- Returns 0 if an error occurred (fd closed, signal, ...); */
-u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
- volatile u8 *stop_soon_p) {
-
- struct timeval timeout;
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- timeout.tv_sec = (timeout_ms / 1000);
- timeout.tv_usec = (timeout_ms % 1000) * 1000;
-
- size_t read_total = 0;
- size_t len_read = 0;
-
- while (len_read < len) {
-
- /* set exceptfds as well to return when a child exited/closed the pipe. */
- int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
-
- if (!sret) {
-
- // printf("Timeout in sret.");
- return timeout_ms + 1;
-
- } else if (sret < 0) {
-
- /* Retry select for all signals other than than ctrl+c */
- if (errno == EINTR && !*stop_soon_p) { continue; }
- return 0;
-
- }
-
- len_read = read(fd, ((u8 *)buf) + len_read, len - len_read);
- if (!len_read) { return 0; }
- read_total += len_read;
-
- }
-
- s32 exec_ms =
- MIN(timeout_ms,
- ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
- return exec_ms > 0 ? exec_ms
- : 1; // at least 1 milli must have passed (0 is an error)
-
-}
-
+/* Reads the map size from ENV */
u32 get_map_size(void) {
uint32_t map_size = MAP_SIZE;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 137a4f99..a549e471 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -101,6 +101,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->exec_tmout = from->exec_tmout;
fsrv_to->mem_limit = from->mem_limit;
fsrv_to->map_size = from->map_size;
+ fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
#ifndef HAVE_ARC4RANDOM
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
@@ -119,7 +120,57 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
}
-/* Internal forkserver for dumb_mode=1 and non-forkserver mode runs.
+/* Wrapper for select() and read(), reading a 32 bit var.
+ Returns the time passed to read.
+ If the wait times out, returns timeout_ms + 1;
+ Returns 0 if an error occurred (fd closed, signal, ...); */
+static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
+ volatile u8 *stop_soon_p) {
+
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ struct timeval timeout;
+ size_t len = 4;
+
+ timeout.tv_sec = (timeout_ms / 1000);
+ timeout.tv_usec = (timeout_ms % 1000) * 1000;
+#if !defined(__linux__)
+ u64 read_start = get_cur_time_us();
+#endif
+
+ /* set exceptfds as well to return when a child exited/closed the pipe. */
+ int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
+
+ if (!sret) {
+
+ *buf = -1;
+ return timeout_ms + 1;
+
+ } else if (sret < 0) {
+
+ *buf = -1;
+ return 0;
+
+ }
+
+ ssize_t len_read = read(fd, ((u8 *)buf), len);
+ if (len_read < len) { return 0; }
+
+#if defined(__linux__)
+ u32 exec_ms =
+ MIN(timeout_ms,
+ ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
+#else
+ u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
+#endif
+
+ // ensure to report 1 ms has passed (0 is an error)
+ return exec_ms > 0 ? exec_ms : 1;
+
+}
+
+/* Internal forkserver for non_instrumented_mode=1 and non-forkserver mode runs.
It execvs for each fork, forwarding exit codes and child pids to afl. */
static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
@@ -228,8 +279,8 @@ static void report_error_and_exit(int error) {
break;
case FS_ERROR_MMAP:
FATAL(
- "the fuzzing target reports that the mmap() call to the share memory "
- "failed.");
+ "the fuzzing target reports that the mmap() call to the shared "
+ "memory failed.");
break;
default:
FATAL("unknown error code %u from fuzzing target!", error);
@@ -238,7 +289,7 @@ static void report_error_and_exit(int error) {
}
-/* Spins up fork server (instrumented mode only). The idea is explained here:
+/* Spins up fork server. The idea is explained here:
http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
@@ -250,14 +301,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
volatile u8 *stop_soon_p, u8 debug_child_output) {
int st_pipe[2], ctl_pipe[2];
- int status;
+ s32 status;
s32 rlen;
if (!be_quiet) { ACTF("Spinning up the fork server..."); }
if (fsrv->use_fauxsrv) {
- /* TODO: Come up with sone nice way to initalize this all */
+ /* TODO: Come up with sone nice way to initialize this all */
if (fsrv->init_child_func != fsrv_exec_child) {
@@ -387,6 +438,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
falling through. */
*(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
+ fprintf(stderr, "Error: execv to target failed\n");
exit(0);
}
@@ -406,14 +458,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
rlen = 0;
if (fsrv->exec_tmout) {
- u32 time = read_timed(fsrv->fsrv_st_fd, &status, 4,
- fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
+ u32 time_ms =
+ read_s32_timed(fsrv->fsrv_st_fd, &status,
+ fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
- if (!time) {
+ if (!time_ms) {
kill(fsrv->fsrv_pid, SIGKILL);
- } else if (time > fsrv->exec_tmout * FORK_WAIT_MULT) {
+ } else if (time_ms > fsrv->exec_tmout * FORK_WAIT_MULT) {
fsrv->last_run_timed_out = 1;
kill(fsrv->fsrv_pid, SIGKILL);
@@ -437,16 +490,16 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (!be_quiet) { OKF("All right - fork server is up."); }
- if ((status & FS_OPT_ERROR) == FS_OPT_ERROR)
- report_error_and_exit(FS_OPT_GET_ERROR(status));
+ if (getenv("AFL_DEBUG")) {
- if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
+ ACTF("Extended forkserver functions received (%08x).", status);
- if (getenv("AFL_DEBUG")) {
+ }
- ACTF("Extended forkserver functions received (%08x).", status);
+ if ((status & FS_OPT_ERROR) == FS_OPT_ERROR)
+ report_error_and_exit(FS_OPT_GET_ERROR(status));
- }
+ if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
@@ -457,9 +510,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_SHDMEM_FUZZ) == FS_OPT_SHDMEM_FUZZ) {
- if (fsrv->support_shdmen_fuzz) {
+ if (fsrv->support_shmem_fuzz) {
- fsrv->use_shdmen_fuzz = 1;
+ fsrv->use_shmem_fuzz = 1;
if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); }
if ((status & FS_OPT_AUTODICT) == 0) {
@@ -473,6 +526,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
+ } else {
+
+ FATAL(
+ "Target requested sharedmem fuzzing, but we failed to enable "
+ "it.");
+
}
}
@@ -512,7 +571,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (fsrv->function_ptr == NULL || fsrv->function_opt == NULL) {
// this is not afl-fuzz - we deny and return
- if (fsrv->use_shdmen_fuzz)
+ if (fsrv->use_shmem_fuzz)
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
@@ -774,10 +833,12 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
- if (fsrv->shdmem_fuzz) {
+ if (fsrv->shmem_fuzz) {
- memcpy(fsrv->shdmem_fuzz, buf, len);
- fsrv->shdmem_fuzz_len = len;
+ *fsrv->shmem_fuzz_len = len;
+ memcpy(fsrv->shmem_fuzz, buf, len);
+ // printf("test case len: %u [0]:0x%02x\n", *fsrv->shmem_fuzz_len, buf[0]);
+ // fflush(stdout);
} else {
@@ -839,8 +900,6 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
MEM_BARRIER();
- if (fsrv->shdmem_fuzz_len) write_value += (fsrv->shdmem_fuzz_len << 8);
-
/* we have the fork server (or faux server) up and running
First, tell it if the previous run timed out. */
@@ -862,8 +921,8 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
if (fsrv->child_pid <= 0) { FATAL("Fork server is misbehaving (OOM?)"); }
- exec_ms = read_timed(fsrv->fsrv_st_fd, &fsrv->child_status, 4, timeout,
- stop_soon_p);
+ exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout,
+ stop_soon_p);
if (exec_ms > timeout) {
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index ff078319..5b98be9e 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -623,14 +623,14 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
/* Timeouts are not very interesting, but we're still obliged to keep
a handful of samples. We use the presence of new bits in the
- hang-specific bitmap as a signal of uniqueness. In "dumb" mode, we
- just keep everything. */
+ hang-specific bitmap as a signal of uniqueness. In "non-instrumented"
+ mode, we just keep everything. */
++afl->total_tmouts;
if (afl->unique_hangs >= KEEP_UNIQUE_HANG) { return keeping; }
- if (likely(!afl->dumb_mode)) {
+ if (likely(!afl->non_instrumented_mode)) {
#ifdef WORD_SIZE_64
simplify_trace(afl, (u64 *)afl->fsrv.trace_bits);
@@ -698,7 +698,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 (likely(!afl->dumb_mode)) {
+ if (likely(!afl->non_instrumented_mode)) {
#ifdef WORD_SIZE_64
simplify_trace(afl, (u64 *)afl->fsrv.trace_bits);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9349fefe..4184fa6b 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1315,10 +1315,10 @@ dir_cleanup_failed:
}
-/* If this is a -S slave, ensure a -M master is running, if a master is
- running when another master is started then warn */
+/* If this is a -S secondary node, ensure a -M main node is running,
+ if a main node is running when another main is started, then warn */
-int check_master_exists(afl_state_t *afl) {
+int check_main_node_exists(afl_state_t *afl) {
DIR * sd;
struct dirent *sd_ent;
@@ -1337,7 +1337,7 @@ int check_master_exists(afl_state_t *afl) {
}
- fn = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
+ fn = alloc_printf("%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
int res = access(fn, F_OK);
free(fn);
if (res == 0) return 1;
@@ -1392,9 +1392,9 @@ void setup_dirs_fds(afl_state_t *afl) {
}
- if (afl->is_master) {
+ if (afl->is_main_node) {
- u8 *x = alloc_printf("%s/is_master", afl->out_dir);
+ u8 *x = alloc_printf("%s/is_main_node", afl->out_dir);
int fd = open(x, O_CREAT | O_RDWR, 0644);
if (fd < 0) FATAL("cannot create %s", x);
free(x);
@@ -1859,7 +1859,11 @@ void fix_up_sync(afl_state_t *afl) {
u8 *x = afl->sync_id;
- if (afl->dumb_mode) { FATAL("-S / -M and -n are mutually exclusive"); }
+ if (afl->non_instrumented_mode) {
+
+ FATAL("-S / -M and -n are mutually exclusive");
+
+ }
while (*x) {
@@ -1949,6 +1953,30 @@ static void handle_skipreq(int sig) {
}
+/* Setup shared map for fuzzing with input via sharedmem */
+
+void setup_testcase_shmem(afl_state_t *afl) {
+
+ afl->shm_fuzz = ck_alloc(sizeof(sharedmem_t));
+
+ // we need to set the non-instrumented mode to not overwrite the SHM_ENV_VAR
+ u8 *map = afl_shm_init(afl->shm_fuzz, MAX_FILE + sizeof(u32), 1);
+
+ if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
+
+#ifdef USEMMAP
+ setenv(SHM_FUZZ_ENV_VAR, afl->shm_fuzz->g_shm_file_path, 1);
+#else
+ u8 *shm_str = alloc_printf("%d", afl->shm_fuzz->shm_id);
+ setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
+ ck_free(shm_str);
+#endif
+ afl->fsrv.support_shmem_fuzz = 1;
+ afl->fsrv.shmem_fuzz_len = (u32 *)map;
+ afl->fsrv.shmem_fuzz = map + sizeof(u32);
+
+}
+
/* Do a PATH search and find target binary to see that it exists and
isn't a shell script - a common and painful mistake. We also check for
a valid ELF header and for evidence of AFL instrumentation. */
@@ -2098,7 +2126,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
#endif /* ^!__APPLE__ */
- if (!afl->fsrv.qemu_mode && !afl->unicorn_mode && !afl->dumb_mode &&
+ if (!afl->fsrv.qemu_mode && !afl->unicorn_mode &&
+ !afl->non_instrumented_mode &&
!memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF("\n" cLRD "[-] " cRST
@@ -2115,8 +2144,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
" mode support. Consult the README.md for tips on how to enable "
"this.\n"
- " (It is also possible to use afl-fuzz as a traditional, \"dumb\" "
- "fuzzer.\n"
+ " (It is also possible to use afl-fuzz as a traditional, "
+ "non-instrumented fuzzer.\n"
" For that, you can use the -n option - but expect much worse "
"results.)\n",
doc_path);
@@ -2153,30 +2182,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
OKF(cPIN "Persistent mode binary detected.");
setenv(PERSIST_ENV_VAR, "1", 1);
afl->persistent_mode = 1;
- // do not fail if we can not get the fuzzing shared mem
- if ((afl->shm_fuzz = calloc(1, sizeof(sharedmem_t)))) {
-
- // we need to set the dumb mode to not overwrite the SHM_ENV_VAR
- if ((afl->fsrv.shdmem_fuzz = afl_shm_init(afl->shm_fuzz, MAX_FILE, 1))) {
-
-#ifdef USEMMAP
- setenv(SHM_FUZZ_ENV_VAR, afl->shm_fuzz->g_shm_file_path, 1);
-#else
- u8 *shm_str;
- shm_str = alloc_printf("%d", afl->shm_fuzz->shm_id);
- setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
- ck_free(shm_str);
-#endif
- afl->fsrv.support_shdmen_fuzz = 1;
- } else {
-
- free(afl->shm_fuzz);
- afl->shm_fuzz = NULL;
-
- }
-
- }
+ afl->shmem_testcase_mode = 1;
} else if (getenv("AFL_PERSISTENT")) {
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 56f16b4c..578ac584 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -415,7 +415,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
- } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
+ } else if (!afl->non_instrumented_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
@@ -512,7 +512,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
* TRIMMING *
************/
- if (!afl->dumb_mode && !afl->queue_cur->trim_done && !afl->disable_trim) {
+ if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
+ !afl->disable_trim) {
u8 res = trim_case(afl, afl->queue_cur, in_buf);
@@ -577,10 +578,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
/* Skip deterministic fuzzing if exec path checksum puts this out of scope
- for this master instance. */
+ for this main instance. */
- if (afl->master_max &&
- (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
+ if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) !=
+ afl->main_node_id - 1) {
goto custom_mutator_stage;
@@ -650,7 +651,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
*/
- if (!afl->dumb_mode && (afl->stage_cur & 7) == 7) {
+ if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
@@ -822,10 +823,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
u32 cksum;
- /* If in dumb mode or if the file is very short, just flag everything
- without wasting time on checksums. */
+ /* If in non-instrumented mode or if the file is very short, just flag
+ everything without wasting time on checksums. */
- if (!afl->dumb_mode && len >= EFF_MIN_LEN) {
+ if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
@@ -2568,7 +2569,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
}
- } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
+ } else if (!afl->non_instrumented_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
@@ -2660,7 +2661,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
* TRIMMING *
************/
- if (!afl->dumb_mode && !afl->queue_cur->trim_done) {
+ if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) {
u8 res = trim_case(afl, afl->queue_cur, in_buf);
@@ -2730,10 +2731,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
}
/* Skip deterministic fuzzing if exec path checksum puts this out of scope
- for this master instance. */
+ for this main instance. */
- if (afl->master_max &&
- (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
+ if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) !=
+ afl->main_node_id - 1) {
goto havoc_stage;
@@ -2803,7 +2804,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
*/
- if (!afl->dumb_mode && (afl->stage_cur & 7) == 7) {
+ if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
@@ -2975,10 +2976,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
u32 cksum;
- /* If in dumb mode or if the file is very short, just flag everything
- without wasting time on checksums. */
+ /* If in non-instrumented mode or if the file is very short, just flag
+ everything without wasting time on checksums. */
- if (!afl->dumb_mode && len >= EFF_MIN_LEN) {
+ if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index cfeb6c5e..ea7f57e2 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -303,7 +303,7 @@ void cull_queue(afl_state_t *afl) {
u32 i;
u8 * temp_v = afl->map_tmp_buf;
- if (afl->dumb_mode || !afl->score_changed) { return; }
+ if (afl->non_instrumented_mode || !afl->score_changed) { return; }
afl->score_changed = 0;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 04450363..a85e00fe 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -27,6 +27,7 @@
#include "afl-fuzz.h"
#include <sys/time.h>
#include <signal.h>
+#include <limits.h>
#include "cmplog.h"
@@ -231,13 +232,13 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child_output);
- if (afl->fsrv.support_shdmen_fuzz && !afl->fsrv.use_shdmen_fuzz) {
+ if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
afl_shm_deinit(afl->shm_fuzz);
- free(afl->shm_fuzz);
+ ck_free(afl->shm_fuzz);
afl->shm_fuzz = NULL;
- afl->fsrv.support_shdmen_fuzz = 0;
- afl->fsrv.shdmem_fuzz = NULL;
+ afl->fsrv.support_shmem_fuzz = 0;
+ afl->fsrv.shmem_fuzz = NULL;
}
@@ -272,7 +273,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
- if (!afl->dumb_mode && !afl->stage_cur &&
+ if (!afl->non_instrumented_mode && !afl->stage_cur &&
!count_bytes(afl, afl->fsrv.trace_bits)) {
fault = FSRV_RUN_NOINST;
@@ -337,7 +338,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
parent. This is a non-critical problem, but something to warn the user
about. */
- if (!afl->dumb_mode && first_run && !fault && !new_bits) {
+ if (!afl->non_instrumented_mode && first_run && !fault && !new_bits) {
fault = FSRV_RUN_NOBITS;
@@ -412,17 +413,17 @@ void sync_fuzzers(afl_state_t *afl) {
entries++;
- // a slave only syncs from a master, a master syncs from everyone
- if (likely(afl->is_slave)) {
+ // secondary nodes only syncs from main, the main node syncs from everyone
+ if (likely(afl->is_secondary_node)) {
- sprintf(qd_path, "%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
+ sprintf(qd_path, "%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
int res = access(qd_path, F_OK);
- if (unlikely(afl->is_master)) { // an elected temporary master
+ if (unlikely(afl->is_main_node)) { // an elected temporary main node
- if (likely(res == 0)) { // there is another master? downgrade.
+ if (likely(res == 0)) { // there is another main node? downgrade.
- afl->is_master = 0;
- sprintf(qd_path, "%s/is_master", afl->out_dir);
+ afl->is_main_node = 0;
+ sprintf(qd_path, "%s/is_main_node", afl->out_dir);
unlink(qd_path);
}
@@ -561,16 +562,17 @@ void sync_fuzzers(afl_state_t *afl) {
closedir(sd);
- // If we are a slave and no master was found to sync then become the master
- if (unlikely(synced == 0) && likely(entries) && likely(afl->is_slave)) {
+ // If we are a secondary and no main was found to sync then become the main
+ if (unlikely(synced == 0) && likely(entries) &&
+ likely(afl->is_secondary_node)) {
- // there is a small race condition here that another slave runs at the same
- // time. If so, the first temporary master running again will demote
+ // there is a small race condition here that another secondary runs at the
+ // same time. If so, the first temporary main node running again will demote
// themselves so this is not an issue
u8 path[PATH_MAX];
- afl->is_master = 1;
- sprintf(path, "%s/is_master", afl->out_dir);
+ afl->is_main_node = 1;
+ sprintf(path, "%s/is_main_node", afl->out_dir);
int fd = open(path, O_CREAT | O_RDWR, 0644);
if (fd >= 0) { close(fd); }
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 014ed34d..374b2411 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -98,12 +98,13 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"exec_timeout : %u\n"
"slowest_exec_ms : %u\n"
"peak_rss_mb : %lu\n"
+ "cpu_affinity : %d\n"
"edges_found : %u\n"
"var_byte_count : %u\n"
"afl_banner : %s\n"
"afl_version : " VERSION
"\n"
- "target_mode : %s%s%s%s%s%s%s%s\n"
+ "target_mode : %s%s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
afl->start_time / 1000, cur_time / 1000,
(cur_time - afl->start_time) / 1000, (u32)getpid(),
@@ -123,13 +124,14 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
#else
(unsigned long int)(rus.ru_maxrss >> 10),
#endif
- t_bytes, afl->var_byte_count, afl->use_banner,
+ afl->cpu_aff, t_bytes, afl->var_byte_count, afl->use_banner,
afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
- afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "",
- afl->crash_mode ? "crash " : "",
+ afl->non_instrumented_mode ? " non_instrumented " : "",
+ afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
afl->persistent_mode ? "persistent " : "",
+ afl->shmem_testcase_mode ? "shmem_testcase " : "",
afl->deferred_mode ? "deferred " : "",
- (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->dumb_mode ||
+ (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->non_instrumented_mode ||
afl->no_forkserver || afl->crash_mode || afl->persistent_mode ||
afl->deferred_mode)
? ""
@@ -137,6 +139,32 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
afl->orig_cmdline);
/* ignore errors */
+ if (afl->debug) {
+
+ uint32_t i = 0;
+ fprintf(f, "virgin_bytes :");
+ for (i = 0; i < afl->fsrv.map_size; i++) {
+
+ if (afl->virgin_bits[i] != 0xff) {
+
+ fprintf(f, " %d[%02x]", i, afl->virgin_bits[i]);
+
+ }
+
+ }
+
+ fprintf(f, "\n");
+ fprintf(f, "var_bytes :");
+ for (i = 0; i < afl->fsrv.map_size; i++) {
+
+ if (afl->var_bytes[i]) { fprintf(f, " %d", i); }
+
+ }
+
+ fprintf(f, "\n");
+
+ }
+
fclose(f);
}
@@ -326,7 +354,7 @@ void show_stats(afl_state_t *afl) {
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
- if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
+ if (!afl->non_instrumented_mode && afl->cycles_wo_finds > 100 &&
!afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done) {
afl->stop_soon = 2;
@@ -414,7 +442,7 @@ void show_stats(afl_state_t *afl) {
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
" overall results " bSTG bH2 bH2 bRT "\n");
- if (afl->dumb_mode) {
+ if (afl->non_instrumented_mode) {
strcpy(tmp, cRST);
@@ -460,7 +488,7 @@ void show_stats(afl_state_t *afl) {
/* We want to warn people about not seeing new paths after a full cycle,
except when resuming fuzzing or running in non-instrumented mode. */
- if (!afl->dumb_mode &&
+ if (!afl->non_instrumented_mode &&
(afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
afl->in_bitmap || afl->crash_mode)) {
@@ -469,7 +497,7 @@ void show_stats(afl_state_t *afl) {
} else {
- if (afl->dumb_mode) {
+ if (afl->non_instrumented_mode) {
SAYF(bV bSTOP " last new path : " cPIN "n/a" cRST
" (non-instrumented mode) ");
@@ -524,8 +552,9 @@ void show_stats(afl_state_t *afl) {
t_byte_ratio);
SAYF(" map density : %s%-21s" bSTG bV "\n",
- t_byte_ratio > 70 ? cLRD
- : ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST),
+ t_byte_ratio > 70
+ ? cLRD
+ : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
tmp);
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths),
@@ -1020,10 +1049,11 @@ void show_init_stats(afl_state_t *afl) {
}
- /* In dumb mode, re-running every timing out test case with a generous time
+ /* In non-instrumented mode, re-running every timing out test case with a
+ generous time
limit is very expensive, so let's select a more conservative default. */
- if (afl->dumb_mode && !(afl->afl_env.afl_hang_tmout)) {
+ if (afl->non_instrumented_mode && !(afl->afl_env.afl_hang_tmout)) {
afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e024e9a4..d5fed9f2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -130,7 +130,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
" -N - do not unlink the fuzzing input file (only for "
"devices etc.!)\n"
" -d - quick & dirty mode (skips deterministic steps)\n"
- " -n - fuzz without instrumentation (dumb mode)\n"
+ " -n - fuzz without instrumentation (non-instrumented mode)\n"
" -x dir - optional fuzzer dictionary (see README.md, its really "
"good!)\n\n"
@@ -246,7 +246,7 @@ int main(int argc, char **argv_orig, char **envp) {
u64 prev_queued = 0;
u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE;
u8 * extras_dir = 0;
- u8 mem_limit_given = 0, exit_1 = 0;
+ u8 mem_limit_given = 0, exit_1 = 0, debug = 0;
char **use_argv;
struct timeval tv;
@@ -257,10 +257,11 @@ int main(int argc, char **argv_orig, char **envp) {
afl_state_t *afl = calloc(1, sizeof(afl_state_t));
if (!afl) { FATAL("Could not create afl state"); }
- if (get_afl_env("AFL_DEBUG")) { afl->debug = 1; }
+ if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; }
map_size = get_map_size();
afl_state_init(afl, map_size);
+ afl->debug = debug;
afl_fsrv_init(&afl->fsrv);
read_afl_environment(afl, envp);
@@ -379,17 +380,19 @@ int main(int argc, char **argv_orig, char **envp) {
*c = 0;
- if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
- !afl->master_id || !afl->master_max ||
- afl->master_id > afl->master_max || afl->master_max > 1000000) {
+ if (sscanf(c + 1, "%u/%u", &afl->main_node_id, &afl->main_node_max) !=
+ 2 ||
+ !afl->main_node_id || !afl->main_node_max ||
+ afl->main_node_id > afl->main_node_max ||
+ afl->main_node_max > 1000000) {
- FATAL("Bogus master ID passed to -M");
+ FATAL("Bogus main node ID passed to -M");
}
}
- afl->is_master = 1;
+ afl->is_main_node = 1;
}
@@ -399,7 +402,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
afl->sync_id = ck_strdup(optarg);
- afl->is_slave = 1;
+ afl->is_secondary_node = 1;
afl->skip_deterministic = 1;
afl->use_splicing = 1;
break;
@@ -533,14 +536,19 @@ int main(int argc, char **argv_orig, char **envp) {
case 'n': /* dumb mode */
- if (afl->dumb_mode) { FATAL("Multiple -n options not supported"); }
+ if (afl->non_instrumented_mode) {
+
+ FATAL("Multiple -n options not supported");
+
+ }
+
if (afl->afl_env.afl_dumb_forksrv) {
- afl->dumb_mode = 2;
+ afl->non_instrumented_mode = 2;
} else {
- afl->dumb_mode = 1;
+ afl->non_instrumented_mode = 1;
}
@@ -556,6 +564,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); }
afl->fsrv.qemu_mode = 1;
+ afl->shmem_testcase_mode = 1;
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
@@ -572,6 +581,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); }
afl->unicorn_mode = 1;
+ afl->shmem_testcase_mode = 1;
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; }
@@ -582,6 +592,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->use_wine) { FATAL("Multiple -W options not supported"); }
afl->fsrv.qemu_mode = 1;
afl->use_wine = 1;
+ afl->shmem_testcase_mode = 1;
if (!mem_limit_given) { afl->fsrv.mem_limit = 0; }
@@ -781,6 +792,8 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
+
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
"Eißfeldt, Andrea Fioraldi and Dominik Maier");
OKF("afl++ is open source, get it at "
@@ -790,10 +803,12 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL");
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
- if (afl->sync_id && afl->is_master && afl->afl_env.afl_custom_mutator_only) {
+ if (afl->sync_id && afl->is_main_node &&
+ afl->afl_env.afl_custom_mutator_only) {
WARNF(
- "Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
+ "Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
+ "will "
"result in no deterministic mutations being done!");
}
@@ -841,7 +856,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- /* randamsa_init installs some signal hadlers, call it before
+ /* radamsa_init installs some signal handlers, call it before
setup_signal_handlers so that AFL++ can then replace those signal
handlers */
radamsa_init_ptr();
@@ -871,7 +886,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (afl->dumb_mode) {
+ if (afl->non_instrumented_mode) {
if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
@@ -954,13 +969,13 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (afl->dumb_mode == 2 && afl->no_forkserver) {
+ if (afl->non_instrumented_mode == 2 && afl->no_forkserver) {
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
}
- afl->fsrv.use_fauxsrv = afl->dumb_mode == 1 || afl->no_forkserver;
+ afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
if (getenv("LD_PRELOAD")) {
@@ -1057,7 +1072,7 @@ int main(int argc, char **argv_orig, char **envp) {
check_cpu_governor(afl);
afl->fsrv.trace_bits =
- afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->dumb_mode);
+ afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); }
memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
@@ -1065,7 +1080,7 @@ int main(int argc, char **argv_orig, char **envp) {
init_count_class16();
- if (afl->is_master && check_master_exists(afl) == 1) {
+ if (afl->is_main_node && check_main_node_exists(afl) == 1) {
WARNF("it is wasteful to run more than one master!");
sleep(1);
@@ -1074,9 +1089,9 @@ int main(int argc, char **argv_orig, char **envp) {
setup_dirs_fds(afl);
- if (afl->is_slave && check_master_exists(afl) == 0) {
+ if (afl->is_secondary_node && check_main_node_exists(afl) == 0) {
- WARNF("no -M master found. You need to run one master!");
+ WARNF("no -M main node found. You need to run one main instance!");
sleep(5);
}
@@ -1178,6 +1193,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_binary(afl, argv[optind]);
+ if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
+
afl->start_time = get_cur_time();
if (afl->fsrv.qemu_mode) {
@@ -1213,6 +1230,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child_output);
+ OKF("Cmplog forkserver successfully started");
}
@@ -1366,10 +1384,10 @@ stop_fuzzing:
time_spent_working / afl->fsrv.total_execs);
#endif
- if (afl->is_master) {
+ if (afl->is_main_node) {
u8 path[PATH_MAX];
- sprintf(path, "%s/is_master", afl->out_dir);
+ sprintf(path, "%s/is_main_node", afl->out_dir);
unlink(path);
}
@@ -1383,7 +1401,7 @@ stop_fuzzing:
if (afl->shm_fuzz) {
afl_shm_deinit(afl->shm_fuzz);
- free(afl->shm_fuzz);
+ ck_free(afl->shm_fuzz);
}
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index f5817293..63013435 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -96,7 +96,8 @@ void afl_shm_deinit(sharedmem_t *shm) {
Returns a pointer to shm->map for ease of use.
*/
-u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
+u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
+ unsigned char non_instrumented_mode) {
shm->map_size = map_size;
@@ -137,12 +138,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
}
- /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
- we don't want them to detect instrumentation, since we won't be sending
- fork server commands. This should be replaced with better auto-detection
- later on, perhaps? */
+ /* If somebody is asking us to fuzz instrumented binaries in non-instrumented
+ mode, we don't want them to detect instrumentation, since we won't be
+ sending fork server commands. This should be replaced with better
+ auto-detection later on, perhaps? */
- if (!dumb_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
+ if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
if (shm->map == -1 || !shm->map) PFATAL("mmap() failed");
@@ -164,12 +165,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
shm_str = alloc_printf("%d", shm->shm_id);
- /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
- we don't want them to detect instrumentation, since we won't be sending
- fork server commands. This should be replaced with better auto-detection
- later on, perhaps? */
+ /* If somebody is asking us to fuzz instrumented binaries in non-instrumented
+ mode, we don't want them to detect instrumentation, since we won't be
+ sending fork server commands. This should be replaced with better
+ auto-detection later on, perhaps? */
- if (!dumb_mode) { setenv(SHM_ENV_VAR, shm_str, 1); }
+ if (!non_instrumented_mode) { setenv(SHM_ENV_VAR, shm_str, 1); }
ck_free(shm_str);
@@ -177,7 +178,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
shm_str = alloc_printf("%d", shm->cmplog_shm_id);
- if (!dumb_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); }
+ if (!non_instrumented_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); }
ck_free(shm_str);