mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 02:58:08 +00:00
fix merge conflicts
This commit is contained in:
@ -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);
|
||||
|
||||
|
33
src/afl-cc.c
33
src/afl-cc.c
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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)) {
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user