Hello community, here is the log from the commit of package afl for openSUSE:Factory checked in at 2017-02-13 07:49:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/afl (Old) and /work/SRC/openSUSE:Factory/.afl.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "afl" Changes: -------- --- /work/SRC/openSUSE:Factory/afl/afl.changes 2016-10-23 12:51:53.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.afl.new/afl.changes 2017-02-13 07:49:36.594041732 +0100 @@ -1,0 +2,25 @@ +Fri Feb 10 12:09:01 UTC 2017 - meiss...@suse.com + +- update to 2.39b: + - Improved error reporting in afl-cmin. Suggested by floyd. + - Made a minor tweak to trace-pc-guard support. Suggested by kcc. + - Added a mention of afl-monitor. + +------------------------------------------------------------------- +Mon Jan 30 14:21:37 UTC 2017 - astie...@suse.com + +- update to 2.38b: + * Added -mllvm -sanitizer-coverage-block-threshold=0 to + trace-pc-guard mode + * Fixed a cosmetic bad free() bug when aborting -S sessions + * Made a small change to afl-whatsup to sort fuzzers by name. + * Fixed a minor issue with malloc(0) in libdislocator + * Changed the clobber pattern in libdislocator to a slightly more + reliable one + * Added a note about THP performance + * Added a somewhat unofficial support for running afl-tmin with a + baseline "mask" that causes it to minimize only for edges that + are unique to the input file, but not to the "boring" baseline. + * "Fixed" a getPassName() problem with never versions of clang. + +------------------------------------------------------------------- Old: ---- afl-2.35b.tgz New: ---- afl-2.39b.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ afl.spec ++++++ --- /var/tmp/diff_new_pack.QsW2PF/_old 2017-02-13 07:49:37.757875568 +0100 +++ /var/tmp/diff_new_pack.QsW2PF/_new 2017-02-13 07:49:37.761874996 +0100 @@ -1,7 +1,7 @@ # # spec file for package afl # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: afl -Version: 2.35b +Version: 2.39b Release: 0 Summary: American fuzzy lop is a security-oriented fuzzer License: Apache-2.0 ++++++ afl-2.35b.tgz -> afl-2.39b.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/Makefile new/afl-2.39b/Makefile --- old/afl-2.35b/Makefile 2016-08-07 09:03:02.000000000 +0200 +++ new/afl-2.39b/Makefile 2017-01-15 02:50:54.000000000 +0100 @@ -123,7 +123,11 @@ install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) rm -f $${DESTDIR}$(BIN_PATH)/afl-as if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi +ifndef AFL_TRACE_PC if [ -f afl-clang-fast -a -f afl-llvm-pass.so -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-pass.so afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi +else + if [ -f afl-clang-fast -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi +endif if [ -f afl-llvm-rt-32.o ]; then set -e; install -m 755 afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi if [ -f afl-llvm-rt-64.o ]; then set -e; install -m 755 afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/$$i; done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-cmin new/afl-2.39b/afl-cmin --- old/afl-2.35b/afl-cmin 2015-09-11 19:20:46.000000000 +0200 +++ new/afl-2.39b/afl-cmin 2017-01-24 23:00:28.000000000 +0100 @@ -240,13 +240,23 @@ IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`)) if [ "$IN_COUNT" = "0" ]; then - echo "No inputs in the target directory - nothing to be done." + echo "[+] Hmm, no inputs in the target directory. Nothing to be done." rm -rf "$TRACE_DIR" exit 1 fi FIRST_FILE=`ls "$IN_DIR" | head -1` +# Make sure that we're not dealing with a directory. + +if [ -d "$IN_DIR/$FIRST_FILE" ]; then + echo "[-] Error: The target directory contains subdirectories - please fix." 1>&2 + rm -rf "$TRACE_DIR" + exit 1 +fi + +# Check for the more efficient way to copy files... + if ln "$IN_DIR/$FIRST_FILE" "$TRACE_DIR/.link_test" 2>/dev/null; then CP_TOOL=ln else @@ -384,7 +394,7 @@ sed 's/^/BEST_FILE[/;s/ /]="/;s/$/"/' >"$TRACE_DIR/.candidate_script" if [ ! -s "$TRACE_DIR/.candidate_script" ]; then - echo "[-] Error: no traces obtained from test cases, check syntax!" + echo "[-] Error: no traces obtained from test cases, check syntax!" 1>&2 test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR" exit 1 fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-fuzz.c new/afl-2.39b/afl-fuzz.c --- old/afl-2.35b/afl-fuzz.c 2016-09-20 04:38:39.000000000 +0200 +++ new/afl-2.39b/afl-fuzz.c 2016-11-27 03:10:23.000000000 +0100 @@ -7317,8 +7317,9 @@ #endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */ - OKF("You have %u CPU cores and %u runnable tasks (utilization: %0.0f%%).", - cpu_core_count, cur_runnable, cur_runnable * 100.0 / cpu_core_count); + OKF("You have %u CPU core%s and %u runnable tasks (utilization: %0.0f%%).", + cpu_core_count, cpu_core_count > 1 ? "s" : "", + cur_runnable, cur_runnable * 100.0 / cpu_core_count); if (cpu_core_count > 1) { @@ -7682,7 +7683,7 @@ case 'S': if (sync_id) FATAL("Multiple -S or -M options not supported"); - sync_id = optarg; + sync_id = ck_strdup(optarg); break; case 'f': /* target file */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-gcc.c new/afl-2.39b/afl-gcc.c --- old/afl-2.35b/afl-gcc.c 2016-08-28 02:09:39.000000000 +0200 +++ new/afl-2.39b/afl-gcc.c 2017-01-13 22:10:12.000000000 +0100 @@ -323,7 +323,6 @@ } - find_as(argv[0]); edit_params(argc, argv); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-showmap.c new/afl-2.39b/afl-showmap.c --- old/afl-2.35b/afl-showmap.c 2016-08-03 19:52:48.000000000 +0200 +++ new/afl-2.39b/afl-showmap.c 2017-01-14 05:12:31.000000000 +0100 @@ -63,7 +63,8 @@ static u8 quiet_mode, /* Hide non-essential messages? */ edges_only, /* Ignore hit counts? */ - cmin_mode; /* Generate output in afl-cmin mode? */ + cmin_mode, /* Generate output in afl-cmin mode? */ + binary_mode; /* Write output as a binary map */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ @@ -73,7 +74,7 @@ /* Classify tuple counts. Instead of mapping to individual bits, as in afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ -static const u8 count_class_lookup[256] = { +static const u8 count_class_human[256] = { [0] = 0, [1] = 1, @@ -87,7 +88,21 @@ }; -static void classify_counts(u8* mem) { +static const u8 count_class_binary[256] = { + + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 4, + [4 ... 7] = 8, + [8 ... 15] = 16, + [16 ... 31] = 32, + [32 ... 127] = 64, + [128 ... 255] = 128 + +}; + +static void classify_counts(u8* mem, const u8* map) { u32 i = MAP_SIZE; @@ -101,7 +116,7 @@ } else { while (i--) { - *mem = count_class_lookup[*mem]; + *mem = map[*mem]; mem++; } @@ -148,8 +163,8 @@ static u32 write_results(void) { s32 fd; - FILE* f; u32 i, ret = 0; + u8 cco = !!getenv("AFL_CMIN_CRASHES_ONLY"), caa = !!getenv("AFL_CMIN_ALLOW_ANY"); @@ -171,27 +186,40 @@ } - f = fdopen(fd, "w"); - if (!f) PFATAL("fdopen() failed"); + if (binary_mode) { - for (i = 0; i < MAP_SIZE; i++) { + for (i = 0; i < MAP_SIZE; i++) + if (trace_bits[i]) ret++; + + ck_write(fd, trace_bits, MAP_SIZE, out_file); + close(fd); - if (!trace_bits[i]) continue; - ret++; + } else { - if (cmin_mode) { + FILE* f = fdopen(fd, "w"); - if (child_timed_out) break; - if (!caa && child_crashed != cco) break; + if (!f) PFATAL("fdopen() failed"); - fprintf(f, "%u%u\n", trace_bits[i], i); + for (i = 0; i < MAP_SIZE; i++) { - } else fprintf(f, "%06u:%u\n", i, trace_bits[i]); + if (!trace_bits[i]) continue; + ret++; - } + if (cmin_mode) { + + if (child_timed_out) break; + if (!caa && child_crashed != cco) break; + + fprintf(f, "%u%u\n", trace_bits[i], i); + + } else fprintf(f, "%06u:%u\n", i, trace_bits[i]); + + } - fclose(f); + fclose(f); + + } return ret; @@ -293,7 +321,8 @@ if (*(u32*)trace_bits == EXEC_FAIL_SIG) FATAL("Unable to execute '%s'", argv[0]); - classify_counts(trace_bits); + classify_counts(trace_bits, binary_mode ? + count_class_binary : count_class_human); if (!quiet_mode) SAYF(cRST "-- Program output ends --\n"); @@ -585,7 +614,7 @@ doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; - while ((opt = getopt(argc,argv,"+o:m:t:A:eqZQ")) > 0) + while ((opt = getopt(argc,argv,"+o:m:t:A:eqZQb")) > 0) switch (opt) { @@ -682,6 +711,14 @@ qemu_mode = 1; break; + case 'b': + + /* Secret undocumented mode. Writes output in raw binary format + similar to that dumped by afl-fuzz in <out_dir/queue/fuzz_bitmap. */ + + binary_mode = 1; + break; + default: usage(argv[0]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-tmin.c new/afl-2.39b/afl-tmin.c --- old/afl-2.35b/afl-tmin.c 2016-08-03 19:53:28.000000000 +0200 +++ new/afl-2.39b/afl-tmin.c 2017-01-14 05:13:56.000000000 +0100 @@ -46,7 +46,8 @@ static s32 child_pid; /* PID of the tested program */ -static u8* trace_bits; /* SHM with instrumentation bitmap */ +static u8 *trace_bits, /* SHM with instrumentation bitmap */ + *mask_bitmap; /* Mask for trace bits (-B) */ static u8 *in_file, /* Minimizer input test case */ *out_file, /* Minimizer output file */ @@ -118,6 +119,25 @@ } +/* Apply mask to classified bitmap (if set). */ + +static void apply_mask(u32* mem, u32* mask) { + + u32 i = (MAP_SIZE >> 2); + + if (!mask) return; + + while (i--) { + + *mem &= ~*mask; + mem++; + mask++; + + } + +} + + /* See if any bytes are set in the bitmap. */ static inline u8 anything_set(void) { @@ -314,6 +334,7 @@ FATAL("Unable to execute '%s'", argv[0]); classify_counts(trace_bits); + apply_mask((u32*)trace_bits, (u32*)mask_bitmap); total_execs++; if (stop_soon) { @@ -919,6 +940,22 @@ } +/* Read mask bitmap from file. This is for the -B option. */ + +static void read_bitmap(u8* fname) { + + s32 fd = open(fname, O_RDONLY); + + if (fd < 0) PFATAL("Unable to open '%s'", fname); + + ck_read(fd, mask_bitmap, MAP_SIZE, fname); + + close(fd); + +} + + + /* Main entry point */ int main(int argc, char** argv) { @@ -931,7 +968,7 @@ SAYF(cCYA "afl-tmin " cBRI VERSION cRST " by <lcam...@google.com>\n"); - while ((opt = getopt(argc,argv,"+i:o:f:m:t:xeQ")) > 0) + while ((opt = getopt(argc,argv,"+i:o:f:m:t:B:xeQ")) > 0) switch (opt) { @@ -1023,6 +1060,26 @@ qemu_mode = 1; break; + case 'B': /* load bitmap */ + + /* This is a secret undocumented option! It is speculated to be useful + if you have a baseline "boring" input file and another "interesting" + file you want to minimize. + + You can dump a binary bitmap for the boring file using + afl-showmap -b, and then load it into afl-tmin via -B. The minimizer + will then minimize to preserve only the edges that are unique to + the interesting input file, but ignoring everything from the + original map. + + The option may be extended and made more official if it proves + to be useful. */ + + if (mask_bitmap) FATAL("Multiple -B options not supported"); + mask_bitmap = ck_alloc(MAP_SIZE); + read_bitmap(optarg); + break; + default: usage(argv[0]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/afl-whatsup new/afl-2.39b/afl-whatsup --- old/afl-2.35b/afl-whatsup 2016-05-15 17:30:06.000000000 +0200 +++ new/afl-2.39b/afl-whatsup 2016-11-20 04:38:08.000000000 +0100 @@ -74,7 +74,7 @@ fi -for i in `find . -maxdepth 2 -iname fuzzer_stats`; do +for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP" . "$TMP" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/config.h new/afl-2.39b/config.h --- old/afl-2.35b/config.h 2016-09-23 17:04:24.000000000 +0200 +++ new/afl-2.39b/config.h 2017-02-02 19:40:52.000000000 +0100 @@ -21,7 +21,7 @@ /* Version string: */ -#define VERSION "2.35b" +#define VERSION "2.39b" /****************************************************** * * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/docs/ChangeLog new/afl-2.39b/docs/ChangeLog --- old/afl-2.35b/docs/ChangeLog 2016-09-23 17:00:52.000000000 +0200 +++ new/afl-2.39b/docs/ChangeLog 2017-02-01 18:49:12.000000000 +0100 @@ -17,6 +17,67 @@ to get on with the times. -------------- +Version 2.39b: +-------------- + + - Improved error reporting in afl-cmin. Suggested by floyd. + + - Made a minor tweak to trace-pc-guard support. Suggested by kcc. + + - Added a mention of afl-monitor. + +-------------- +Version 2.38b: +-------------- + + - Added -mllvm -sanitizer-coverage-block-threshold=0 to trace-pc-guard + mode, as suggested by Kostya Serebryany. + +-------------- +Version 2.37b: +-------------- + + - Fixed a typo. Spotted by Jakub Wilk. + + - Fixed support for make install when using trace-pc. Spotted by + Kurt Roeckx. + + - Switched trace-pc to trace-pc-guard, which should be considerably + faster and is less quirky. Kudos to Konstantin Serebryany (and sorry + for dragging my feet). + + Note that for some reason, this mode doesn't perform as well as + "vanilla" afl-clang-fast / afl-clang. + +-------------- +Version 2.36b: +-------------- + + - Fixed a cosmetic bad free() bug when aborting -S sessions. Spotted + by Johannes S. + + - Made a small change to afl-whatsup to sort fuzzers by name. + + - Fixed a minor issue with malloc(0) in libdislocator. Spotted by + Rene Freingruber. + + - Changed the clobber pattern in libdislocator to a slightly more + reliable one. Suggested by Rene Freingruber. + + - Added a note about THP performance. Suggested by Sergey Davidoff. + + - Added a somewhat unofficial support for running afl-tmin with a + baseline "mask" that causes it to minimize only for edges that + are unique to the input file, but not to the "boring" baseline. + Suggested by Sami Liedes. + + - "Fixed" a getPassName() problem with never versions of clang. + Reported by Craig Young and several other folks. + + Yep, I know I have a backlog on several other feature requests. + Stay tuned! + +-------------- Version 2.35b: -------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/docs/README new/afl-2.39b/docs/README --- old/afl-2.35b/docs/README 2016-08-23 08:54:15.000000000 +0200 +++ new/afl-2.39b/docs/README 2017-01-13 22:41:35.000000000 +0100 @@ -479,6 +479,8 @@ Kurt Roeckx Marcel Bohme Van-Thuan Pham Abhik Roychoudhury Joshua J. Drake Toby Hutton + Rene Freingruber Sergey Davidoff + Sami Liedes Craig Young Thank you! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/docs/perf_tips.txt new/afl-2.39b/docs/perf_tips.txt --- old/afl-2.35b/docs/perf_tips.txt 2016-08-18 19:09:31.000000000 +0200 +++ new/afl-2.39b/docs/perf_tips.txt 2017-01-13 22:02:41.000000000 +0100 @@ -167,6 +167,12 @@ On other systems, the impact of CPU scaling will be different; when fuzzing, use OS-specific tools to find out if all cores are running at full speed. + - Transparent huge pages. Some allocators, such as jemalloc, can incur a + heavy fuzzing penalty when transparent huge pages (THP) are enabled in the + kernel. You can disable this via: + + echo never > /sys/kernel/mm/transparent_hugepage/enabled + - Suboptimal scheduling strategies. The significance of this will vary from one target to another, but on Linux, you may want to make sure that the following options are set: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/docs/sister_projects.txt new/afl-2.39b/docs/sister_projects.txt --- old/afl-2.35b/docs/sister_projects.txt 2016-09-23 17:04:16.000000000 +0200 +++ new/afl-2.39b/docs/sister_projects.txt 2017-02-01 18:48:38.000000000 +0100 @@ -148,6 +148,13 @@ https://github.com/d33tah/afl-sid +afl-monitor (Paul S. Ziegler) +----------------------------- + + Provides more detailed and versatile statistics about your running AFL jobs. + + https://github.com/reflare/afl-monitor + ----------------------------------------------------------- Crash triage, coverage analysis, and other companion tools: ----------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/libdislocator/libdislocator.so.c new/afl-2.39b/libdislocator/libdislocator.so.c --- old/afl-2.35b/libdislocator/libdislocator.so.c 2016-09-23 17:02:36.000000000 +0200 +++ new/afl-2.39b/libdislocator/libdislocator.so.c 2017-01-13 21:47:39.000000000 +0100 @@ -64,7 +64,7 @@ /* Canary & clobber bytes: */ #define ALLOC_CANARY 0xAACCAACC -#define ALLOC_CLOBBER 0x41 +#define ALLOC_CLOBBER 0xCC #define PTR_C(_p) (((u32*)(_p))[-1]) #define PTR_L(_p) (((u32*)(_p))[-2]) @@ -90,7 +90,7 @@ void* ret; - if (total_mem + len > max_mem || total_mem + len <= total_mem) { + if (total_mem + len > max_mem || total_mem + len < total_mem) { if (hard_fail) FATAL("total allocs exceed %u MB", max_mem / 1024 / 1024); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/llvm_mode/README.llvm new/afl-2.39b/llvm_mode/README.llvm --- old/afl-2.35b/llvm_mode/README.llvm 2016-08-06 06:35:27.000000000 +0200 +++ new/afl-2.39b/llvm_mode/README.llvm 2017-01-26 03:32:59.000000000 +0100 @@ -166,14 +166,14 @@ faster than the normal fork() model, and compared to in-process fuzzing, should be a lot more robust. -6) Bonus feature #3: new 'trace-pc' mode ----------------------------------------- +6) Bonus feature #3: new 'trace-pc-guard' mode +---------------------------------------------- Recent versions of LLVM are shipping with a built-in execution tracing feature -that is fairly usable for AFL, without the need to post-process the assembly -or install any compiler plugins. See: +that provides AFL with the necessary tracing data without the need to +post-process the assembly or install any compiler plugins. See: - http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs + http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards As of this writing, the feature is only available on SVN trunk, and is yet to make it to an official release of LLVM. Nevertheless, if you have a @@ -182,10 +182,9 @@ AFL_TRACE_PC=1 make clean all -Since a form of 'trace-pc' is also supported in GCC, this mode may become a -longer-term solution to all our needs. +Note that this mode is currently about 20% slower than "vanilla" afl-clang-fast, +and about 5-10% slower than afl-clang. This is likely because the +instrumentation is not inlined, and instead involves a function call. On systems +that support it, compiling your target with -flto should help. + -Note that this mode supports AFL_INST_RATIO at run time, not at compilation -time. This is somewhat similar to the behavior of the QEMU mode. Because of -the need to support it at run time, the mode is also a tad slower than the -plugin-based approach. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/llvm_mode/afl-clang-fast.c new/afl-2.39b/llvm_mode/afl-clang-fast.c --- old/afl-2.35b/llvm_mode/afl-clang-fast.c 2016-08-23 08:53:27.000000000 +0200 +++ new/afl-2.39b/llvm_mode/afl-clang-fast.c 2017-01-25 03:51:26.000000000 +0100 @@ -114,13 +114,15 @@ /* There are two ways to compile afl-clang-fast. In the traditional mode, we use afl-llvm-pass.so to inject instrumentation. In the experimental - 'trace-pc' mode, we use native LLVM instrumentation callbacks instead. - The latter is a very recent addition - see: + 'trace-pc-guard' mode, we use native LLVM instrumentation callbacks + instead. The latter is a very recent addition - see: - http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs */ + http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */ #ifdef USE_TRACE_PC - cc_params[cc_par_cnt++] = "-fsanitize-coverage=bb,trace-pc"; + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; + cc_params[cc_par_cnt++] = "-mllvm"; + cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0"; #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; @@ -313,7 +315,11 @@ if (isatty(2) && !getenv("AFL_QUIET")) { +#ifdef USE_TRACE_PC + SAYF(cCYA "afl-clang-fast [tpcg] " cBRI VERSION cRST " by <lszeke...@google.com>\n"); +#else SAYF(cCYA "afl-clang-fast " cBRI VERSION cRST " by <lszeke...@google.com>\n"); +#endif /* ^USE_TRACE_PC */ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/llvm_mode/afl-llvm-pass.so.cc new/afl-2.39b/llvm_mode/afl-llvm-pass.so.cc --- old/afl-2.35b/llvm_mode/afl-llvm-pass.so.cc 2016-06-23 17:45:02.000000000 +0200 +++ new/afl-2.39b/llvm_mode/afl-llvm-pass.so.cc 2017-01-22 09:26:08.000000000 +0100 @@ -49,9 +49,9 @@ bool runOnModule(Module &M) override; - const char *getPassName() const override { - return "American Fuzzy Lop Instrumentation"; - } + // StringRef getPassName() const override { + // return "American Fuzzy Lop Instrumentation"; + // } }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/llvm_mode/afl-llvm-rt.o.c new/afl-2.39b/llvm_mode/afl-llvm-rt.o.c --- old/afl-2.35b/llvm_mode/afl-llvm-rt.o.c 2016-08-08 23:38:18.000000000 +0200 +++ new/afl-2.39b/llvm_mode/afl-llvm-rt.o.c 2017-02-01 02:59:41.000000000 +0100 @@ -34,6 +34,16 @@ #include <sys/wait.h> #include <sys/types.h> +/* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode. + Basically, we need to make sure that the forkserver is initialized after + the LLVM-generated runtime initialization pass, not before. */ + +#ifdef USE_TRACE_PC +# define CONST_PRIO 5 +#else +# define CONST_PRIO 0 +#endif /* ^USE_TRACE_PC */ + /* Globals needed by the injected instrumentation. The __afl_area_initial region is used for instrumentation output before __afl_map_shm() has a chance to run. @@ -234,17 +244,12 @@ } -static void __afl_trace_pc_init(void); - - /* Proper initialization routine. */ -__attribute__((constructor(0))) void __afl_auto_init(void) { +__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) { is_persistent = !!getenv(PERSIST_ENV_VAR); - __afl_trace_pc_init(); - if (getenv(DEFER_ENV_VAR)) return; __afl_manual_init(); @@ -252,63 +257,50 @@ } -/* The following stuff deals with support for -fsanitize-coverage=bb,trace-pc. +/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard. It remains non-operational in the traditional, plugin-backed LLVM mode. - For more info about 'trace-pc', see README.llvm. - - The first function (__sanitizer_cov_trace_pc) is called back on every - basic block. Since LLVM is not giving us any stable IDs for the blocks, - we use 12 least significant bits of the return address (which should be - stable even with ASLR; more significant bits may vary across runs). - - Since MAP_SIZE is usually larger than 12 bits, we "pad" it by combining - left-shifted __afl_prev_loc. This gives us a theoretical maximum of 24 - bits, although instruction alignment likely reduces this somewhat. */ - - -static u32 inst_ratio_scaled = MIN(4096, MAP_SIZE); + For more info about 'trace-pc-guard', see README.llvm. -void __sanitizer_cov_trace_pc(void) { - - u32 cur = ((u32)__builtin_return_address(0)) & MIN(4095, MAP_SIZE - 1); - - if (cur > inst_ratio_scaled) return; - - __afl_area_ptr[cur ^ __afl_prev_loc]++; - -#if MAP_SIZE_POW2 > 12 - __afl_prev_loc = cur << (MAP_SIZE_POW2 - 12); -#else - __afl_prev_loc = cur >> 1; -#endif /* ^MAP_SIZE_POW2 > 12 */ + The first function (__sanitizer_cov_trace_pc_guard) is called back on every + edge (as opposed to every basic block). */ +void __sanitizer_cov_trace_pc_guard(uint32_t* guard) { + __afl_area_ptr[*guard]++; } -/* Init callback. Unfortunately, LLVM does not support compile-time - instrumentation density scaling, at least not just yet. This means - taking some performance hit by checking inst_ratio_scaled at runtime. */ +/* Init callback. Populates instrumentation IDs. Note that we're using + ID of 0 as a special value to indicate non-instrumented bits. That may + still touch the bitmap, but in a fairly harmless way. */ -static void __afl_trace_pc_init(void) { +void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) { - u8* x = getenv("AFL_INST_RATIO"); + u32 inst_ratio = 100; + u8* x; - if (!x) return; + if (start == stop || *start) return; - inst_ratio_scaled = atoi(x); + x = getenv("AFL_INST_RATIO"); + if (x) inst_ratio = atoi(x); - if (!inst_ratio_scaled || inst_ratio_scaled > 100) { + if (!inst_ratio || inst_ratio > 100) { fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n"); abort(); } - inst_ratio_scaled = inst_ratio_scaled * MIN(4096, MAP_SIZE) / 100; + /* Make sure that the first element in the range is always set - we use that + to avoid duplicate calls (which can happen as an artifact of the underlying + implementation in LLVM). */ -} + *(start++) = R(MAP_SIZE - 1) + 1; + + while (start < stop) { + if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1; + else *start = 0; -/* Work around a short-lived bug in LLVM with -fsanitize-coverage=trace-pc. */ + start++; -void __sanitizer_cov_module_init(void) __attribute__((weak)); -void __sanitizer_cov_module_init(void) { } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/afl-2.35b/qemu_mode/README.qemu new/afl-2.39b/qemu_mode/README.qemu --- old/afl-2.35b/qemu_mode/README.qemu 2015-10-06 07:40:06.000000000 +0200 +++ new/afl-2.39b/qemu_mode/README.qemu 2017-01-15 02:51:50.000000000 +0100 @@ -98,6 +98,11 @@ security boundary. The binaries can freely interact with the host OS. If you somehow need to fuzz an untrusted binary, put everything in a sandbox first. +QEMU does not necessarily support all CPU or hardware features that your +target program may be utilizing. In particular, it does not appear to have +full support for AVX2 / FMA3. Using binaries for older CPUs, or recompiling them +with -march=core2, can help. + Beyond that, this is an early-stage mechanism, so fields reports are welcome. You can send them to <afl-us...@googlegroups.com>.