aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--README.md1
-rw-r--r--include/afl-fuzz.h4
-rw-r--r--include/common.h10
-rw-r--r--include/debug.h4
-rw-r--r--include/forkserver.h16
-rw-r--r--llvm_mode/README.lto.md16
-rw-r--r--llvm_mode/afl-clang-fast.c6
-rw-r--r--src/afl-analyze.c73
-rw-r--r--src/afl-common.c80
-rw-r--r--src/afl-forkserver.c84
-rw-r--r--src/afl-fuzz-bitmap.c36
-rw-r--r--src/afl-fuzz-cmplog.c2
-rw-r--r--src/afl-fuzz-mutators.c5
-rw-r--r--src/afl-fuzz-one.c4
-rw-r--r--src/afl-fuzz-python.c2
-rw-r--r--src/afl-fuzz-redqueen.c4
-rw-r--r--src/afl-fuzz-run.c56
-rw-r--r--src/afl-fuzz.c4
-rw-r--r--src/afl-sharedmem.c2
-rw-r--r--src/afl-showmap.c133
-rw-r--r--src/afl-tmin.c161
-rw-r--r--src/third_party/libradamsa/libradamsa.c76
-rw-r--r--src/third_party/libradamsa/radamsa.h6
-rw-r--r--test/unittests/unit_list.c2
-rw-r--r--test/unittests/unit_maybe_alloc.c2
-rw-r--r--test/unittests/unit_preallocable.c2
27 files changed, 345 insertions, 448 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 74a290e6..11dfa803 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -69,7 +69,7 @@ ifneq "$(shell uname -m)" "x86_64"
endif
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
-override CFLAGS += -Wall -g -Wno-pointer-sign \
+override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
diff --git a/README.md b/README.md
index f14ccd36..a6afe73a 100644
--- a/README.md
+++ b/README.md
@@ -352,6 +352,7 @@ Here are some good writeups to show how to effectively use AFL++:
* [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
* [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
* [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
+ * [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
If you are interested in fuzzing structured data (where you define what the
structure is), these two links have you covered:
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 7c6019e6..363776cb 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -808,6 +808,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
/* Python */
#ifdef USE_PYTHON
+void load_custom_mutator_py(afl_state_t *, char *);
void finalize_py_module(void *);
size_t pre_save_py(void *, u8 *, size_t, u8 **);
@@ -835,7 +836,6 @@ u32 calculate_score(afl_state_t *, struct queue_entry *);
/* Bitmap */
-void read_bitmap(afl_state_t *, u8 *);
void write_bitmap(afl_state_t *);
u32 count_bits(afl_state_t *, u8 *);
u32 count_bytes(afl_state_t *, u8 *);
@@ -873,7 +873,7 @@ void show_init_stats(afl_state_t *);
/* Run */
-fsrv_run_result_t run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
+fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
void write_to_testcase(afl_state_t *, void *, u32);
u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
void sync_fuzzers(afl_state_t *);
diff --git a/include/common.h b/include/common.h
index 8dd66355..f5ace878 100644
--- a/include/common.h
+++ b/include/common.h
@@ -51,6 +51,16 @@ char * get_afl_env(char *env);
extern u8 be_quiet;
extern u8 *doc_path; /* path to documentation dir */
+/* Find binary, used by analyze, showmap, tmin
+ @returns the path, allocating the string */
+
+u8 *find_binary(u8 *fname);
+
+/* Read a bitmap from file fname to memory
+ This is for the -B option again. */
+
+void read_bitmap(u8 *fname, u8 *map, size_t len);
+
/* Get unix time in milliseconds */
u64 get_cur_time(void);
diff --git a/include/debug.h b/include/debug.h
index 8824ff6b..4cce56b5 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -29,12 +29,8 @@
#include "config.h"
/* __FUNCTION__ is non-iso */
-#ifndef __FUNCTION__
#ifdef __func__
#define __FUNCTION__ __func__
-#else
-#define __FUNCTION__ "func_unknown"
-#endif
#endif
/*******************
diff --git a/include/forkserver.h b/include/forkserver.h
index f24393bc..ac89b681 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -51,6 +51,8 @@ typedef struct afl_forkserver {
fsrv_ctl_fd, /* Fork server control pipe (write) */
fsrv_st_fd; /* Fork server status pipe (read) */
+ u8 no_unlink; /* do not unlink cur_input */
+
u32 exec_tmout; /* Configurable exec timeout (ms) */
u32 map_size; /* map size used by the target */
u32 snapshot; /* is snapshot feature used */
@@ -63,7 +65,8 @@ typedef struct afl_forkserver {
FILE *plot_file; /* Gnuplot output file */
- u8 last_run_timed_out; /* Traced process timed out? */
+ /* Note: lat_run_timed_out is u32 to send it to the child as 4 byte array */
+ u32 last_run_timed_out; /* Traced process timed out? */
u8 last_kill_signal; /* Signal that killed the child */
@@ -97,12 +100,11 @@ void afl_fsrv_init(afl_forkserver_t *fsrv);
void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from);
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
volatile u8 *stop_soon_p, u8 debug_child_output);
-fsrv_run_result_t afl_fsrv_run_target(
- afl_forkserver_t *fsrv, u32 timeout,
- void(classify_counts_func)(afl_forkserver_t *fsrv),
- volatile u8 *stop_soon_p);
-void afl_fsrv_killall(void);
-void afl_fsrv_deinit(afl_forkserver_t *fsrv);
+void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len);
+fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
+ volatile u8 *stop_soon_p);
+void afl_fsrv_killall(void);
+void afl_fsrv_deinit(afl_forkserver_t *fsrv);
#ifdef __APPLE__
#define MSG_FORK_ON_APPLE \
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 51b50544..9af9ffff 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -17,17 +17,17 @@ This version requires a current llvm 11 compiled from the github master.
## Introduction and problem description
A big issue with how afl/afl++ works is that the basic block IDs that are
-set during compilation are random - and hence natually the larger the number
-of instrumented locations, the higher the number of edge collisions in the
+set during compilation are random - and hence naturally the larger the number
+of instrumented locations, the higher the number of edge collisions are in the
map. This can result in not discovering new paths and therefore degrade the
-efficiency of the fuzzing.
+efficiency of the fuzzing process.
-*This issue is understimated in the fuzzing community!*
+*This issue is underestimated in the fuzzing community!*
With a 2^16 = 64kb standard map at already 256 instrumented blocks there is
on average one collision. On average a target has 10.000 to 50.000
instrumented blocks hence the real collisions are between 750-18.000!
-To get to a solution that prevents any collision took several approaches
+To reach a solution that prevents any collisions took several approaches
and many dead ends until we got to this:
* We instrument at link time when we have all files pre-compiled
@@ -76,7 +76,7 @@ $ make install
## How to use afl-clang-lto
-Just use afl-clang-lto like you did afl-clang-fast or afl-gcc.
+Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc.
Also whitelisting (AFL_LLVM_WHITELIST -> [README.whitelist.md](README.whitelist.md)) and
laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work.
@@ -120,7 +120,7 @@ Please report issues at:
## Upcoming Work
-1. Currently the LTO whitelist feature does not allow to not instrument main,
+1. Currently the LTO whitelist feature does not allow to instrument main,
start and init functions
## History
@@ -138,7 +138,7 @@ This was first implemented in January and work ... kinda.
The LTO time instrumentation worked, however the "how" the basic blocks were
instrumented was a problem, as reducing duplicates turned out to be very,
very difficult with a program that has so many paths and therefore so many
-dependencies. At lot of stratgies were implemented - and failed.
+dependencies. At lot of strategies were implemented - and failed.
And then sat solvers were tried, but with over 10.000 variables that turned
out to be a dead-end too.
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 57d7b89a..c0471033 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -223,8 +223,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (getenv("LAF_TRANSFORM_COMPARES") ||
- getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
+ if ((!(getenv("AFL_LLVM_LTO_AUTODICTIONARY") // disabled when autodictionary
+ && instrument_mode != INSTRUMENT_LTO)) // and lto_mode is used
+ && (getenv("LAF_TRANSFORM_COMPARES") ||
+ getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) {
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 952786b0..6f946ed5 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -209,7 +209,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
/* Execute target application. Returns exec checksum, or 0 if program
times out. */
-static u32 run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
+static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
static struct itimerval it;
int status = 0;
@@ -560,16 +560,16 @@ static void analyze(char **argv) {
code. */
in_data[i] ^= 0xff;
- xor_ff = run_target(argv, in_data, in_len, 0);
+ xor_ff = analyze_run_target(argv, in_data, in_len, 0);
in_data[i] ^= 0xfe;
- xor_01 = run_target(argv, in_data, in_len, 0);
+ xor_01 = analyze_run_target(argv, in_data, in_len, 0);
in_data[i] = (in_data[i] ^ 0x01) - 0x10;
- sub_10 = run_target(argv, in_data, in_len, 0);
+ sub_10 = analyze_run_target(argv, in_data, in_len, 0);
in_data[i] += 0x20;
- add_10 = run_target(argv, in_data, in_len, 0);
+ add_10 = analyze_run_target(argv, in_data, in_len, 0);
in_data[i] -= 0x10;
/* Classify current behavior. */
@@ -805,61 +805,6 @@ static void usage(u8 *argv0) {
}
-/* Find binary. */
-
-static void find_binary(u8 *fname) {
-
- u8 * env_path = 0;
- struct stat st;
-
- if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
- target_path = ck_strdup(fname);
-
- if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
- !(st.st_mode & 0111) || st.st_size < 4)
- FATAL("Program '%s' not found or not executable", fname);
-
- } else {
-
- while (env_path) {
-
- u8 *cur_elem, *delim = strchr(env_path, ':');
-
- if (delim) {
-
- cur_elem = ck_alloc(delim - env_path + 1);
- memcpy(cur_elem, env_path, delim - env_path);
- delim++;
-
- } else
-
- cur_elem = ck_strdup(env_path);
-
- env_path = delim;
-
- if (cur_elem[0])
- target_path = alloc_printf("%s/%s", cur_elem, fname);
- else
- target_path = ck_strdup(fname);
-
- ck_free(cur_elem);
-
- if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
- (st.st_mode & 0111) && st.st_size >= 4)
- break;
-
- ck_free(target_path);
- target_path = 0;
-
- }
-
- if (!target_path) FATAL("Program '%s' not found or not executable", fname);
-
- }
-
-}
-
/* Main entry point */
int main(int argc, char **argv, char **envp) {
@@ -902,7 +847,7 @@ int main(int argc, char **argv, char **envp) {
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
- if (!optarg) { FATAL("Bad syntax used for -m"); }
+ if (!optarg) { FATAL("Wrong usage of -m"); }
if (!strcmp(optarg, "none")) {
@@ -997,7 +942,7 @@ int main(int argc, char **argv, char **envp) {
set_up_environment();
- find_binary(argv[optind]);
+ target_path = find_binary(argv[optind]);
detect_file_args(argv + optind, prog_in, &use_stdin);
if (qemu_mode) {
@@ -1020,7 +965,7 @@ int main(int argc, char **argv, char **envp) {
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
mem_limit, exec_tmout, edges_only ? ", edges only" : "");
- run_target(use_argv, in_data, in_len, 1);
+ analyze_run_target(use_argv, in_data, in_len, 1);
if (child_timed_out)
FATAL("Target binary times out (adjusting -t may help).");
@@ -1032,6 +977,8 @@ int main(int argc, char **argv, char **envp) {
OKF("We're done here. Have a nice day!\n");
+ if (target_path) ck_free(target_path);
+
afl_shm_deinit(&shm);
exit(0);
diff --git a/src/afl-common.c b/src/afl-common.c
index 1ac1a2f3..ffc32533 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -37,6 +37,10 @@
#include <unistd.h>
#endif
#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
u8 be_quiet = 0;
u8 *doc_path = "";
@@ -353,6 +357,68 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
}
+/* Find binary, used by analyze, showmap, tmin
+ @returns the path, allocating the string */
+
+u8 *find_binary(u8 *fname) {
+
+ // TODO: Merge this function with check_binary of afl-fuzz-init.c
+
+ u8 *env_path = NULL;
+ u8 *target_path = NULL;
+
+ struct stat st;
+
+ if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
+
+ target_path = ck_strdup(fname);
+
+ if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
+ !(st.st_mode & 0111) || st.st_size < 4)
+ FATAL("Program '%s' not found or not executable", fname);
+
+ } else {
+
+ while (env_path) {
+
+ u8 *cur_elem, *delim = strchr(env_path, ':');
+
+ if (delim) {
+
+ cur_elem = ck_alloc(delim - env_path + 1);
+ memcpy(cur_elem, env_path, delim - env_path);
+ delim++;
+
+ } else
+
+ cur_elem = ck_strdup(env_path);
+
+ env_path = delim;
+
+ if (cur_elem[0])
+ target_path = alloc_printf("%s/%s", cur_elem, fname);
+ else
+ target_path = ck_strdup(fname);
+
+ ck_free(cur_elem);
+
+ if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
+ (st.st_mode & 0111) && st.st_size >= 4)
+ break;
+
+ ck_free(target_path);
+ target_path = NULL;
+
+ }
+
+ if (!target_path) FATAL("Program '%s' not found or not executable", fname);
+
+ }
+
+ return target_path;
+
+}
+
void check_environment_vars(char **envp) {
if (be_quiet) return;
@@ -414,6 +480,20 @@ char *get_afl_env(char *env) {
}
+/* Read mask bitmap from file. This is for the -B option. */
+
+void read_bitmap(u8 *fname, u8 *map, size_t len) {
+
+ s32 fd = open(fname, O_RDONLY);
+
+ if (fd < 0) PFATAL("Unable to open '%s'", fname);
+
+ ck_read(fd, map, len, fname);
+
+ close(fd);
+
+}
+
u64 get_cur_time(void) {
struct timeval tv;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 9c89a723..006764d9 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -8,7 +8,9 @@
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
- Andrea Fioraldi <andreafioraldi@gmail.com>
+ Andrea Fioraldi <andreafioraldi@gmail.com> and
+ Dominik Maier <mail@dmnk.co>
+
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
@@ -38,10 +40,12 @@
#include <time.h>
#include <errno.h>
#include <signal.h>
+#include <fcntl.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/stat.h>
/**
* The correct fds for reading and writing pipes
@@ -64,15 +68,20 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
// this structure needs default so we initialize it if this was not done
// already
- fsrv->use_stdin = 1;
fsrv->out_fd = -1;
fsrv->out_dir_fd = -1;
fsrv->dev_null_fd = -1;
#ifndef HAVE_ARC4RANDOM
fsrv->dev_urandom_fd = -1;
#endif
+ /* Settings */
+ fsrv->use_stdin = 1;
+ fsrv->no_unlink = 0;
fsrv->exec_tmout = EXEC_TIMEOUT;
fsrv->mem_limit = MEM_LIMIT;
+ fsrv->out_file = NULL;
+
+ /* exec related stuff */
fsrv->child_pid = -1;
fsrv->map_size = MAP_SIZE;
fsrv->use_fauxsrv = 0;
@@ -103,6 +112,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->child_pid = -1;
fsrv_to->use_fauxsrv = 0;
fsrv_to->last_run_timed_out = 0;
+ fsrv_to->out_file = NULL;
fsrv_to->init_child_func = fsrv_exec_child;
@@ -385,7 +395,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
- if (!be_quiet)
+ if (!be_quiet && getenv("AFL_DEBUG"))
ACTF("Extended forkserver functions received (%08x).", status);
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
@@ -398,13 +408,19 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
fsrv->map_size = FS_OPT_GET_MAPSIZE(status);
- if (fsrv->map_size % 8) // should not happen
+ if (unlikely(fsrv->map_size % 8)) {
+
+ // should not happen
+ WARNF("Target reported non-aligned map size of %ud", fsrv->map_size);
fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3);
+
+ }
+
if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size);
if (fsrv->map_size > MAP_SIZE)
FATAL(
"Target's coverage map size of %u is larger than the one this "
- "afl++ is compiled with (%u)\n",
+ "afl++ is compiled with (%u) (change MAP_SIZE and recompile)\n",
fsrv->map_size, MAP_SIZE);
}
@@ -434,7 +450,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
u32 len = status, offset = 0, count = 0;
u8 *dict = ck_alloc(len);
if (dict == NULL)
- FATAL("Could not allocate %u bytes of autodictionary memmory", len);
+ FATAL("Could not allocate %u bytes of autodictionary memory", len);
while (len != 0) {
@@ -640,13 +656,53 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
}
+/* Delete the current testcase and write the buf to the testcase file */
+
+void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
+
+ s32 fd = fsrv->out_fd;
+
+ if (fsrv->out_file) {
+
+ if (fsrv->no_unlink) {
+
+ fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+
+ } else {
+
+ unlink(fsrv->out_file); /* Ignore errors. */
+ fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+
+ }
+
+ if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+
+ } else {
+
+ lseek(fd, 0, SEEK_SET);
+
+ }
+
+ ck_write(fd, buf, len, fsrv->out_file);
+
+ if (!fsrv->out_file) {
+
+ if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
+ lseek(fd, 0, SEEK_SET);
+
+ } else {
+
+ close(fd);
+
+ }
+
+}
+
/* Execute target application, monitoring for timeouts. Return status
information. The called program will update afl->fsrv->trace_bits. */
-fsrv_run_result_t afl_fsrv_run_target(
- afl_forkserver_t *fsrv, u32 timeout,
- void(classify_counts_func)(afl_forkserver_t *fsrv),
- volatile u8 *stop_soon_p) {
+fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
+ volatile u8 *stop_soon_p) {
s32 res;
u32 exec_ms;
@@ -675,7 +731,7 @@ fsrv_run_result_t afl_fsrv_run_target(
if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
- if (stop_soon_p) return 0;
+ if (*stop_soon_p) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
}
@@ -732,9 +788,6 @@ fsrv_run_result_t afl_fsrv_run_target(
behave very normally and do not have to be treated as volatile. */
MEM_BARRIER();
- u32 tb4 = *(u32 *)fsrv->trace_bits;
-
- if (likely(classify_counts_func)) classify_counts_func(fsrv);
/* Report outcome to caller. */
@@ -759,7 +812,8 @@ fsrv_run_result_t afl_fsrv_run_target(
}
- if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
+ // Fauxserver should handle this now.
+ // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
return FSRV_RUN_OK;
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 852e3a7c..be8f504e 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -49,20 +49,6 @@ void write_bitmap(afl_state_t *afl) {
}
-/* Read bitmap from file. This is for the -B option again. */
-
-void read_bitmap(afl_state_t *afl, u8 *fname) {
-
- s32 fd = open(fname, O_RDONLY);
-
- if (fd < 0) PFATAL("Unable to open '%s'", fname);
-
- ck_read(fd, afl->virgin_bits, MAP_SIZE, fname);
-
- close(fd);
-
-}
-
/* Check if the current execution path brings anything new to the table.
Update virgin bits to reflect the finds. Returns 1 if the only change is
the hit-count for a particular tuple; 2 if there are new tuples seen.
@@ -88,7 +74,8 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
u32 i = (afl->fsrv.map_size >> 2);
#endif /* ^WORD_SIZE_64 */
- if (i == 0) i = 1;
+ // the map size must be a minimum of 8 bytes.
+ // for variable/dynamic map sizes this is ensured in the forkserver
u8 ret = 0;
@@ -98,6 +85,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
that have not been already cleared from the virgin map - since this will
almost always be the case. */
+ // the (*current) is unnecessary but speeds up the overall comparison
if (unlikely(*current) && unlikely(*current & *virgin)) {
if (likely(ret < 2)) {
@@ -110,18 +98,20 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
#ifdef WORD_SIZE_64
- if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
- (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff) ||
- (cur[4] && vir[4] == 0xff) || (cur[5] && vir[5] == 0xff) ||
- (cur[6] && vir[6] == 0xff) || (cur[7] && vir[7] == 0xff))
+ if (*virgin == 0xffffffffffffffff || (cur[0] && vir[0] == 0xff) ||
+ (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
+ (cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) ||
+ (cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) ||
+ (cur[7] && vir[7] == 0xff))
ret = 2;
else
ret = 1;
#else
- if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
- (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff))
+ if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) ||
+ (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
+ (cur[3] && vir[3] == 0xff))
ret = 2;
else
ret = 1;
@@ -139,7 +129,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
}
- if (unlikely(ret) && unlikely(virgin_map == afl->virgin_bits))
+ if (unlikely(ret) && likely(virgin_map == afl->virgin_bits))
afl->bitmap_changed = 1;
return ret;
@@ -649,7 +639,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
u8 new_fault;
write_to_testcase(afl, mem, len);
- new_fault = run_target(afl, &afl->fsrv, afl->hang_tmout);
+ new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
/* A corner case that one user reported bumping into: increasing the
timeout actually uncovers a crash. Make sure we don't discard it if
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index ab93d838..12c814ba 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -62,7 +62,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
write_to_testcase(afl, out_buf, len);
- fault = run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
+ fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
if (afl->stop_soon) return 1;
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 7bf23e84..434b4673 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -27,9 +27,6 @@
#include "afl-fuzz.h"
void load_custom_mutator(afl_state_t *, const char *);
-#ifdef USE_PYTHON
-void load_custom_mutator_py(afl_state_t *, char *);
-#endif
void setup_custom_mutator(afl_state_t *afl) {
@@ -239,7 +236,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
write_to_testcase(afl, retbuf, retlen);
- fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+ fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
++afl->trim_execs;
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index cc97654a..a4ba739e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -27,7 +27,7 @@
/* MOpt */
-int select_algorithm(afl_state_t *afl) {
+static int select_algorithm(afl_state_t *afl) {
int i_puppet, j_puppet;
@@ -2366,7 +2366,7 @@ abandon_entry:
}
/* MOpt mode */
-u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
+static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (!MOpt_globals.is_pilot_mode) {
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 12c3a09d..33f01797 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -41,7 +41,7 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
(void **)&((py_mutator_t *)py_mutator)->name##_buf, \
&((py_mutator_t *)py_mutator)->name##_size
-size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
+static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
u8 *add_buf, size_t add_buf_size, size_t max_size) {
size_t mutated_size;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 6f2fb144..3e9af088 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -37,7 +37,7 @@ struct range {
};
-struct range *add_range(struct range *ranges, u32 start, u32 end) {
+static struct range *add_range(struct range *ranges, u32 start, u32 end) {
struct range *r = ck_alloc_nozero(sizeof(struct range));
r->start = start;
@@ -47,7 +47,7 @@ struct range *add_range(struct range *ranges, u32 start, u32 end) {
}
-struct range *pop_biggest_range(struct range **ranges) {
+static struct range *pop_biggest_range(struct range **ranges) {
struct range *r = *ranges;
struct range *prev = NULL;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index c3ed59ef..6ad6444a 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -6,7 +6,8 @@
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
- Andrea Fioraldi <andreafioraldi@gmail.com>
+ Andrea Fioraldi <andreafioraldi@gmail.com> and
+ Dominik Maier <mail@dmnk.co>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
@@ -32,10 +33,13 @@
/* Execute target application, monitoring for timeouts. Return status
information. The called program will update afl->fsrv->trace_bits. */
-fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
+fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
u32 timeout) {
- return afl_fsrv_run_target(fsrv, timeout, classify_counts, &afl->stop_soon);
+ fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
+ // TODO: Don't classify for faults?
+ classify_counts(fsrv);
+ return res;
}
@@ -45,13 +49,11 @@ fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
- s32 fd = afl->fsrv.out_fd;
-
#ifdef _AFL_DOCUMENT_MUTATIONS
s32 doc_fd;
char fn[PATH_MAX];
- snprintf(fn, PATH_MAX, ("%s/mutations/%09u:%s", afl->out_dir,
- afl->document_counter++, describe_op(afl, 0));
+ snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir,
+ afl->document_counter++, describe_op(afl, 0));
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
@@ -63,25 +65,6 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
#endif
- if (afl->fsrv.out_file) {
-
- if (afl->no_unlink) {
-
- fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-
- } else {
-
- unlink(afl->fsrv.out_file); /* Ignore errors. */
- fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
-
- }
-
- if (fd < 0) PFATAL("Unable to create '%s'", afl->fsrv.out_file);
-
- } else
-
- lseek(fd, 0, SEEK_SET);
-
if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) {
u8 *new_buf = NULL;
@@ -93,24 +76,15 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
/* everything as planned. use the new data. */
- ck_write(fd, new_buf, new_size, afl->fsrv.out_file);
+ afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
} else {
/* boring uncustom. */
- ck_write(fd, mem, len, afl->fsrv.out_file);
+ afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
}
- if (!afl->fsrv.out_file) {
-
- if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
- lseek(fd, 0, SEEK_SET);
-
- } else
-
- close(fd);
-
}
/* The same, but with an adjustable gap. Used for trimming. */
@@ -217,7 +191,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
write_to_testcase(afl, use_mem, q->len);
- fault = run_target(afl, &afl->fsrv, use_tmout);
+ fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
we want to bail out quickly. */
@@ -435,7 +409,7 @@ void sync_fuzzers(afl_state_t *afl) {
write_to_testcase(afl, mem, st.st_size);
- fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+ fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
if (afl->stop_soon) goto close_sync;
@@ -522,7 +496,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
- fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+ fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
++afl->trim_execs;
if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming;
@@ -629,7 +603,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
write_to_testcase(afl, out_buf, len);
- fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+ fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
if (afl->stop_soon) return 1;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9f17b61b..925dbb1a 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -420,6 +420,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
+ if (!optarg) FATAL("Wrong usage of -m");
+
if (!strcmp(optarg, "none")) {
afl->fsrv.mem_limit = 0;
@@ -474,7 +476,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->in_bitmap) FATAL("Multiple -B options not supported");
afl->in_bitmap = optarg;
- read_bitmap(afl, afl->in_bitmap);
+ read_bitmap(afl->in_bitmap, afl->virgin_bits, MAP_SIZE);
break;
case 'C': /* crash mode */
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 16d6fe41..01ba62aa 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -60,7 +60,7 @@
#include <sys/shm.h>
#endif
-list_t shm_list = {.element_prealloc_count = 0};
+static list_t shm_list = {.element_prealloc_count = 0};
/* Get rid of shared memory. */
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 2326d469..61c1754f 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -8,7 +8,8 @@
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
- Andrea Fioraldi <andreafioraldi@gmail.com>
+ Andrea Fioraldi <andreafioraldi@gmail.com> and
+ Dominik Maier <mail@dmnk.co>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
@@ -61,8 +62,8 @@
static char *stdin_file; /* stdin file */
-static u8 *in_dir, /* input folder */
- *at_file = NULL; /* Substitution string for @@ */
+static u8 *in_dir = NULL, /* input folder */
+ *out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
static u8 *in_data; /* Input data */
@@ -157,7 +158,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
fd = open(outfile, O_WRONLY);
- if (fd < 0) PFATAL("Unable to open '%s'", fsrv->out_file);
+ if (fd < 0) PFATAL("Unable to open '%s'", out_file);
} else if (!strcmp(outfile, "-")) {
@@ -215,41 +216,22 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
}
-/* Write results. */
-
-static u32 write_results(afl_forkserver_t *fsrv) {
-
- return write_results_to_file(fsrv, fsrv->out_file);
-
-}
-
-/* Write modified data to file for testing. If use_stdin is clear, the old file
- is unlinked and a new one is created. Otherwise, out_fd is rewound and
- truncated. */
-
-static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
-
- lseek(fsrv->out_fd, 0, SEEK_SET);
- ck_write(fsrv->out_fd, mem, len, fsrv->out_file);
- if (ftruncate(fsrv->out_fd, len)) PFATAL("ftruncate() failed");
- lseek(fsrv->out_fd, 0, SEEK_SET);
-
-}
-
/* Execute target application. */
-void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
+static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
u32 len) {
- write_to_testcase(fsrv, mem, len);
+ afl_fsrv_write_to_testcase(fsrv, mem, len);
- if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts,
- &stop_soon) == FSRV_RUN_ERROR) {
+ if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) ==
+ FSRV_RUN_ERROR) {
FATAL("Error running target");
}
+ classify_counts(fsrv);
+
if (stop_soon) {
SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST);
@@ -261,7 +243,7 @@ void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
/* Read initial file. */
-u32 read_file(u8 *in_file) {
+static u32 read_file(u8 *in_file) {
struct stat st;
s32 fd = open(in_file, O_RDONLY);
@@ -286,7 +268,7 @@ u32 read_file(u8 *in_file) {
/* Execute target application. */
-static void run_target(afl_forkserver_t *fsrv, char **argv) {
+static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
static struct itimerval it;
int status = 0;
@@ -544,62 +526,6 @@ static void usage(u8 *argv0) {
}
-/* Find binary. */
-
-static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
-
- u8 * env_path = 0;
- struct stat st;
-
- if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
- fsrv->target_path = ck_strdup(fname);
-
- if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
- !(st.st_mode & 0111) || st.st_size < 4)
- FATAL("Program '%s' not found or not executable", fname);
-
- } else {
-
- while (env_path) {
-
- u8 *cur_elem, *delim = strchr(env_path, ':');
-
- if (delim) {
-
- cur_elem = ck_alloc(delim - env_path + 1);
- memcpy(cur_elem, env_path, delim - env_path);
- delim++;
-
- } else
-
- cur_elem = ck_strdup(env_path);
-
- env_path = delim;
-
- if (cur_elem[0])
- fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
- else
- fsrv->target_path = ck_strdup(fname);
-
- ck_free(cur_elem);
-
- if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
- (st.st_mode & 0111) && st.st_size >= 4)
- break;
-
- ck_free(fsrv->target_path);
- fsrv->target_path = NULL;
-
- }
-
- if (!fsrv->target_path)
- FATAL("Program '%s' not found or not executable", fname);
-
- }
-
-}
-
/* Main entry point */
int main(int argc, char **argv_orig, char **envp) {
@@ -632,8 +558,8 @@ int main(int argc, char **argv_orig, char **envp) {
case 'o':
- if (fsrv->out_file) FATAL("Multiple -o options not supported");
- fsrv->out_file = optarg;
+ if (out_file) FATAL("Multiple -o options not supported");
+ out_file = optarg;
break;
case 'm': {
@@ -643,6 +569,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
+ if (!optarg) FATAL("Wrong usage of -m");
+
if (!strcmp(optarg, "none")) {
fsrv->mem_limit = 0;
@@ -686,6 +614,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (timeout_given) FATAL("Multiple -t options not supported");
timeout_given = 1;
+ if (!optarg) FATAL("Wrong usage of -t");
+
if (strcmp(optarg, "none")) {
fsrv->exec_tmout = atoi(optarg);
@@ -780,7 +710,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (optind == argc || !fsrv->out_file) usage(argv[0]);
+ if (optind == argc || !out_file) usage(argv[0]);
check_environment_vars(envp);
@@ -790,7 +720,7 @@ int main(int argc, char **argv_orig, char **envp) {
set_up_environment(fsrv);
- find_binary(fsrv, argv[optind]);
+ fsrv->target_path = find_binary(argv[optind]);
if (!quiet_mode) {
@@ -831,7 +761,7 @@ int main(int argc, char **argv_orig, char **envp) {
DIR * dir_in, *dir_out;
struct dirent *dir_ent;
int done = 0;
- u8 infile[4096], outfile[4096];
+ u8 infile[PATH_MAX], outfile[PATH_MAX];
#if !defined(DT_REG)
struct stat statbuf;
#endif
@@ -841,9 +771,9 @@ int main(int argc, char **argv_orig, char **envp) {
if (!(dir_in = opendir(in_dir))) PFATAL("cannot open directory %s", in_dir);
- if (!(dir_out = opendir(fsrv->out_file)))
- if (mkdir(fsrv->out_file, 0700))
- PFATAL("cannot create output directory %s", fsrv->out_file);
+ if (!(dir_out = opendir(out_file)))
+ if (mkdir(out_file, 0700))
+ PFATAL("cannot create output directory %s", out_file);
u8 *use_dir = ".";
@@ -858,7 +788,7 @@ int main(int argc, char **argv_orig, char **envp) {
unlink(stdin_file);
atexit(at_exit_handler);
fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+ if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
if (arg_offset && argv[arg_offset] != stdin_file) {
@@ -897,12 +827,11 @@ int main(int argc, char **argv_orig, char **envp) {
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
#endif
- snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file,
- dir_ent->d_name);
+ snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
if (read_file(infile)) {
- run_target_forkserver(fsrv, use_argv, in_data, in_len);
+ showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
ck_free(in_data);
tcnt = write_results_to_file(fsrv, outfile);
@@ -917,8 +846,8 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
- run_target(fsrv, use_argv);
- tcnt = write_results(fsrv);
+ showmap_run_target(fsrv, use_argv);
+ tcnt = write_results_to_file(fsrv, out_file);
}
@@ -926,7 +855,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!tcnt) FATAL("No instrumentation detected" cRST);
OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST,
- tcnt, highest, total, fsrv->out_file);
+ tcnt, highest, total, out_file);
}
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 84e9a498..431ff0c4 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -8,7 +8,8 @@
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
- Andrea Fioraldi <andreafioraldi@gmail.com>
+ Andrea Fioraldi <andreafioraldi@gmail.com> and
+ Dominik Maier <mail@dmnk.co>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
@@ -61,7 +62,7 @@
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
static u8 *in_file, /* Minimizer input test case */
- *output_file; /* Minimizer output file */
+ *out_file, *output_file; /* Minimizer output file */
static u8 *in_data; /* Input data for trimming */
@@ -120,8 +121,6 @@ static void apply_mask(u32 *mem, u32 *mask) {
static void classify_counts(afl_forkserver_t *fsrv) {
- if (hang_mode) return; /* We only want hangs */
-
u8 *mem = fsrv->trace_bits;
u32 i = MAP_SIZE;
@@ -145,8 +144,6 @@ static void classify_counts(afl_forkserver_t *fsrv) {
}
- apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
-
}
/* See if any bytes are set in the bitmap. */
@@ -214,49 +211,16 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
}
-/* Write modified data to file for testing. If use_stdin is clear, the old file
- is unlinked and a new one is created. Otherwise, out_fd is rewound and
- truncated. */
-
-static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
-
- s32 fd = fsrv->out_fd;
-
- if (!fsrv->use_stdin) {
-
- unlink(fsrv->out_file); /* Ignore errors. */
-
- fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
-
- if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
-
- } else
-
- lseek(fd, 0, SEEK_SET);
-
- ck_write(fd, mem, len, fsrv->out_file);
-
- if (fsrv->use_stdin) {
-
- if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
- lseek(fd, 0, SEEK_SET);
-
- } else
-
- close(fd);
-
-}
-
/* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */
-static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
+static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
u8 first_run) {
- write_to_testcase(fsrv, mem, len);
+ afl_fsrv_write_to_testcase(fsrv, mem, len);
fsrv_run_result_t ret =
- afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts, &stop_soon);
+ afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child");
@@ -282,6 +246,9 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
}
+ classify_counts(fsrv);
+ apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
+
if (ret == FSRV_RUN_TMOUT) {
missed_hangs++;
@@ -369,7 +336,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
memset(tmp_buf + set_pos, '0', use_len);
u8 res;
- res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+ res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
if (res) {
@@ -442,7 +409,7 @@ next_del_blksize:
/* Tail */
memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);
- res = run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
+ res = tmin_run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
if (res) {
@@ -505,7 +472,7 @@ next_del_blksize:
for (r = 0; r < in_len; r++)
if (tmp_buf[r] == i) tmp_buf[r] = '0';
- res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+ res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
if (res) {
@@ -541,7 +508,7 @@ next_del_blksize:
if (orig == '0') continue;
tmp_buf[i] = '0';
- res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+ res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
if (res) {
@@ -613,7 +580,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv->dev_null_fd < 0) PFATAL("Unable to open /dev/null");
- if (!fsrv->out_file) {
+ if (!out_file) {
u8 *use_dir = ".";
@@ -624,15 +591,15 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
- fsrv->out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
+ out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
}
- unlink(fsrv->out_file);
+ unlink(out_file);
- fsrv->out_fd = open(fsrv->out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
+ fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+ if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
/* Set sane defaults... */
@@ -782,76 +749,6 @@ static void usage(u8 *argv0) {
}
-/* Find binary. */
-
-static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
-
- u8 * env_path = 0;
- struct stat st;
-
- if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
- fsrv->target_path = ck_strdup(fname);
-
- if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
- !(st.st_mode & 0111) || st.st_size < 4)
- FATAL("Program '%s' not found or not executable", fname);
-
- } else {
-
- while (env_path) {
-
- u8 *cur_elem, *delim = strchr(env_path, ':');
-
- if (delim) {
-
- cur_elem = ck_alloc(delim - env_path + 1);
- memcpy(cur_elem, env_path, delim - env_path);
- delim++;
-
- } else
-
- cur_elem = ck_strdup(env_path);
-
- env_path = delim;
-
- if (cur_elem[0])
- fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
- else
- fsrv->target_path = ck_strdup(fname);
-
- ck_free(cur_elem);
-
- if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
- (st.st_mode & 0111) && st.st_size >= 4)
- break;
-
- ck_free(fsrv->target_path);
- fsrv->target_path = NULL;
-
- }
-
- if (!fsrv->target_path)
- FATAL("Program '%s' not found or not executable", fname);
-
- }
-
-}
-
-/* Read mask bitmap from file. This is for the -B option. */
-
-static void read_bitmap(u8 *fname) {
-
- s32 fd = open(fname, O_RDONLY);
-
- if (fd < 0) PFATAL("Unable to open '%s'", fname);
-
- ck_read(fd, mask_bitmap, MAP_SIZE, fname);
-
- close(fd);
-
-}
-
/* Main entry point */
int main(int argc, char **argv_orig, char **envp) {
@@ -888,9 +785,9 @@ int main(int argc, char **argv_orig, char **envp) {
case 'f':
- if (fsrv->out_file) FATAL("Multiple -f options not supported");
+ if (out_file) FATAL("Multiple -f options not supported");
fsrv->use_stdin = 0;
- fsrv->out_file = optarg;
+ out_file = optarg;
break;
case 'e':
@@ -914,6 +811,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
+ if (!optarg) FATAL("Wrong usage of -m");
+
if (!strcmp(optarg, "none")) {
fsrv->mem_limit = 0;
@@ -950,6 +849,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (timeout_given) FATAL("Multiple -t options not supported");
timeout_given = 1;
+ if (!optarg) FATAL("Wrong usage of -t");
+
fsrv->exec_tmout = atoi(optarg);
if (fsrv->exec_tmout < 10 || optarg[0] == '-')
@@ -1010,7 +911,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (mask_bitmap) FATAL("Multiple -B options not supported");
mask_bitmap = ck_alloc(MAP_SIZE);
- read_bitmap(optarg);
+ read_bitmap(optarg, mask_bitmap, MAP_SIZE);
break;
case 'h':
@@ -1034,8 +935,8 @@ int main(int argc, char **argv_orig, char **envp) {
set_up_environment(fsrv);
- find_binary(fsrv, argv[optind]);
- detect_file_args(argv + optind, fsrv->out_file, &fsrv->use_stdin);
+ fsrv->target_path = find_binary(argv[optind]);
+ detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
if (fsrv->qemu_mode) {
@@ -1069,7 +970,7 @@ int main(int argc, char **argv_orig, char **envp) {
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
- run_target(fsrv, use_argv, in_data, in_len, 1);
+ tmin_run_target(fsrv, use_argv, in_data, in_len, 1);
if (hang_mode && !fsrv->last_run_timed_out)
FATAL(
@@ -1105,9 +1006,9 @@ int main(int argc, char **argv_orig, char **envp) {
ACTF("Writing output to '%s'...", output_file);
- unlink(fsrv->out_file);
- if (fsrv->out_file) ck_free(fsrv->out_file);
- fsrv->out_file = NULL;
+ unlink(out_file);
+ if (out_file) ck_free(out_file);
+ out_file = NULL;
close(write_to_file(output_file, in_data, in_len));
diff --git a/src/third_party/libradamsa/libradamsa.c b/src/third_party/libradamsa/libradamsa.c
index 27cf91bc..4f5515e5 100644
--- a/src/third_party/libradamsa/libradamsa.c
+++ b/src/third_party/libradamsa/libradamsa.c
@@ -1841,6 +1841,8 @@ static const unsigned char heap[] = {2,3,4,105,111,116,97,2,3,7,112,97,116,116,1
#include <stdio.h>
#include <netdb.h>
+#include "./radamsa.h"
+
#ifndef EMULTIHOP
#define EMULTIHOP -1
#endif
@@ -2155,17 +2157,17 @@ static word *gc(int size, word *regs) {
/*** OS Interaction and Helpers ***/
-static void signal_handler(int signal) {
- switch (signal) {
- case SIGINT:
- breaked |= 2;
- break;
- case SIGPIPE:
- break; /* can cause loop when reporting errors */
- default:
- breaked |= 4;
- }
-}
+//static void signal_handler(int signal) {
+// switch (signal) {
+// case SIGINT:
+// breaked |= 2;
+// break;
+// case SIGPIPE:
+// break; /* can cause loop when reporting errors */
+// default:
+// breaked |= 4;
+// }
+//}
/* list length, no overflow or valid termination checks */
static uint llen(word *ptr) {
@@ -2176,7 +2178,7 @@ static uint llen(word *ptr) {
}
return len;
}
-
+/*
static void set_signal_handler(void) {
struct sigaction sa;
sa.sa_handler = signal_handler;
@@ -2185,7 +2187,7 @@ static void set_signal_handler(void) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
}
-
+*/
static word mkpair(word h, word a, word d) {
word *pair;
allocate(3, pair);
@@ -30683,7 +30685,7 @@ static void heap_metrics(int *rwords, int *rnobjs) {
get_obj_metrics(rwords, rnobjs);
hp = hp_start;
}
-
+/*
static void read_heap(const char *path) {
struct stat st;
off_t pos = 0;
@@ -30703,25 +30705,26 @@ static void read_heap(const char *path) {
} while (n && (pos += n) < st.st_size);
close(fd);
}
+*/
/* find a fasl image source to *hp or exit */
-static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
- file_heap = NULL;
- if ((word)heap == 0) {
+//static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
+// file_heap = NULL;
+// if ((word)heap == 0) {
/* if no preloaded heap, try to load it from first vm arg */
- if (*nargs < 2)
- exit(1);
- read_heap(argv[0][1]);
- ++*argv;
- --*nargs;
- hp = file_heap;
- if (*hp == '#')
- while (*hp++ != '\n');
- } else {
- hp = heap; /* builtin heap */
- }
- heap_metrics(nwords, nobjs);
-}
+// if (*nargs < 2)
+// exit(1);
+// read_heap(argv[0][1]);
+// ++*argv;
+// --*nargs;
+// hp = file_heap;
+// if (*hp == '#')
+// while (*hp++ != '\n');
+// } else {
+// hp = heap; /* builtin heap */
+// }
+// heap_metrics(nwords, nobjs);
+//}
static word *decode_fasl(uint nobjs) {
word *ptrs;
@@ -30744,7 +30747,7 @@ static word *load_heap(uint nobjs) {
free(file_heap);
return entry;
}
-
+/*
static void setup(int nwords, int nobjs) {
tcgetattr(0, &tsettings);
state = IFALSE;
@@ -30757,7 +30760,7 @@ static void setup(int nwords, int nobjs) {
memend = memstart + nwords - MEMPAD;
}
-int secondary(int nargs, char **argv) {
+static int secondary(int nargs, char **argv) {
word *prog;
int rval, nobjs=0, nwords=0;
find_heap(&nargs, &argv, &nobjs, &nwords);
@@ -30772,6 +30775,7 @@ int secondary(int nargs, char **argv) {
}
return 127;
}
+*/
void radamsa_init(void) {
int nobjs=0, nwords=0;
@@ -30787,7 +30791,7 @@ void radamsa_init(void) {
}
/* bvec → value library call test with preserved state */
-word library_call(word val) {
+static word library_call(word val) {
word program_state = state;
word res;
state = IFALSE;
@@ -30798,7 +30802,8 @@ word library_call(word val) {
return res;
}
-size_t list_length(word lispval) {
+/*
+static size_t list_length(word lispval) {
size_t l = 0;
while(lispval != INULL) {
lispval = G(lispval, 2);
@@ -30806,8 +30811,9 @@ size_t list_length(word lispval) {
}
return l;
}
+*/
-size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
+static size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
size_t n = 0;
while(pairp((word)lispval) && max-- && lispval != INULL) {
*ptr++ = 255 & immval(G(lispval, 1)); // *ptr++ = car(list)
diff --git a/src/third_party/libradamsa/radamsa.h b/src/third_party/libradamsa/radamsa.h
index 33cccde4..073599da 100644
--- a/src/third_party/libradamsa/radamsa.h
+++ b/src/third_party/libradamsa/radamsa.h
@@ -1,13 +1,13 @@
#include <inttypes.h>
#include <stddef.h>
-extern void radamsa_init(void);
+void radamsa_init(void);
-extern size_t radamsa(uint8_t *ptr, size_t len,
+size_t radamsa(uint8_t *ptr, size_t len,
uint8_t *target, size_t max,
unsigned int seed);
-extern size_t radamsa_inplace(uint8_t *ptr,
+size_t radamsa_inplace(uint8_t *ptr,
size_t len,
size_t max,
unsigned int seed);
diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c
index 11d3227c..90700a11 100644
--- a/test/unittests/unit_list.c
+++ b/test/unittests/unit_list.c
@@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
(compile with `--wrap=exit`) */
extern void exit(int status);
extern void __real_exit(int status);
+void __wrap_exit(int status);
void __wrap_exit(int status) {
assert(0);
}
@@ -34,6 +35,7 @@ void __wrap_exit(int status) {
/* ignore all printfs */
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}
diff --git a/test/unittests/unit_maybe_alloc.c b/test/unittests/unit_maybe_alloc.c
index d9c037a0..8cd8b11a 100644
--- a/test/unittests/unit_maybe_alloc.c
+++ b/test/unittests/unit_maybe_alloc.c
@@ -22,6 +22,7 @@ extern void mock_assert(const int result, const char* const expression,
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
#include "alloc-inl.h"
+void __wrap_exit(int status);
/* remap exit -> assert, then use cmocka's mock_assert
(compile with `--wrap=exit`) */
extern void exit(int status);
@@ -30,6 +31,7 @@ void __wrap_exit(int status) {
assert(0);
}
+int __wrap_printf(const char *format, ...);
/* ignore all printfs */
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
diff --git a/test/unittests/unit_preallocable.c b/test/unittests/unit_preallocable.c
index 8cd36165..8d619b78 100644
--- a/test/unittests/unit_preallocable.c
+++ b/test/unittests/unit_preallocable.c
@@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
(compile with `--wrap=exit`) */
extern void exit(int status);
extern void __real_exit(int status);
+void __wrap_exit(int status);
void __wrap_exit(int status) {
assert(0);
}
@@ -34,6 +35,7 @@ void __wrap_exit(int status) {
/* ignore all printfs */
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}