aboutsummaryrefslogtreecommitdiff
path: root/src/afl-fuzz.c
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2019-09-02 18:49:43 +0200
committerAndrea Fioraldi <andreafioraldi@gmail.com>2019-09-02 18:49:43 +0200
commitb24639d0113e15933e749ea0f96abe3f25a134a0 (patch)
tree4272020625c80c0d6982d3787bebc573c0da01b8 /src/afl-fuzz.c
parent2ae4ca91b48407add0e940ee13bd8b385e319a7a (diff)
downloadafl++-b24639d0113e15933e749ea0f96abe3f25a134a0.tar.gz
run code formatter
Diffstat (limited to 'src/afl-fuzz.c')
-rw-r--r--src/afl-fuzz.c609
1 files changed, 361 insertions, 248 deletions
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 2242dd6b..685840c6 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -27,53 +27,62 @@
static void usage(u8* argv0) {
#ifdef USE_PYTHON
-#define PHYTON_SUPPORT \
- "Compiled with Python 2.7 module support, see docs/python_mutators.txt\n"
+# define PHYTON_SUPPORT\
+ "Compiled with Python 2.7 module support, see docs/python_mutators.txt\n"
#else
-#define PHYTON_SUPPORT ""
+# define PHYTON_SUPPORT ""
#endif
- SAYF("\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
-
- "Required parameters:\n"
- " -i dir - input directory with test cases\n"
- " -o dir - output directory for fuzzer findings\n\n"
-
- "Execution control settings:\n"
- " -p schedule - power schedules recompute a seed's performance score.\n"
- " <explore (default), fast, coe, lin, quad, or exploit>\n"
- " see docs/power_schedules.txt\n"
- " -f file - location read by the fuzzed program (stdin)\n"
- " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
- " -m megs - memory limit for child process (%d MB)\n"
- " -Q - use binary-only instrumentation (QEMU mode)\n"
- " -U - use Unicorn-based instrumentation (Unicorn mode)\n\n"
- " -L minutes - use MOpt(imize) mode and set the limit time for entering the\n"
- " pacemaker mode (minutes of no new paths, 0 = immediately).\n"
- " a recommended value is 10-60. see docs/README.MOpt\n\n"
-
- "Fuzzing behavior settings:\n"
- " -d - quick & dirty mode (skips deterministic steps)\n"
- " -n - fuzz without instrumentation (dumb mode)\n"
- " -x dir - optional fuzzer dictionary (see README)\n\n"
-
- "Testing settings:\n"
- " -s seed - use a fixed seed for the RNG\n"
- " -V seconds - fuzz for a maximum total time of seconds then terminate\n"
- " -E execs - fuzz for a maximum number of total executions then terminate\n\n"
-
- "Other stuff:\n"
- " -T text - text banner to show on the screen\n"
- " -M / -S id - distributed mode (see parallel_fuzzing.txt)\n"
- " -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap file\n"
- " -C - crash exploration mode (the peruvian rabbit thing)\n"
- " -e ext - File extension for the temporarily generated test case\n\n"
-
- PHYTON_SUPPORT
-
- "For additional tips, please consult %s/README\n\n",
-
- argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
+ SAYF(
+ "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
+
+ "Required parameters:\n"
+ " -i dir - input directory with test cases\n"
+ " -o dir - output directory for fuzzer findings\n\n"
+
+ "Execution control settings:\n"
+ " -p schedule - power schedules recompute a seed's performance "
+ "score.\n"
+ " <explore (default), fast, coe, lin, quad, or "
+ "exploit>\n"
+ " see docs/power_schedules.txt\n"
+ " -f file - location read by the fuzzed program (stdin)\n"
+ " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
+ " -m megs - memory limit for child process (%d MB)\n"
+ " -Q - use binary-only instrumentation (QEMU mode)\n"
+ " -U - use Unicorn-based instrumentation (Unicorn mode)\n\n"
+ " -L minutes - use MOpt(imize) mode and set the limit time for "
+ "entering the\n"
+ " pacemaker mode (minutes of no new paths, 0 = "
+ "immediately).\n"
+ " a recommended value is 10-60. see docs/README.MOpt\n\n"
+
+ "Fuzzing behavior settings:\n"
+ " -d - quick & dirty mode (skips deterministic steps)\n"
+ " -n - fuzz without instrumentation (dumb mode)\n"
+ " -x dir - optional fuzzer dictionary (see README)\n\n"
+
+ "Testing settings:\n"
+ " -s seed - use a fixed seed for the RNG\n"
+ " -V seconds - fuzz for a maximum total time of seconds then "
+ "terminate\n"
+ " -E execs - fuzz for a maximum number of total executions then "
+ "terminate\n\n"
+
+ "Other stuff:\n"
+ " -T text - text banner to show on the screen\n"
+ " -M / -S id - distributed mode (see parallel_fuzzing.txt)\n"
+ " -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap "
+ "file\n"
+ " -C - crash exploration mode (the peruvian rabbit thing)\n"
+ " -e ext - File extension for the temporarily generated test "
+ "case\n\n"
+
+ PHYTON_SUPPORT
+
+ "For additional tips, please consult %s/README\n\n",
+
+ argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
exit(1);
#undef PHYTON_SUPPORT
@@ -82,65 +91,90 @@ static void usage(u8* argv0) {
#ifndef AFL_LIB
-static int stricmp(char const *a, char const *b) {
+static int stricmp(char const* a, char const* b) {
+
for (;; ++a, ++b) {
+
int d;
d = tolower(*a) - tolower(*b);
- if (d != 0 || !*a)
- return d;
+ if (d != 0 || !*a) return d;
+
}
+
}
/* Main entry point */
int main(int argc, char** argv) {
- s32 opt;
- u64 prev_queued = 0;
- u32 sync_interval_cnt = 0, seek_to;
- u8 *extras_dir = 0;
- u8 mem_limit_given = 0;
- u8 exit_1 = !!getenv("AFL_BENCH_JUST_ONE");
+ s32 opt;
+ u64 prev_queued = 0;
+ u32 sync_interval_cnt = 0, seek_to;
+ u8* extras_dir = 0;
+ u8 mem_limit_given = 0;
+ u8 exit_1 = !!getenv("AFL_BENCH_JUST_ONE");
char** use_argv;
- s64 init_seed;
+ s64 init_seed;
- struct timeval tv;
+ struct timeval tv;
struct timezone tz;
- SAYF(cCYA "afl-fuzz" VERSION cRST " based on afl by <lcamtuf@google.com> and a big online community\n");
+ SAYF(cCYA
+ "afl-fuzz" VERSION cRST
+ " based on afl by <lcamtuf@google.com> and a big online community\n");
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
gettimeofday(&tv, &tz);
init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
- while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:QUe:p:s:V:E:L:")) > 0)
+ while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:QUe:p:s:V:E:L:")) >
+ 0)
switch (opt) {
case 's': {
+
init_seed = strtoul(optarg, 0L, 10);
fixed_seed = 1;
break;
+
}
- case 'p': /* Power schedule */
+ case 'p': /* Power schedule */
if (!stricmp(optarg, "fast")) {
+
schedule = FAST;
+
} else if (!stricmp(optarg, "coe")) {
+
schedule = COE;
+
} else if (!stricmp(optarg, "exploit")) {
+
schedule = EXPLOIT;
+
} else if (!stricmp(optarg, "lin")) {
+
schedule = LIN;
+
} else if (!stricmp(optarg, "quad")) {
+
schedule = QUAD;
- } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
+
+ } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
+
+ !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
+
schedule = EXPLORE;
+
} else {
+
FATAL("Unknown -p power schedule");
+
}
+
break;
case 'e':
@@ -151,7 +185,7 @@ int main(int argc, char** argv) {
break;
- case 'i': /* input dir */
+ case 'i': /* input dir */
if (in_dir) FATAL("Multiple -i options not supported");
in_dir = optarg;
@@ -160,115 +194,121 @@ int main(int argc, char** argv) {
break;
- case 'o': /* output dir */
+ case 'o': /* output dir */
if (out_dir) FATAL("Multiple -o options not supported");
out_dir = optarg;
break;
- case 'M': { /* master sync ID */
+ case 'M': { /* master sync ID */
- u8* c;
+ u8* c;
- if (sync_id) FATAL("Multiple -S or -M options not supported");
- sync_id = ck_strdup(optarg);
+ if (sync_id) FATAL("Multiple -S or -M options not supported");
+ sync_id = ck_strdup(optarg);
- if ((c = strchr(sync_id, ':'))) {
+ if ((c = strchr(sync_id, ':'))) {
- *c = 0;
+ *c = 0;
- if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 ||
- !master_id || !master_max || master_id > master_max ||
- master_max > 1000000) FATAL("Bogus master ID passed to -M");
+ if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 ||
+ !master_id || !master_max || master_id > master_max ||
+ master_max > 1000000)
+ FATAL("Bogus master ID passed to -M");
- }
+ }
- force_deterministic = 1;
+ force_deterministic = 1;
- }
+ }
- break;
+ break;
- case 'S':
+ case 'S':
if (sync_id) FATAL("Multiple -S or -M options not supported");
sync_id = ck_strdup(optarg);
break;
- case 'f': /* target file */
+ case 'f': /* target file */
if (out_file) FATAL("Multiple -f options not supported");
out_file = optarg;
break;
- case 'x': /* dictionary */
+ case 'x': /* dictionary */
if (extras_dir) FATAL("Multiple -x options not supported");
extras_dir = optarg;
break;
- case 't': { /* timeout */
+ case 't': { /* timeout */
- u8 suffix = 0;
+ u8 suffix = 0;
- if (timeout_given) FATAL("Multiple -t options not supported");
+ if (timeout_given) FATAL("Multiple -t options not supported");
- if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 ||
- optarg[0] == '-') FATAL("Bad syntax used for -t");
+ if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 ||
+ optarg[0] == '-')
+ FATAL("Bad syntax used for -t");
- if (exec_tmout < 5) FATAL("Dangerously low value of -t");
+ if (exec_tmout < 5) FATAL("Dangerously low value of -t");
- if (suffix == '+') timeout_given = 2; else timeout_given = 1;
+ if (suffix == '+')
+ timeout_given = 2;
+ else
+ timeout_given = 1;
- break;
+ break;
}
- case 'm': { /* mem limit */
+ case 'm': { /* mem limit */
- u8 suffix = 'M';
+ u8 suffix = 'M';
- if (mem_limit_given) FATAL("Multiple -m options not supported");
- mem_limit_given = 1;
+ if (mem_limit_given) FATAL("Multiple -m options not supported");
+ mem_limit_given = 1;
- if (!strcmp(optarg, "none")) {
+ if (!strcmp(optarg, "none")) {
- mem_limit = 0;
- break;
+ mem_limit = 0;
+ break;
- }
+ }
- if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
- optarg[0] == '-') FATAL("Bad syntax used for -m");
+ if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
+ optarg[0] == '-')
+ FATAL("Bad syntax used for -m");
- switch (suffix) {
+ switch (suffix) {
- case 'T': mem_limit *= 1024 * 1024; break;
- case 'G': mem_limit *= 1024; break;
- case 'k': mem_limit /= 1024; break;
- case 'M': break;
+ case 'T': mem_limit *= 1024 * 1024; break;
+ case 'G': mem_limit *= 1024; break;
+ case 'k': mem_limit /= 1024; break;
+ case 'M': break;
- default: FATAL("Unsupported suffix or bad syntax for -m");
+ default: FATAL("Unsupported suffix or bad syntax for -m");
- }
+ }
- if (mem_limit < 5) FATAL("Dangerously low value of -m");
+ if (mem_limit < 5) FATAL("Dangerously low value of -m");
- if (sizeof(rlim_t) == 4 && mem_limit > 2000)
- FATAL("Value of -m out of range on 32-bit systems");
+ if (sizeof(rlim_t) == 4 && mem_limit > 2000)
+ FATAL("Value of -m out of range on 32-bit systems");
- }
+ }
- break;
+ break;
- case 'd': /* skip deterministic */
+ case 'd': /* skip deterministic */
if (skip_deterministic) FATAL("Multiple -d options not supported");
skip_deterministic = 1;
use_splicing = 1;
break;
- case 'B': /* load bitmap */
+ case 'B': /* load bitmap */
/* This is a secret undocumented option! It is useful if you find
an interesting test case during a normal fuzzing process, and want
@@ -287,26 +327,29 @@ int main(int argc, char** argv) {
read_bitmap(in_bitmap);
break;
- case 'C': /* crash mode */
+ case 'C': /* crash mode */
if (crash_mode) FATAL("Multiple -C options not supported");
crash_mode = FAULT_CRASH;
break;
- case 'n': /* dumb mode */
+ case 'n': /* dumb mode */
if (dumb_mode) FATAL("Multiple -n options not supported");
- if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2; else dumb_mode = 1;
+ if (getenv("AFL_DUMB_FORKSRV"))
+ dumb_mode = 2;
+ else
+ dumb_mode = 1;
break;
- case 'T': /* banner */
+ case 'T': /* banner */
if (use_banner) FATAL("Multiple -T options not supported");
use_banner = optarg;
break;
- case 'Q': /* QEMU mode */
+ case 'Q': /* QEMU mode */
if (qemu_mode) FATAL("Multiple -Q options not supported");
qemu_mode = 1;
@@ -315,7 +358,7 @@ int main(int argc, char** argv) {
break;
- case 'U': /* Unicorn mode */
+ case 'U': /* Unicorn mode */
if (unicorn_mode) FATAL("Multiple -U options not supported");
unicorn_mode = 1;
@@ -325,115 +368,132 @@ int main(int argc, char** argv) {
break;
case 'V': {
- most_time_key = 1;
- if (sscanf(optarg, "%llu", &most_time) < 1 || optarg[0] == '-')
- FATAL("Bad syntax used for -V");
- }
- break;
+
+ most_time_key = 1;
+ if (sscanf(optarg, "%llu", &most_time) < 1 || optarg[0] == '-')
+ FATAL("Bad syntax used for -V");
+
+ } break;
case 'E': {
- most_execs_key = 1;
- if (sscanf(optarg, "%llu", &most_execs) < 1 || optarg[0] == '-')
- FATAL("Bad syntax used for -E");
- }
- break;
- case 'L': { /* MOpt mode */
+ most_execs_key = 1;
+ if (sscanf(optarg, "%llu", &most_execs) < 1 || optarg[0] == '-')
+ FATAL("Bad syntax used for -E");
- if (limit_time_sig) FATAL("Multiple -L options not supported");
- limit_time_sig = 1;
- havoc_max_mult = HAVOC_MAX_MULT_MOPT;
+ } break;
- if (sscanf(optarg, "%llu", &limit_time_puppet) < 1 ||
- optarg[0] == '-') FATAL("Bad syntax used for -L");
+ case 'L': { /* MOpt mode */
- u64 limit_time_puppet2 = limit_time_puppet * 60 * 1000;
+ if (limit_time_sig) FATAL("Multiple -L options not supported");
+ limit_time_sig = 1;
+ havoc_max_mult = HAVOC_MAX_MULT_MOPT;
- if (limit_time_puppet2 < limit_time_puppet ) FATAL("limit_time overflow");
- limit_time_puppet = limit_time_puppet2;
+ if (sscanf(optarg, "%llu", &limit_time_puppet) < 1 || optarg[0] == '-')
+ FATAL("Bad syntax used for -L");
- SAYF("limit_time_puppet %llu\n",limit_time_puppet);
- swarm_now = 0;
+ u64 limit_time_puppet2 = limit_time_puppet * 60 * 1000;
- if (limit_time_puppet == 0 )
- key_puppet = 1;
+ if (limit_time_puppet2 < limit_time_puppet)
+ FATAL("limit_time overflow");
+ limit_time_puppet = limit_time_puppet2;
- int i;
- int tmp_swarm = 0;
+ SAYF("limit_time_puppet %llu\n", limit_time_puppet);
+ swarm_now = 0;
- if (g_now > g_max) g_now = 0;
- w_now = (w_init - w_end)*(g_max - g_now) / (g_max)+w_end;
+ if (limit_time_puppet == 0) key_puppet = 1;
- for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) {
- double total_puppet_temp = 0.0;
- swarm_fitness[tmp_swarm] = 0.0;
+ int i;
+ int tmp_swarm = 0;
- for (i = 0; i < operator_num; ++i) {
- stage_finds_puppet[tmp_swarm][i] = 0;
- probability_now[tmp_swarm][i] = 0.0;
- x_now[tmp_swarm][i] = ((double)(random() % 7000)*0.0001 + 0.1);
- total_puppet_temp += x_now[tmp_swarm][i];
- v_now[tmp_swarm][i] = 0.1;
- L_best[tmp_swarm][i] = 0.5;
- G_best[i] = 0.5;
- eff_best[tmp_swarm][i] = 0.0;
+ if (g_now > g_max) g_now = 0;
+ w_now = (w_init - w_end) * (g_max - g_now) / (g_max) + w_end;
- }
+ for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) {
- for (i = 0; i < operator_num; ++i) {
- stage_cycles_puppet_v2[tmp_swarm][i] = stage_cycles_puppet[tmp_swarm][i];
- stage_finds_puppet_v2[tmp_swarm][i] = stage_finds_puppet[tmp_swarm][i];
- x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / total_puppet_temp;
- }
+ double total_puppet_temp = 0.0;
+ swarm_fitness[tmp_swarm] = 0.0;
- double x_temp = 0.0;
+ for (i = 0; i < operator_num; ++i) {
- for (i = 0; i < operator_num; ++i) {
- probability_now[tmp_swarm][i] = 0.0;
- v_now[tmp_swarm][i] = w_now * v_now[tmp_swarm][i] + RAND_C * (L_best[tmp_swarm][i] - x_now[tmp_swarm][i]) + RAND_C * (G_best[i] - x_now[tmp_swarm][i]);
+ stage_finds_puppet[tmp_swarm][i] = 0;
+ probability_now[tmp_swarm][i] = 0.0;
+ x_now[tmp_swarm][i] = ((double)(random() % 7000) * 0.0001 + 0.1);
+ total_puppet_temp += x_now[tmp_swarm][i];
+ v_now[tmp_swarm][i] = 0.1;
+ L_best[tmp_swarm][i] = 0.5;
+ G_best[i] = 0.5;
+ eff_best[tmp_swarm][i] = 0.0;
- x_now[tmp_swarm][i] += v_now[tmp_swarm][i];
+ }
+
+ for (i = 0; i < operator_num; ++i) {
+
+ stage_cycles_puppet_v2[tmp_swarm][i] =
+ stage_cycles_puppet[tmp_swarm][i];
+ stage_finds_puppet_v2[tmp_swarm][i] =
+ stage_finds_puppet[tmp_swarm][i];
+ x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / total_puppet_temp;
+
+ }
+
+ double x_temp = 0.0;
+
+ for (i = 0; i < operator_num; ++i) {
- if (x_now[tmp_swarm][i] > v_max)
- x_now[tmp_swarm][i] = v_max;
- else if (x_now[tmp_swarm][i] < v_min)
- x_now[tmp_swarm][i] = v_min;
+ probability_now[tmp_swarm][i] = 0.0;
+ v_now[tmp_swarm][i] =
+ w_now * v_now[tmp_swarm][i] +
+ RAND_C * (L_best[tmp_swarm][i] - x_now[tmp_swarm][i]) +
+ RAND_C * (G_best[i] - x_now[tmp_swarm][i]);
- x_temp += x_now[tmp_swarm][i];
- }
+ x_now[tmp_swarm][i] += v_now[tmp_swarm][i];
- for (i = 0; i < operator_num; ++i) {
- x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / x_temp;
- if (likely(i != 0))
- probability_now[tmp_swarm][i] = probability_now[tmp_swarm][i - 1] + x_now[tmp_swarm][i];
- else
- probability_now[tmp_swarm][i] = x_now[tmp_swarm][i];
- }
- if (probability_now[tmp_swarm][operator_num - 1] < 0.99 || probability_now[tmp_swarm][operator_num - 1] > 1.01)
- FATAL("ERROR probability");
- }
+ if (x_now[tmp_swarm][i] > v_max)
+ x_now[tmp_swarm][i] = v_max;
+ else if (x_now[tmp_swarm][i] < v_min)
+ x_now[tmp_swarm][i] = v_min;
+
+ x_temp += x_now[tmp_swarm][i];
+
+ }
+
+ for (i = 0; i < operator_num; ++i) {
+
+ x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / x_temp;
+ if (likely(i != 0))
+ probability_now[tmp_swarm][i] =
+ probability_now[tmp_swarm][i - 1] + x_now[tmp_swarm][i];
+ else
+ probability_now[tmp_swarm][i] = x_now[tmp_swarm][i];
+
+ }
- for (i = 0; i < operator_num; ++i) {
- core_operator_finds_puppet[i] = 0;
- core_operator_finds_puppet_v2[i] = 0;
- core_operator_cycles_puppet[i] = 0;
- core_operator_cycles_puppet_v2[i] = 0;
- core_operator_cycles_puppet_v3[i] = 0;
- }
+ if (probability_now[tmp_swarm][operator_num - 1] < 0.99 ||
+ probability_now[tmp_swarm][operator_num - 1] > 1.01)
+ FATAL("ERROR probability");
+
+ }
+
+ for (i = 0; i < operator_num; ++i) {
+
+ core_operator_finds_puppet[i] = 0;
+ core_operator_finds_puppet_v2[i] = 0;
+ core_operator_cycles_puppet[i] = 0;
+ core_operator_cycles_puppet_v2[i] = 0;
+ core_operator_cycles_puppet_v3[i] = 0;
}
- break;
- default:
+ } break;
- usage(argv[0]);
+ default: usage(argv[0]);
}
if (optind == argc || !in_dir || !out_dir) usage(argv[0]);
- if (fixed_seed)
- OKF("Running with fixed seed: %u", (u32)init_seed);
+ if (fixed_seed) OKF("Running with fixed seed: %u", (u32)init_seed);
srandom((u32)init_seed);
setup_signal_handlers();
check_asan_opts();
@@ -446,28 +506,39 @@ int main(int argc, char** argv) {
FATAL("Input and output directories can't be the same");
if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL) {
+
char tmpfile[strlen(tmp_dir + 16)];
sprintf(tmpfile, "%s/%s", tmp_dir, ".cur_input");
- if (access(tmpfile, F_OK) != -1) // there is still a race condition here, but well ...
- FATAL("TMP_DIR already has an existing temporary input file: %s", tmpfile);
+ if (access(tmpfile, F_OK) !=
+ -1) // there is still a race condition here, but well ...
+ FATAL("TMP_DIR already has an existing temporary input file: %s",
+ tmpfile);
+
} else
+
tmp_dir = out_dir;
if (dumb_mode) {
if (crash_mode) FATAL("-C and -n are mutually exclusive");
- if (qemu_mode) FATAL("-Q and -n are mutually exclusive");
+ if (qemu_mode) FATAL("-Q and -n are mutually exclusive");
if (unicorn_mode) FATAL("-U and -n are mutually exclusive");
}
-
+
if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI"))
FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive");
-
- if (strchr(argv[optind], '/') == NULL) WARNF(cLRD "Target binary called without a prefixed path, make sure you are fuzzing the right binary: " cRST "%s", argv[optind]);
- OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" Eissfeldt and Andrea Fioraldi");
- OKF("afl++ is open source, get it at https://github.com/vanhauser-thc/AFLplusplus");
+ if (strchr(argv[optind], '/') == NULL)
+ WARNF(cLRD
+ "Target binary called without a prefixed path, make sure you are "
+ "fuzzing the right binary: " cRST "%s",
+ argv[optind]);
+
+ OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
+ "Eissfeldt and Andrea Fioraldi");
+ OKF("afl++ is open source, get it at "
+ "https://github.com/vanhauser-thc/AFLplusplus");
OKF("Power schedules from github.com/mboehme/aflfast");
OKF("Python Mutator and llvm_mode whitelisting from github.com/choller/afl");
OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL");
@@ -475,32 +546,42 @@ int main(int argc, char** argv) {
ACTF("Getting to work...");
switch (schedule) {
- case FAST: OKF ("Using exponential power schedule (FAST)"); break;
- case COE: OKF ("Using cut-off exponential power schedule (COE)"); break;
- case EXPLOIT: OKF ("Using exploitation-based constant power schedule (EXPLOIT)"); break;
- case LIN: OKF ("Using linear power schedule (LIN)"); break;
- case QUAD: OKF ("Using quadratic power schedule (QUAD)"); break;
- case EXPLORE: OKF ("Using exploration-based constant power schedule (EXPLORE)"); break;
- default : FATAL ("Unknown power schedule"); break;
+
+ case FAST: OKF("Using exponential power schedule (FAST)"); break;
+ case COE: OKF("Using cut-off exponential power schedule (COE)"); break;
+ case EXPLOIT:
+ OKF("Using exploitation-based constant power schedule (EXPLOIT)");
+ break;
+ case LIN: OKF("Using linear power schedule (LIN)"); break;
+ case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
+ case EXPLORE:
+ OKF("Using exploration-based constant power schedule (EXPLORE)");
+ break;
+ default: FATAL("Unknown power schedule"); break;
+
}
- if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
- if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;
- if (getenv("AFL_NO_ARITH")) no_arith = 1;
- if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1;
- if (getenv("AFL_FAST_CAL")) fast_cal = 1;
+ if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
+ if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;
+ if (getenv("AFL_NO_ARITH")) no_arith = 1;
+ if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1;
+ if (getenv("AFL_FAST_CAL")) fast_cal = 1;
if (getenv("AFL_HANG_TMOUT")) {
+
hang_tmout = atoi(getenv("AFL_HANG_TMOUT"));
if (!hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT");
+
}
if (dumb_mode == 2 && no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
if (getenv("AFL_PRELOAD")) {
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
+
}
if (getenv("AFL_LD_PRELOAD"))
@@ -511,31 +592,33 @@ int main(int argc, char** argv) {
fix_up_banner(argv[optind]);
check_if_tty();
- if (getenv("AFL_FORCE_UI"))
- not_on_tty = 0;
+ if (getenv("AFL_FORCE_UI")) not_on_tty = 0;
if (getenv("AFL_CAL_FAST")) {
+
/* Use less calibration cycles, for slow applications */
cal_cycles = 3;
cal_cycles_long = 5;
+
}
- if (getenv("AFL_DEBUG"))
- debug = 1;
+ if (getenv("AFL_DEBUG")) debug = 1;
if (getenv("AFL_PYTHON_ONLY")) {
+
/* This ensures we don't proceed to havoc/splice */
python_only = 1;
/* Ensure we also skip all deterministic steps */
skip_deterministic = 1;
+
}
get_core_count();
-#ifdef HAVE_AFFINITY
+# ifdef HAVE_AFFINITY
bind_to_free_cpu();
-#endif /* HAVE_AFFINITY */
+# endif /* HAVE_AFFINITY */
check_crash_handling();
check_cpu_governor();
@@ -552,13 +635,12 @@ int main(int argc, char** argv) {
setup_dirs_fds();
-#ifdef USE_PYTHON
- if (init_py())
- FATAL("Failed to initialize Python module");
-#else
+# ifdef USE_PYTHON
+ if (init_py()) FATAL("Failed to initialize Python module");
+# else
if (getenv("AFL_PYTHON_MODULE"))
- FATAL("Your AFL binary was built without Python support");
-#endif
+ FATAL("Your AFL binary was built without Python support");
+# endif
setup_cmdline_file(argv + optind);
@@ -574,24 +656,33 @@ int main(int argc, char** argv) {
/* If we don't have a file name chosen yet, use a safe default. */
if (!out_file) {
+
u32 i = optind + 1;
while (argv[i]) {
u8* aa_loc = strstr(argv[i], "@@");
if (aa_loc && !out_file) {
+
if (file_extension) {
+
out_file = alloc_printf("%s/.cur_input.%s", out_dir, file_extension);
+
} else {
+
out_file = alloc_printf("%s/.cur_input", out_dir);
+
}
+
detect_file_args(argv + optind + 1, out_file);
- break;
+ break;
+
}
++i;
}
+
}
if (!out_file) setup_stdio_file();
@@ -621,9 +712,11 @@ int main(int argc, char** argv) {
/* Woop woop woop */
if (!not_on_tty) {
+
sleep(4);
start_time += 4000;
if (stop_soon) goto stop_fuzzing;
+
}
// real start time, we reset, so this works correctly with -V
@@ -638,21 +731,25 @@ int main(int argc, char** argv) {
if (!queue_cur) {
++queue_cycle;
- current_entry = 0;
+ current_entry = 0;
cur_skipped_paths = 0;
- queue_cur = queue;
+ queue_cur = queue;
while (seek_to) {
+
++current_entry;
--seek_to;
queue_cur = queue_cur->next;
+
}
show_stats();
if (not_on_tty) {
+
ACTF("Entering queue cycle %llu.", queue_cycle);
fflush(stdout);
+
}
/* If we had a full queue cycle with no new finds, try
@@ -660,9 +757,14 @@ int main(int argc, char** argv) {
if (queued_paths == prev_queued) {
- if (use_splicing) ++cycles_wo_finds; else use_splicing = 1;
+ if (use_splicing)
+ ++cycles_wo_finds;
+ else
+ use_splicing = 1;
- } else cycles_wo_finds = 0;
+ } else
+
+ cycles_wo_finds = 0;
prev_queued = queued_paths;
@@ -674,9 +776,8 @@ int main(int argc, char** argv) {
skipped_fuzz = fuzz_one(use_argv);
if (!stop_soon && sync_id && !skipped_fuzz) {
-
- if (!(sync_interval_cnt++ % SYNC_INTERVAL))
- sync_fuzzers(use_argv);
+
+ if (!(sync_interval_cnt++ % SYNC_INTERVAL)) sync_fuzzers(use_argv);
}
@@ -688,18 +789,28 @@ int main(int argc, char** argv) {
++current_entry;
if (most_time_key == 1) {
+
u64 cur_ms_lv = get_cur_time();
- if (most_time * 1000 < cur_ms_lv - start_time) {
+ if (most_time * 1000 < cur_ms_lv - start_time) {
+
most_time_key = 2;
break;
+
}
+
}
+
if (most_execs_key == 1) {
+
if (most_execs <= total_execs) {
+
most_execs_key = 2;
break;
+
}
+
}
+
}
if (queue_cur) show_stats();
@@ -708,19 +819,20 @@ int main(int argc, char** argv) {
* ATTENTION - the following 10 lines were copied from a PR to Google's afl
* repository - and slightly fixed.
* These lines have nothing to do with the purpose of original PR though.
- * Looks like when an exit condition was completed (AFL_BENCH_JUST_ONE,
+ * Looks like when an exit condition was completed (AFL_BENCH_JUST_ONE,
* AFL_EXIT_WHEN_DONE or AFL_BENCH_UNTIL_CRASH) the child and forkserver
* where not killed?
*/
- /* if we stopped programmatically, we kill the forkserver and the current runner.
- if we stopped manually, this is done by the signal handler */
- if (stop_soon == 2){
+ /* if we stopped programmatically, we kill the forkserver and the current
+ runner. if we stopped manually, this is done by the signal handler */
+ if (stop_soon == 2) {
+
if (child_pid > 0) kill(child_pid, SIGKILL);
if (forksrv_pid > 0) kill(forksrv_pid, SIGKILL);
- /* Now that we've killed the forkserver, we wait for it to be able to get rusage stats. */
- if (waitpid(forksrv_pid, NULL, 0) <= 0) {
- WARNF("error waitpid\n");
- }
+ /* Now that we've killed the forkserver, we wait for it to be able to get
+ * rusage stats. */
+ if (waitpid(forksrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
+
}
write_bitmap();
@@ -732,8 +844,7 @@ stop_fuzzing:
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
stop_soon == 2 ? "programmatically" : "by user");
- if (most_time_key == 2)
- SAYF(cYEL "[!] " cRST "Time limit was reached\n");
+ if (most_time_key == 2) SAYF(cYEL "[!] " cRST "Time limit was reached\n");
if (most_execs_key == 2)
SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
@@ -742,8 +853,9 @@ stop_fuzzing:
if (queue_cycle == 1 && get_cur_time() - start_time > 30 * 60 * 1000) {
SAYF("\n" cYEL "[!] " cRST
- "Stopped during the first cycle, results may be incomplete.\n"
- " (For info on resuming, see %s/README)\n", doc_path);
+ "Stopped during the first cycle, results may be incomplete.\n"
+ " (For info on resuming, see %s/README)\n",
+ doc_path);
}
@@ -755,9 +867,9 @@ stop_fuzzing:
alloc_report();
-#ifdef USE_PYTHON
+# ifdef USE_PYTHON
finalize_py();
-#endif
+# endif
OKF("We're done here. Have a nice day!\n");
@@ -766,3 +878,4 @@ stop_fuzzing:
}
#endif /* !AFL_LIB */
+