afl-tmin hang mode added

This commit is contained in:
Dominik Maier
2020-03-07 03:37:32 +01:00
parent 2287534ec6
commit 1e30c3a941
3 changed files with 82 additions and 11 deletions

View File

@ -16,6 +16,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- afl-fuzz basic tools now report on the environment variables picked up - afl-fuzz basic tools now report on the environment variables picked up
- more tools get environment variable usage info in the help output - more tools get environment variable usage info in the help output
- AFL_AUTORESUME will resume execution without the need to specify `-i -` - AFL_AUTORESUME will resume execution without the need to specify `-i -`
- afl-tmin now supports hang mode `-H` to minimize hangs
- fixed potential afl-tmin missbehavior for targets with multiple hangs
### Version ++2.62c (release): ### Version ++2.62c (release):

View File

@ -286,8 +286,9 @@ operation of `afl-tmin` is as follows.
First, the tool automatically selects the operating mode. If the initial input First, the tool automatically selects the operating mode. If the initial input
crashes the target binary, afl-tmin will run in non-instrumented mode, simply crashes the target binary, afl-tmin will run in non-instrumented mode, simply
keeping any tweaks that produce a simpler file but still crash the target. If keeping any tweaks that produce a simpler file but still crash the target.
the target is non-crashing, the tool uses an instrumented mode and keeps only The same mode is used for hangs, if `-H` (hang mode) is specified.
If the target is non-crashing, the tool uses an instrumented mode and keeps only
the tweaks that produce exactly the same execution path. the tweaks that produce exactly the same execution path.
The actual minimization algorithm is: The actual minimization algorithm is:

View File

