Skip to content

Commit

Permalink
1.89b
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-huet committed Sep 1, 2015
1 parent dac1eea commit fcf6d73
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 133 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#

PROGNAME = afl
VERSION = 1.88b
VERSION = 1.89b

PREFIX ?= /usr/local
BIN_PATH = $(PREFIX)/bin
Expand Down
37 changes: 27 additions & 10 deletions afl-fuzz.c
Original file line number Diff line number Diff line change
Expand Up @@ -2072,9 +2072,9 @@ static void init_forkserver(char** argv) {

" - Less likely, there is a horrible bug in the fuzzer. If other options\n"
" fail, poke <[email protected]> for troubleshooting tips.\n",
getenv("AFL_DEFER_FORKSRV") ? "three" : "two",
getenv("AFL_DEFER_FORKSRV") ?
" - You are using AFL_DEFER_FORKSRV, but __afl_manual_init() is never\n"
getenv(DEFER_ENV_VAR) ? "three" : "two",
getenv(DEFER_ENV_VAR) ?
" - You are using deferred forkserver, but __AFL_INIT() is never\n"
" reached before the program terminates.\n\n" : "",
DMS(mem_limit << 20), mem_limit - 1);

Expand Down Expand Up @@ -6605,6 +6605,23 @@ static void check_binary(u8* fname) {
if (memmem(f_data, f_len, "libasan.so", 10) ||
memmem(f_data, f_len, "__msan_init", 11)) uses_asan = 1;

/* Detect persistent & deferred init signatures in the binary. */

if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {

OKF("Persistent-mode binary detected.");
setenv(PERSIST_ENV_VAR, "1", 1);
no_var_check = 1;

}

if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {

OKF("Deferred forkserver binary detected.");
setenv(DEFER_ENV_VAR, "1", 1);

}

if (munmap(f_data, f_len)) PFATAL("unmap() failed");

}
Expand Down Expand Up @@ -6877,7 +6894,8 @@ static void check_crash_handling(void) {
" launchctl unload -w ${SL}/LaunchAgents/${PL}.plist\n"
" sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist\n");

FATAL("Crash reporter detected");
if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES"))
FATAL("Crash reporter detected");

#else

Expand All @@ -6904,7 +6922,8 @@ static void check_crash_handling(void) {

" echo core >/proc/sys/kernel/core_pattern\n");

FATAL("Pipe at the beginning of 'core_pattern'");
if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES"))
FATAL("Pipe at the beginning of 'core_pattern'");

}

Expand Down Expand Up @@ -7491,11 +7510,9 @@ int main(int argc, char** argv) {

}

if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;

if (getenv("AFL_NO_VAR_CHECK") || getenv("AFL_PERSISTENT"))
no_var_check = 1;
if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;
if (getenv("AFL_NO_VAR_CHECK")) no_var_check = 1;

if (dumb_mode == 2 && no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
Expand Down
5 changes: 2 additions & 3 deletions afl-showmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,6 @@ static void set_up_environment(void) {
setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
"msan_track_origins=0", 0);

unsetenv("AFL_PERSISTENT");

}


Expand Down Expand Up @@ -444,7 +442,8 @@ static void usage(u8* argv0) {
" -q - sink program's output and don't show messages\n"
" -e - show edge coverage only, ignore hit counts\n\n"

"For additional tips, please consult %s/README.\n\n",
"This tool displays raw tuple data captured by AFL instrumentation.\n"
"For additional help, consult %s/README.\n\n",

argv0, MEM_LIMIT, doc_path);

Expand Down
2 changes: 0 additions & 2 deletions afl-tmin.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,6 @@ static void set_up_environment(void) {
setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
"msan_track_origins=0", 0);

unsetenv("AFL_PERSISTENT");

}


Expand Down
7 changes: 7 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,13 @@

#define CLANG_ENV_VAR "__AFL_CLANG_MODE"
#define AS_LOOP_ENV_VAR "__AFL_AS_LOOPCHECK"
#define PERSIST_ENV_VAR "__AFL_PERSISTENT"
#define DEFER_ENV_VAR "__AFL_DEFER_FORKSRV"

/* In-code signatures for deferred and persistent mode. */

#define PERSIST_SIG "##SIG_AFL_PERSISTENT##"
#define DEFER_SIG "##SIG_AFL_DEFER_FORKSRV##"

/* Distinctive bitmap signature used to indicate failed execution: */

Expand Down
10 changes: 10 additions & 0 deletions docs/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ Not sure if you should upgrade? The lowest currently recommended version
is 1.76b. If you're stuck on an earlier release, it's strongly advisable
to get on with the times.

--------------
Version 1.89b:
--------------

- Revamped the support for persistent and deferred forkserver modes.
Both now feature simpler syntax and do not require companion env
variables. Suggested by Jakub Wilk.

- Added a bit more info about afl-showmap. Suggested by Jacek Wielemborek.

--------------
Version 1.88b:
--------------
Expand Down
23 changes: 5 additions & 18 deletions docs/env_variables.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,8 @@ checks or alter some of the more exotic semantics of the tool:

