fix merge conflicts

This commit is contained in:
vanhauser-thc
2021-07-19 10:48:41 +02:00
116 changed files with 8029 additions and 2394 deletions

View File

@ -55,12 +55,7 @@
#include <sys/types.h>
#include <sys/resource.h>
static s32 child_pid; /* PID of the tested program */
static u8 *trace_bits; /* SHM with instrumentation bitmap */
static u8 *in_file, /* Analyzer input test case */
*prog_in; /* Targeted program input file */
static u8 *in_file; /* Analyzer input test case */
static u8 *in_data; /* Input data for analysis */
@ -73,20 +68,19 @@ static u64 orig_cksum; /* Original checksum */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
static s32 dev_null_fd = -1; /* FD to /dev/null */
static bool edges_only, /* Ignore hit counts? */
use_hex_offsets, /* Show hex offsets? */
use_stdin = true; /* Use stdin for program input? */
static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_timed_out; /* Child timed out? */
static volatile u8 stop_soon; /* Ctrl-C pressed? */
static u8 *target_path;
static u8 frida_mode;
static u8 qemu_mode;
static u32 map_size = MAP_SIZE;
static afl_forkserver_t fsrv = {0}; /* The forkserver */
/* Constants used for describing byte behavior. */
#define RESP_NONE 0x00 /* Changing byte is a no-op. */
@ -156,7 +150,7 @@ static void classify_counts(u8 *mem) {
static inline u8 anything_set(void) {
u32 *ptr = (u32 *)trace_bits;
u32 *ptr = (u32 *)fsrv.trace_bits;
u32 i = (map_size >> 2);
while (i--) {
@ -173,7 +167,7 @@ static inline u8 anything_set(void) {
static void at_exit_handler(void) {
unlink(prog_in); /* Ignore errors */
unlink(fsrv.out_file); /* Ignore errors */
}
@ -205,116 +199,29 @@ static void read_initial_file(void) {
}
/* Write output file. */
static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
s32 ret;
unlink(path); /* Ignore errors */
ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
if (ret < 0) { PFATAL("Unable to create '%s'", path); }
ck_write(ret, mem, len, path);
lseek(ret, 0, SEEK_SET);
return ret;
}
/* Execute target application. Returns exec checksum, or 0 if program
times out. */
static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
static u32 analyze_run_target(u8 *mem, u32 len, u8 first_run) {
static struct itimerval it;
int status = 0;
afl_fsrv_write_to_testcase(&fsrv, mem, len);
fsrv_run_result_t ret = afl_fsrv_run_target(&fsrv, exec_tmout, &stop_soon);
s32 prog_in_fd;
u64 cksum;
if (ret == FSRV_RUN_ERROR) {
memset(trace_bits, 0, map_size);
MEM_BARRIER();
FATAL("Error in forkserver");
prog_in_fd = write_to_file(prog_in, mem, len);
} else if (ret == FSRV_RUN_NOINST) {
child_pid = fork();
FATAL("Target not instrumented");
if (child_pid < 0) { PFATAL("fork() failed"); }
} else if (ret == FSRV_RUN_NOBITS) {
if (!child_pid) {
struct rlimit r;
if (dup2(use_stdin ? prog_in_fd : dev_null_fd, 0) < 0 ||
dup2(dev_null_fd, 1) < 0 || dup2(dev_null_fd, 2) < 0) {
*(u32 *)trace_bits = EXEC_FAIL_SIG;
PFATAL("dup2() failed");
}
close(dev_null_fd);
close(prog_in_fd);
if (mem_limit) {
r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;
#ifdef RLIMIT_AS
setrlimit(RLIMIT_AS, &r); /* Ignore errors */
#else
setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
#endif /* ^RLIMIT_AS */
}
r.rlim_max = r.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
execv(target_path, argv);
*(u32 *)trace_bits = EXEC_FAIL_SIG;
exit(0);
FATAL("Failed to run target");
}
close(prog_in_fd);
/* Configure timeout, wait for child, cancel timeout. */
child_timed_out = 0;
it.it_value.tv_sec = (exec_tmout / 1000);
it.it_value.tv_usec = (exec_tmout % 1000) * 1000;
setitimer(ITIMER_REAL, &it, NULL);
if (waitpid(child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
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 *)trace_bits == EXEC_FAIL_SIG) {
FATAL("Unable to execute '%s'", argv[0]);
}
classify_counts(trace_bits);
classify_counts(fsrv.trace_bits);
total_execs++;
if (stop_soon) {
@ -326,21 +233,19 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
/* Always discard inputs that time out. */
if (child_timed_out) {
if (fsrv.last_run_timed_out) {
exec_hangs++;
return 0;
}
cksum = hash64(trace_bits, map_size, HASH_CONST);
u64 cksum = hash64(fsrv.trace_bits, fsrv.map_size, HASH_CONST);
/* We don't actually care if the target is crashing or not,
except that when it does, the checksum should be different. */
if (ret == FSRV_RUN_CRASH) {
if (WIFSIGNALED(status) ||
(WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) ||
(WIFEXITED(status) && WEXITSTATUS(status))) {
/* We don't actually care if the target is crashing or not,
except that when it does, the checksum should be different. */
cksum ^= 0xffffffff;
@ -604,7 +509,7 @@ static void dump_hex(u32 len, u8 *b_data) {
/* Actually analyze! */
static void analyze(char **argv) {
static void analyze() {
u32 i;
u32 boring_len = 0, prev_xff = 0, prev_x01 = 0, prev_s10 = 0, prev_a10 = 0;
@ -630,16 +535,16 @@ static void analyze(char **argv) {
code. */
in_data[i] ^= 0xff;
xor_ff = analyze_run_target(argv, in_data, in_len, 0);
xor_ff = analyze_run_target(in_data, in_len, 0);
in_data[i] ^= 0xfe;
xor_01 = analyze_run_target(argv, in_data, in_len, 0);
xor_01 = analyze_run_target(in_data, in_len, 0);
in_data[i] = (in_data[i] ^ 0x01) - 0x10;
sub_10 = analyze_run_target(argv, in_data, in_len, 0);
sub_10 = analyze_run_target(in_data, in_len, 0);
in_data[i] += 0x20;
add_10 = analyze_run_target(argv, in_data, in_len, 0);
add_10 = analyze_run_target(in_data, in_len, 0);
in_data[i] -= 0x10;
/* Classify current behavior. */
@ -712,7 +617,7 @@ static void handle_stop_sig(int sig) {
(void)sig;
stop_soon = 1;
if (child_pid > 0) { kill(child_pid, SIGKILL); }
afl_fsrv_killall();
}
@ -724,10 +629,10 @@ static void set_up_environment(char **argv) {
char *afl_preload;
char *frida_afl_preload = NULL;
dev_null_fd = open("/dev/null", O_RDWR);
if (dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
fsrv.dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
if (!prog_in) {
if (!fsrv.out_file) {
u8 *use_dir = ".";
@ -738,10 +643,17 @@ static void set_up_environment(char **argv) {
}
prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid());
fsrv.out_file =
alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid());
}
unlink(fsrv.out_file);
fsrv.out_fd =
open(fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
if (fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fsrv.out_file); }
/* Set sane defaults... */
x = get_afl_env("ASAN_OPTIONS");
@ -977,9 +889,9 @@ int main(int argc, char **argv_orig, char **envp) {
case 'f':
if (prog_in) { FATAL("Multiple -f options not supported"); }
use_stdin = 0;
prog_in = optarg;
if (fsrv.out_file) { FATAL("Multiple -f options not supported"); }
fsrv.use_stdin = 0;
fsrv.out_file = ck_strdup(optarg);
break;
case 'e':
@ -1000,6 +912,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!strcmp(optarg, "none")) {
mem_limit = 0;
fsrv.mem_limit = 0;
break;
}
@ -1038,6 +951,8 @@ int main(int argc, char **argv_orig, char **envp) {
}
fsrv.mem_limit = mem_limit;
}
break;
@ -1057,6 +972,17 @@ int main(int argc, char **argv_orig, char **envp) {
}
fsrv.exec_tmout = exec_tmout;
break;
case 'O': /* FRIDA mode */
if (frida_mode) { FATAL("Multiple -O options not supported"); }
frida_mode = 1;
fsrv.frida_mode = frida_mode;
break;
case 'O': /* FRIDA mode */
@ -1073,6 +999,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (!mem_limit_given) { mem_limit = MEM_LIMIT_QEMU; }
qemu_mode = 1;
fsrv.mem_limit = mem_limit;
fsrv.qemu_mode = qemu_mode;
break;
case 'U':
@ -1081,6 +1009,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!mem_limit_given) { mem_limit = MEM_LIMIT_UNICORN; }
unicorn_mode = 1;
fsrv.mem_limit = mem_limit;
break;
case 'W': /* Wine+QEMU mode */
@ -1090,6 +1019,8 @@ int main(int argc, char **argv_orig, char **envp) {
use_wine = 1;
if (!mem_limit_given) { mem_limit = 0; }
fsrv.qemu_mode = qemu_mode;
fsrv.mem_limit = mem_limit;
break;
@ -1108,6 +1039,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (optind == argc || !in_file) { usage(argv[0]); }
map_size = get_map_size();
fsrv.map_size = map_size;
use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
@ -1117,14 +1049,15 @@ int main(int argc, char **argv_orig, char **envp) {
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler);
setup_signal_handlers();
set_up_environment(argv);
target_path = find_binary(argv[optind]);
detect_file_args(argv + optind, prog_in, &use_stdin);
fsrv.target_path = find_binary(argv[optind]);
fsrv.trace_bits = afl_shm_init(&shm, map_size, 0);
detect_file_args(argv + optind, fsrv.out_file, &use_stdin);
if (qemu_mode) {
@ -1148,14 +1081,31 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF("\n");
if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
if (forksrv_init_tmout < 1) {
FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
}
fsrv.init_tmout = (u32)forksrv_init_tmout;
}
fsrv.kill_signal =
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
read_initial_file();
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
mem_limit, exec_tmout, edges_only ? ", edges only" : "");
analyze_run_target(use_argv, in_data, in_len, 1);
afl_fsrv_start(&fsrv, use_argv, &stop_soon, false);
analyze_run_target(in_data, in_len, 1);
if (child_timed_out) {
if (fsrv.last_run_timed_out) {
FATAL("Target binary times out (adjusting -t may help).");
@ -1167,13 +1117,14 @@ int main(int argc, char **argv_orig, char **envp) {
}
analyze(use_argv);
analyze();
OKF("We're done here. Have a nice day!\n");
if (target_path) { ck_free(target_path); }
afl_shm_deinit(&shm);
afl_fsrv_deinit(&fsrv);
if (fsrv.target_path) { ck_free(fsrv.target_path); }
if (in_data) { ck_free(in_data); }
exit(0);

View File

@ -315,7 +315,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
have_c = 0;
have_c = 0, partial_linking = 0;
cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
@ -514,14 +514,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
unsetenv("AFL_LD");
unsetenv("AFL_LD_CALLER");
if (cmplog_mode) {
if (lto_mode && !have_c) {
cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path);
cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path);
"-Wl,-mllvm=-load=%s/cmplog-switches-pass.so", obj_path);
cc_params[cc_par_cnt++] = alloc_printf(
"-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path);
@ -531,13 +531,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] =
alloc_printf("%s/cmplog-routines-pass.so", obj_path);
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/cmplog-instructions-pass.so", obj_path);
alloc_printf("%s/cmplog-switches-pass.so", obj_path);
// reuse split switches from laf
cc_params[cc_par_cnt++] = "-Xclang";
@ -746,6 +740,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] = afllib;
#ifdef __APPLE__
cc_params[cc_par_cnt++] = "-undefined";
cc_params[cc_par_cnt++] = "dynamic_lookup";
#endif
}
continue;
@ -767,6 +766,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (!strcmp(cur, "-x")) x_set = 1;
if (!strcmp(cur, "-E")) preprocessor_only = 1;
if (!strcmp(cur, "-shared")) shared_linking = 1;
if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
if (!strcmp(cur, "-r")) partial_linking = 1;
if (!strcmp(cur, "--relocatable")) partial_linking = 1;
if (!strcmp(cur, "-c")) have_c = 1;
if (!strncmp(cur, "-O", 2)) have_o = 1;
@ -996,7 +999,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
switch (bit_mode) {
case 0:
if (!shared_linking)
if (!shared_linking && !partial_linking)
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-compiler-rt.o", obj_path);
if (lto_mode)
@ -1005,7 +1008,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
break;
case 32:
if (!shared_linking) {
if (!shared_linking && !partial_linking) {
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
@ -1026,7 +1029,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
break;
case 64:
if (!shared_linking) {
if (!shared_linking && !partial_linking) {
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
@ -1049,7 +1052,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
#if !defined(__APPLE__) && !defined(__sun)
if (!shared_linking)
if (!shared_linking && !partial_linking)
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
#endif

View File

@ -751,6 +751,8 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
}
/* Get unix time in milliseconds */
u64 get_cur_time(void) {
struct timeval tv;

View File

@ -90,6 +90,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
/* exec related stuff */
fsrv->child_pid = -1;
fsrv->map_size = get_map_size();
fsrv->real_map_size = fsrv->map_size;
fsrv->use_fauxsrv = false;
fsrv->last_run_timed_out = false;
fsrv->debug = false;
@ -110,6 +111,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->init_tmout = from->init_tmout;
fsrv_to->mem_limit = from->mem_limit;
fsrv_to->map_size = from->map_size;
fsrv_to->real_map_size = from->real_map_size;
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
fsrv_to->out_file = from->out_file;
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
@ -691,15 +693,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; }
if (unlikely(tmp_map_size % 64)) {
fsrv->real_map_size = tmp_map_size;
if (tmp_map_size % 64) {
// should not happen
WARNF("Target reported non-aligned map size of %u", tmp_map_size);
tmp_map_size = (((tmp_map_size + 63) >> 6) << 6);
}
if (!be_quiet) { ACTF("Target map size: %u", tmp_map_size); }
if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); }
if (tmp_map_size > fsrv->map_size) {
FATAL(

View File

@ -551,19 +551,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
if (cksum)
afl->queue_top->exec_cksum = cksum;
else
cksum = afl->queue_top->exec_cksum =
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
if (afl->schedule >= FAST && afl->schedule <= RARE) {
/* AFLFast schedule? update the new queue entry */
if (cksum) {
afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
}
/* due to classify counts we have to recalculate the checksum */
cksum = afl->queue_top->exec_cksum =
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
/* Try to calibrate inline; this also calls update_bitmap_score() when
successful. */

View File

@ -480,13 +480,22 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
for (iter = 0; iter < afl->foreign_sync_cnt; iter++) {
if (afl->foreign_syncs[iter].dir != NULL &&
afl->foreign_syncs[iter].dir[0] != 0) {
if (afl->foreign_syncs[iter].dir && afl->foreign_syncs[iter].dir[0]) {
if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir);
time_t mtime_max = 0;
u8 * name = strrchr(afl->foreign_syncs[iter].dir, '/');
if (!name) { name = afl->foreign_syncs[iter].dir; }
u8 *name = strrchr(afl->foreign_syncs[iter].dir, '/');
if (!name) {
name = afl->foreign_syncs[iter].dir;
} else {
++name;
}
if (!strcmp(name, "queue") || !strcmp(name, "out") ||
!strcmp(name, "default")) {
@ -701,96 +710,103 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
}
for (i = 0; i < (u32)nl_cnt; ++i) {
if (nl_cnt) {
struct stat st;
i = nl_cnt;
do {
u8 dfn[PATH_MAX];
snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir,
nl[i]->d_name);
u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
--i;
u8 passed_det = 0;
struct stat st;
u8 dfn[PATH_MAX];
snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir,
nl[i]->d_name);
u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
if (lstat(fn2, &st) || access(fn2, R_OK)) {
u8 passed_det = 0;
PFATAL("Unable to access '%s'", fn2);
if (lstat(fn2, &st) || access(fn2, R_OK)) {
}
PFATAL("Unable to access '%s'", fn2);
/* obviously we want to skip "descending" into . and .. directories,
however it is a good idea to skip also directories that start with
a dot */
if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
}
free(nl[i]); /* not tracked */
read_testcases(afl, fn2);
ck_free(fn2);
continue;
/* obviously we want to skip "descending" into . and .. directories,
however it is a good idea to skip also directories that start with
a dot */
if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
}
free(nl[i]); /* not tracked */
read_testcases(afl, fn2);
ck_free(fn2);
continue;
free(nl[i]);
}
if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) {
free(nl[i]);
ck_free(fn2);
continue;
if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) {
}
ck_free(fn2);
continue;
if (st.st_size > MAX_FILE) {
}
WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", fn2,
stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
if (st.st_size > MAX_FILE) {
}
WARNF("Test case '%s' is too big (%s, limit is %s), partial reading",
fn2,
stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
/* Check for metadata that indicates that deterministic fuzzing
is complete for this entry. We don't want to repeat deterministic
fuzzing when resuming aborted scans, because it would be pointless
and probably very time-consuming. */
}
if (!access(dfn, F_OK)) { passed_det = 1; }
/* Check for metadata that indicates that deterministic fuzzing
is complete for this entry. We don't want to repeat deterministic
fuzzing when resuming aborted scans, because it would be pointless
and probably very time-consuming. */
add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size,
passed_det);
if (!access(dfn, F_OK)) { passed_det = 1; }
if (unlikely(afl->shm.cmplog_mode)) {
add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size,
passed_det);
if (afl->cmplog_lvl == 1) {
if (unlikely(afl->shm.cmplog_mode)) {
if (!afl->cmplog_max_filesize ||
afl->cmplog_max_filesize < st.st_size) {
if (afl->cmplog_lvl == 1) {
afl->cmplog_max_filesize = st.st_size;
if (!afl->cmplog_max_filesize ||
afl->cmplog_max_filesize < st.st_size) {
}
afl->cmplog_max_filesize = st.st_size;
} else if (afl->cmplog_lvl == 2) {
}
if (!afl->cmplog_max_filesize ||
afl->cmplog_max_filesize > st.st_size) {
} else if (afl->cmplog_lvl == 2) {
afl->cmplog_max_filesize = st.st_size;
if (!afl->cmplog_max_filesize ||
afl->cmplog_max_filesize > st.st_size) {
afl->cmplog_max_filesize = st.st_size;
}
}
}
}
/*
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
/*
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size,
HASH_CONST); afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size,
HASH_CONST); afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
}
}
*/
*/
} while (i > 0);
}

View File

@ -393,6 +393,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
classify_counts(&afl->fsrv);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
}

View File

@ -73,7 +73,7 @@ static int select_algorithm(afl_state_t *afl, u32 max_algorithm) {
/* Helper to choose random block len for block operations in fuzz_one().
Doesn't return zero, provided that max_len is > 0. */
static u32 choose_block_len(afl_state_t *afl, u32 limit) {
static inline u32 choose_block_len(afl_state_t *afl, u32 limit) {
u32 min_value, max_value;
u32 rlim = MIN(afl->queue_cycle, (u32)3);
@ -2057,7 +2057,7 @@ havoc_stage:
temp_len = new_len;
if (out_buf != custom_havoc_buf) {
afl_realloc(AFL_BUF_PARAM(out), temp_len);
out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len);
if (unlikely(!afl->out_buf)) { PFATAL("alloc"); }
memcpy(out_buf, custom_havoc_buf, temp_len);
@ -2102,9 +2102,9 @@ havoc_stage:
case 8 ... 9: {
/* Set word to interesting value, randomly choosing endian. */
case 8 ... 9: {
if (temp_len < 2) { break; }
/* Set word to interesting value, little endian. */
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
@ -2136,9 +2136,9 @@ havoc_stage:
case 12 ... 13: {
/* Set dword to interesting value, randomly choosing endian. */
case 12 ... 13: {
if (temp_len < 4) { break; }
/* Set dword to interesting value, little endian. */
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
@ -2862,6 +2862,7 @@ abandon_entry:
--afl->pending_not_fuzzed;
afl->queue_cur->was_fuzzed = 1;
afl->reinit_table = 1;
if (afl->queue_cur->favored) { --afl->pending_favored; }
}

View File

@ -58,7 +58,8 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); }
weight *= (log(q->bitmap_size) / avg_bitmap_size);
weight *= (1 + (q->tc_ref / avg_top_size));
if (unlikely(q->favored)) weight *= 5;
if (unlikely(q->favored)) { weight *= 5; }
if (unlikely(!q->was_fuzzed)) { weight *= 2; }
return weight;
@ -198,6 +199,8 @@ void create_alias_table(afl_state_t *afl) {
while (nS)
afl->alias_probability[S[--nS]] = 1;
afl->reinit_table = 0;
/*
#ifdef INTROSPECTION
u8 fn[PATH_MAX];
@ -1132,12 +1135,10 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
do_once = 1;
// release unneeded memory
u8 *ptr = ck_realloc(
afl->q_testcase_cache = ck_realloc(
afl->q_testcase_cache,
(afl->q_testcase_max_cache_entries + 1) * sizeof(size_t));
if (ptr) { afl->q_testcase_cache = (struct queue_entry **)ptr; }
}
/* Cache full. We neet to evict one or more to map one.

View File

@ -252,7 +252,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
u64 start_time = get_cur_time();
#endif
u32 screen_update = 1000000 / afl->queue_cur->exec_us;
u32 screen_update;
u64 orig_hit_cnt, new_hit_cnt, exec_cksum;
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -261,6 +261,24 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
afl->stage_max = (len << 1);
afl->stage_cur = 0;
if (likely(afl->queue_cur->exec_us)) {
if (likely((100000 / 2) >= afl->queue_cur->exec_us)) {
screen_update = 100000 / afl->queue_cur->exec_us;
} else {
screen_update = 1;
}
} else {
screen_update = 100000;
}
// in colorization we do not classify counts, hence we have to calculate
// the original checksum.
if (unlikely(get_exec_checksum(afl, buf, len, &exec_cksum))) {
@ -905,17 +923,16 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."
s64 diff = pattern - b_val;
s64 o_diff = o_pattern - o_b_val;
/*
fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
h->shape + 1, o_pattern, o_b_val, o_diff);
fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
b_val, diff);*/
/* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
h->shape + 1, o_pattern, o_b_val, o_diff);
fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
b_val, diff); */
if (diff == o_diff && diff) {
// this could be an arithmetic transformation
u64 new_repl = (u64)((s64)repl - diff);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
if (unlikely(cmp_extend_encoding(
afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
@ -935,15 +952,17 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
diff = pattern ^ b_val;
s64 o_diff = o_pattern ^ o_b_val;
/* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr,
"DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/
/* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
if (diff == o_diff && diff) {
// this could be a XOR transformation
u64 new_repl = (u64)((s64)repl ^ diff);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
if (unlikely(cmp_extend_encoding(
afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
@ -982,15 +1001,17 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr,
"DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/
/* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
if (o_diff && diff) {
// this could be a lower to upper
u64 new_repl = (repl & (0x5f5f5f5f5f5f5f5f & mask));
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
if (unlikely(cmp_extend_encoding(
afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
@ -1029,15 +1050,17 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr,
"DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/
/* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
if (o_diff && diff) {
// this could be a lower to upper
u64 new_repl = (repl | (0x2020202020202020 & mask));
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
// fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
if (unlikely(cmp_extend_encoding(
afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
@ -1383,7 +1406,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
//#endif /* CMPLOG_SOLVE_ARITHMETIC
//#endif /*
// CMPLOG_SOLVE_ARITHMETIC
return 0;
@ -2152,7 +2176,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
memcpy(buf + idx, tmp, i + 1);
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
// fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex, *status);
// fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex,
// *status);
}
@ -2235,7 +2260,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
for (j = 0; j <= i; j++)
buf[idx + j] = repl[j] - arith_val[j];
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
// fprintf(stderr, "RTN ATTEMPT arith %u result %u\n", arith, *status);
// fprintf(stderr, "RTN ATTEMPT arith %u result %u\n", arith,
// *status);
}
@ -2328,16 +2354,17 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
/*
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
h->shape, h->attribute); for (j = 0; j < 8; j++) fprintf(stderr, "%02x",
o->v0[j]); fprintf(stderr, " v1="); for (j = 0; j < 8; j++) fprintf(stderr,
"%02x", o->v1[j]); fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u
o0=", hh->hits, hh->id, hh->shape, hh->attribute); for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v0[j]);
fprintf(stderr, " o1=");
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v1[j]);
fprintf(stderr, "\n");
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits,
h->id, h->shape, h->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v0[j]);
fprintf(stderr, " v1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v1[j]);
fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=",
hh->hits, hh->id, hh->shape, hh->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v0[j]);
fprintf(stderr, " o1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v1[j]);
fprintf(stderr, "\n");
*/
t = taint;
@ -2663,7 +2690,12 @@ exit_its:
afl->queue_cur->colorized = CMPLOG_LVL_MAX;
ck_free(afl->queue_cur->cmplog_colorinput);
if (afl->queue_cur->cmplog_colorinput) {
ck_free(afl->queue_cur->cmplog_colorinput);
}
while (taint) {
t = taint->next;

View File

@ -314,7 +314,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
++q->cal_failed;
afl->stage_name = "calibration";
afl->stage_max = afl->fast_cal ? 3 : CAL_CYCLES;
afl->stage_max = afl->afl_env.afl_cal_fast ? 3 : CAL_CYCLES;
/* Make sure the forkserver is up before we do anything, and let's not
count its spin-up time toward binary calibration. */
@ -333,7 +333,6 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz);
afl->shm_fuzz = NULL;
@ -356,6 +355,12 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
if (unlikely(afl->debug)) {
DEBUGF("calibration stage %d/%d\n", afl->stage_cur + 1, afl->stage_max);
}
u64 cksum;
write_to_testcase(afl, use_mem, q->len);
@ -403,6 +408,21 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
}
if (unlikely(!var_detected)) {
// note: from_queue seems to only be set during initialization
if (afl->afl_env.afl_no_ui || from_queue) {
WARNF("instability detected during calibration");
} else if (afl->debug) {
DEBUGF("instability detected during calibration\n");
}
}
var_detected = 1;
afl->stage_max = afl->fast_cal ? CAL_CYCLES : CAL_CYCLES_LONG;

View File

@ -96,8 +96,6 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->splicing_with = -1; /* Splicing with which test case? */
afl->cpu_to_bind = -1;
afl->havoc_stack_pow2 = HAVOC_STACK_POW2;
afl->cal_cycles = CAL_CYCLES;
afl->cal_cycles_long = CAL_CYCLES_LONG;
afl->hang_tmout = EXEC_TIMEOUT;
afl->exit_on_time = 0;
afl->stats_update_freq = 1;
@ -341,6 +339,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_cal_fast =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
} else if (!strncmp(env, "AFL_FAST_CAL",
afl_environment_variable_len)) {
afl->afl_env.afl_cal_fast =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
} else if (!strncmp(env, "AFL_STATSD",
afl_environment_variable_len)) {

View File

@ -264,6 +264,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"peak_rss_mb : %lu\n"
"cpu_affinity : %d\n"
"edges_found : %u\n"
"total_edges : %u\n"
"var_byte_count : %u\n"
"havoc_expansion : %u\n"
"testcache_size : %llu\n"
@ -303,10 +304,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
#else
-1,
#endif
t_bytes, afl->var_byte_count, afl->expand_havoc,
afl->q_testcase_cache_size, afl->q_testcase_cache_count,
afl->q_testcase_evictions, afl->use_banner,
afl->unicorn_mode ? "unicorn" : "",
t_bytes, afl->fsrv.real_map_size, afl->var_byte_count,
afl->expand_havoc, afl->q_testcase_cache_size,
afl->q_testcase_cache_count, afl->q_testcase_evictions,
afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->fsrv.qemu_mode ? "qemu " : "",
afl->non_instrumented_mode ? " non_instrumented " : "",
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
@ -326,7 +327,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
u32 i = 0;
fprintf(f, "virgin_bytes :");
for (i = 0; i < afl->fsrv.map_size; i++) {
for (i = 0; i < afl->fsrv.real_map_size; i++) {
if (afl->virgin_bits[i] != 0xff) {
@ -338,7 +339,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
fprintf(f, "\n");
fprintf(f, "var_bytes :");
for (i = 0; i < afl->fsrv.map_size; i++) {
for (i = 0; i < afl->fsrv.real_map_size; i++) {
if (afl->var_bytes[i]) { fprintf(f, " %u", i); }
@ -520,7 +521,7 @@ void show_stats(afl_state_t *afl) {
/* Do some bitmap stats. */
t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.map_size;
t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.real_map_size;
if (likely(t_bytes) && unlikely(afl->var_byte_count)) {
@ -766,9 +767,9 @@ void show_stats(afl_state_t *afl) {
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
time_tmp, tmp);
SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bH2 bHB bH bSTOP cCYA
" map coverage" bSTG bHT bH20 bH2 bVL "\n");
/* This gets funny because we want to print several variable-length variables
together, but then cram them into a fixed-width field - so we need to
@ -778,13 +779,13 @@ void show_stats(afl_state_t *afl) {
afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level,
((double)afl->current_entry * 100) / afl->queued_paths);
SAYF(bV bSTOP " now processing : " cRST "%-16s " bSTG bV bSTOP, tmp);
SAYF(bV bSTOP " now processing : " cRST "%-18s " bSTG bV bSTOP, tmp);
sprintf(tmp, "%0.02f%% / %0.02f%%",
((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.map_size,
((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.real_map_size,
t_byte_ratio);
SAYF(" map density : %s%-21s" bSTG bV "\n",
SAYF(" map density : %s%-19s" bSTG bV "\n",
t_byte_ratio > 70
? cLRD
: ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
@ -793,23 +794,23 @@ void show_stats(afl_state_t *afl) {
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths),
((double)afl->cur_skipped_paths * 100) / afl->queued_paths);
SAYF(bV bSTOP " paths timed out : " cRST "%-16s " bSTG bV, tmp);
SAYF(bV bSTOP " paths timed out : " cRST "%-18s " bSTG bV, tmp);
sprintf(tmp, "%0.02f bits/tuple", t_bytes ? (((double)t_bits) / t_bytes) : 0);
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
SAYF(bSTOP " count coverage : " cRST "%-19s" bSTG bV "\n", tmp);
SAYF(bVR bH bSTOP cCYA
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
SAYF(bVR bH bSTOP cCYA
" stage progress " bSTG bH10 bH5 bH2 bH2 bH2 bX bH bSTOP cCYA
" findings in depth " bSTG bH10 bH5 bH2 bVL "\n");
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
((double)afl->queued_favored) * 100 / afl->queued_paths);
/* Yeah... it's still going on... halp? */
SAYF(bV bSTOP " now trying : " cRST "%-20s " bSTG bV bSTOP
" favored paths : " cRST "%-22s" bSTG bV "\n",
SAYF(bV bSTOP " now trying : " cRST "%-22s " bSTG bV bSTOP
" favored paths : " cRST "%-20s" bSTG bV "\n",
afl->stage_name, tmp);
if (!afl->stage_max) {
@ -824,12 +825,12 @@ void show_stats(afl_state_t *afl) {
}
SAYF(bV bSTOP " stage execs : " cRST "%-21s" bSTG bV bSTOP, tmp);
SAYF(bV bSTOP " stage execs : " cRST "%-23s" bSTG bV bSTOP, tmp);
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov),
((double)afl->queued_with_cov) * 100 / afl->queued_paths);
SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp);
SAYF(" new edges on : " cRST "%-20s" bSTG bV "\n", tmp);
sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_crashes),
u_stringify_int(IB(1), afl->unique_crashes),
@ -837,14 +838,14 @@ void show_stats(afl_state_t *afl) {
if (afl->crash_mode) {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" new crashes : %s%-22s" bSTG bV "\n",
SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
" new crashes : %s%-20s" bSTG bV "\n",
u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
} else {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" total crashes : %s%-22s" bSTG bV "\n",
SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
" total crashes : %s%-20s" bSTG bV "\n",
u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
}
@ -856,12 +857,12 @@ void show_stats(afl_state_t *afl) {
sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp);
SAYF(bV bSTOP " exec speed : " cLRD "%-22s ", tmp);
} else {
sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec));
SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp);
SAYF(bV bSTOP " exec speed : " cRST "%-22s ", tmp);
}
@ -869,13 +870,16 @@ void show_stats(afl_state_t *afl) {
u_stringify_int(IB(1), afl->unique_tmouts),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-20s" bSTG bV "\n", tmp);
/* Aaaalmost there... hold on! */
SAYF(bVR bH cCYA bSTOP
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
" path geometry " bSTG bH5 bH2 bVL "\n");
SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bH2 bHT bH10 bH2
bH bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n");
if (unlikely(afl->custom_only)) {
strcpy(tmp, "disabled (custom-mutator-only mode)");
if (unlikely(afl->custom_only)) {

View File

@ -125,7 +125,7 @@ static void usage(u8 *argv0, int more_help) {
"entering the\n"
" pacemaker mode (minutes of no new paths). 0 = "
"immediately,\n"
" -1 = immediately and together with normal mutation).\n"
" -1 = immediately and together with normal mutation.\n"
" See docs/README.MOpt.md\n"
" -c program - enable CmpLog by specifying a binary compiled for "
"it.\n"
@ -143,7 +143,7 @@ static void usage(u8 *argv0, int more_help) {
" -x dict_file - fuzzer dictionary (see README.md, specify up to 4 "
"times)\n\n"
"Testing settings:\n"
"Test settings:\n"
" -s seed - use a fixed seed for the RNG\n"
" -V seconds - fuzz for a specified time then terminate\n"
" -E execs - fuzz for an approx. no. of total executions then "
@ -158,7 +158,7 @@ static void usage(u8 *argv0, int more_help) {
" -F path - sync to a foreign fuzzer queue directory (requires "
"-M, can\n"
" be specified up to %u times)\n"
" -d - skip deterministic fuzzing in -M mode\n"
// " -d - skip deterministic fuzzing in -M mode\n"
" -T text - text banner to show on the screen\n"
" -I command - execute this command/script when a new crash is "
"found\n"
@ -575,7 +575,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
afl->sync_id = ck_strdup(optarg);
afl->skip_deterministic = 0; // force deterministic fuzzing
afl->old_seed_selection = 1; // force old queue walking seed selection
afl->disable_trim = 1; // disable trimming
@ -1206,6 +1205,8 @@ int main(int argc, char **argv_orig, char **envp) {
}
setenv("__AFL_OUT_DIR", afl->out_dir, 1);
if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; }
if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) {
@ -1275,7 +1276,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; }
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
if (get_afl_env("AFL_FAST_CAL")) { afl->fast_cal = 1; }
if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
if (afl->afl_env.afl_autoresume) {
@ -1488,14 +1488,6 @@ int main(int argc, char **argv_orig, char **envp) {
check_if_tty(afl);
if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
if (afl->afl_env.afl_cal_fast) {
/* Use less calibration cycles, for slow applications */
afl->cal_cycles = 3;
afl->cal_cycles_long = 5;
}
if (afl->afl_env.afl_custom_mutator_only) {
/* This ensures we don't proceed to havoc/splice */
@ -1919,7 +1911,12 @@ int main(int argc, char **argv_orig, char **envp) {
if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl);
afl->start_time = get_cur_time();
if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl);
if (afl->in_place_resume || afl->afl_env.afl_autoresume) {
load_stats_file(afl);
}
write_stats_file(afl, 0, 0, 0, 0);
maybe_update_plot_file(afl, 0, 0, 0);
save_auto(afl);
@ -2157,7 +2154,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (likely(!afl->old_seed_selection)) {
if (unlikely(prev_queued_paths < afl->queued_paths)) {
if (unlikely(prev_queued_paths < afl->queued_paths ||
afl->reinit_table)) {
// we have new queue entries since the last run, recreate alias table
prev_queued_paths = afl->queued_paths;
@ -2283,13 +2281,10 @@ stop_fuzzing:
destroy_queue(afl);
destroy_extras(afl);
destroy_custom_mutators(afl);
unsetenv(SHM_ENV_VAR);
unsetenv(CMPLOG_SHM_ENV_VAR);
afl_shm_deinit(&afl->shm);
if (afl->shm_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz);

View File

@ -67,6 +67,8 @@ static char *stdin_file; /* stdin file */
static u8 *in_dir = NULL, /* input folder */
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
static u8 outfile[PATH_MAX];
static u8 *in_data, /* Input data */
*coverage_map; /* Coverage map */
@ -230,7 +232,11 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
u8 cco = !!getenv("AFL_CMIN_CRASHES_ONLY"),
caa = !!getenv("AFL_CMIN_ALLOW_ANY");
if (!outfile) { FATAL("Output filename not set (Bug in AFL++?)"); }
if (!outfile || !*outfile) {
FATAL("Output filename not set (Bug in AFL++?)");
}
if (cmin_mode &&
(fsrv->last_run_timed_out || (!caa && child_crashed != cco))) {
@ -394,7 +400,28 @@ static u32 read_file(u8 *in_file) {
if (fstat(fd, &st) || !st.st_size) {
WARNF("Zero-sized input file '%s'.", in_file);
if (!be_quiet && !quiet_mode) {
WARNF("Zero-sized input file '%s'.", in_file);
}
}
if (st.st_size > MAX_FILE) {
if (!be_quiet && !quiet_mode) {
WARNF("Input file '%s' is too large, only reading %u bytes.", in_file,
MAX_FILE);
}
in_len = MAX_FILE;
} else {
in_len = st.st_size;
}
@ -692,6 +719,96 @@ static void setup_signal_handlers(void) {
}
u32 execute_testcases(u8 *dir) {
struct dirent **nl;
s32 nl_cnt, subdirs = 1;
u32 i, done = 0;
u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
if (!be_quiet) { ACTF("Scanning '%s'...", dir); }
/* We use scandir() + alphasort() rather than readdir() because otherwise,
the ordering of test cases would vary somewhat randomly and would be
difficult to control. */
nl_cnt = scandir(dir, &nl, NULL, alphasort);
if (nl_cnt < 0) { return 0; }
for (i = 0; i < (u32)nl_cnt; ++i) {
struct stat st;
u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
if (lstat(fn2, &st) || access(fn2, R_OK)) {
PFATAL("Unable to access '%s'", fn2);
}
/* obviously we want to skip "descending" into . and .. directories,
however it is a good idea to skip also directories that start with
a dot */
if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
free(nl[i]); /* not tracked */
done += execute_testcases(fn2);
ck_free(fn2);
continue;
}
if (!S_ISREG(st.st_mode) || !st.st_size) {
free(nl[i]);
ck_free(fn2);
continue;
}
if (st.st_size > MAX_FILE && !be_quiet && !quiet_mode) {
WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", fn2,
stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
}
if (!collect_coverage)
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, nl[i]->d_name);
free(nl[i]);
if (read_file(fn2)) {
if (wait_for_gdb) {
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
kill(0, SIGSTOP);
}
showmap_run_target_forkserver(fsrv, in_data, in_len);
ck_free(in_data);
++done;
if (collect_coverage)
analyze_results(fsrv);
else
tcnt = write_results_to_file(fsrv, outfile);
}
}
free(nl); /* not tracked */
return done;
}
/* Show banner. */
static void show_banner(void) {
@ -710,7 +827,7 @@ static void usage(u8 *argv0) {
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
"Required parameters:\n"
" -o file - file to write the trace data to\n\n"
" -o file - file to write the trace data to\n\n"
"Execution control settings:\n"
" -t msec - timeout for each run (none)\n"
@ -722,19 +839,19 @@ static void usage(u8 *argv0) {
" (Not necessary, here for consistency with other afl-* "
"tools)\n\n"
"Other settings:\n"
" -i dir - process all files in this directory, must be combined "
" -i dir - process all files below this directory, must be combined "
"with -o.\n"
" With -C, -o is a file, without -C it must be a "
" With -C, -o is a file, without -C it must be a "
"directory\n"
" and each bitmap will be written there individually.\n"
" -C - collect coverage, writes all edges to -o and gives a "
" and each bitmap will be written there individually.\n"
" -C - collect coverage, writes all edges to -o and gives a "
"summary\n"
" Must be combined with -i.\n"
" -q - sink program's output and don't show messages\n"
" -e - show edge coverage only, ignore hit counts\n"
" -r - show real tuple values instead of AFL filter values\n"
" -s - do not classify the map\n"
" -c - allow core dumps\n\n"
" Must be combined with -i.\n"
" -q - sink program's output and don't show messages\n"
" -e - show edge coverage only, ignore hit counts\n"
" -r - show real tuple values instead of AFL filter values\n"
" -s - do not classify the map\n"
" -c - allow core dumps\n\n"
"This tool displays raw tuple data captured by AFL instrumentation.\n"
"For additional help, consult %s/README.md.\n\n"
@ -1000,6 +1117,11 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp);
if (getenv("AFL_NO_FORKSRV")) { /* if set, use the fauxserver */
fsrv->use_fauxsrv = true;
}
if (getenv("AFL_DEBUG")) {
DEBUGF("");
@ -1177,7 +1299,7 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
if ((coverage_map = (u8 *)malloc(map_size)) == NULL)
if ((coverage_map = (u8 *)malloc(map_size + 64)) == NULL)
FATAL("coult not grab memory");
edges_only = false;
raw_instr_output = true;
@ -1260,44 +1382,7 @@ int main(int argc, char **argv_orig, char **envp) {
continue; // skip anything that starts with '.'
}
#if defined(DT_REG) /* Posix and Solaris do not know d_type and DT_REG */
if (dir_ent->d_type != DT_REG) {
continue; // only regular files
}
#endif
snprintf(infile, sizeof(infile), "%s/%s", in_dir, dir_ent->d_name);
#if !defined(DT_REG) /* use stat() */
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
#endif
if (!collect_coverage)
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
if (read_file(infile)) {
if (wait_for_gdb) {
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
kill(0, SIGSTOP);
}
showmap_run_target_forkserver(fsrv, in_data, in_len);
ck_free(in_data);
if (collect_coverage)
analyze_results(fsrv);
else
tcnt = write_results_to_file(fsrv, outfile);
}
FATAL("could not read input testcases from %s", in_dir);
}

View File

@ -877,12 +877,13 @@ static void usage(u8 *argv0) {
" the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
"ASAN_OPTIONS: custom settings for ASAN\n"
" (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
"TMPDIR: directory to use for temporary input files\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
"TMPDIR: directory to use for temporary input files\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
exit(1);
@ -1104,6 +1105,12 @@ int main(int argc, char **argv_orig, char **envp) {
if (optind == argc || !in_file || !output_file) { usage(argv[0]); }
check_environment_vars(envp);
if (getenv("AFL_NO_FORKSRV")) { /* if set, use the fauxserver */
fsrv->use_fauxsrv = true;
}
setenv("AFL_NO_AUTODICT", "1", 1);
/* initialize cmplog_mode */