From 8c228b0d23e303499dccf3df77c5d0b3a8b59b7b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 24 Apr 2023 18:08:27 +0200 Subject: afl-showmap -I option --- src/afl-showmap.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 154 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 0b9fc211..09a1d2dc 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -69,7 +69,9 @@ static afl_state_t *afl; static char *stdin_file; /* stdin file */ static u8 *in_dir = NULL, /* input folder */ - *out_file = NULL, *at_file = NULL; /* Substitution string for @@ */ + *out_file = NULL, /* output file or directory */ + *at_file = NULL, /* Substitution string for @@ */ + *in_filelist = NULL; /* input file list */ static u8 outfile[PATH_MAX]; @@ -878,6 +880,104 @@ u32 execute_testcases(u8 *dir) { } +u32 execute_testcases_filelist(u8 *fn) { + + u32 done = 0; + u8 buf[4096]; + u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; + FILE *f; + + if (!be_quiet) { ACTF("Reading from '%s'...", fn); } + + if ((f = fopen(fn, "r")) == NULL) { FATAL("could not open '%s'", fn); } + + while (fgets(buf, sizeof(buf), f) != NULL) { + + struct stat st; + + u8 *fn2 = buf, *fn3; + ; + + while (*fn2 == ' ') { + + ++fn2; + + } + + if (*fn2) { + + while (fn2[strlen(fn2) - 1] == '\r' || fn2[strlen(fn2) - 1] == '\n' || + fn2[strlen(fn2) - 1] == ' ') { + + fn2[strlen(fn2) - 1] = 0; + + } + + } + + if (debug) { printf("Getting coverage for '%s'\n", fn2); } + + if (!*fn2) { continue; } + + if (lstat(fn2, &st) || access(fn2, R_OK)) { + + WARNF("Unable to access '%s'", fn2); + continue; + + } + + if (!S_ISREG(st.st_mode) || !st.st_size) { continue; } + + if ((fn3 = strrchr(fn2, '/'))) { + + ++fn3; + + } else { + + fn3 = fn2; + + } + + 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, fn3); + + 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 (child_crashed && debug) { WARNF("crashed: %s", fn2); } + + if (collect_coverage) + analyze_results(fsrv); + else + tcnt = write_results_to_file(fsrv, outfile); + + } + + } + + return done; + +} + /* Show banner. */ static void show_banner(void) { @@ -920,6 +1020,7 @@ static void usage(u8 *argv0) { " With -C, -o is a file, without -C it must be a " "directory\n" " and each bitmap will be written there individually.\n" + " -I filelist - alternatively to -i, -I is a list of files\n" " -C - collect coverage, writes all edges to -o and gives a " "summary\n" " Must be combined with -i.\n" @@ -932,7 +1033,7 @@ static void usage(u8 *argv0) { "This tool displays raw tuple data captured by AFL instrumentation.\n" "For additional help, consult %s/README.md.\n\n" - "If you use -i mode, then custom mutator post_process send send " + "If you use -i/-I mode, then custom mutator post_process send send " "functionality\n" "is supported.\n\n" @@ -994,7 +1095,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) { + while ((opt = getopt(argc, argv, "+i:I:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) { switch (opt) { @@ -1012,6 +1113,11 @@ int main(int argc, char **argv_orig, char **envp) { in_dir = optarg; break; + case 'I': + if (in_filelist) { FATAL("Multiple -I options not supported"); } + in_filelist = optarg; + break; + case 'o': if (out_file) { FATAL("Multiple -o options not supported"); } @@ -1234,10 +1340,12 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !out_file) { usage(argv[0]); } - if (in_dir) { + if (in_dir && in_filelist) { FATAL("you can only specify either -i or -I"); } + + if (in_dir || in_filelist) { if (!out_file && !collect_coverage) - FATAL("for -i you need to specify either -C and/or -o"); + FATAL("for -i/-I you need to specify either -C and/or -o"); } @@ -1294,7 +1402,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (in_dir) { + if (in_dir || in_filelist) { /* If we don't have a file name chosen yet, use a safe default. */ u8 *use_dir = "."; @@ -1400,7 +1508,7 @@ int main(int argc, char **argv_orig, char **envp) { } #ifdef __linux__ - if (!fsrv->nyx_mode && in_dir) { + if (!fsrv->nyx_mode && (in_dir || in_filelist)) { (void)check_binary_signatures(fsrv->target_path); @@ -1483,7 +1591,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (in_dir) { + if (in_dir || in_filelist) { afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); afl->afl_env.afl_custom_mutator_library = @@ -1496,33 +1604,46 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_CUSTOM_MUTATOR_LIBRARY") || getenv("AFL_PYTHON_MODULE")) { WARNF( - "Custom mutator environment detected, this is only supported in -i " - "mode!\n"); + "Custom mutator environment detected, this is only supported in " + "-i/-I mode!\n"); } } - if (in_dir) { + if (in_dir || in_filelist) { DIR *dir_in, *dir_out = NULL; + u8 *dn = NULL; if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true; fsrv->dev_null_fd = open("/dev/null", O_RDWR); if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } - // if a queue subdirectory exists switch to that - u8 *dn = alloc_printf("%s/queue", in_dir); - if ((dir_in = opendir(dn)) != NULL) { + if (in_filelist) { + + if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist); + + } else { + + // if a queue subdirectory exists switch to that + dn = alloc_printf("%s/queue", in_dir); + + if ((dir_in = opendir(dn)) != NULL) { + + closedir(dir_in); + in_dir = dn; + + } else { + + ck_free(dn); - closedir(dir_in); - in_dir = dn; + } - } else + if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir); - ck_free(dn); - if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir); + } if (!collect_coverage) { @@ -1576,9 +1697,21 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - if (execute_testcases(in_dir) == 0) { + if (in_dir) { + + if (execute_testcases(in_dir) == 0) { + + FATAL("could not read input testcases from %s", in_dir); + + } + + } else { - FATAL("could not read input testcases from %s", in_dir); + if (execute_testcases_filelist(in_filelist) == 0) { + + FATAL("could not read input testcases from %s", in_filelist); + + } } -- cgit 1.4.1 From 7c3c0b26d1ae477fbae6944c0de18256621e1993 Mon Sep 17 00:00:00 2001 From: Keno Hassler <40292329+kenohassler@users.noreply.github.com> Date: Mon, 24 Apr 2023 20:21:54 +0200 Subject: document new env var --- docs/env_variables.md | 6 ++++-- src/afl-cc.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/docs/env_variables.md b/docs/env_variables.md index c5995d13..087ccdb7 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -156,7 +156,7 @@ Available options: - LTO - LTO instrumentation - NATIVE - clang's original pcguard based instrumentation - NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16) - - PCGUARD - our own pcgard based instrumentation (default) + - PCGUARD - our own pcguard based instrumentation (default) #### CMPLOG @@ -240,7 +240,9 @@ combined. the default `0x10000`. A value of 0 or empty sets the map address to be dynamic (the original AFL way, which is slower). - `AFL_LLVM_MAP_DYNAMIC` sets the shared memory address to be dynamic. - + - `AFL_LLVM_LTO_SKIPINIT` skips adding initialization code. Some global vars + (e.g. the highest location ID) are not injected. Needed to instrument with + [WAFL](https://github.com/fgsect/WAFL.git). For more information, see [instrumentation/README.lto.md](../instrumentation/README.lto.md). diff --git a/src/afl-cc.c b/src/afl-cc.c index 7f15ad76..d1001187 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -2099,6 +2099,8 @@ int main(int argc, char **argv, char **envp) { "bb\n" " AFL_REAL_LD: use this lld linker instead of the compiled in " "path\n" + " AFL_LLVM_LTO_SKIPINIT: don't inject initialization code " + "(used in WAFL mode)\n" "If anything fails - be sure to read README.lto.md!\n"); #endif -- cgit 1.4.1 From c0ecf7cf61fdca901b041d57e7e2bb78bc8fcf80 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 08:33:51 +0200 Subject: only reverse reading the queue on restart --- docs/Changelog.md | 4 ++++ src/afl-fuzz-init.c | 30 ++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index d4e68036..14323ae0 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -7,6 +7,10 @@ - afl-fuzz: - new env `AFL_POST_PROCESS_KEEP_ORIGINAL` to keep the orignal data before post process on finds + - reverse reading the seeds only on restarts + - afl-cc: + - new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM + (https://github.com/fgsect/WAFL) project - afl-showmap: - added custom mutator post_process and send support - add `-I filelist` option, an alternative to `-i in_dir` diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 01d1e82e..002a26f8 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -718,10 +718,21 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (nl_cnt) { - i = nl_cnt; + u32 done = 0; + + if (unlikely(afl->in_place_resume)) { + + i = nl_cnt; + + } else { + + i = 0; + + } + do { - --i; + if (unlikely(afl->in_place_resume)) { --i; } struct stat st; u8 dfn[PATH_MAX]; @@ -801,18 +812,17 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } - /* - if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->in_place_resume)) { - 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; + if (unlikely(i == 0)) { done = 1; } - } + } else { + + if (unlikely(++i == (u32)nl_cnt)) { done = 1; } - */ + } - } while (i > 0); + } while (!done); } -- cgit 1.4.1 From bc969f78f634035abf88bc73a5076848660901e7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 11:56:50 +0200 Subject: fixes --- afl-cmin.bash | 9 +++++++-- src/afl-fuzz-init.c | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/afl-cmin.bash b/afl-cmin.bash index ba7083fa..0e2d973d 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -316,12 +316,16 @@ if [ ! "$T_ARG" = "" ]; then if [ "$T_ARG" = "all" ]; then THREADS=$(nproc) else - if [ "$T_ARG" -gt 0 -a "$T_ARG" -le "$(nproc)" ]; then + if [ "$T_ARG" -gt 1 -a "$T_ARG" -le "$(nproc)" ]; then THREADS=$T_ARG else - echo "[-] Error: -T parameter must between 1 and $(nproc) or \"all\"." 1>&2 + echo "[-] Error: -T parameter must between 2 and $(nproc) or \"all\"." 1>&2 fi fi +else + if [ "$F_ARG" = ""]; then + echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?" + fi fi IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`)) @@ -332,6 +336,7 @@ if [ "$IN_COUNT" = "0" ]; then exit 1 fi +echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?" echo "[+] Found $IN_COUNT files for minimizing." FIRST_FILE=`ls "$IN_DIR" | head -1` diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 002a26f8..bd591c8f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -756,7 +756,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) { free(nl[i]); /* not tracked */ read_testcases(afl, fn2); ck_free(fn2); - continue; + goto next_entry; } @@ -765,7 +765,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { ck_free(fn2); - continue; + goto next_entry; } @@ -812,13 +812,14 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } + next_entry: if (unlikely(afl->in_place_resume)) { if (unlikely(i == 0)) { done = 1; } } else { - if (unlikely(++i == (u32)nl_cnt)) { done = 1; } + if (unlikely(++i >= (u32)nl_cnt)) { done = 1; } } -- cgit 1.4.1 From d822181467ec41f1ee2d840c3c5b1918c72ffc86 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 13:13:43 +0200 Subject: afl-cmin -T support --- afl-cmin | 143 ++++++++++++++++++++++++++++++++++++++++++------------ docs/Changelog.md | 2 +- src/afl-showmap.c | 23 +++++---- 3 files changed, 124 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/afl-cmin b/afl-cmin index 6b36c261..c8bbd8d7 100755 --- a/afl-cmin +++ b/afl-cmin @@ -103,9 +103,10 @@ function usage() { " -o dir - output directory for minimized files\n" \ "\n" \ "Execution control settings:\n" \ +" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \ " -f file - location read by the fuzzed program (stdin)\n" \ " -m megs - memory limit for child process ("mem_limit" MB)\n" \ -" -t msec - run time limit for child process (default: none)\n" \ +" -t msec - run time limit for child process (default: 5000)\n" \ " -O - use binary-only instrumentation (FRIDA mode)\n" \ " -Q - use binary-only instrumentation (QEMU mode)\n" \ " -U - use unicorn-based instrumentation (unicorn mode)\n" \ @@ -119,7 +120,6 @@ function usage() { "For additional tips, please consult README.md\n" \ "\n" \ "Environment variables used:\n" \ -"AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n" \ "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \ "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ "AFL_KEEP_TRACES: leave the temporary /.traces directory\n" \ @@ -159,13 +159,19 @@ BEGIN { # process options Opterr = 1 # default is to diagnose Optind = 1 # skip ARGV[0] - while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXY?")) != -1) { + while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXYT:?")) != -1) { if (_go_c == "i") { if (!Optarg) usage() if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} in_dir = Optarg continue } else + if (_go_c == "T") { + if (!Optarg) usage() + if (threads) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} + threads = Optarg + continue + } else if (_go_c == "o") { if (!Optarg) usage() if (out_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} @@ -253,21 +259,30 @@ BEGIN { # Do a sanity check to discourage the use of /tmp, since we can't really # handle this safely from an awk script. - if (!ENVIRON["AFL_ALLOW_TMP"]) { - dirlist[0] = in_dir - dirlist[1] = target_bin - dirlist[2] = out_dir - dirlist[3] = stdin_file - "pwd" | getline dirlist[4] # current directory - for (dirind in dirlist) { - dir = dirlist[dirind] - - if (dir ~ /^(\/var)?\/tmp/) { - print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr" - exit 1 - } - } - delete dirlist + #if (!ENVIRON["AFL_ALLOW_TMP"]) { + # dirlist[0] = in_dir + # dirlist[1] = target_bin + # dirlist[2] = out_dir + # dirlist[3] = stdin_file + # "pwd" | getline dirlist[4] # current directory + # for (dirind in dirlist) { + # dir = dirlist[dirind] + # + # if (dir ~ /^(\/var)?\/tmp/) { + # print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr" + # exit 1 + # } + # } + # delete dirlist + #} + + if (threads && stdin_file) { + print "[-] Error: -T and -f cannot be used together." > "/dev/stderr" + exit 1 + } + + if (!threads && !stdin_file) { + print "[*] Are you aware of the '-T all' parallelize option that massively improves the speed for large corpuses?" } # If @@ is specified, but there's no -f, let's come up with a temporary input @@ -350,6 +365,18 @@ BEGIN { exit 1 } + if (threads) { + "nproc" | getline nproc + if (threads == "all") { + threads = nproc + } else { + if (!(threads > 1 && threads <= nproc)) { + print "[-] Error: -T option must be between 1 and "nproc" or \"all\"." > "/dev/stderr" + exit 1 + } + } + } + # Check for the more efficient way to copy files... if (0 != system("mkdir -p -m 0700 "trace_dir)) { print "[-] Error: Cannot create directory "trace_dir > "/dev/stderr" @@ -459,27 +486,81 @@ BEGIN { # STEP 1: Collecting traces # ############################# + if (threads) { + + inputsperfile = in_count / threads + if (in_count % threads) { + inputsperfile++; + } + + cnt = 0; + tmpfile=out_dir "/.filelist" + for (instance = 1; instance < threads; instance++) { + for (i = 0; i < inputsperfile; i++) { + print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."instance + cnt++ + } + } + for (; cnt < in_count; cnt++) { + print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."threads + } + + print "ls -l "tmpfile"*" + + } + print "[*] Obtaining traces for "in_count" input files in '"in_dir"'." cur = 0; - if (!stdin_file) { - print " Processing "in_count" files (forkserver mode)..." -# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string - retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string) + + if (threads > 1) { + + print "[*] Creating " threads " parallel tasks with about " inputsperfile " each." + for (i = 1; i <= threads; i++) { + + if (!stdin_file) { +# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &" + retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &") + } else { + stdin_file=tmpfile"."i".stdin" +# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" "tmpfile"."i".done ; } &" + retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" "tmpfile"."i".done ; } &") + } + } + print "[*] Waiting for parallel tasks to complete ..." + # wait for all processes to finish + ok=0 + while (ok < threads) { + ok=0 + for (i = 1; i <= threads; i++) { + if (system("test -f "tmpfile"."i".done") == 0) { + ok++ + } + } + } + print "[*] Done!" + system("rm -f "tmpfile"*") } else { - print " Processing "in_count" files (forkserver mode)..." + if (!stdin_file) { + print " Processing "in_count" files (forkserver mode)..." +# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string + retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string) + } else { + print " Processing "in_count" files (forkserver mode)..." # print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" /dev/null") - system("rmdir "out_dir) + if (!ENVIRON["AFL_KEEP_TRACES"]) { + system("rm -rf "trace_dir" 2>/dev/null") + system("rmdir "out_dir) + } + exit retval } - exit retval + } ####################################################### diff --git a/docs/Changelog.md b/docs/Changelog.md index 816a864d..667fd634 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,7 +14,7 @@ - afl-showmap: - added custom mutator post_process and send support - add `-I filelist` option, an alternative to `-i in_dir` - - afl-cmin.bash: + - afl-cmin + afl-cmin.bash: - `-T threads` parallel task support, huge speedup! - a new grammar custom mutator atnwalk was submitted by @voidptr127 ! diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 09a1d2dc..d0e01cb1 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -894,9 +894,7 @@ u32 execute_testcases_filelist(u8 *fn) { while (fgets(buf, sizeof(buf), f) != NULL) { struct stat st; - - u8 *fn2 = buf, *fn3; - ; + u8 *fn2 = buf, *fn3; while (*fn2 == ' ') { @@ -904,14 +902,11 @@ u32 execute_testcases_filelist(u8 *fn) { } - if (*fn2) { - - while (fn2[strlen(fn2) - 1] == '\r' || fn2[strlen(fn2) - 1] == '\n' || - fn2[strlen(fn2) - 1] == ' ') { - - fn2[strlen(fn2) - 1] = 0; + while (*fn2 && + (fn2[strlen(fn2) - 1] == '\r' || fn2[strlen(fn2) - 1] == '\n' || + fn2[strlen(fn2) - 1] == ' ')) { - } + fn2[strlen(fn2) - 1] = 0; } @@ -926,6 +921,8 @@ u32 execute_testcases_filelist(u8 *fn) { } + ++done; + if (!S_ISREG(st.st_mode) || !st.st_size) { continue; } if ((fn3 = strrchr(fn2, '/'))) { @@ -946,9 +943,12 @@ u32 execute_testcases_filelist(u8 *fn) { } - if (!collect_coverage) + if (!collect_coverage) { + snprintf(outfile, sizeof(outfile), "%s/%s", out_file, fn3); + } + if (read_file(fn2)) { if (wait_for_gdb) { @@ -961,7 +961,6 @@ u32 execute_testcases_filelist(u8 *fn) { showmap_run_target_forkserver(fsrv, in_data, in_len); ck_free(in_data); - ++done; if (child_crashed && debug) { WARNF("crashed: %s", fn2); } -- cgit 1.4.1 From 21865c622483d2e2285de3dfad4626c28ca27843 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 16:47:37 +0200 Subject: rename env to AFL_IGNORE_PROBLEMS_COVERAGE --- docs/FAQ.md | 3 ++- docs/env_variables.md | 3 ++- include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 4 ++-- src/afl-fuzz.c | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/docs/FAQ.md b/docs/FAQ.md index 4a9080f8..76350c79 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -229,7 +229,8 @@ If you find an interesting or important question missing, submit it via If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then the existing map will be used also for the newly loaded libraries, which allows it to work, however, the efficiency of the fuzzing will be partially - degraded. + degraded. Note that there is additionally `AFL_IGNORE_PROBLEMS_COVERAGE` to + additionally tell AFL++ to ignore any coverage from the late loaded libaries.

diff --git a/docs/env_variables.md b/docs/env_variables.md index 087ccdb7..b1f23159 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -406,7 +406,8 @@ checks or alter some of the more exotic semantics of the tool: - If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session (not at startup), it will terminate. If you do not want this, then you can - set `AFL_IGNORE_PROBLEMS`. + set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage + from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`. - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the fuzzer to import test cases from other instances before doing anything else. diff --git a/include/envs.h b/include/envs.h index 5e68c80b..fe5ee0e3 100644 --- a/include/envs.h +++ b/include/envs.h @@ -106,6 +106,7 @@ static char *afl_environment_variables[] = { "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS", + "AFL_IGNORE_PROBLEMS_COVERAGE", "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 74506e4c..0912e52b 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1565,13 +1565,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { "be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n" "To ignore this set AFL_IGNORE_PROBLEMS=1 but this will lead to " "ambiguous coverage data.\n" - "In addition, you can set AFL_LLVM_IGNORE_PROBLEMS_COVERAGE=1 to " + "In addition, you can set AFL_IGNORE_PROBLEMS_COVERAGE=1 to " "ignore the additional coverage instead (use with caution!).\n"); abort(); } else { - u8 ignore_dso_after_fs = !!getenv("AFL_LLVM_IGNORE_PROBLEMS_COVERAGE"); + u8 ignore_dso_after_fs = !!getenv("AFL_IGNORE_PROBLEMS_COVERAGE"); if (__afl_debug && ignore_dso_after_fs) { fprintf(stderr, "Ignoring coverage from dynamically loaded code\n"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ebdbb3fa..c44144f5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -259,6 +259,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n" + "AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n + " ignore those libs for coverage\n" "AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n" "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" -- cgit 1.4.1 From 96848398d45e08eaa69be245c986375808d2b3a7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 17:56:36 +0200 Subject: fix --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c44144f5..71d2afd8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -259,7 +259,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n" - "AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n + "AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n" " ignore those libs for coverage\n" "AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n" "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" -- cgit 1.4.1