- When running in the -M or -S mode, setting AFL_IMPORT_FIRST causes the
fuzzer to import test cases from other instances before doing anything
else. This is in contrast with the default mode, where the instances are
allowed to run on their own for a while before syncing, so that they
acquire some initial variability in their respective input sets.

The benefit of AFL_IMPORT_FIRST is that it makes the "own finds" counter
in the UI more accurately reflect the number of findings made by the
instance (that the remaining instances did not already have). Beyond
counter aesthetics, not much else should change.
else. This makes the "own finds" counter in the UI more accurate
Beyond counter aesthetics, not much else should change.

- Setting AFL_POST_LIBRARY allows you to configure a postprocessor for
mutated files - say, to fix up checksums. See experimental/post_library/
Expand All @@ -139,18 +133,11 @@ 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 programs not compiled with afl-clang-fast.

(Technically speaking, the setting is passed down to the binary itself,
and not handled in any special way by afl-fuzz.)

- In LLVM mode, AFL_PERSISTENT can be set to fuzz in persistent mode. See
llvm_mode/README.llvm for additional information on what this means.

- In QEMU mode (-Q), AFL_PATH will be searched for afl-qemu-trace.

- If you are Jakub, you may need AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES.
Others need not apply.

4) Settings for afl-qemu-trace
------------------------------

Expand Down
78 changes: 32 additions & 46 deletions experimental/persistent_demo/persistent_demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
across runs.
To make this work, the library and this shim need to be compiled in LLVM
mode using afl-clang-fast (other compiler wrappers will *not* work); and
afl-fuzz must be called with AFL_PERSISTENT set.
mode using afl-clang-fast (other compiler wrappers will *not* work).
*/

Expand All @@ -29,14 +28,6 @@
#include <signal.h>
#include <string.h>

/* This constant specifies the number of inputs to process before restarting.
This is optional, but helps limit the impact of memory leaks and similar
hiccups. */

#define PERSIST_MAX 1000

unsigned int persist_cnt;


/* Main entry point. */

Expand All @@ -45,57 +36,52 @@ int main(int argc, char** argv) {
char buf[100]; /* Example-only buffer, you'd replace it with other global or
local variables appropriate for your use case. */

try_again:
/* The number passed to __AFL_LOOP() controls the maximum number of
iterations before the loop exits and the program is allowed to
terminate normally. This limits the impact of accidental memory leaks
and similar hiccups. */

while (__AFL_LOOP(1000)) {

/*** PLACEHOLDER CODE ***/
/*** PLACEHOLDER CODE ***/

/* STEP 1: Fully re-initialize all critical variables. In our example, this
involves zeroing buf[], our input buffer. */
/* STEP 1: Fully re-initialize all critical variables. In our example, this
involves zeroing buf[], our input buffer. */

memset(buf, 0, 100);
memset(buf, 0, 100);

/* STEP 2: Read input data. When reading from stdin, no special preparation
is required. When reading from a named file, you need to close the
old descriptor and reopen the file first!
/* STEP 2: Read input data. When reading from stdin, no special preparation
is required. When reading from a named file, you need to close
the old descriptor and reopen the file first!
Beware of reading from buffered FILE* objects such as stdin. Use
raw file descriptors or call fopen() / fdopen() in every pass. */
Beware of reading from buffered FILE* objects such as stdin. Use
raw file descriptors or call fopen() / fdopen() in every pass. */

read(0, buf, 100);
read(0, buf, 100);

/* STEP 3: This is where we'd call the tested library on the read data. Here,
we just have some trivial inline code that faults on 'foo!'. */
/* STEP 3: This is where we'd call the tested library on the read data.
We just have some trivial inline code that faults on 'foo!'. */

if (buf[0] == 'f') {
printf("one\n");
if (buf[1] == 'o') {
printf("two\n");
if (buf[2] == 'o') {
printf("three\n");
if (buf[3] == '!') {
printf("four\n");
abort();
if (buf[0] == 'f') {
printf("one\n");
if (buf[1] == 'o') {
printf("two\n");
if (buf[2] == 'o') {
printf("three\n");
if (buf[3] == '!') {
printf("four\n");
abort();
}
}
}
}
}

/*** END PLACEHOLDER CODE ***/

/* STEP 4: To signal successful completion of a run, we need to deliver
SIGSTOP to our own process, then loop to the very beginning
once we're resumed by the supervisor process. We do this only
if AFL_PERSISTENT is set to retain normal behavior when the
program is executed directly; and take note of PERSIST_MAX. */

if (getenv("AFL_PERSISTENT") && persist_cnt++ < PERSIST_MAX) {

raise(SIGSTOP);
goto try_again;
/*** END PLACEHOLDER CODE ***/

}

/* If AFL_PERSISTENT not set or PERSIST_MAX exceeded, exit normally. */
/* Once the loop is exited, terminate normally - AFL will restat the process
from scratch. */

return 0;

Expand Down
2 changes: 1 addition & 1 deletion llvm_mode/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ test_deps:

test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..."
unset AFL_USE_ASAN AFL_USE_MSAN AFL_DEFER_FORKSRV; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
echo 0 | ../afl-showmap -m none -q -o .test-instr0 ./test-instr
echo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr
@rm -f test-instr
Expand Down
Loading

0 comments on commit fcf6d73

Please sign in to comment.