From 995e556065375c34206f6f05c8572e0758c288ef Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 13 Apr 2020 08:54:59 +0200 Subject: cmplog forkserver tidying --- src/afl-sharedmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/afl-sharedmem.c') diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 7bdf8d03..9db84e77 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -95,7 +95,7 @@ void afl_shm_deinit(sharedmem_t *shm) { /* At exit, remove all leftover maps */ -void afl_shm_atexit() { +void afl_shm_atexit(void) { LIST_FOREACH(&shm_list, sharedmem_t, { afl_shm_deinit(el); }); -- cgit 1.4.1 From 326ab632c378878c96f44586a6e1f3dfa3db2276 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 13 Apr 2020 16:57:19 +0200 Subject: fixed uaf and warnings --- src/afl-analyze.c | 8 ++++++++ src/afl-common.c | 11 +++++++---- src/afl-forkserver.c | 1 - src/afl-fuzz-bitmap.c | 8 ++++---- src/afl-fuzz-extras.c | 2 ++ src/afl-fuzz-init.c | 2 ++ src/afl-fuzz-one.c | 3 --- src/afl-fuzz-queue.c | 2 ++ src/afl-fuzz-redqueen.c | 8 +++++++- src/afl-fuzz-stats.c | 1 - src/afl-sharedmem.c | 10 +--------- src/afl-showmap.c | 2 +- 12 files changed, 34 insertions(+), 24 deletions(-) (limited to 'src/afl-sharedmem.c') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 510ec94a..2c98982f 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -902,6 +902,12 @@ int main(int argc, char **argv, char **envp) { if (mem_limit_given) FATAL("Multiple -m options not supported"); mem_limit_given = 1; + if (!optarg) { + + FATAL("Bad syntax used for -m"); + + } + if (!strcmp(optarg, "none")) { mem_limit = 0; @@ -938,6 +944,8 @@ int main(int argc, char **argv, char **envp) { if (timeout_given) FATAL("Multiple -t options not supported"); timeout_given = 1; + if (!optarg) FATAL("Wrong usage of -t"); + exec_tmout = atoi(optarg); if (exec_tmout < 10 || optarg[0] == '-') diff --git a/src/afl-common.c b/src/afl-common.c index 7eba6ae4..1ac1a2f3 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -292,11 +292,10 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { *rsl = 0; cp = alloc_printf("%s/afl-qemu-trace", own_copy); - ck_free(own_copy); - if (!access(cp, X_OK)) { + if (cp && !access(cp, X_OK)) { - if (cp != NULL) ck_free(cp); + ck_free(cp); cp = alloc_printf("%s/afl-wine-trace", own_copy); @@ -309,10 +308,14 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } - } else + ck_free(own_copy); + + } else { ck_free(own_copy); + } + u8 *ncp = BIN_PATH "/afl-qemu-trace"; if (!access(ncp, X_OK)) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b282a119..b054a64d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -455,7 +455,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - len = status; offset = 0; while (offset < status && (u8)dict[offset] + offset < status) { diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index b6a494db..9603f2f5 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -535,7 +535,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) return 0; u8 *queue_fn = ""; - u8 hnb; + u8 hnb = '\0'; s32 fd; u8 keeping = 0, res; @@ -718,9 +718,9 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { // if the user wants to be informed on new crashes - do that #if !TARGET_OS_IPHONE - if (system(afl->infoexec) == -1) - hnb += 0; // we dont care if system errors, but we dont want a - // compiler warning either + // we dont care if system errors, but we dont want a + // compiler warning either + (void)(system(afl->infoexec)+1); #else WARNF("command execution unsupported"); #endif diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 55146dd9..c366cc5b 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -130,6 +130,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr); + if (!wptr) PFATAL("no mem for data"); + while (*lptr) { char *hexdigits = "0123456789abcdef"; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 54cc81ef..10417da6 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2178,6 +2178,8 @@ void save_cmdline(afl_state_t *afl, u32 argc, char **argv) { u32 l = strlen(argv[i]); + if (!argv[i] || !buf) FATAL("null deref detected"); + memcpy(buf, argv[i], l); buf += l; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 95d622f2..475c710b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -3593,7 +3593,6 @@ pacemaker_fuzzing: } s32 temp_len_puppet; - cur_ms_lv = get_cur_time(); // for (; afl->swarm_now < swarm_num; ++afl->swarm_now) { @@ -4167,8 +4166,6 @@ pacemaker_fuzzing: afl->orig_hit_cnt_puppet))) { afl->key_puppet = 0; - cur_ms_lv = get_cur_time(); - new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->orig_hit_cnt_puppet = 0; afl->last_limit_time_start = 0; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 346c2639..5eb110d0 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -438,6 +438,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } + if (unlikely(!n_paths)) FATAL("Queue state corrupt"); + fuzz_mu = fuzz_total / n_paths; if (fuzz <= fuzz_mu) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 517f8d7c..b9b41c74 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -115,7 +115,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) { afl->stage_short = "colorization"; afl->stage_max = 1000; - struct range *rng; + struct range *rng = NULL; afl->stage_cur = 0; while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { @@ -141,6 +141,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) { empty_range: ck_free(rng); + rng = NULL; ++afl->stage_cur; } @@ -157,6 +158,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) { rng = ranges; ranges = ranges->next; ck_free(rng); + rng = NULL; } @@ -186,6 +188,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) { } + return 0; checksum_fail: @@ -196,9 +199,12 @@ checksum_fail: rng = ranges; ranges = ranges->next; ck_free(rng); + rng = NULL; } + // TODO: clang notices a _potential_ leak of mem pointed to by rng + return 1; } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 2e680dbb..d42df2db 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -56,7 +56,6 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, bitmap_cvg = afl->last_bitmap_cvg; stability = afl->last_stability; - eps = afl->last_eps; } else { diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 9db84e77..eea1cc95 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -67,6 +67,7 @@ list_t shm_list = {.element_prealloc_count = 0}; void afl_shm_deinit(sharedmem_t *shm) { + // TODO: clang reports a potential UAF in this function/makro(?) list_remove(&shm_list, shm); #ifdef USEMMAP @@ -93,14 +94,6 @@ void afl_shm_deinit(sharedmem_t *shm) { } -/* At exit, remove all leftover maps */ - -void afl_shm_atexit(void) { - - LIST_FOREACH(&shm_list, sharedmem_t, { afl_shm_deinit(el); }); - -} - /* Configure shared memory. Returns a pointer to shm->map for ease of use. */ @@ -207,7 +200,6 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) { #endif list_append(&shm_list, shm); - atexit(afl_shm_atexit); return shm->map; diff --git a/src/afl-showmap.c b/src/afl-showmap.c index c84fa36c..63c8caa8 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -983,7 +983,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!quiet_mode) OKF("Processed %u input files.", total_execs); closedir(dir_in); - closedir(dir_out); + if (dir_out) closedir(dir_out); } else { -- cgit 1.4.1 From 6dc36f1e6e7d2d781cc6b14f2898b3f7021e1d06 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 14 Apr 2020 19:27:25 +0200 Subject: unified forkservered run_target, fixes #308 --- include/afl-fuzz.h | 16 +----- include/forkserver.h | 21 ++++++-- src/afl-analyze.c | 2 +- src/afl-forkserver.c | 132 +++++++++++++++++++++++++++++++++++++++++++++--- src/afl-fuzz-bitmap.c | 16 +++--- src/afl-fuzz-cmplog.c | 2 +- src/afl-fuzz-init.c | 14 ++--- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-one.c | 12 ++--- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-redqueen.c | 4 +- src/afl-fuzz-run.c | 128 +++------------------------------------------- src/afl-fuzz-stats.c | 18 +++---- src/afl-fuzz.c | 2 +- src/afl-sharedmem.c | 1 - src/afl-showmap.c | 95 ++++------------------------------ src/afl-tmin.c | 109 ++++++++------------------------------- 17 files changed, 222 insertions(+), 354 deletions(-) (limited to 'src/afl-sharedmem.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 3df99a58..abaa71b5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -195,18 +195,6 @@ enum { }; -/* Execution status fault codes */ - -enum { - - /* 00 */ FAULT_NONE, - /* 01 */ FAULT_TMOUT, - /* 02 */ FAULT_CRASH, - /* 03 */ FAULT_ERROR, - /* 04 */ FAULT_NOINST, - /* 05 */ FAULT_NOBITS - -}; #define operator_num 16 #define swarm_num 5 @@ -433,7 +421,6 @@ typedef struct afl_state { use_splicing, /* Recombine input files? */ dumb_mode, /* Run in non-instrumented mode? */ score_changed, /* Scoring for favorites changed? */ - kill_signal, /* Signal that killed the child */ resuming_fuzz, /* Resuming an older fuzzing job? */ timeout_given, /* Specific timeout given? */ not_on_tty, /* stdout is not a tty */ @@ -488,7 +475,6 @@ typedef struct afl_state { total_tmouts, /* Total number of timeouts */ unique_tmouts, /* Timeouts with unique signatures */ unique_hangs, /* Hangs with unique signatures */ - total_execs, /* Total execve() calls */ last_crash_execs, /* Exec counter at last crash */ queue_cycle, /* Queue round counter */ cycles_wo_finds, /* Cycles without any new paths */ @@ -888,7 +874,7 @@ void show_init_stats(afl_state_t *); /* Run */ -u8 run_target(afl_state_t *, afl_forkserver_t *fsrv, u32); +fsrv_run_result_t run_target(afl_state_t *, afl_forkserver_t *fsrv, u32); void write_to_testcase(afl_state_t *, void *, u32); u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8); void sync_fuzzers(afl_state_t *); diff --git a/include/forkserver.h b/include/forkserver.h index 6fbaf612..7559e785 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -29,6 +29,7 @@ #define __AFL_FORKSERVER_H #include +#include typedef struct afl_forkserver { @@ -55,16 +56,18 @@ typedef struct afl_forkserver { u32 snapshot; /* is snapshot feature used */ u64 mem_limit; /* Memory cap for child (MB) */ + u64 total_execs; /* How often run_target was called */ + u8 *out_file, /* File to fuzz, if any */ *target_path; /* Path of the target */ FILE *plot_file; /* Gnuplot output file */ - u8 child_timed_out; /* Traced process timed out? */ + u8 last_run_timed_out; /* Traced process timed out? */ - u8 use_fauxsrv; /* Fauxsrv for non-forking targets? */ + u8 last_kill_signal; /* Signal that killed the child */ - u32 prev_timed_out; /* if prev forkserver run timed out */ + u8 use_fauxsrv; /* Fauxsrv for non-forking targets? */ u8 qemu_mode; /* if running in qemu mode or not */ @@ -79,10 +82,22 @@ typedef struct afl_forkserver { } afl_forkserver_t; +typedef enum fsrv_run_result { + + /* 00 */ FSRV_RUN_OK = 0, + /* 01 */ FSRV_RUN_TMOUT, + /* 02 */ FSRV_RUN_CRASH, + /* 03 */ FSRV_RUN_ERROR, + /* 04 */ FSRV_RUN_NOINST, + /* 05 */ FSRV_RUN_NOBITS, + +} fsrv_run_result_t; + void afl_fsrv_init(afl_forkserver_t *fsrv); void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from); void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, u8 debug_child_output); +fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, volatile u8 *stop_soon_p); void afl_fsrv_killall(void); void afl_fsrv_deinit(afl_forkserver_t *fsrv); diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 952786b0..8625cfda 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -80,7 +80,7 @@ static u8 edges_only, /* Ignore hit counts? */ use_stdin = 1; /* Use stdin for program input? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ - child_timed_out; /* Child timed out? */ + child_timed_out; /* Child timed out? */ static u8 *target_path; static u8 qemu_mode; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index f647ff5d..a7be8e8b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -76,7 +76,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->child_pid = -1; fsrv->map_size = MAP_SIZE; fsrv->use_fauxsrv = 0; - fsrv->prev_timed_out = 0; + fsrv->last_run_timed_out = 0; fsrv->init_child_func = fsrv_exec_child; @@ -102,7 +102,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->out_dir_fd = -1; fsrv_to->child_pid = -1; fsrv_to->use_fauxsrv = 0; - fsrv_to->prev_timed_out = 0; + fsrv_to->last_run_timed_out = 0; fsrv_to->init_child_func = fsrv_exec_child; @@ -217,7 +217,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL("pipe() failed"); - fsrv->child_timed_out = 0; + fsrv->last_run_timed_out = 0; fsrv->fsrv_pid = fork(); if (fsrv->fsrv_pid < 0) PFATAL("fork() failed"); @@ -361,7 +361,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else if (time > fsrv->exec_tmout * FORK_WAIT_MULT) { - fsrv->child_timed_out = 1; + fsrv->last_run_timed_out = 1; kill(fsrv->fsrv_pid, SIGKILL); } else { @@ -476,7 +476,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if (fsrv->child_timed_out) + if (fsrv->last_run_timed_out) FATAL("Timeout while initializing fork server (adjusting -t may help)"); if (waitpid(fsrv->fsrv_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); @@ -640,6 +640,127 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) { } +/* Execute target application, monitoring for timeouts. Return status + information. The called program will update afl->fsrv->trace_bits. */ + +fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, volatile u8 *stop_soon_p) { + + s32 res; + u32 exec_ms; + + int status = 0; + + u32 timeout = fsrv->exec_tmout; + + /* After this memset, fsrv->trace_bits[] are effectively volatile, so we + must prevent any earlier operations from venturing into that + territory. */ + + memset(fsrv->trace_bits, 0, fsrv->map_size); + + MEM_BARRIER(); + + /* we have the fork server (or faux server) up and running + First, tell it if the previous run timed out. */ + + if ((res = write(fsrv->fsrv_ctl_fd, &fsrv->last_run_timed_out, 4)) != 4) { + + if (*stop_soon_p) return 0; + RPFATAL(res, "Unable to request new process from fork server (OOM?)"); + + } + + fsrv->last_run_timed_out = 0; + + if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) { + + if (stop_soon_p) return 0; + RPFATAL(res, "Unable to request new process from fork server (OOM?)"); + + } + + if (fsrv->child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); + + exec_ms = read_timed(fsrv->fsrv_st_fd, &status, 4, timeout, stop_soon_p); + + if (exec_ms > timeout) { + + /* If there was no response from forkserver after timeout seconds, + we kill the child. The forkserver should inform us afterwards */ + + kill(fsrv->child_pid, SIGKILL); + fsrv->last_run_timed_out = 1; + if (read(fsrv->fsrv_st_fd, &status, 4) < 4) exec_ms = 0; + + } + + if (!exec_ms) { + + if (*stop_soon_p) 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" + " - If using persistent mode with QEMU, " + "AFL_QEMU_PERSISTENT_ADDR " + "is\n" + " probably not valid (hint: add the base address in case of " + "PIE)" + "\n\n" + "If all else fails you can disable the fork server via " + "AFL_NO_FORKSRV=1.\n", + fsrv->mem_limit); + RPFATAL(res, "Unable to communicate with fork server"); + + } + + if (!WIFSTOPPED(status)) fsrv->child_pid = 0; + + fsrv->total_execs++; + + /* Any subsequent operations on fsrv->trace_bits must not be moved by the + compiler below this point. Past this location, fsrv->trace_bits[] + behave very normally and do not have to be treated as volatile. */ + + MEM_BARRIER(); + + /* Report outcome to caller. */ + + if (WIFSIGNALED(status) && !*stop_soon_p) { + + fsrv->last_kill_signal = WTERMSIG(status); + + if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL) + return FSRV_RUN_TMOUT; + + return FSRV_RUN_CRASH; + + } + + /* A somewhat nasty hack for MSAN, which doesn't support abort_on_error and + must use a special exit code. */ + + if (fsrv->uses_asan && WEXITSTATUS(status) == MSAN_ERROR) { + + fsrv->last_kill_signal = 0; + return FSRV_RUN_CRASH; + + } + + if ((*(u32 *)fsrv->trace_bits) == EXEC_FAIL_SIG) return FSRV_RUN_NOINST; + + return FSRV_RUN_OK; + +} + void afl_fsrv_killall() { LIST_FOREACH(&fsrv_list, afl_forkserver_t, { @@ -656,4 +777,3 @@ void afl_fsrv_deinit(afl_forkserver_t *fsrv) { list_remove(&fsrv_list, fsrv); } - diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index a0a720fa..66b1e60d 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -598,7 +598,7 @@ 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 (unlikely(res == FAULT_ERROR)) + if (unlikely(res == FSRV_RUN_ERROR)) FATAL("Unable to execute target application"); fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); @@ -612,7 +612,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { switch (fault) { - case FAULT_TMOUT: + case FSRV_RUN_TMOUT: /* 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 @@ -651,9 +651,9 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { timeout actually uncovers a crash. Make sure we don't discard it if so. */ - if (!afl->stop_soon && new_fault == FAULT_CRASH) goto keep_as_crash; + if (!afl->stop_soon && new_fault == FSRV_RUN_CRASH) goto keep_as_crash; - if (afl->stop_soon || new_fault != FAULT_TMOUT) return keeping; + if (afl->stop_soon || new_fault != FSRV_RUN_TMOUT) return keeping; } @@ -675,7 +675,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { break; - case FAULT_CRASH: + case FSRV_RUN_CRASH: keep_as_crash: @@ -704,7 +704,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, - afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); + afl->unique_crashes, afl->fsrv.last_kill_signal, describe_op(afl, 0)); #else @@ -730,11 +730,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } afl->last_crash_time = get_cur_time(); - afl->last_crash_execs = afl->total_execs; + afl->last_crash_execs = afl->fsrv.total_execs; break; - case FAULT_ERROR: FATAL("Unable to execute target application"); + case FSRV_RUN_ERROR: FATAL("Unable to execute target application"); default: return keeping; diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index e2747097..ab93d838 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -66,7 +66,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->stop_soon) return 1; - if (fault == FAULT_TMOUT) { + if (fault == FSRV_RUN_TMOUT) { if (afl->subseq_tmouts++ > TMOUT_LIMIT) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 10417da6..55f7ce53 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -493,13 +493,13 @@ void perform_dry_run(afl_state_t *afl) { if (afl->stop_soon) return; - if (res == afl->crash_mode || res == FAULT_NOBITS) + if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) SAYF(cGRA " len = %u, map size = %u, exec speed = %llu us\n" cRST, q->len, q->bitmap_size, q->exec_us); switch (res) { - case FAULT_NONE: + case FSRV_RUN_OK: if (q == afl->queue) check_map_coverage(afl); @@ -507,7 +507,7 @@ void perform_dry_run(afl_state_t *afl) { break; - case FAULT_TMOUT: + case FSRV_RUN_TMOUT: if (afl->timeout_given) { @@ -556,7 +556,7 @@ void perform_dry_run(afl_state_t *afl) { } - case FAULT_CRASH: + case FSRV_RUN_CRASH: if (afl->crash_mode) break; @@ -650,13 +650,13 @@ void perform_dry_run(afl_state_t *afl) { FATAL("Test case '%s' results in a crash", fn); - case FAULT_ERROR: + case FSRV_RUN_ERROR: FATAL("Unable to execute target application ('%s')", afl->argv[0]); - case FAULT_NOINST: FATAL("No instrumentation detected"); + case FSRV_RUN_NOINST: FATAL("No instrumentation detected"); - case FAULT_NOBITS: + case FSRV_RUN_NOBITS: ++afl->useless_at_start; diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index efb1c117..7bf23e84 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -242,7 +242,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); ++afl->trim_execs; - if (afl->stop_soon || fault == FAULT_ERROR) { goto abort_trimming; } + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 961a29d6..cc97654a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -442,14 +442,14 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->queue_cur->cal_failed)) { - u8 res = FAULT_TMOUT; + u8 res = FSRV_RUN_TMOUT; if (afl->queue_cur->cal_failed < CAL_CHANCES) { res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); - if (unlikely(res == FAULT_ERROR)) + if (unlikely(res == FSRV_RUN_ERROR)) FATAL("Unable to execute target application"); } @@ -471,7 +471,7 @@ u8 fuzz_one_original(afl_state_t *afl) { u8 res = trim_case(afl, afl->queue_cur, in_buf); - if (unlikely(res == FAULT_ERROR)) + if (unlikely(res == FSRV_RUN_ERROR)) FATAL("Unable to execute target application"); if (unlikely(afl->stop_soon)) { @@ -2469,14 +2469,14 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (afl->queue_cur->cal_failed) { - u8 res = FAULT_TMOUT; + u8 res = FSRV_RUN_TMOUT; if (afl->queue_cur->cal_failed < CAL_CHANCES) { 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 (res == FSRV_RUN_ERROR) FATAL("Unable to execute target application"); } @@ -2497,7 +2497,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { u8 res = trim_case(afl, afl->queue_cur, in_buf); - if (res == FAULT_ERROR) FATAL("Unable to execute target application"); + if (res == FSRV_RUN_ERROR) FATAL("Unable to execute target application"); if (afl->stop_soon) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 5eb110d0..d05eee08 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -492,7 +492,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // 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)); + (1 - (double)((double)q->n_fuzz / (double)afl->fsrv.total_execs)); break; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 6a01ec89..8cea01e8 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -622,7 +622,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) return 1; u64 orig_hit_cnt, new_hit_cnt; - u64 orig_execs = afl->total_execs; + u64 orig_execs = afl->fsrv.total_execs; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_name = "input-to-state"; @@ -670,7 +670,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, exit_its: new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; - afl->stage_cycles[STAGE_ITS] += afl->total_execs - orig_execs; + afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs; memcpy(orig_buf, buf, len); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 514ba9ef..b20c5436 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -32,95 +32,9 @@ /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ -u8 run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { +fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { - s32 res; - u32 exec_ms; - - int status = 0; - u32 tb4; - - fsrv->child_timed_out = 0; - - /* After this memset, fsrv->trace_bits[] are effectively volatile, so we - must prevent any earlier operations from venturing into that - territory. */ - - memset(fsrv->trace_bits, 0, fsrv->map_size); - - MEM_BARRIER(); - - /* 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(fsrv->fsrv_ctl_fd, &fsrv->prev_timed_out, 4)) != 4) { - - if (afl->stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) { - - if (afl->stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if (fsrv->child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - - exec_ms = read_timed(fsrv->fsrv_st_fd, &status, 4, timeout, &afl->stop_soon); - - if (exec_ms > timeout) { - - /* If there was no response from forkserver after timeout seconds, - we kill the child. The forkserver should inform us afterwards */ - - kill(fsrv->child_pid, SIGKILL); - fsrv->child_timed_out = 1; - if (read(fsrv->fsrv_st_fd, &status, 4) < 4) exec_ms = 0; - - } - - if (!exec_ms) { - - 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" - " - If using persistent mode with QEMU, " - "AFL_QEMU_PERSISTENT_ADDR " - "is\n" - " probably not valid (hint: add the base address in case of " - "PIE)" - "\n\n" - "If all else fails you can disable the fork server via " - "AFL_NO_FORKSRV=1.\n", - fsrv->mem_limit); - RPFATAL(res, "Unable to communicate with fork server"); - - } - - if (!WIFSTOPPED(status)) fsrv->child_pid = 0; - - ++afl->total_execs; - - /* Any subsequent operations on fsrv->trace_bits must not be moved by the - compiler below this point. Past this location, fsrv->trace_bits[] - behave very normally and do not have to be treated as volatile. */ - - MEM_BARRIER(); - - tb4 = *(u32 *)fsrv->trace_bits; + fsrv_run_result_t res = afl_fsrv_run_target(&afl->fsrv, &afl->stop_soon); #ifdef WORD_SIZE_64 classify_counts(afl, (u64 *)fsrv->trace_bits); @@ -128,35 +42,7 @@ u8 run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { classify_counts(afl, (u32 *)fsrv->trace_bits); #endif /* ^WORD_SIZE_64 */ - fsrv->prev_timed_out = fsrv->child_timed_out; - - /* Report outcome to caller. */ - - if (WIFSIGNALED(status) && !afl->stop_soon) { - - afl->kill_signal = WTERMSIG(status); - - if (fsrv->child_timed_out && afl->kill_signal == SIGKILL) - return FAULT_TMOUT; - - return FAULT_CRASH; - - } - - /* A somewhat nasty hack for MSAN, which doesn't support abort_on_error and - must use a special exit code. */ - - if (fsrv->uses_asan && WEXITSTATUS(status) == MSAN_ERROR) { - - afl->kill_signal = 0; - return FAULT_CRASH; - - } - - if ((afl->dumb_mode == 1 || afl->no_forkserver) && tb4 == EXEC_FAIL_SIG) - return FAULT_ERROR; - - return FAULT_NONE; + return res; } @@ -348,7 +234,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, if (!afl->dumb_mode && !afl->stage_cur && !count_bytes(afl, afl->fsrv.trace_bits)) { - fault = FAULT_NOINST; + fault = FSRV_RUN_NOINST; goto abort_calibration; } @@ -408,7 +294,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) fault = FAULT_NOBITS; + if (!afl->dumb_mode && first_run && !fault && !new_bits) fault = FSRV_RUN_NOBITS; abort_calibration: @@ -645,7 +531,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); ++afl->trim_execs; - if (afl->stop_soon || fault == FAULT_ERROR) goto abort_trimming; + if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming; /* Note that we don't keep track of crashes or hangs here; maybe TODO? */ @@ -753,7 +639,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->stop_soon) return 1; - if (fault == FAULT_TMOUT) { + if (fault == FSRV_RUN_TMOUT) { if (afl->subseq_tmouts++ > TMOUT_LIMIT) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d48dd5e3..52148dc2 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -108,14 +108,14 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, 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->fsrv.total_execs, + afl->fsrv.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, stability, bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->last_path_time / 1000, afl->last_crash_time / 1000, - afl->last_hang_time / 1000, afl->total_execs - afl->last_crash_execs, + afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs, afl->fsrv.exec_tmout, afl->slowest_exec_ms, #ifdef __APPLE__ (unsigned long int)(rus.ru_maxrss >> 20), @@ -227,7 +227,7 @@ void show_stats(afl_state_t *afl) { if (afl->most_execs_key == 1) { - if (afl->most_execs <= afl->total_execs) { + if (afl->most_execs <= afl->fsrv.total_execs) { afl->most_execs_key = 2; afl->stop_soon = 2; @@ -251,11 +251,11 @@ void show_stats(afl_state_t *afl) { if (!afl->stats_last_execs) { afl->stats_avg_exec = - ((double)afl->total_execs) * 1000 / (cur_ms - afl->start_time); + ((double)afl->fsrv.total_execs) * 1000 / (cur_ms - afl->start_time); } else { - double cur_avg = ((double)(afl->total_execs - afl->stats_last_execs)) * + double cur_avg = ((double)(afl->fsrv.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 @@ -270,7 +270,7 @@ void show_stats(afl_state_t *afl) { } afl->stats_last_ms = cur_ms; - afl->stats_last_execs = afl->total_execs; + afl->stats_last_execs = afl->fsrv.total_execs; /* Tell the callers when to contact us (as measured in execs). */ @@ -543,14 +543,14 @@ void show_stats(afl_state_t *afl) { SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP " new crashes : %s%-22s" bSTG bV "\n", - u_stringify_int(IB(0), afl->total_execs), + u_stringify_int(IB(0), afl->fsrv.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", - u_stringify_int(IB(0), afl->total_execs), + u_stringify_int(IB(0), afl->fsrv.total_execs), afl->unique_crashes ? cLRD : cRST, tmp); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 07067691..9f17b61b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -480,7 +480,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'C': /* crash mode */ if (afl->crash_mode) FATAL("Multiple -C options not supported"); - afl->crash_mode = FAULT_CRASH; + afl->crash_mode = FSRV_RUN_CRASH; break; case 'n': /* dumb mode */ diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index eea1cc95..16d6fe41 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -40,7 +40,6 @@ #include #include -#include #include #include #include diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 3fcc1d2b..5f622c25 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -69,7 +69,7 @@ static u8 *in_data; /* Input data */ static u32 total, highest; /* tuple content information */ static u32 in_len, /* Input data length */ - arg_offset, total_execs; /* Total number of execs */ + arg_offset; /* Total number of execs */ static u8 quiet_mode, /* Hide non-essential messages? */ edges_only, /* Ignore hit counts? */ @@ -193,7 +193,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (cmin_mode) { - if (fsrv->child_timed_out) break; + if (fsrv->last_run_timed_out) break; if (!caa && child_crashed != cco) break; fprintf(f, "%u%u\n", fsrv->trace_bits[i], i); @@ -233,75 +233,18 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) { } -/* Execute target application. Returns 0 if the changes are a dud, or - 1 if they should be kept. */ +/* Execute target application. */ -static u8 run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem, +void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len) { - struct itimerval it; - int status = 0; - - memset(fsrv->trace_bits, 0, MAP_SIZE); - MEM_BARRIER(); - write_to_testcase(fsrv, mem, len); - s32 res; - - /* 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, &fsrv->prev_timed_out, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if (fsrv->child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - - /* Configure timeout, wait for child, cancel timeout. */ - - if (fsrv->exec_tmout) { - - it.it_value.tv_sec = (fsrv->exec_tmout / 1000); - it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000; - - } - - setitimer(ITIMER_REAL, &it, NULL); - - if ((res = read(fsrv->fsrv_st_fd, &status, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to communicate with fork server (OOM?)"); - - } - - fsrv->child_pid = 0; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 0; - - setitimer(ITIMER_REAL, &it, NULL); - - MEM_BARRIER(); - - /* Clean up bitmap, analyze exit condition, etc. */ - - if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) - FATAL("Unable to execute '%s'", argv[0]); + fsrv_run_result_t res = afl_fsrv_run_target(fsrv, &stop_soon); + if (res == FSRV_RUN_NOINST || res == FSRV_RUN_ERROR) FATAL("Error running target"); classify_counts(fsrv->trace_bits, binary_mode ? count_class_binary : count_class_human); - total_execs++; if (stop_soon) { @@ -310,22 +253,6 @@ static u8 run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem, } - /* Always discard inputs that time out. */ - - if (fsrv->child_timed_out) { return 0; } - - /* Handle crashing inputs depending on current mode. */ - - if (WIFSIGNALED(status) || - (WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) || - (WIFEXITED(status) && WEXITSTATUS(status))) { - - return 0; - - } - - return 0; - } /* Read initial file. */ @@ -425,7 +352,7 @@ static void run_target(afl_forkserver_t *fsrv, char **argv) { if (fsrv->exec_tmout) { - fsrv->child_timed_out = 0; + fsrv->last_run_timed_out = 0; it.it_value.tv_sec = (fsrv->exec_tmout / 1000); it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000; @@ -452,12 +379,12 @@ static void run_target(afl_forkserver_t *fsrv, char **argv) { if (!quiet_mode) SAYF(cRST "-- Program output ends --\n"); - if (!fsrv->child_timed_out && !stop_soon && WIFSIGNALED(status)) + if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(status)) child_crashed = 1; if (!quiet_mode) { - if (fsrv->child_timed_out) + if (fsrv->last_run_timed_out) SAYF(cLRD "\n+++ Program timed off +++\n" cRST); else if (stop_soon) SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST); @@ -980,7 +907,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!quiet_mode) OKF("Processed %u input files.", total_execs); + if (!quiet_mode) OKF("Processed %llu input files.", fsrv->total_execs); closedir(dir_in); if (dir_out) closedir(dir_out); @@ -1010,7 +937,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_shm_deinit(&shm); - u32 ret = child_crashed * 2 + fsrv->child_timed_out; + u32 ret = child_crashed * 2 + fsrv->last_run_timed_out; if (fsrv->target_path) ck_free(fsrv->target_path); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 31fad1df..999d5f65 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -67,7 +67,6 @@ static u8 *in_data; /* Input data for trimming */ static u32 in_len, /* Input data length */ orig_cksum, /* Original checksum */ - total_execs, /* Total number of execs */ missed_hangs, /* Misses due to hangs */ missed_crashes, /* Misses due to crashes */ missed_paths; /* Misses due to exec path diffs */ @@ -249,69 +248,11 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) { static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, u8 first_run) { - struct itimerval it; - int status = 0; - - u32 cksum; - - fsrv->child_timed_out = 0; - - memset(fsrv->trace_bits, 0, fsrv->map_size); - MEM_BARRIER(); - write_to_testcase(fsrv, mem, len); - s32 res; - - /* 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, &fsrv->prev_timed_out, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to request new process from fork server (OOM?)"); - - } - - if (fsrv->child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - - /* Configure timeout, wait for child, cancel timeout. */ - - if (fsrv->exec_tmout) { - - it.it_value.tv_sec = (fsrv->exec_tmout / 1000); - it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000; - - } - - setitimer(ITIMER_REAL, &it, NULL); + fsrv_run_result_t ret = afl_fsrv_run_target(fsrv, &stop_soon); - if ((res = read(fsrv->fsrv_st_fd, &status, 4)) != 4) { - - if (stop_soon) return 0; - RPFATAL(res, "Unable to communicate with fork server (OOM?)"); - - } - - fsrv->child_pid = 0; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 0; - - setitimer(ITIMER_REAL, &it, NULL); - - MEM_BARRIER(); - - /* Clean up bitmap, analyze exit condition, etc. */ - - if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) - FATAL("Unable to execute '%s'", argv[0]); + if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child"); if (!hang_mode) { @@ -320,8 +261,6 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, } - total_execs++; - if (stop_soon) { SAYF(cRST cLRD "\n+++ Minimization aborted by user +++\n" cRST); @@ -334,25 +273,21 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, if (hang_mode) { - if (fsrv->child_timed_out) return 1; - - if (WIFSIGNALED(status) || - (WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) || - (WIFEXITED(status) && WEXITSTATUS(status) && exit_crash)) { - + switch (ret) + { + case FSRV_RUN_TMOUT: + return 1; + case FSRV_RUN_CRASH: missed_crashes++; - - } else { - + return 0; + default: missed_hangs++; - + return 0; } - return 0; - } - if (fsrv->child_timed_out) { + if (ret == FSRV_RUN_TMOUT) { missed_hangs++; return 0; @@ -361,9 +296,7 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, /* Handle crashing inputs depending on current mode. */ - if (WIFSIGNALED(status) || - (WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) || - (WIFEXITED(status) && WEXITSTATUS(status) && exit_crash)) { + if (ret == FSRV_RUN_CRASH) { if (first_run) crash_mode = 1; @@ -391,7 +324,9 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, } - cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST); + if (ret == FSRV_RUN_NOINST) FATAL("Binary not instrumented?"); + + u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST); if (first_run) orig_cksum = cksum; @@ -640,11 +575,11 @@ finalize_all: SAYF("\n" cGRA " File size reduced by : " cRST "%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST - "%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA + "%0.02f%%\n" cGRA " Number of execs done : " cRST "%llu\n" cGRA " Fruitless execs : " cRST "termination=%u crash=%u\n\n", 100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? "" : "s", - ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs, + ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), fsrv->total_execs, missed_paths, missed_crashes); return; @@ -652,13 +587,13 @@ finalize_all: SAYF("\n" cGRA " File size reduced by : " cRST "%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST - "%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA + "%0.02f%%\n" cGRA " Number of execs done : " cRST "%llu\n" cGRA " Fruitless execs : " cRST "path=%u crash=%u hang=%s%u\n\n", 100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? "" : "s", - ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs, + ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), fsrv->total_execs, missed_paths, missed_crashes, missed_hangs ? cLRD : "", missed_hangs); - if (total_execs > 50 && missed_hangs * 10 > total_execs && !hang_mode) + if (fsrv->total_execs > 50 && missed_hangs * 10 > fsrv->total_execs && !hang_mode) WARNF(cLRD "Frequent timeouts - results may be skewed." cRST); } @@ -1139,13 +1074,13 @@ int main(int argc, char **argv_orig, char **envp) { run_target(fsrv, use_argv, in_data, in_len, 1); - if (hang_mode && !fsrv->child_timed_out) + if (hang_mode && !fsrv->last_run_timed_out) FATAL( "Target binary did not time out but hang minimization mode " "(-H) was set (-t %u).", fsrv->exec_tmout); - if (fsrv->child_timed_out && !hang_mode) + if (fsrv->last_run_timed_out && !hang_mode) FATAL( "Target binary times out (adjusting -t may help). Use -H to minimize a " "hang."); -- cgit 1.4.1 From 6940e136296d185391a34b5d829a759ac517594e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 16 Apr 2020 17:50:08 +0200 Subject: removed redundent funcs --- include/afl-fuzz.h | 1 - include/common.h | 10 +++++++ src/afl-analyze.c | 57 +----------------------------------- src/afl-common.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-bitmap.c | 14 --------- src/afl-fuzz.c | 2 +- src/afl-sharedmem.c | 2 +- src/afl-showmap.c | 58 +------------------------------------ src/afl-tmin.c | 74 ++--------------------------------------------- 9 files changed, 96 insertions(+), 202 deletions(-) (limited to 'src/afl-sharedmem.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 57ef5d58..363776cb 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -836,7 +836,6 @@ u32 calculate_score(afl_state_t *, struct queue_entry *); /* Bitmap */ -void read_bitmap(afl_state_t *, u8 *); void write_bitmap(afl_state_t *); u32 count_bits(afl_state_t *, u8 *); u32 count_bytes(afl_state_t *, u8 *); diff --git a/include/common.h b/include/common.h index 8dd66355..f5ace878 100644 --- a/include/common.h +++ b/include/common.h @@ -51,6 +51,16 @@ char * get_afl_env(char *env); extern u8 be_quiet; extern u8 *doc_path; /* path to documentation dir */ +/* Find binary, used by analyze, showmap, tmin + @returns the path, allocating the string */ + +u8 *find_binary(u8 *fname); + +/* Read a bitmap from file fname to memory + This is for the -B option again. */ + +void read_bitmap(u8 *fname, u8 *map, size_t len); + /* Get unix time in milliseconds */ u64 get_cur_time(void); diff --git a/src/afl-analyze.c b/src/afl-analyze.c index f2a54a20..fa58ca81 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -805,61 +805,6 @@ static void usage(u8 *argv0) { } -/* Find binary. */ - -static void find_binary(u8 *fname) { - - u8 * env_path = 0; - struct stat st; - - if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { - - target_path = ck_strdup(fname); - - if (stat(target_path, &st) || !S_ISREG(st.st_mode) || - !(st.st_mode & 0111) || st.st_size < 4) - FATAL("Program '%s' not found or not executable", fname); - - } else { - - while (env_path) { - - u8 *cur_elem, *delim = strchr(env_path, ':'); - - if (delim) { - - cur_elem = ck_alloc(delim - env_path + 1); - memcpy(cur_elem, env_path, delim - env_path); - delim++; - - } else - - cur_elem = ck_strdup(env_path); - - env_path = delim; - - if (cur_elem[0]) - target_path = alloc_printf("%s/%s", cur_elem, fname); - else - target_path = ck_strdup(fname); - - ck_free(cur_elem); - - if (!stat(target_path, &st) && S_ISREG(st.st_mode) && - (st.st_mode & 0111) && st.st_size >= 4) - break; - - ck_free(target_path); - target_path = 0; - - } - - if (!target_path) FATAL("Program '%s' not found or not executable", fname); - - } - -} - /* Main entry point */ int main(int argc, char **argv, char **envp) { @@ -997,7 +942,7 @@ int main(int argc, char **argv, char **envp) { set_up_environment(); - find_binary(argv[optind]); + target_path = find_binary(argv[optind]); detect_file_args(argv + optind, prog_in, &use_stdin); if (qemu_mode) { diff --git a/src/afl-common.c b/src/afl-common.c index 1ac1a2f3..ffc32533 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -37,6 +37,10 @@ #include #endif #include +#include +#include +#include +#include u8 be_quiet = 0; u8 *doc_path = ""; @@ -353,6 +357,68 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } +/* Find binary, used by analyze, showmap, tmin + @returns the path, allocating the string */ + +u8 *find_binary(u8 *fname) { + + // TODO: Merge this function with check_binary of afl-fuzz-init.c + + u8 *env_path = NULL; + u8 *target_path = NULL; + + struct stat st; + + if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { + + target_path = ck_strdup(fname); + + if (stat(target_path, &st) || !S_ISREG(st.st_mode) || + !(st.st_mode & 0111) || st.st_size < 4) + FATAL("Program '%s' not found or not executable", fname); + + } else { + + while (env_path) { + + u8 *cur_elem, *delim = strchr(env_path, ':'); + + if (delim) { + + cur_elem = ck_alloc(delim - env_path + 1); + memcpy(cur_elem, env_path, delim - env_path); + delim++; + + } else + + cur_elem = ck_strdup(env_path); + + env_path = delim; + + if (cur_elem[0]) + target_path = alloc_printf("%s/%s", cur_elem, fname); + else + target_path = ck_strdup(fname); + + ck_free(cur_elem); + + if (!stat(target_path, &st) && S_ISREG(st.st_mode) && + (st.st_mode & 0111) && st.st_size >= 4) + break; + + ck_free(target_path); + target_path = NULL; + + } + + if (!target_path) FATAL("Program '%s' not found or not executable", fname); + + } + + return target_path; + +} + void check_environment_vars(char **envp) { if (be_quiet) return; @@ -414,6 +480,20 @@ char *get_afl_env(char *env) { } +/* Read mask bitmap from file. This is for the -B option. */ + +void read_bitmap(u8 *fname, u8 *map, size_t len) { + + s32 fd = open(fname, O_RDONLY); + + if (fd < 0) PFATAL("Unable to open '%s'", fname); + + ck_read(fd, map, len, fname); + + close(fd); + +} + u64 get_cur_time(void) { struct timeval tv; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 6042b4b8..be8f504e 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -49,20 +49,6 @@ void write_bitmap(afl_state_t *afl) { } -/* Read bitmap from file. This is for the -B option again. */ - -void read_bitmap(afl_state_t *afl, u8 *fname) { - - s32 fd = open(fname, O_RDONLY); - - if (fd < 0) PFATAL("Unable to open '%s'", fname); - - ck_read(fd, afl->virgin_bits, MAP_SIZE, fname); - - close(fd); - -} - /* Check if the current execution path brings anything new to the table. Update virgin bits to reflect the finds. Returns 1 if the only change is the hit-count for a particular tuple; 2 if there are new tuples seen. diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9f17b61b..edae7bb1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -474,7 +474,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->in_bitmap) FATAL("Multiple -B options not supported"); afl->in_bitmap = optarg; - read_bitmap(afl, afl->in_bitmap); + read_bitmap(afl->in_bitmap, afl->virgin_bits, MAP_SIZE); break; case 'C': /* crash mode */ diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 16d6fe41..01ba62aa 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -60,7 +60,7 @@ #include #endif -list_t shm_list = {.element_prealloc_count = 0}; +static list_t shm_list = {.element_prealloc_count = 0}; /* Get rid of shared memory. */ diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 55f7d438..86386df3 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -526,62 +526,6 @@ static void usage(u8 *argv0) { } -/* Find binary. */ - -static void find_binary(afl_forkserver_t *fsrv, u8 *fname) { - - u8 * env_path = 0; - struct stat st; - - if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { - - fsrv->target_path = ck_strdup(fname); - - if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) || - !(st.st_mode & 0111) || st.st_size < 4) - FATAL("Program '%s' not found or not executable", fname); - - } else { - - while (env_path) { - - u8 *cur_elem, *delim = strchr(env_path, ':'); - - if (delim) { - - cur_elem = ck_alloc(delim - env_path + 1); - memcpy(cur_elem, env_path, delim - env_path); - delim++; - - } else - - cur_elem = ck_strdup(env_path); - - env_path = delim; - - if (cur_elem[0]) - fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname); - else - fsrv->target_path = ck_strdup(fname); - - ck_free(cur_elem); - - if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) && - (st.st_mode & 0111) && st.st_size >= 4) - break; - - ck_free(fsrv->target_path); - fsrv->target_path = NULL; - - } - - if (!fsrv->target_path) - FATAL("Program '%s' not found or not executable", fname); - - } - -} - /* Main entry point */ int main(int argc, char **argv_orig, char **envp) { @@ -772,7 +716,7 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv); - find_binary(fsrv, argv[optind]); + fsrv->target_path = find_binary(argv[optind]); if (!quiet_mode) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 409bf01d..80692984 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -749,76 +749,6 @@ static void usage(u8 *argv0) { } -/* Find binary. */ - -static void find_binary(afl_forkserver_t *fsrv, u8 *fname) { - - u8 * env_path = 0; - struct stat st; - - if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { - - fsrv->target_path = ck_strdup(fname); - - if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) || - !(st.st_mode & 0111) || st.st_size < 4) - FATAL("Program '%s' not found or not executable", fname); - - } else { - - while (env_path) { - - u8 *cur_elem, *delim = strchr(env_path, ':'); - - if (delim) { - - cur_elem = ck_alloc(delim - env_path + 1); - memcpy(cur_elem, env_path, delim - env_path); - delim++; - - } else - - cur_elem = ck_strdup(env_path); - - env_path = delim; - - if (cur_elem[0]) - fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname); - else - fsrv->target_path = ck_strdup(fname); - - ck_free(cur_elem); - - if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) && - (st.st_mode & 0111) && st.st_size >= 4) - break; - - ck_free(fsrv->target_path); - fsrv->target_path = NULL; - - } - - if (!fsrv->target_path) - FATAL("Program '%s' not found or not executable", fname); - - } - -} - -/* Read mask bitmap from file. This is for the -B option. */ - -static void read_bitmap(u8 *fname) { - - s32 fd = open(fname, O_RDONLY); - - if (fd < 0) PFATAL("Unable to open '%s'", fname); - - ck_read(fd, mask_bitmap, MAP_SIZE, fname); - - close(fd); - -} - /* Main entry point */ int main(int argc, char **argv_orig, char **envp) { @@ -977,7 +907,7 @@ int main(int argc, char **argv_orig, char **envp) { if (mask_bitmap) FATAL("Multiple -B options not supported"); mask_bitmap = ck_alloc(MAP_SIZE); - read_bitmap(optarg); + read_bitmap(optarg, mask_bitmap, MAP_SIZE); break; case 'h': @@ -1001,7 +931,7 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv); - find_binary(fsrv, argv[optind]); + fsrv->target_path = find_binary(argv[optind]); detect_file_args(argv + optind, out_file, &fsrv->use_stdin); if (fsrv->qemu_mode) { -- cgit 1.4.1 From 1931838a112a23567b41ac0f018ae811ef7fbe1c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 17 Apr 2020 11:39:38 +0200 Subject: remove unnecessary map_size variables --- include/afl-fuzz.h | 2 -- include/sharedmem.h | 3 +-- llvm_mode/afl-clang-fast.c | 22 ++++++++++++---------- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 2 +- src/afl-sharedmem.c | 4 ++-- 6 files changed, 17 insertions(+), 18 deletions(-) (limited to 'src/afl-sharedmem.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index beef3d58..f6912aea 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -325,8 +325,6 @@ typedef struct afl_env_vars { *afl_python_module, *afl_path, *afl_hang_tmout, *afl_skip_crashes, *afl_preload; - uint32_t map_size; - } afl_env_vars_t; struct afl_pass_stat { diff --git a/include/sharedmem.h b/include/sharedmem.h index 57ab6cf0..6aef4b84 100644 --- a/include/sharedmem.h +++ b/include/sharedmem.h @@ -44,8 +44,7 @@ typedef struct sharedmem { u8 *map; /* shared memory region */ - size_t size_alloc; /* actual allocated size */ - size_t size_used; /* in use by shmem app */ + size_t map_size; /* actual allocated size */ int cmplog_mode; struct cmp_map *cmp_map; diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 7466db26..6584b11f 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -223,18 +223,20 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if ((!(getenv("AFL_LLVM_LTO_AUTODICTIONARY") // disabled when autodictionary - && instrument_mode != INSTRUMENT_LTO)) // and lto_mode is used - && (getenv("LAF_TRANSFORM_COMPARES") || - getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) { + if (getenv("LAF_TRANSFORM_COMPARES") || + getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) { - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/compare-transform-pass.so", obj_path); + if (!be_quiet && getenv("AFL_LLVM_LTO_AUTODICTIONARY") && + instrument_mode != INSTRUMENT_LTO)) + WARNF("using AFL_LLVM_LAF_TRANSFORM_COMPARES together with AFL_LLVM_LTO_AUTODICTIONARY makes no sense. Use only AFL_LLVM_LTO_AUTODICTIONARY."); - } + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/compare-transform-pass.so", obj_path); + + } if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES")) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 86dafb3e..72bdd91e 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -81,7 +81,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { and out_size are NULL/0 by default. */ memset(afl, 0, sizeof(afl_state_t)); - if (!map_size) map_size = MAP_SIZE; + if (!map_size) afl->shm.map_size = MAP_SIZE; afl->w_init = 0.9; afl->w_end = 0.3; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 93e83eed..03726eb0 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -264,7 +264,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_init(&afl->fsrv); read_afl_environment(afl, envp); - if (afl->afl_env.map_size) afl->fsrv.map_size = afl->afl_env.map_size; + if (afl->shm.map_size) afl->fsrv.map_size = afl->shm.map_size; exit_1 = !!afl->afl_env.afl_bench_just_one; SAYF(cCYA "afl-fuzz" VERSION cRST diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 01ba62aa..a130411e 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -72,7 +72,7 @@ void afl_shm_deinit(sharedmem_t *shm) { #ifdef USEMMAP if (shm->map != NULL) { - munmap(shm->map, shm->size_alloc); + munmap(shm->map, shm->map_size); shm->map = NULL; } @@ -99,7 +99,7 @@ void afl_shm_deinit(sharedmem_t *shm) { u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) { - shm->size_alloc = shm->size_used = map_size; + shm->map_size = map_size; shm->map = NULL; -- cgit 1.4.1