diff --git a/Makefile b/Makefile index 7a4771a5..40128933 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ # PROGNAME = afl -VERSION = 1.94b +VERSION = 1.95b PREFIX ?= /usr/local BIN_PATH = $(PREFIX)/bin diff --git a/afl-as.h b/afl-as.h index 0866bd2d..1cca7986 100644 --- a/afl-as.h +++ b/afl-as.h @@ -334,7 +334,7 @@ static const u8* main_payload_32 = "__afl_die:\n" "\n" " xorl %eax, %eax\n" - " call exit\n" + " call _exit\n" "\n" "__afl_setup_abort:\n" "\n" @@ -639,7 +639,7 @@ static const u8* main_payload_64 = "__afl_die:\n" "\n" " xorq %rax, %rax\n" - CALL_L64("exit") + CALL_L64("_exit") "\n" "__afl_setup_abort:\n" "\n" diff --git a/afl-fuzz.c b/afl-fuzz.c index 2192d4de..88839d0a 100644 --- a/afl-fuzz.c +++ b/afl-fuzz.c @@ -1201,8 +1201,7 @@ static void setup_shm(void) { fork server commands. This should be replaced with better auto-detection later on, perhaps? */ - if (dumb_mode != 1) - setenv(SHM_ENV_VAR, shm_str, 1); + if (!dumb_mode) setenv(SHM_ENV_VAR, shm_str, 1); ck_free(shm_str); @@ -3700,7 +3699,7 @@ static void show_stats(void) { /* Honor AFL_EXIT_WHEN_DONE. */ if (!dumb_mode && cycles_wo_finds > 20 && !pending_not_fuzzed && - getenv("AFL_EXIT_WHEN_DONE")) stop_soon = 1; + getenv("AFL_EXIT_WHEN_DONE")) stop_soon = 2; /* If we're not on TTY, bail out. */ @@ -6613,6 +6612,10 @@ static void check_binary(u8* fname) { setenv(PERSIST_ENV_VAR, "1", 1); no_var_check = 1; + } else if (getenv("AFL_PERSISTENT")) { + + WARNF("AFL_PERSISTENT is no longer supported and may misbehave!"); + } if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { @@ -6620,6 +6623,10 @@ static void check_binary(u8* fname) { OKF(cPIN "Deferred forkserver binary detected."); setenv(DEFER_ENV_VAR, "1", 1); + } else if (getenv("AFL_DEFER_FORKSRV")) { + + WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!"); + } if (munmap(f_data, f_len)) PFATAL("unmap() failed"); @@ -7468,7 +7475,7 @@ int main(int argc, char** argv) { case 'n': if (dumb_mode) FATAL("Multiple -n options not supported"); - if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2 ; else dumb_mode = 1; + if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2; else dumb_mode = 1; break; @@ -7640,7 +7647,8 @@ int main(int argc, char** argv) { stop_fuzzing: - SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted by user +++\n" cRST); + SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing %s +++\n" cRST, + stop_soon == 2 ? "ended via AFL_EXIT_WHEN_DONE" : "aborted by user"); /* Running for more than 30 minutes but still doing first cycle? */ diff --git a/afl-gcc.c b/afl-gcc.c index 1bbf2bae..89c2bbc1 100644 --- a/afl-gcc.c +++ b/afl-gcc.c @@ -184,7 +184,7 @@ static void edit_params(u32 argc, char** argv) { if (!be_quiet) WARNF("-B is already set, overriding"); - if (!cur[2] && argc) { argc--; argv++; } + if (!cur[2] && argc > 1) { argc--; argv++; } continue; } diff --git a/docs/ChangeLog b/docs/ChangeLog index 408e0b99..eb28122b 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -16,6 +16,23 @@ Not sure if you should upgrade? The lowest currently recommended version is 1.92b. If you're stuck on an earlier release, it's strongly advisable to get on with the times. +-------------- +Version 1.95b: +-------------- + + - Fixed a harmless bug when handling -B. Spotted by Jacek Wielemborek. + + - Made the exit message a bit more accurate when AFL_EXIT_WHEN_DONE is set. + + - Added some error-checking for old-style forkserver syntax. Suggested by + Ben Nagy. + + - Switched from exit() to _exit() in injected code to avoid snafus with + destructors in C++ code. Spotted by sunblate. + + - Made a change to avoid spuriously setting __AFL_SHM_ID when + AFL_DUMB_FORKSRV is set in conjunction with -n. Spotted by Jakub Wilk. + -------------- Version 1.94b: -------------- diff --git a/hash.h b/hash.h index fed2d0b4..530cd632 100644 --- a/hash.h +++ b/hash.h @@ -10,7 +10,7 @@ similar to the original; the 64-bit one is a custom hack with mostly-unproven properties. - Austin's original code is public domain; so is this variant. + Austin's original code is public domain. */ diff --git a/llvm_mode/README.llvm b/llvm_mode/README.llvm index 8006a064..c70b20f6 100644 --- a/llvm_mode/README.llvm +++ b/llvm_mode/README.llvm @@ -95,7 +95,7 @@ to read the fuzzed input and parse it; in some cases, this can offer a 10x+ performance gain. You can implement delayed initialization in LLVM mode in a fairly simple way. -First, locate a suitable location in the code where the delayed cloning can +First, find a suitable location in the code where the delayed cloning can take place. This needs to be done with *extreme* care to avoid breaking the binary. In particular, the program will probably malfunction if you select a location after: @@ -118,8 +118,8 @@ With the location selected, add this code in the appropriate spot: __AFL_INIT(); #endif -You don't need the #ifdef guards, but they will make the program still work as -usual when compiled with a tool other than afl-clang-fast. +You don't need the #ifdef guards, but including them ensures that the program +will keep working normally when compiled with a tool other than afl-clang-fast. Finally, recompile the pogram with afl-clang-fast (afl-gcc or afl-clang will *not* generate a deferred-initialization binary) - and you should be all set! @@ -153,9 +153,9 @@ Similarly to the previous mode, the feature works only with afl-clang-fast; #ifdef guards can be used to suppress it when using other compilers. Note that as with the previous mode, the feature is easy to misuse; if you -do not reset the critical state fully, you may end up with false positives or +do not fully reset the critical state, you may end up with false positives or waste a whole lot of CPU power doing nothing useful at all. Be particularly -wary of memory leaks and the state of file descriptors. +wary of memory leaks and of the state of file descriptors. When running in this mode, the execution paths will inherently vary a bit depending on whether the input loop is being entered for the first time or diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index ab9151e9..03e2afe0 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -65,7 +65,7 @@ static void __afl_map_shm(void) { /* Whooooops. */ - if (__afl_area_ptr == (void *)-1) exit(1); + if (__afl_area_ptr == (void *)-1) _exit(1); /* Write something into the bitmap so that even with low AFL_INST_RATIO, our parent doesn't give up on us. */ @@ -98,7 +98,7 @@ static void __afl_start_forkserver(void) { /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(1); + if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); /* If we stopped the child in persistent mode, but there was a race condition and afl-fuzz already issued SIGKILL, write off the old @@ -106,7 +106,7 @@ static void __afl_start_forkserver(void) { if (child_stopped && was_killed) { child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) exit(1); + if (waitpid(child_pid, &status, 0) < 0) _exit(1); } if (!child_stopped) { @@ -114,7 +114,7 @@ static void __afl_start_forkserver(void) { /* Once woken up, create a clone of our process. */ child_pid = fork(); - if (child_pid < 0) exit(1); + if (child_pid < 0) _exit(1); /* In child process: close fds, resume execution. */ @@ -138,10 +138,10 @@ static void __afl_start_forkserver(void) { /* In parent process: write PID to pipe, then wait for child. */ - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(1); + if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1); if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) - exit(1); + _exit(1); /* In persistent mode, the child stops itself with SIGSTOP to indicate a successful run. In this case, we want to wake it up without forking @@ -151,7 +151,7 @@ static void __afl_start_forkserver(void) { /* Relay wait status to pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1); + if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1); } diff --git a/qemu_mode/README.qemu b/qemu_mode/README.qemu index 290bd4cf..ce4181e4 100644 --- a/qemu_mode/README.qemu +++ b/qemu_mode/README.qemu @@ -39,7 +39,8 @@ to 200 MB when specifying -Q to afl-fuzz; be careful when overriding this. In principle, if you set CPU_TARGET before calling ./build_qemu_support.sh, you should get a build capable of running non-native binaries (say, you -can try CPU_TARGET=arm). I haven't played with this. +can try CPU_TARGET=arm). This is also necessary for running 32-bit binaries +on a 64-bit system (CPU_TARGET=i386). Note: if you want the QEMU helper to be installed on your system for all users, you need to build it before issuing 'make install' in the parent @@ -104,10 +105,9 @@ You can send them to . --------------------------------- Statically rewriting binaries just once, instead of attempting to translate -them at run time, can be a faster alternative to what is being attempted here. -That said, static rewriting is fraught with peril, because it depends on being -able to properly and fully model program control flow without actually running -it. +them at run time, can be a faster alternative. That said, static rewriting is +fraught with peril, because it depends on being able to properly and fully model +program control flow without actually executing each and every code path. If you want to experiment with this mode of operation, there is a module contributed by Aleksandar Nikolich: