From e1384b5086e918350426cd0ece7dbe9c451f771f Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 18 Mar 2021 09:11:00 +0000 Subject: Add support for FRIDA mode --- src/afl-fuzz-init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 70a49a6b..cb0190a0 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2692,7 +2692,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { #endif /* ^!__APPLE__ */ - if (!afl->fsrv.qemu_mode && !afl->unicorn_mode && + if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode && !afl->unicorn_mode && !afl->non_instrumented_mode && !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { @@ -2720,7 +2720,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if ((afl->fsrv.qemu_mode) && + if ((afl->fsrv.qemu_mode || afl->fsrv.frida_mode) && memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { SAYF("\n" cLRD "[-] " cRST @@ -2757,7 +2757,8 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + if (afl->fsrv.frida_mode || + memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { OKF(cPIN "Deferred forkserver binary detected."); setenv(DEFER_ENV_VAR, "1", 1); -- cgit 1.4.1 From 920e9402a4d6101bbbed2ef7584d85a3c3de0eaa Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Fri, 2 Apr 2021 22:23:11 +0000 Subject: Add support for standalone leak-sanitizer, introducting the environment variable AFL_USE_LSAN. AFL_USE_LSAN introduces the macro __AFL_CHECK_LEAK() which will check for a memory leak when the macro is run. This is especially helpful when using __AFL_LOOP(). If __AFL_LEAK_CHECK() is not used when AFL_USE_LSAN=1 is set, the leak checker will run when the program exits. --- GNUmakefile | 4 ++-- README.md | 2 +- docs/env_variables.md | 20 ++++++++++++++++---- docs/notes_for_asan.md | 7 +++++++ include/config.h | 4 ++++ include/envs.h | 1 + src/afl-analyze.c | 19 +++++++++++++++++++ src/afl-as.c | 7 ++++--- src/afl-cc.c | 16 ++++++++++++++-- src/afl-forkserver.c | 17 +++++++++++++---- src/afl-fuzz-init.c | 17 ++++++++++++++++- src/afl-showmap.c | 4 ++++ src/afl-tmin.c | 18 ++++++++++++++++++ test/test-pre.sh | 1 + 14 files changed, 120 insertions(+), 17 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/GNUmakefile b/GNUmakefile index f885f998..a6314a8b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -517,7 +517,7 @@ code-format: ifndef AFL_NO_X86 test_build: afl-cc afl-gcc afl-as afl-showmap @echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..." - @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) + @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr @rm -f test-instr @@ -525,7 +525,7 @@ test_build: afl-cc afl-gcc afl-as afl-showmap @echo @echo "[+] All right, the instrumentation of afl-cc seems to be working!" # @echo "[*] Testing the CC wrapper afl-gcc and its instrumentation output..." -# @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_ASAN AFL_USE_MSAN; AFL_CC=$(CC) ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-gcc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-gcc failed"; exit 1 ) +# @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; AFL_CC=$(CC) ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-gcc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-gcc failed"; exit 1 ) # ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null # echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr # @rm -f test-instr diff --git a/README.md b/README.md index 2528e1d1..41d55e9c 100644 --- a/README.md +++ b/README.md @@ -601,7 +601,7 @@ Every -M/-S entry needs a unique name (that can be whatever), however the same For every secondary fuzzer there should be a variation, e.g.: * one should fuzz the target that was compiled differently: with sanitizers activated (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; - export AFL_USE_CFISAN=1 ; ` + export AFL_USE_CFISAN=1 ; export AFL_USE_LSAN`) * one should fuzz the target with CMPLOG/redqueen (see above) * one to three fuzzers should fuzz a target compiled with laf-intel/COMPCOV (see above). Important note: If you run more than one laf-intel/COMPCOV diff --git a/docs/env_variables.md b/docs/env_variables.md index c6ad0aa4..682ab7f1 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -55,7 +55,7 @@ make fairly broad use of environmental variables instead: overridden. - Setting `AFL_USE_ASAN` automatically enables ASAN, provided that your - compiler supports that. Note that fuzzing with ASAN is mildly challenging + compiler supports itt. Note that fuzzing with ASAN is mildly challenging - see [notes_for_asan.md](notes_for_asan.md). (You can also enable MSAN via `AFL_USE_MSAN`; ASAN and MSAN come with the @@ -64,6 +64,13 @@ make fairly broad use of environmental variables instead: there is the Control Flow Integrity sanitizer that can be activated by `AFL_USE_CFISAN=1`) + - Setting `AFL_USE_LSAN` automatically enables Leak-Sanitizer, provided + that your compiler supports it. To perform a leak check within your + program at a certain point (such as at the end of an __AFL_LOOP, + you can run the macro __AFL_CHECK_LEAK(); which will cause + an abort if any memory is leaked (you can combine this with the + LSAN_OPTIONS=suppressions option to supress some known leaks). + - Setting `AFL_CC`, `AFL_CXX`, and `AFL_AS` lets you use alternate downstream compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries in your `$PATH`. @@ -628,7 +635,12 @@ optimal values if not already present in the environment: msan_track_origins=0 allocator_may_return_null=1 ``` - Be sure to include the first one when customizing anything, since some - MSAN versions don't call `abort()` on error, and we need a way to detect - faults. + - Similarly, the default `LSAN_OPTIONS` are set to: +``` + exit_code=86 + fast_unwind_on_malloc=0 +```` + Be sure to include the first ones for LSAN and MSAN when customizing + anything, since some MSAN and LSAN versions don't call `abort()` on + error, and we need a way to detect faults. diff --git a/docs/notes_for_asan.md b/docs/notes_for_asan.md index 2b3bc028..26f34fad 100644 --- a/docs/notes_for_asan.md +++ b/docs/notes_for_asan.md @@ -28,6 +28,13 @@ Note that ASAN is incompatible with -static, so be mindful of that. (You can also use AFL_USE_MSAN=1 to enable MSAN instead.) +When compiling with AFL_USE_LSAN, the leak sanitizer will normally run +when the program exits. In order to utilize this check at different times, +such as at the end of a loop, you may use the macro __AFL_CHECK_LEAK();. +This macro will report a crash in afl-fuzz if any memory is left leaking +at this stage. You can also use LSAN_OPTIONS and a supressions file +for more fine-tuned checking, however make sure you keep exitcode=23. + NOTE: if you run several secondary instances, only one should run the target compiled with ASAN (and UBSAN, CFISAN), the others should run the target with no sanitizers compiled in. diff --git a/include/config.h b/include/config.h index 29225f6b..6490a5fe 100644 --- a/include/config.h +++ b/include/config.h @@ -393,6 +393,10 @@ #define MSAN_ERROR 86 +/* Distinctive exit code used to indicate LSAN trip condition: */ + +#define LSAN_ERROR 23 + /* Designated file descriptors for forkserver commands (the application will use FORKSRV_FD and FORKSRV_FD + 1): */ diff --git a/include/envs.h b/include/envs.h index 2ce50be7..d1856c50 100644 --- a/include/envs.h +++ b/include/envs.h @@ -172,6 +172,7 @@ static char *afl_environment_variables[] = { "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_CFISAN", + "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", "AFL_EXPAND_HAVOC_NOW", diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 86b0f7e9..90305714 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -781,6 +781,19 @@ static void set_up_environment(void) { } + x = get_afl_env("LSAN_OPTIONS"); + + if (x) { + + if (!strstr(x, "exit_code=" STRINGIFY(LSAN_ERROR))) { + + FATAL("Custom LSAN_OPTIONS set without exit_code=" STRINGIFY( + LSAN_ERROR) " - please fix!"); + + } + + } + setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" @@ -818,6 +831,12 @@ static void set_up_environment(void) { "handle_sigfpe=0:" "handle_sigill=0", 0); + setenv("LSAN_OPTIONS", + "exitcode=" STRINGIFY(MSAN_ERROR) ":" + "fast_unwind_on_malloc=0", + 0); + + if (get_afl_env("AFL_PRELOAD")) { if (qemu_mode) { diff --git a/src/afl-as.c b/src/afl-as.c index 7de267a3..dfae44f2 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -517,11 +517,12 @@ static void add_instrumentation(void) { } else { char modeline[100]; - snprintf(modeline, sizeof(modeline), "%s%s%s%s", + snprintf(modeline, sizeof(modeline), "%s%s%s%s%s", getenv("AFL_HARDEN") ? "hardened" : "non-hardened", getenv("AFL_USE_ASAN") ? ", ASAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "", - getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); + getenv("AFL_USE_UBSAN") ? ", UBSAN" : "", + getenv("AFL_USE_LSAN") ? ", LSAN" : ""); OKF("Instrumented %u locations (%s-bit, %s mode, ratio %u%%).", ins_lines, use_64bit ? "64" : "32", modeline, inst_ratio); @@ -585,7 +586,7 @@ int main(int argc, char **argv) { "AFL_QUIET: suppress verbose output\n" "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n" "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n" - "AFL_HARDEN, AFL_USE_ASAN, AFL_USE_MSAN, AFL_USE_UBSAN:\n" + "AFL_HARDEN, AFL_USE_ASAN, AFL_USE_MSAN, AFL_USE_UBSAN, AFL_USE_LSAN:\n" " used in the instrumentation summary message\n", argv[0]); diff --git a/src/afl-cc.c b/src/afl-cc.c index 5251465b..e0478503 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -758,7 +758,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) have_instr_list = 1; - if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) + if (!(strcmp(cur, "-fsanitize=address") && strcmp(cur, "-fsanitize=memory"))) asan_set = 1; if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; @@ -817,6 +817,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } + if (getenv("AFL_USE_LSAN")) { + cc_params[cc_par_cnt++] = "-fsanitize=leak"; + } + if (getenv("AFL_USE_CFISAN")) { if (!lto_mode) { @@ -914,6 +918,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { } + if (getenv("AFL_USE_LSAN")) { + cc_params[cc_par_cnt++] = "-includesanitizer/lsan_interface.h"; + } + + cc_params[cc_par_cnt++] = + "-D__AFL_CHECK_LEAK()=__lsan_do_leak_check()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = " "1;"; @@ -1740,7 +1751,8 @@ int main(int argc, char **argv, char **envp) { " AFL_USE_ASAN: activate address sanitizer\n" " AFL_USE_CFISAN: activate control flow sanitizer\n" " AFL_USE_MSAN: activate memory sanitizer\n" - " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); + " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + " AFL_USE_LSAN: activate leak-checker sanitizer\n"); if (have_gcc_plugin) SAYF( diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 68995388..fa89713a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -483,7 +483,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 1); } - /* Set sane defaults for ASAN if nothing else specified. */ + /* Set sane defaults for ASAN if nothing else is specified. */ if (!getenv("ASAN_OPTIONS")) setenv("ASAN_OPTIONS", @@ -500,7 +500,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_sigill=0", 1); - /* Set sane defaults for UBSAN if nothing else specified. */ + /* Set sane defaults for UBSAN if nothing else is specified. */ if (!getenv("UBSAN_OPTIONS")) setenv("UBSAN_OPTIONS", @@ -538,6 +538,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_sigill=0", 1); + /* LSAN, too, does not support abort_on_error=1. */ + + if (!getenv("LSAN_OPTIONS")) + setenv("LSAN_OPTIONS", + "exitcode=" STRINGIFY(LSAN_ERROR) ":" + "fast_unwind_on_malloc=0", + 1); + fsrv->init_child_func(fsrv, argv); /* Use a distinctive bitmap signature to tell the parent about execv() @@ -1210,8 +1218,9 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (unlikely( /* A normal crash/abort */ (WIFSIGNALED(fsrv->child_status)) || - /* special handling for msan */ - (fsrv->uses_asan && WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) || + /* special handling for msan and lsan */ + (fsrv->uses_asan && (WEXITSTATUS(fsrv->child_status) == MSAN_ERROR || + WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) || /* the custom crash_exitcode was returned by the target */ (fsrv->uses_crash_exitcode && WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 82c1799e..24f5c5b5 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2466,6 +2466,20 @@ void check_asan_opts(afl_state_t *afl) { } + x = get_afl_env("LSAN_OPTIONS"); + + if (x) { + + if (!strstr(x, "exit_code=" STRINGIFY(LSAN_ERROR))) { + + FATAL("Custom LSAN_OPTIONS set without exit_code=" STRINGIFY( + LSAN_ERROR) " - please fix!"); + + } + + } + + } /* Handle stop signal (Ctrl-C, etc). */ @@ -2711,7 +2725,8 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if (memmem(f_data, f_len, "__asan_init", 11) || - memmem(f_data, f_len, "__msan_init", 11)) { + memmem(f_data, f_len, "__msan_init", 11) || + memmem(f_data, f_len, "__lsan_init", 11)) { afl->fsrv.uses_asan = 1; diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 7bf5a9c7..bf076683 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -570,6 +570,10 @@ static void set_up_environment(afl_forkserver_t *fsrv) { "handle_sigfpe=0:" "handle_sigill=0", 0); + setenv("LSAN_OPTIONS", + "exitcode=" STRINGIFY(LSAN_ERROR) ":" + "fast_unwind_on_malloc=0", + 0); setenv("UBSAN_OPTIONS", "halt_on_error=1:" diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 7ef8b9bf..a2741a07 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -712,6 +712,19 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } + x = get_afl_env("LSAN_OPTIONS"); + + if (x) { + + if (!strstr(x, "exit_code=" STRINGIFY(LSAN_ERROR))) { + + FATAL("Custom LSAN_OPTIONS set without exit_code=" STRINGIFY( + LSAN_ERROR) " - please fix!"); + + } + + } + setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" @@ -749,6 +762,11 @@ static void set_up_environment(afl_forkserver_t *fsrv) { "handle_sigfpe=0:" "handle_sigill=0", 0); + setenv("LSAN_OPTIONS", + "exitcode=" STRINGIFY(LSAN_ERROR) ":" + "fast_unwind_on_malloc=0", + 0); + if (get_afl_env("AFL_PRELOAD")) { if (fsrv->qemu_mode) { diff --git a/test/test-pre.sh b/test/test-pre.sh index 85ac320b..174f2f7f 100755 --- a/test/test-pre.sh +++ b/test/test-pre.sh @@ -71,6 +71,7 @@ unset AFL_HARDEN unset AFL_USE_ASAN unset AFL_USE_MSAN unset AFL_USE_UBSAN +unset AFL_USE_LSAN unset AFL_TMPDIR unset AFL_CC unset AFL_PRELOAD -- cgit 1.4.1 From afc4da47f78a24d5e441e3815e5b322d1b27fd56 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Sat, 3 Apr 2021 14:50:35 +0000 Subject: Fix typos, Use symbolize=0 for LSAN, Remove syntactic sugar. --- README.md | 2 +- docs/env_variables.md | 3 ++- src/afl-analyze.c | 8 ++++---- src/afl-cc.c | 2 +- src/afl-forkserver.c | 3 ++- src/afl-fuzz-init.c | 5 ++--- src/afl-showmap.c | 4 +++- src/afl-tmin.c | 3 ++- 8 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/README.md b/README.md index 41d55e9c..4d3f8aa9 100644 --- a/README.md +++ b/README.md @@ -601,7 +601,7 @@ Every -M/-S entry needs a unique name (that can be whatever), however the same For every secondary fuzzer there should be a variation, e.g.: * one should fuzz the target that was compiled differently: with sanitizers activated (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; - export AFL_USE_CFISAN=1 ; export AFL_USE_LSAN`) + export AFL_USE_CFISAN=1 ; export AFL_USE_LSAN=1`) * one should fuzz the target with CMPLOG/redqueen (see above) * one to three fuzzers should fuzz a target compiled with laf-intel/COMPCOV (see above). Important note: If you run more than one laf-intel/COMPCOV diff --git a/docs/env_variables.md b/docs/env_variables.md index 85c2efd7..5f9233d7 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -639,7 +639,8 @@ optimal values if not already present in the environment: ``` exit_code=23 fast_unwind_on_malloc=0 -```` + symbolize=0 +``` Be sure to include the first ones for LSAN and MSAN when customizing anything, since some MSAN and LSAN versions don't call `abort()` on error, and we need a way to detect faults. diff --git a/src/afl-analyze.c b/src/afl-analyze.c index f961f13a..38a40556 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -785,10 +785,9 @@ static void set_up_environment(void) { if (x) { - if (!strstr(x, "exit_code=" STRINGIFY(LSAN_ERROR))) { + if (!strstr(x, "symbolize=0")) { - FATAL("Custom LSAN_OPTIONS set without exit_code=" STRINGIFY( - LSAN_ERROR) " - please fix!"); + FATAL("Custom LSAN_OPTIONS set without symbolize=0 - please fix!"); } @@ -833,7 +832,8 @@ static void set_up_environment(void) { setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0", + "fast_unwind_on_malloc=0:" + "symbolize=0", 0); diff --git a/src/afl-cc.c b/src/afl-cc.c index 975b28d1..650e4e43 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -758,7 +758,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) have_instr_list = 1; - if (!(strcmp(cur, "-fsanitize=address") && strcmp(cur, "-fsanitize=memory"))) + if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index fa89713a..f102b73b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -543,7 +543,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!getenv("LSAN_OPTIONS")) setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0", + "fast_unwind_on_malloc=0:" + "symbolize=0", 1); fsrv->init_child_func(fsrv, argv); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 24f5c5b5..6f663021 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2470,10 +2470,9 @@ void check_asan_opts(afl_state_t *afl) { if (x) { - if (!strstr(x, "exit_code=" STRINGIFY(LSAN_ERROR))) { + if (!strstr(x, "symbolize=0")) { - FATAL("Custom LSAN_OPTIONS set without exit_code=" STRINGIFY( - LSAN_ERROR) " - please fix!"); + FATAL("Custom LSAN_OPTIONS set without symbolize=0 - please fix!"); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index bf076683..2b7d200b 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -570,9 +570,11 @@ static void set_up_environment(afl_forkserver_t *fsrv) { "handle_sigfpe=0:" "handle_sigill=0", 0); + setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0", + "fast_unwind_on_malloc=0:" + "symbolize=0", 0); setenv("UBSAN_OPTIONS", diff --git a/src/afl-tmin.c b/src/afl-tmin.c index a2741a07..c257b67c 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -764,7 +764,8 @@ static void set_up_environment(afl_forkserver_t *fsrv) { setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0", + "fast_unwind_on_malloc=0:" + "symbolize=0", 0); if (get_afl_env("AFL_PRELOAD")) { -- cgit 1.4.1 From 3c846859eef4d17d2587ea28db83c680b51723a7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 4 Apr 2021 20:05:02 +0200 Subject: cleanup --- GNUmakefile | 38 ++++++++++++---------- GNUmakefile.gcc_plugin | 12 ++++--- GNUmakefile.llvm | 8 +++-- docs/Changelog.md | 3 ++ include/android-ashmem.h | 16 +++++---- instrumentation/afl-llvm-lto-instrumentation.so.cc | 2 +- src/afl-analyze.c | 3 +- src/afl-cc.c | 5 +-- src/afl-forkserver.c | 7 ++-- src/afl-fuzz-init.c | 1 - src/afl-tmin.c | 2 +- 11 files changed, 55 insertions(+), 42 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/GNUmakefile b/GNUmakefile index fdbcd542..d5fb570d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -36,6 +36,11 @@ SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8 ASAN_OPTIONS=detect_leaks=0 +SYS = $(shell uname -s) +ARCH = $(shell uname -m) + +$(info [*] Compiling afl++ for OS $(SYS) on ARCH $(ARCH)) + ifdef NO_SPLICING override CFLAGS += -DNO_SPLICING endif @@ -82,7 +87,7 @@ endif # endif #endif -ifneq "$(shell uname)" "Darwin" +ifneq "$(SYS)" "Darwin" #ifeq "$(HAVE_MARCHNATIVE)" "1" # SPECIAL_PERFORMANCE += -march=native #endif @@ -92,7 +97,7 @@ ifneq "$(shell uname)" "Darwin" endif endif -ifeq "$(shell uname)" "SunOS" +ifeq "$(SYS)" "SunOS" CFLAGS_OPT += -Wno-format-truncation LDFLAGS = -lkstat -lrt endif @@ -119,11 +124,10 @@ ifdef INTROSPECTION CFLAGS_OPT += -DINTROSPECTION=1 endif - -ifneq "$(shell uname -m)" "x86_64" - ifneq "$(patsubst i%86,i386,$(shell uname -m))" "i386" - ifneq "$(shell uname -m)" "amd64" - ifneq "$(shell uname -m)" "i86pc" +ifneq "$(ARCH)" "x86_64" + ifneq "$(patsubst i%86,i386,$(ARCH))" "i386" + ifneq "$(ARCH)" "amd64" + ifneq "$(ARCH)" "i86pc" AFL_NO_X86=1 endif endif @@ -141,27 +145,27 @@ override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wpoi -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \ -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" -ifeq "$(shell uname -s)" "FreeBSD" +ifeq "$(SYS)" "FreeBSD" override CFLAGS += -I /usr/local/include/ LDFLAGS += -L /usr/local/lib/ endif -ifeq "$(shell uname -s)" "DragonFly" +ifeq "$(SYS)" "DragonFly" override CFLAGS += -I /usr/local/include/ LDFLAGS += -L /usr/local/lib/ endif -ifeq "$(shell uname -s)" "OpenBSD" +ifeq "$(SYS)" "OpenBSD" override CFLAGS += -I /usr/local/include/ -mno-retpoline LDFLAGS += -Wl,-z,notext -L /usr/local/lib/ endif -ifeq "$(shell uname -s)" "NetBSD" +ifeq "$(SYS)" "NetBSD" override CFLAGS += -I /usr/pkg/include/ LDFLAGS += -L /usr/pkg/lib/ endif -ifeq "$(shell uname -s)" "Haiku" +ifeq "$(SYS)" "Haiku" SHMAT_OK=0 override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fPIC LDFLAGS += -Wno-deprecated-declarations -lgnu @@ -236,24 +240,24 @@ else BUILD_DATE ?= $(shell date "+%Y-%m-%d") endif -ifneq "$(filter Linux GNU%,$(shell uname))" "" +ifneq "$(filter Linux GNU%,$(SYS))" "" ifndef DEBUG override CFLAGS += -D_FORTIFY_SOURCE=2 endif LDFLAGS += -ldl -lrt -lm endif -ifneq "$(findstring FreeBSD, $(shell uname))" "" +ifneq "$(findstring FreeBSD, $(ARCH))" "" override CFLAGS += -pthread LDFLAGS += -lpthread endif -ifneq "$(findstring NetBSD, $(shell uname))" "" +ifneq "$(findstring NetBSD, $(ARCH))" "" override CFLAGS += -pthread LDFLAGS += -lpthread endif -ifneq "$(findstring OpenBSD, $(shell uname))" "" +ifneq "$(findstring OpenBSD, $(ARCH))" "" override CFLAGS += -pthread LDFLAGS += -lpthread endif @@ -485,7 +489,7 @@ unit_clean: @rm -f ./test/unittests/unit_preallocable ./test/unittests/unit_list ./test/unittests/unit_maybe_alloc test/unittests/*.o .PHONY: unit -ifneq "$(shell uname)" "Darwin" +ifneq "$(ARCH)" "Darwin" unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash else unit: diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index aa93c688..b0f90f1b 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -41,6 +41,8 @@ CXXEFLAGS := $(CXXFLAGS) -Wall -std=c++11 CC ?= gcc CXX ?= g++ +SYS = $(shell uname -s) + ifeq "clang" "$(CC)" CC = gcc CXX = g++ @@ -75,25 +77,25 @@ ifeq "$(TEST_MMAP)" "1" override CFLAGS_SAFE += -DUSEMMAP=1 endif -ifneq "$(shell uname -s)" "Haiku" -ifneq "$(shell uname -s)" "OpenBSD" +ifneq "$(SYS)" "Haiku" +ifneq "$(SYS)" "OpenBSD" LDFLAGS += -lrt endif else CFLAGS_SAFE += -DUSEMMAP=1 endif -ifeq "$(shell uname -s)" "OpenBSD" +ifeq "$(SYS)" "OpenBSD" CC = egcc CXX = eg++ PLUGIN_FLAGS += -I/usr/local/include endif -ifeq "$(shell uname -s)" "DragonFly" +ifeq "$(SYS)" "DragonFly" PLUGIN_FLAGS += -I/usr/local/include endif -ifeq "$(shell uname -s)" "SunOS" +ifeq "$(SYS)" "SunOS" PLUGIN_FLAGS += -I/usr/include/gmp endif diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 4b5ac520..61c17e92 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -30,7 +30,9 @@ BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/nul VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2) -ifeq "$(shell uname)" "OpenBSD" +SYS = $(shell uname -s) + +ifeq "$(SYS)" "OpenBSD" LLVM_CONFIG ?= $(BIN_PATH)/llvm-config HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1) ifeq "$(HAS_OPT)" "1" @@ -275,13 +277,13 @@ CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) # User teor2345 reports that this is required to make things work on MacOS X. -ifeq "$(shell uname)" "Darwin" +ifeq "$(SYS)" "Darwin" CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress else CLANG_CPPFL += -Wl,-znodelete endif -ifeq "$(shell uname)" "OpenBSD" +ifeq "$(SYS)" "OpenBSD" CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so CLANG_CPPFL += -mno-retpoline CFLAGS += -mno-retpoline diff --git a/docs/Changelog.md b/docs/Changelog.md index 91d1a8cc..24877f9a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,6 +11,8 @@ sending a mail to . ### Version ++3.13a (development) - frida_mode - new mode that uses frida to fuzz binary-only targets, thanks to @WorksButNotTested! + - create a fuzzing dictionary with the help of CodeQL thanks to + @microsvuln! see utils/autodict_ql - afl-fuzz: - added patch by @realmadsci to support @@ as part of command line options, e.g. `afl-fuzz ... -- ./target --infile=@@` @@ -20,6 +22,7 @@ sending a mail to . - default cmplog level (-l) is now 2, better efficiency. - ensure one fuzzer sync per cycle - afl-cc: + - Leak Sanitizer support (AFL_USE_LSAN) added by Joshua Rogers, thanks! - Removed InsTrim instrumentation as it is not as good as PCGUARD ### Version ++3.12c (release) diff --git a/include/android-ashmem.h b/include/android-ashmem.h index 44fe556a..1bfd3220 100644 --- a/include/android-ashmem.h +++ b/include/android-ashmem.h @@ -13,12 +13,14 @@ #include #define ASHMEM_DEVICE "/dev/ashmem" -int shmdt(const void* address) { -#if defined(SYS_shmdt) +int shmdt(const void *address) { + + #if defined(SYS_shmdt) return syscall(SYS_shmdt, address); -#else + #else return syscall(SYS_ipc, SHMDT, 0, 0, 0, address, 0); -#endif + #endif + } int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { @@ -26,7 +28,7 @@ int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { int ret = 0; if (__cmd == IPC_RMID) { - int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); + int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); struct ashmem_pin pin = {0, length}; ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); close(__shmid); @@ -77,6 +79,6 @@ void *shmat(int __shmid, const void *__shmaddr, int __shmflg) { } - #endif /* !_ANDROID_ASHMEM_H */ -#endif /* !__ANDROID__ */ + #endif /* !_ANDROID_ASHMEM_H */ +#endif /* !__ANDROID__ */ diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 50306224..6eb19060 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -176,7 +176,7 @@ bool AFLLTOPass::runOnModule(Module &M) { } - if (debug) { fprintf(stderr, "map address is 0x%lx\n", map_addr); } + if (debug) { fprintf(stderr, "map address is 0x%llx\n", map_addr); } /* Get/set the globals for the SHM region. */ diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 7d7519fa..aabdbf1a 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -833,14 +833,13 @@ static void set_up_environment(char **argv) { "handle_sigfpe=0:" "handle_sigill=0", 0); - setenv("LSAN_OPTIONS", + setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" "fast_unwind_on_malloc=0:" "symbolize=0:" "print_suppressions=0", 0); - if (get_afl_env("AFL_PRELOAD")) { if (qemu_mode) { diff --git a/src/afl-cc.c b/src/afl-cc.c index d4c0a6b7..3af31b3c 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -820,10 +820,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } if (getenv("AFL_USE_LSAN")) { + cc_params[cc_par_cnt++] = "-fsanitize=leak"; cc_params[cc_par_cnt++] = "-includesanitizer/lsan_interface.h"; - cc_params[cc_par_cnt++] = - "-D__AFL_LEAK_CHECK()=__lsan_do_leak_check()"; + cc_params[cc_par_cnt++] = "-D__AFL_LEAK_CHECK()=__lsan_do_leak_check()"; + } if (getenv("AFL_USE_CFISAN")) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index cd04e23d..2c502621 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -560,7 +560,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* LSAN, too, does not support abort_on_error=1. */ if (!getenv("LSAN_OPTIONS")) - setenv("LSAN_OPTIONS", + setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" "fast_unwind_on_malloc=0:" "symbolize=0:" @@ -1314,8 +1314,9 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* A normal crash/abort */ (WIFSIGNALED(fsrv->child_status)) || /* special handling for msan and lsan */ - (fsrv->uses_asan && (WEXITSTATUS(fsrv->child_status) == MSAN_ERROR || - WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) || + (fsrv->uses_asan && + (WEXITSTATUS(fsrv->child_status) == MSAN_ERROR || + WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) || /* the custom crash_exitcode was returned by the target */ (fsrv->uses_crash_exitcode && WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 48f3289d..e505abd4 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2502,7 +2502,6 @@ void check_asan_opts(afl_state_t *afl) { } - } /* Handle stop signal (Ctrl-C, etc). */ diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 6aad748c..6656712a 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -763,7 +763,7 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) { "handle_sigfpe=0:" "handle_sigill=0", 0); - setenv("LSAN_OPTIONS", + setenv("LSAN_OPTIONS", "exitcode=" STRINGIFY(LSAN_ERROR) ":" "fast_unwind_on_malloc=0:" "symbolize=0:" -- cgit 1.4.1 From be880f2476963b8ebebe9d8cc196e4e74104c7a6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 13 Apr 2021 13:01:50 +0200 Subject: add AFL_EXIT_ON_SEED_ISSUES --- docs/Changelog.md | 3 +++ docs/env_variables.md | 3 +++ include/afl-fuzz.h | 3 ++- include/envs.h | 1 + src/afl-fuzz-init.c | 8 +++++++- src/afl-fuzz-state.c | 7 +++++++ 6 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/docs/Changelog.md b/docs/Changelog.md index 4139a9b3..14a0bdaf 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -24,6 +24,9 @@ sending a mail to . - ensure one fuzzer sync per cycle - fix afl_custom_queue_new_entry original file name when syncing from fuzzers + - added AFL_EXIT_ON_SEED_ISSUES env that will exit if a seed in + -i dir crashes the target or results in a timeout. By default + afl++ ignores these and uses them for splicing instead. - afl-cc: - Leak Sanitizer support (AFL_USE_LSAN) added by Joshua Rogers, thanks! - Removed InsTrim instrumentation as it is not as good as PCGUARD diff --git a/docs/env_variables.md b/docs/env_variables.md index 8d482e20..1f4dfef9 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -284,6 +284,9 @@ checks or alter some of the more exotic semantics of the tool: normally indicated by the cycle counter in the UI turning green. May be convenient for some types of automated jobs. + - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behaviour + which does not allow crashes or timeout seeds in the initial -i corpus. + - `AFL_MAP_SIZE` sets the size of the shared map that afl-fuzz, afl-showmap, afl-tmin and afl-analyze create to gather instrumentation data from the target. This must be equal or larger than the size the target was diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 325168f2..f201782a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -384,7 +384,8 @@ typedef struct afl_env_vars { afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui, afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, - afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new; + afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, + afl_exit_on_seed_issues; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, diff --git a/include/envs.h b/include/envs.h index 466ab087..ebe98257 100644 --- a/include/envs.h +++ b/include/envs.h @@ -49,6 +49,7 @@ static char *afl_environment_variables[] = { "AFL_DUMB_FORKSRV", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", + "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index e505abd4..b6bfbc29 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -881,7 +881,7 @@ void perform_dry_run(afl_state_t *afl) { case FSRV_RUN_TMOUT: - if (afl->timeout_given) { + if (afl->timeout_given && !afl->afl_env.afl_exit_on_seed_issues) { /* if we have a timeout but a timeout value was given then always skip. The '+' meaning has been changed! */ @@ -1036,6 +1036,12 @@ void perform_dry_run(afl_state_t *afl) { } + if (afl->afl_env.afl_exit_on_seed_issues) { + + FATAL("As AFL_EXIT_ON_SEED_ISSUES is set, afl-fuzz exits."); + + } + /* Remove from fuzzing queue but keep for splicing */ struct queue_entry *p = afl->queue; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index f65ff1bb..28d3339a 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -306,6 +306,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->cycle_schedules = afl->afl_env.afl_cycle_schedules = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_EXIT_ON_SEED_ISSUES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_exit_on_seed_issues = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_EXPAND_HAVOC_NOW", afl_environment_variable_len)) { -- cgit 1.4.1