@ -89,6 +89,7 @@ u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
s32 dev_null_fd = -1; /* FD to /dev/null */ s32 dev_null_fd = -1; /* FD to /dev/null */
u8 crash_mode, /* Crash-centric mode? */ u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */
exit_crash, /* Treat non-zero exit as crash? */ exit_crash, /* Treat non-zero exit as crash? */
edges_only, /* Ignore hit counts? */ edges_only, /* Ignore hit counts? */
exact_mode, /* Require path match for crashes? */ exact_mode, /* Require path match for crashes? */
@ -98,6 +99,7 @@ static volatile u8 stop_soon; /* Ctrl-C pressed? */
static u8 qemu_mode; static u8 qemu_mode;
/* /*
* forkserver section * forkserver section
*/ */
@ -427,6 +429,8 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
u32 cksum; u32 cksum;
child_timed_out = 0;
memset(trace_bits, 0, MAP_SIZE); memset(trace_bits, 0, MAP_SIZE);
MEM_BARRIER(); MEM_BARRIER();
@ -484,8 +488,13 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
if (*(u32*)trace_bits == EXEC_FAIL_SIG) if (*(u32*)trace_bits == EXEC_FAIL_SIG)
FATAL("Unable to execute '%s'", argv[0]); FATAL("Unable to execute '%s'", argv[0]);
classify_counts(trace_bits); if (!hang_mode) {
apply_mask((u32*)trace_bits, (u32*)mask_bitmap);
classify_counts(trace_bits);
apply_mask((u32*)trace_bits, (u32*)mask_bitmap);
}
total_execs++; total_execs++;
if (stop_soon) { if (stop_soon) {
@ -496,7 +505,27 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
} }
/* Always discard inputs that time out. */ /* Always discard inputs that time out, unless we are in hang mode */
if (hang_mode) {
if (child_timed_out) return 1;
if (WIFSIGNALED(status) ||
(WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) ||
(WIFEXITED(status) && WEXITSTATUS(status) && exit_crash)) {
missed_crashes++;
} else {
missed_hangs++;
}
return 0;
}
if (child_timed_out) { if (child_timed_out) {
@ -504,7 +533,7 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
return 0; return 0;
} }
/* Handle crashing inputs depending on current mode. */ /* Handle crashing inputs depending on current mode. */
if (WIFSIGNALED(status) || if (WIFSIGNALED(status) ||
@ -791,6 +820,19 @@ next_del_blksize:
finalize_all: finalize_all:
if (hang_mode) {
SAYF("\n" cGRA " File size reduced by : " cRST
"%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST
"%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA
" Fruitless execs : " cRST "termination=%u crash=%u\n\n",
100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? "" : "s",
((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs,
missed_paths, missed_crashes);
return;
}
SAYF("\n" cGRA " File size reduced by : " cRST SAYF("\n" cGRA " File size reduced by : " cRST
"%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST "%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST
"%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA "%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA
@ -799,7 +841,7 @@ finalize_all:
((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs, ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs,
missed_paths, missed_crashes, missed_hangs ? cLRD : "", missed_hangs); missed_paths, missed_crashes, missed_hangs ? cLRD : "", missed_hangs);
if (total_execs > 50 && missed_hangs * 10 > total_execs) if (total_execs > 50 && missed_hangs * 10 > total_execs && !hang_mode)
WARNF(cLRD "Frequent timeouts - results may be skewed." cRST); WARNF(cLRD "Frequent timeouts - results may be skewed." cRST);
} }
@ -978,6 +1020,7 @@ static void usage(u8* argv0) {
" -e - solve for edge coverage only, ignore hit counts\n" " -e - solve for edge coverage only, ignore hit counts\n"
" -x - treat non-zero exit codes as crashes\n\n" " -x - treat non-zero exit codes as crashes\n\n"
" -H - minimize a hang (hang mode)\n"
"For additional tips, please consult %s/README.md.\n\n" "For additional tips, please consult %s/README.md.\n\n"
@ -1077,7 +1120,7 @@ int main(int argc, char** argv, char** envp) {
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeQUWh")) > 0) while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeQUWHh")) > 0)
switch (opt) { switch (opt) {
@ -1103,6 +1146,7 @@ int main(int argc, char** argv, char** envp) {
case 'e': case 'e':
if (edges_only) FATAL("Multiple -e options not supported"); if (edges_only) FATAL("Multiple -e options not supported");
if (hang_mode) FATAL("Edges only and hang mode are mutually exclusive.");
edges_only = 1; edges_only = 1;
break; break;
@ -1188,6 +1232,15 @@ int main(int argc, char** argv, char** envp) {
break; break;
case 'H': /* Hang Mode */
/* Minimizes a testcase to the minimum that still times out */
if (hang_mode) FATAL("Multipe -H options not supported");
if (edges_only) FATAL("Edges only and hang mode are mutually exclusive.");
hang_mode = 1;
break;
case 'B': /* load bitmap */ case 'B': /* load bitmap */
/* This is a secret undocumented option! It is speculated to be useful /* This is a secret undocumented option! It is speculated to be useful
@ -1242,6 +1295,13 @@ int main(int argc, char** argv, char** envp) {
exact_mode = !!get_afl_env("AFL_TMIN_EXACT"); exact_mode = !!get_afl_env("AFL_TMIN_EXACT");
if (hang_mode && exact_mode) {
SAYF("AFL_TMIN_EXACT won't work for loops in hang mode, ignoring.");
exact_mode = 0;
}
SAYF("\n"); SAYF("\n");
read_initial_file(); read_initial_file();
@ -1253,10 +1313,18 @@ int main(int argc, char** argv, char** envp) {
run_target(use_argv, in_data, in_len, 1); run_target(use_argv, in_data, in_len, 1);
if (child_timed_out) if (hang_mode && !child_timed_out)
FATAL("Target binary times out (adjusting -t may help)."); FATAL("Target binary did not time out but hang minimization mode "
"(-H) was set (-t %u).", exec_tmout);
if (!crash_mode) { if (child_timed_out && !hang_mode)
FATAL("Target binary times out (adjusting -t may help). Use -H to minimize a hang.");
if (hang_mode) {
OKF("Program hangs as expected, minimizing in " cCYA "hang" cRST " mode.");
} else if (!crash_mode) {
OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST
" mode."); " mode.");