diff options
author | hexcoder- <heiko@hexco.de> | 2019-10-18 19:53:10 +0200 |
---|---|---|
committer | hexcoder- <heiko@hexco.de> | 2019-10-18 19:53:10 +0200 |
commit | e7ab8be0cd97f9a18e6ca2f855afa69768322dfb (patch) | |
tree | d8248acacb9135473f35da77c832eddf4ae3d949 | |
parent | b1822f26022c323e4b47198abbb7d5f5ea6a57e5 (diff) | |
download | afl++-e7ab8be0cd97f9a18e6ca2f855afa69768322dfb.tar.gz |
sync afl-fast-gcc with afl-clang-fast, add tests for gcc_plugin
-rw-r--r-- | gcc_plugin/afl-gcc-fast.c | 50 | ||||
-rw-r--r-- | gcc_plugin/afl-gcc-pass.so.cc | 4 | ||||
-rw-r--r-- | llvm_mode/afl-clang-fast.c | 4 | ||||
-rw-r--r-- | src/afl-gcc.c | 2 | ||||
-rwxr-xr-x | test/test.sh | 69 |
5 files changed, 108 insertions, 21 deletions
diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index 8be05bb5..25ecf310 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -104,7 +104,7 @@ static void edit_params(u32 argc, char** argv) { cc_params = ck_alloc((argc + 64) * sizeof(u8*)); name = strrchr(argv[0], '/'); - if (!name) name = argv[0]; else name++; + if (!name) name = argv[0]; else ++name; if (!strcmp(name, "afl-g++-fast")) { u8* alt_cxx = getenv("AFL_CXX"); @@ -114,9 +114,15 @@ static void edit_params(u32 argc, char** argv) { cc_params[0] = alt_cc ? alt_cc : (u8*)"gcc"; } + + char* fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); cc_params[cc_par_cnt++] = fplugin_arg; + /* Detect stray -v calls from ./configure scripts. */ + + if (argc == 1 && !strcmp(argv[1], "-v")) maybe_linking = 0; + while (--argc) { u8* cur = *(++argv); @@ -134,6 +140,8 @@ static void edit_params(u32 argc, char** argv) { if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; + if (!strcmp(cur, "-shared")) maybe_linking = 0; + cc_params[cc_par_cnt++] = cur; } @@ -151,17 +159,23 @@ static void edit_params(u32 argc, char** argv) { if (getenv("AFL_USE_ASAN")) { - cc_params[cc_par_cnt++] = "-fsanitize=address"; + if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive"); + + if (getenv("AFL_HARDEN")) + FATAL("ASAN and AFL_HARDEN are mutually exclusive"); - if (getenv("AFL_USE_MSAN")) - FATAL("ASAN and MSAN are mutually exclusive"); + cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; + cc_params[cc_par_cnt++] = "-fsanitize=address"; } else if (getenv("AFL_USE_MSAN")) { - cc_params[cc_par_cnt++] = "-fsanitize=memory"; + if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive"); + + if (getenv("AFL_HARDEN")) + FATAL("MSAN and AFL_HARDEN are mutually exclusive"); - if (getenv("AFL_USE_ASAN")) - FATAL("ASAN and MSAN are mutually exclusive"); + cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; + cc_params[cc_par_cnt++] = "-fsanitize=memory"; } @@ -175,7 +189,13 @@ static void edit_params(u32 argc, char** argv) { } +#ifdef USEMMAP + cc_params[cc_par_cnt++] = "-lrt"; +#endif + cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; + cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; + cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; /* When the user tries to use persistent or deferred forkserver modes by appending a single line to the program, we want to reliably inject a @@ -237,15 +257,10 @@ static void edit_params(u32 argc, char** argv) { int main(int argc, char** argv) { - if (isatty(2) && !getenv("AFL_QUIET")) { - - SAYF(cCYA "afl-gcc-fast " cBRI VERSION cRST " initially by <aseipp@pobox.com>, maintainer: hexcoder-\n"); - - } - - if (argc < 2) { + if (argc < 2 || strcmp(argv[1], "-h") == 0) { - SAYF("\n" + printf(cCYA "afl-gcc-fast" VERSION cRST " initially by <aseipp@pobox.com>, maintainer: hexcoder-\n" + "\n" "This is a helper application for afl-fuzz. It serves as a drop-in replacement\n" "for gcc, letting you recompile third-party code with the required runtime\n" "instrumentation. A common use pattern would be one of the following:\n\n" @@ -263,8 +278,11 @@ int main(int argc, char** argv) { exit(1); - } + } else if (isatty(2) && !getenv("AFL_QUIET")) { + SAYF(cCYA "afl-gcc-fast" VERSION cRST " initially by <aseipp@pobox.com>, maintainer: hexcoder-\n"); + + } find_obj(argv[0]); diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc index f0f5b30b..a44f5a74 100644 --- a/gcc_plugin/afl-gcc-pass.so.cc +++ b/gcc_plugin/afl-gcc-pass.so.cc @@ -416,7 +416,7 @@ public: /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ - if (!instrumentBlock) return 0;; + if (!instrumentBlock) return 0; } return do_ext_call ? ext_call_instrument(fun) : inline_instrument(fun); @@ -464,7 +464,7 @@ int plugin_init(struct plugin_name_args *plugin_info, /* Show a banner */ if (isatty(2) && !getenv("AFL_QUIET")) { - SAYF(G_(cCYA "afl-gcc-pass " cBRI VERSION cRST " initially by <aseipp@pobox.com>, maintainer: hexcoder-\n")); + SAYF(G_(cCYA "afl-gcc-pass" VERSION cRST " initially by <aseipp@pobox.com>, maintainer: hexcoder-\n")); } else be_quiet = 1; diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 142d6331..54f9e6e9 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -112,7 +112,7 @@ static void edit_params(u32 argc, char** argv) { if (!name) name = argv[0]; else - name++; + ++name; if (!strcmp(name, "afl-clang-fast++")) { @@ -128,7 +128,7 @@ static void edit_params(u32 argc, char** argv) { /* There are three ways to compile with afl-clang-fast. In the traditional mode, we use afl-llvm-pass.so, then there is libLLVMInsTrim.so which is - much faster but has less coverage. Finally tere is the experimental + much faster but has less coverage. Finally there is the experimental 'trace-pc-guard' mode, we use native LLVM instrumentation callbacks instead. For trace-pc-guard see: http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 8982ca97..dd7ba4d6 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -131,7 +131,7 @@ static void edit_params(u32 argc, char** argv) { if (!name) name = argv[0]; else - name++; + ++name; if (!strncmp(name, "afl-clang", 9)) { diff --git a/test/test.sh b/test/test.sh index ab2985fe..1c5cdda6 100755 --- a/test/test.sh +++ b/test/test.sh @@ -200,6 +200,75 @@ test -e ../afl-clang-fast && { rm -f test-persistent } || $ECHO "$YELLOW[-] llvm_mode not compiled, cannot test" +$ECHO "$BLUE[*] Testing: gcc_plugin" +export AFL_CC=`which gcc` +test -e ../afl-gcc-fast && { + ../afl-gcc-fast -o test-instr.plain.gccpi ../test-instr.c > /dev/null 2>&1 + AFL_HARDEN=1 ../afl-gcc-fast -o test-compcov.harden.gccpi test-compcov.c > /dev/null 2>&1 + test -e test-instr.plain.gccpi && { + $ECHO "$GREEN[+] gcc_plugin compilation succeeded" + echo 0 | ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.0 -r -- ./test-instr.plain.gccpi > /dev/null 2>&1 + ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.1 -r -- ./test-instr.plain.gccpi < /dev/null > /dev/null 2>&1 + test -e test-instr.plain.0 -a -e test-instr.plain.1 && { + diff -q test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && { + $ECHO "$RED[!] gcc_plugin instrumentation should be different on different input but is not" + } || $ECHO "$GREEN[+] gcc_plugin instrumentation present and working correctly" + } || $ECHO "$RED[!] gcc_plugin instrumentation failed" + rm -f test-instr.plain.0 test-instr.plain.1 + } || $ECHO "$RED[!] gcc_plugin failed" + + test -e test-compcov.harden.gccpi && { + grep -Eqa 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden.gccpi > /dev/null 2>&1 && { + $ECHO "$GREEN[+] gcc_plugin hardened mode succeeded and is working" + } || $ECHO "$RED[!] gcc_plugin hardened mode is not hardened" + rm -f test-compcov.harden.gccpi + } || $ECHO "$RED[!] gcc_plugin hardened mode compilation failed" + # now we want to be sure that afl-fuzz is working + (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { + $ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" + true + }) || + # make sure crash reporter is disabled on Mac OS X + (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && { + $ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET" + true + }) || { + mkdir -p in + echo 0 > in/in + $ECHO "$GREY[*] running afl-fuzz for gcc_plugin, this will take approx 10 seconds" + { + ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain.gccpi >>errors 2>&1 + } >>errors 2>&1 + test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { + $ECHO "$GREEN[+] afl-fuzz is working correctly with gcc_plugin" + } || { + echo CUT------------------------------------------------------------------CUT + cat errors + echo CUT------------------------------------------------------------------CUT + $ECHO "$RED[!] afl-fuzz is not working correctly with gcc_plugin" + } + rm -rf in out errors + } + rm -f test-instr.plain.gccpi + + # now for the special gcc_plugin things + echo foobar.c > whitelist.txt + AFL_GCC_WHITELIST=whitelist.txt ../afl-gcc-fast -o test-compcov test-compcov.c > /dev/null 2>&1 + test -e test-compcov && { + echo 1 | ../afl-showmap -m ${MEM_LIMIT} -o - -r -- ./test-compcov 2>&1 | grep -q "Captured 1 tuples" && { + $ECHO "$GREEN[+] gcc_plugin whitelist feature works correctly" + } || $ECHO "$RED[!] gcc_plugin whitelist feature failed" + } || $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" + rm -f test-compcov test.out whitelist.txt + ../afl-gcc-fast -o test-persistent ../experimental/persistent_demo/persistent_demo.c > /dev/null 2>&1 + test -e test-persistent && { + echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { + $ECHO "$GREEN[+] gcc_plugin persistent mode feature works correctly" + } || $ECHO "$RED[!] gcc_plugin persistent mode feature failed to work" + } || $ECHO "$RED[!] gcc_plugin persistent mode feature compilation failed" + rm -f test-persistent +} || $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" + $ECHO "$BLUE[*] Testing: shared library extensions" gcc -o test-compcov test-compcov.c > /dev/null 2>&1 test -e ../libtokencap.so && { |