diff --git a/Makefile b/Makefile index 78db6858..3c1bc08a 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ # PROGNAME = afl -VERSION = 1.68b +VERSION = 1.69b PREFIX ?= /usr/local BIN_PATH = $(PREFIX)/bin diff --git a/docs/ChangeLog b/docs/ChangeLog index 8be8ffed..c66ebeef 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -16,6 +16,13 @@ Not sure if you should upgrade? The lowest currently recommended version is 1.48b. If you're stuck on an earlier release, it's strongly advisable to get on with the times. +-------------- +Version 1.69b: +-------------- + + - Added support for deferred initialization in LLVM mode. Suggested by + Richard Godbee. + -------------- Version 1.68b: -------------- diff --git a/docs/README b/docs/README index a1fe1bca..cc1d17be 100644 --- a/docs/README +++ b/docs/README @@ -422,7 +422,7 @@ bug reports, or patches from: Aidan Thornton Aleksandar Nikolich Sam Hakim Laszlo Szekeres David A. Wheeler Turo Lamminen - Andreas Stieger + Andreas Stieger Richard Godbee Thank you! @@ -439,9 +439,9 @@ archives first, try: https://groups.google.com/group/afl-users PS. If you wish to submit raw code to be incorporated into the project, please -be aware that the copyright on most of AFL is formally claimed by Google. While -you do retain copyright on your contributions, they do ask people to agree -to a simple CLA first: +be aware that the copyright on most of AFL is claimed by Google. While you do +retain copyright on your contributions, they do ask people to agree to a simple +CLA first: https://cla.developers.google.com/clas diff --git a/docs/env_variables.txt b/docs/env_variables.txt index 5aae1f2b..9d3a481d 100644 --- a/docs/env_variables.txt +++ b/docs/env_variables.txt @@ -110,6 +110,10 @@ checks or alter some of the more exotic semantics of the tool: may complain of high load prematurely, especially on systems with low core counts. To avoid the alarming red color, you can set AFL_NO_CPU_RED. + - In LLVM mode, AFL_DEFER_FORKSRV can be set to require the forkserver to + be initialized manually (see llvm_mode/README.llvm). This setting has no + effect for progrms not compiled with afl-clang-fast. + 3) Settings for afl-qemu-trace ------------------------------ diff --git a/docs/perf_tips.txt b/docs/perf_tips.txt index 5d6f04d4..5115aeea 100644 --- a/docs/perf_tips.txt +++ b/docs/perf_tips.txt @@ -86,6 +86,9 @@ things would be calling other utilities via exec*(), popen(), system(), or equivalent calls. Some programs may intentionally call sleep(), usleep(), or nanosleep(), etc. +In programs that are slow due to unavoidable initialization overhead, you may +want to try the LLVM deferred forkserver mode (see llvm_mode/README.llvm). + Last but not least, if you are using ASAN and the performance is unacceptable, consider turning it off for now, and manually examining the generated corpus with an ASAN-enabled binary later on. diff --git a/docs/vuln_samples/sqlite-use-after-free.sql b/docs/vuln_samples/sqlite-use-after-free.sql new file mode 100644 index 00000000..4083ee64 --- /dev/null +++ b/docs/vuln_samples/sqlite-use-after-free.sql @@ -0,0 +1 @@ +create table t(s);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql='ANALYZE;CREATE VIRTUAL TABLE t USING fts3;DROP TABLE t;DROP TABLE EXISTS t';PRAGMA r;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t; diff --git a/llvm_mode/README.llvm b/llvm_mode/README.llvm index 9fbb11c6..2124ce94 100644 --- a/llvm_mode/README.llvm +++ b/llvm_mode/README.llvm @@ -72,3 +72,44 @@ directory. This is an early-stage mechanism, so field reports are welcome. You can send bug reports to . + +4) Bonus feature: deferred instrumentation +------------------------------------------ + +AFL tries to optimize performance by executing the targeted binary just once, +stopping it just before main(), and then cloning this "master" process to get +a steady supply of targets to fuzz. + +Although this approach eliminates much of the OS-, linker- and libc-level +costs of executing the program, it does not always help with binaries that +perform other time-consuming initialization steps before getting to the input +file. + +In such cases, it would be beneficial to initialize the forkserver a bit later, +once most of the initialization work is already done, and the binary is about +to read the fuzzed input and parse it. You can do this in LLVM mode in a fairly +simple way: + +1) First, locate a suitable location in the code for the deferred initialization + to take place. This needs to be done with *extreme* care to avoid breaking + the binary. In particular, the program will probably malfunction if the + initialization happens after: + + - The creation of any vital threads or child processes - since the forkserver + can't clone them easily. + + - The creation of temporary files, network sockets, offset-sensitive file + descriptors, and similar shared-state resources - but only provided that + they actually influence the behavior of the program later on. + + - Any access to the fuzzed input or the metadata about its size. + +2) Next, insert the following global function declaration somewhere in the + source file: + + void __afl_manual_init(void); + + ...and add a call to this function in the desired location before recompiling + the project with afl-clang-fast (afl-gcc and afl-clang will *not* work). + +3) Finally, be sure to set AFL_DEFER_FORKSRV=1 before invoking afl-fuzz. diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 927c0fbe..17637d7d 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -27,6 +27,7 @@ #include #include #include +#include /* Globals needed by the injected instrumentation. The __afl_area_initial region @@ -37,7 +38,6 @@ u8 __afl_area_initial[MAP_SIZE]; u8* __afl_area_ptr = __afl_area_initial; u16 __afl_prev_loc; - /* SHM setup. */ static void __afl_map_shm(void) { @@ -117,10 +117,30 @@ static void __afl_start_forkserver(void) { } +/* This one can be called from user code when AFL_DEFER_FORKSRV is set. */ + +void __afl_manual_init(void) { + + static u8 init_done; + + if (!init_done) { + + __afl_map_shm(); + __afl_start_forkserver(); + init_done = 1; + + } + +} + + /* Proper initialization routine. */ -__attribute__((constructor(0))) void __afl_init() { - __afl_map_shm(); - __afl_start_forkserver(); +__attribute__((constructor(0))) void __afl_auto_init(void) { + + if (getenv("AFL_DEFER_FORKSRV")) return; + __afl_manual_init(); + } +