aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/README.md24
-rw-r--r--src/README.src22
-rw-r--r--src/afl-analyze.c5
-rw-r--r--src/afl-common.c399
-rw-r--r--src/afl-forkserver.c30
-rw-r--r--src/afl-fuzz-bitmap.c47
-rw-r--r--src/afl-fuzz-cmplog.c76
-rw-r--r--src/afl-fuzz-init.c33
-rw-r--r--src/afl-fuzz-mutators.c61
-rw-r--r--src/afl-fuzz-one.c150
-rw-r--r--src/afl-fuzz-python.c130
-rw-r--r--src/afl-fuzz-queue.c57
-rw-r--r--src/afl-fuzz-redqueen.c5
-rw-r--r--src/afl-fuzz-run.c83
-rw-r--r--src/afl-fuzz-state.c (renamed from src/afl-fuzz-globals.c)13
-rw-r--r--src/afl-fuzz-stats.c125
-rw-r--r--src/afl-fuzz.c13
-rw-r--r--src/afl-showmap.c25
-rw-r--r--src/afl-tmin.c21
-rw-r--r--src/third_party/libradamsa/libradamsa.c2
20 files changed, 872 insertions, 449 deletions
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 00000000..6da534c3
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,24 @@
+# Source Folder
+
+Quick explanation about the files here:
+
+- `afl-analyze.c` - afl-analyze binary tool
+- `afl-as.c` - afl-as binary tool
+- `afl-gotcpu.c` - afl-gotcpu binary tool
+- `afl-showmap.c` - afl-showmap binary tool
+- `afl-tmin.c` - afl-tmin binary tool
+- `afl-fuzz.c` - afl-fuzz binary tool (just main() and usage())
+- `afl-fuzz-bitmap.c` - afl-fuzz bitmap handling
+- `afl-fuzz-extras.c` - afl-fuzz the *extra* function calls
+- `afl-fuzz-state.c` - afl-fuzz state and globals
+- `afl-fuzz-init.c` - afl-fuzz initialization
+- `afl-fuzz-misc.c` - afl-fuzz misc functions
+- `afl-fuzz-one.c` - afl-fuzz fuzzer_one big loop, this is where the mutation is happening
+- `afl-fuzz-python.c` - afl-fuzz the python mutator extension
+- `afl-fuzz-queue.c` - afl-fuzz handling the queue
+- `afl-fuzz-run.c` - afl-fuzz running the target
+- `afl-fuzz-stats.c` - afl-fuzz writing the statistics file
+- `afl-gcc.c` - afl-gcc binary tool (deprecated)
+- `afl-common.c` - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin
+- `afl-forkserver.c` - forkserver implementation, used by afl-fuzz and afl-tmin
+afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin
diff --git a/src/README.src b/src/README.src
deleted file mode 100644
index 244f5ddd..00000000
--- a/src/README.src
+++ /dev/null
@@ -1,22 +0,0 @@
-Quick explanation about the files here:
-
-afl-analyze.c - afl-analyze binary tool
-afl-as.c - afl-as binary tool
-afl-gotcpu.c - afl-gotcpu binary tool
-afl-showmap.c - afl-showmap binary tool
-afl-tmin.c - afl-tmin binary tool
-afl-fuzz.c - afl-fuzz binary tool (just main() and usage())
-afl-fuzz-bitmap.c - afl-fuzz bitmap handling
-afl-fuzz-extras.c - afl-fuzz the *extra* function calls
-afl-fuzz-globals.c - afl-fuzz global variables
-afl-fuzz-init.c - afl-fuzz initialization
-afl-fuzz-misc.c - afl-fuzz misc functions
-afl-fuzz-one.c - afl-fuzz fuzzer_one big loop, this is where the mutation is happening
-afl-fuzz-python.c - afl-fuzz the python mutator extension
-afl-fuzz-queue.c - afl-fuzz handling the queue
-afl-fuzz-run.c - afl-fuzz running the target
-afl-fuzz-stats.c - afl-fuzz writing the statistics file
-afl-gcc.c - afl-gcc binary tool (deprecated)
-afl-common.c - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin
-afl-forkserver.c - forkserver implementation, used by afl-fuzz and afl-tmin
-afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d509c43e..427fbe6d 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -60,8 +60,7 @@ static s32 child_pid; /* PID of the tested program */
u8 *trace_bits; /* SHM with instrumentation bitmap */
static u8 *in_file, /* Analyzer input test case */
- *prog_in, /* Targeted program input file */
- *doc_path; /* Path to docs */
+ *prog_in; /* Targeted program input file */
static u8 *in_data; /* Input data for analysis */
@@ -77,7 +76,7 @@ static s32 dev_null_fd = -1; /* FD to /dev/null */
u8 edges_only, /* Ignore hit counts? */
use_hex_offsets, /* Show hex offsets? */
- be_quiet, use_stdin = 1; /* Use stdin for program input? */
+ use_stdin = 1; /* Use stdin for program input? */
static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_timed_out; /* Child timed out? */
diff --git a/src/afl-common.c b/src/afl-common.c
index 8c4d53e8..920c7dfd 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -30,6 +30,7 @@
#include "debug.h"
#include "alloc-inl.h"
#include "envs.h"
+#include "common.h"
/* Detect @@ in args. */
#ifndef __glibc__
@@ -37,8 +38,10 @@
#endif
#include <limits.h>
-extern u8 be_quiet;
-char * afl_environment_variables[] = {
+u8 be_quiet = 0;
+u8 *doc_path = "";
+
+char *afl_environment_variables[] = {
"AFL_ALIGNED_ALLOC", "AFL_ALLOW_TMP", "AFL_ANALYZE_HEX", "AFL_AS",
"AFL_AUTORESUME", "AFL_AS_FORCE_INSTRUMENT", "AFL_BENCH_JUST_ONE",
@@ -73,7 +76,7 @@ char * afl_environment_variables[] = {
"AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ",
"AFL_SKIP_CRASHES", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE",
"AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC",
- "AFL_USE_UBSAN", "AFL_WINE_PATH", NULL};
+ "AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", NULL};
void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {
@@ -393,3 +396,393 @@ char *get_afl_env(char *env) {
}
+u64 get_cur_time(void) {
+
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv, &tz);
+
+ return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
+
+}
+
+/* Get unix time in microseconds */
+
+u64 get_cur_time_us(void) {
+
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv, &tz);
+
+ return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
+
+}
+
+/* Describe integer. The buf should be
+ at least 6 bytes to fit all ints we randomly see.
+ Will return buf for convenience. */
+
+u8 *stringify_int(u8 *buf, size_t len, u64 val) {
+\
+#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
+ do { \
+ \
+ if (val < (_divisor) * (_limit_mult)) { \
+ \
+ snprintf(buf, len, _fmt, ((_cast)val) / (_divisor)); \
+ return buf; \
+ \
+ } \
+ \
+ } while (0)
+
+ /* 0-9999 */
+ CHK_FORMAT(1, 10000, "%llu", u64);
+
+ /* 10.0k - 99.9k */
+ CHK_FORMAT(1000, 99.95, "%0.01fk", double);
+
+ /* 100k - 999k */
+ CHK_FORMAT(1000, 1000, "%lluk", u64);
+
+ /* 1.00M - 9.99M */
+ CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double);
+
+ /* 10.0M - 99.9M */
+ CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double);
+
+ /* 100M - 999M */
+ CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64);
+
+ /* 1.00G - 9.99G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double);
+
+ /* 10.0G - 99.9G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double);
+
+ /* 100G - 999G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64);
+
+ /* 1.00T - 9.99G */
+ CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double);
+
+ /* 10.0T - 99.9T */
+ CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double);
+
+ /* 100T+ */
+ strncpy(buf, "infty", len);
+ buf[len - 1] = '\0';
+
+ return buf;
+
+}
+
+/* Describe float. Similar as int. */
+
+u8 *stringify_float(u8 *buf, size_t len, double val) {
+
+ if (val < 99.995) {
+
+ snprintf(buf, len, "%0.02f", val);
+
+ } else if (val < 999.95) {
+
+ snprintf(buf, len, "%0.01f", val);
+
+ } else {
+
+ stringify_int(buf, len, (u64)val);
+
+ }
+
+ return buf;
+
+}
+
+/* Describe integer as memory size. */
+
+u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) {
+
+ /* 0-9999 */
+ CHK_FORMAT(1, 10000, "%llu B", u64);
+
+ /* 10.0k - 99.9k */
+ CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
+
+ /* 100k - 999k */
+ CHK_FORMAT(1024, 1000, "%llu kB", u64);
+
+ /* 1.00M - 9.99M */
+ CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
+
+ /* 10.0M - 99.9M */
+ CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
+
+ /* 100M - 999M */
+ CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
+
+ /* 1.00G - 9.99G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
+
+ /* 10.0G - 99.9G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
+
+ /* 100G - 999G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
+
+ /* 1.00T - 9.99G */
+ CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
+
+ /* 10.0T - 99.9T */
+ CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
+
+#undef CHK_FORMAT
+
+ /* 100T+ */
+ strncpy(buf, "infty", len - 1);
+ buf[len - 1] = '\0';
+
+ return buf;
+
+}
+
+/* Describe time delta as string.
+ Returns a pointer to buf for convenience. */
+
+u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
+
+ u64 delta;
+ s32 t_d, t_h, t_m, t_s;
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
+ if (!event_ms) {
+
+ snprintf(buf, len, "none seen yet");
+
+ } else {
+
+ delta = cur_ms - event_ms;
+
+ t_d = delta / 1000 / 60 / 60 / 24;
+ t_h = (delta / 1000 / 60 / 60) % 24;
+ t_m = (delta / 1000 / 60) % 60;
+ t_s = (delta / 1000) % 60;
+
+ stringify_int(val_buf, sizeof(val_buf), t_d);
+ snprintf(buf, len, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m,
+ t_s);
+
+ }
+
+ return buf;
+
+}
+
+/* Unsafe Describe integer. The buf sizes are not checked.
+ This is unsafe but fast.
+ Will return buf for convenience. */
+
+u8 *u_stringify_int(u8 *buf, u64 val) {
+\
+#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
+ do { \
+ \
+ if (val < (_divisor) * (_limit_mult)) { \
+ \
+ sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \
+ return buf; \
+ \
+ } \
+ \
+ } while (0)
+
+ /* 0-9999 */
+ CHK_FORMAT(1, 10000, "%llu", u64);
+
+ /* 10.0k - 99.9k */
+ CHK_FORMAT(1000, 99.95, "%0.01fk", double);
+
+ /* 100k - 999k */
+ CHK_FORMAT(1000, 1000, "%lluk", u64);
+
+ /* 1.00M - 9.99M */
+ CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double);
+
+ /* 10.0M - 99.9M */
+ CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double);
+
+ /* 100M - 999M */
+ CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64);
+
+ /* 1.00G - 9.99G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double);
+
+ /* 10.0G - 99.9G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double);
+
+ /* 100G - 999G */
+ CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64);
+
+ /* 1.00T - 9.99G */
+ CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double);
+
+ /* 10.0T - 99.9T */
+ CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double);
+
+ /* 100T+ */
+ strcpy(buf, "infty");
+
+ return buf;
+
+}
+
+/* Unsafe describe float. Similar as unsafe int. */
+
+u8 *u_stringify_float(u8 *buf, double val) {
+
+ if (val < 99.995) {
+
+ sprintf(buf, "%0.02f", val);
+
+ } else if (val < 999.95) {
+
+ sprintf(buf, "%0.01f", val);
+
+ } else {
+
+ return u_stringify_int(buf, (u64)val);
+
+ }
+
+ return buf;
+
+}
+
+/* Unsafe describe integer as memory size. */
+
+u8 *u_stringify_mem_size(u8 *buf, u64 val) {
+
+ /* 0-9999 */
+ CHK_FORMAT(1, 10000, "%llu B", u64);
+
+ /* 10.0k - 99.9k */
+ CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
+
+ /* 100k - 999k */
+ CHK_FORMAT(1024, 1000, "%llu kB", u64);
+
+ /* 1.00M - 9.99M */
+ CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
+
+ /* 10.0M - 99.9M */
+ CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
+
+ /* 100M - 999M */
+ CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
+
+ /* 1.00G - 9.99G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
+
+ /* 10.0G - 99.9G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
+
+ /* 100G - 999G */
+ CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
+
+ /* 1.00T - 9.99G */
+ CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
+
+ /* 10.0T - 99.9T */
+ CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
+
+#undef CHK_FORMAT
+
+ /* 100T+ */
+ strcpy(buf, "infty");
+
+ return buf;
+
+}
+
+/* Unsafe describe time delta as string.
+ Returns a pointer to buf for convenience. */
+
+u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
+
+ u64 delta;
+ s32 t_d, t_h, t_m, t_s;
+ u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+
+ if (!event_ms) {
+
+ sprintf(buf, "none seen yet");
+
+ } else {
+
+ delta = cur_ms - event_ms;
+
+ t_d = delta / 1000 / 60 / 60 / 24;
+ t_h = (delta / 1000 / 60 / 60) % 24;
+ t_m = (delta / 1000 / 60) % 60;
+ t_s = (delta / 1000) % 60;
+
+ u_stringify_int(val_buf, t_d);
+ sprintf(buf, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, t_s);
+
+ }
+
+ return buf;
+
+}
+
+/* Wrapper for select() and read(), reading exactly len bytes.
+ Returns the time passed to read.
+ If the wait times out, returns timeout_ms + 1;
+ Returns 0 if an error occurred (fd closed, signal, ...); */
+u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) {
+
+ struct timeval timeout;
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ timeout.tv_sec = (timeout_ms / 1000);
+ timeout.tv_usec = (timeout_ms % 1000) * 1000;
+
+ size_t read_total = 0;
+ size_t len_read = 0;
+
+ while (len_read < len) {
+
+ /* set exceptfds as well to return when a child exited/closed the pipe. */
+ int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
+
+ if (!sret) {
+
+ // printf("Timeout in sret.");
+ return timeout_ms + 1;
+
+ } else if (sret < 0) {
+
+ // perror("sret malloc");
+ // TODO: catch other (errno == EINTR) than ctrl+c?
+ return 0;
+
+ }
+
+ len_read = read(fd, ((u8 *)buf) + len_read, len - len_read);
+ if (!len_read) { return 0; }
+ read_total += len_read;
+
+ }
+
+ s32 exec_ms =
+ MIN(timeout_ms,
+ ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
+ return exec_ms > 0 ? exec_ms
+ : 1; // at least 1 milli must have passed (0 is an error)
+
+}
+
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 2dd7a9f0..11b359da 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -49,8 +49,6 @@
/* Describe integer as memory size. */
-extern u8 *doc_path;
-
list_t fsrv_list = {.element_prealloc_count = 0};
/* Initializes the struct */
@@ -164,10 +162,9 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
- struct timeval timeout;
- int st_pipe[2], ctl_pipe[2];
- int status;
- s32 rlen;
+ int st_pipe[2], ctl_pipe[2];
+ int status;
+ s32 rlen;
if (fsrv->use_fauxsrv) ACTF("Using Fauxserver:");
@@ -318,26 +315,19 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
rlen = 0;
if (fsrv->exec_tmout) {
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(fsrv->fsrv_st_fd, &readfds);
- timeout.tv_sec = ((fsrv->exec_tmout * FORK_WAIT_MULT) / 1000);
- timeout.tv_usec = ((fsrv->exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;
+ rlen = 4;
+ u32 time = read_timed(fsrv->fsrv_st_fd, &status, rlen,
+ fsrv->exec_tmout * FORK_WAIT_MULT);
- int sret = select(fsrv->fsrv_st_fd + 1, &readfds, NULL, NULL, &timeout);
-
- if (sret == 0) {
+ if (time > fsrv->exec_tmout * FORK_WAIT_MULT) {
fsrv->child_timed_out = 1;
- kill(fsrv->child_pid, SIGKILL);
-
- } else {
-
- rlen = read(fsrv->fsrv_st_fd, &status, 4);
+ kill(fsrv->fsrv_pid, SIGKILL);
}
+ if (!time) { kill(fsrv->fsrv_pid, SIGKILL); }
+
} else {
rlen = read(fsrv->fsrv_st_fd, &status, 4);
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 0d5b542d..8ca286b2 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -31,13 +31,13 @@
void write_bitmap(afl_state_t *afl) {
- u8 *fname;
+ u8 fname[PATH_MAX];
s32 fd;
if (!afl->bitmap_changed) return;
afl->bitmap_changed = 0;
- fname = alloc_printf("%s/fuzz_bitmap", afl->out_dir);
+ snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0) PFATAL("Unable to open '%s'", fname);
@@ -45,7 +45,6 @@ void write_bitmap(afl_state_t *afl) {
ck_write(fd, afl->virgin_bits, MAP_SIZE, fname);
close(fd);
- ck_free(fname);
}
@@ -462,14 +461,15 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) {
static void write_crash_readme(afl_state_t *afl) {
- u8 * fn = alloc_printf("%s/crashes/README.txt", afl->out_dir);
+ u8 fn[PATH_MAX];
s32 fd;
FILE *f;
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
+ sprintf(fn, "%s/crashes/README.txt", afl->out_dir);
+
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
- ck_free(fn);
/* Do not die on errors here - that would be impolite. */
@@ -520,11 +520,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (unlikely(len == 0)) return 0;
- u8 *fn = "";
+ u8 *queue_fn = "";
u8 hnb;
s32 fd;
u8 keeping = 0, res;
+ u8 fn[PATH_MAX];
+
/* Update path frequency. */
u32 cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST);
@@ -556,16 +558,17 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
- fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths,
- describe_op(afl, hnb));
+ queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir,
+ afl->queued_paths, describe_op(afl, hnb));
#else
- fn = alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths);
+ queue_fn =
+ alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths);
#endif /* ^!SIMPLE_FILES */
- add_to_queue(afl, fn, len, 0);
+ add_to_queue(afl, queue_fn, len, 0);
if (hnb == 2) {
@@ -584,9 +587,9 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (unlikely(res == FAULT_ERROR))
FATAL("Unable to execute target application");
- fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", fn);
- ck_write(fd, mem, len, fn);
+ fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", queue_fn);
+ ck_write(fd, mem, len, queue_fn);
close(fd);
keeping = 1;
@@ -642,12 +645,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
- fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir,
- afl->unique_hangs, describe_op(afl, 0));
+ snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir,
+ afl->unique_hangs, describe_op(afl, 0));
#else
- fn = alloc_printf("%s/hangs/id_%06llu", afl->out_dir, afl->unique_hangs);
+ snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir,
+ afl->unique_hangs);
#endif /* ^!SIMPLE_FILES */
@@ -685,14 +689,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
- fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
- afl->unique_crashes, afl->kill_signal,
- describe_op(afl, 0));
+ snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
+ afl->unique_crashes, afl->kill_signal, describe_op(afl, 0));
#else
- fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir,
- afl->unique_crashes, afl->kill_signal);
+ snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
+ afl->unique_crashes, afl->kill_signal);
#endif /* ^!SIMPLE_FILES */
@@ -729,8 +732,6 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
ck_write(fd, mem, len, fn);
close(fd);
- ck_free(fn);
-
return keeping;
}
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 6c6f05ac..f932f33b 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -31,10 +31,9 @@
void init_cmplog_forkserver(afl_state_t *afl) {
- struct timeval timeout;
- int st_pipe[2], ctl_pipe[2];
- int status;
- s32 rlen;
+ int st_pipe[2], ctl_pipe[2];
+ int status;
+ s32 rlen;
ACTF("Spinning up the cmplog fork server...");
@@ -185,21 +184,19 @@ void init_cmplog_forkserver(afl_state_t *afl) {
rlen = 0;
if (afl->fsrv.exec_tmout) {
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(afl->cmplog_fsrv_st_fd, &readfds);
- timeout.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000);
- timeout.tv_usec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;
+ rlen = 4;
+ u32 timeout_ms = afl->fsrv.exec_tmout * FORK_WAIT_MULT;
+ /* Reuse readfds as exceptfds to see when the child closed the pipe */
+ u32 exec_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, rlen, timeout_ms);
- int sret =
- select(afl->cmplog_fsrv_st_fd + 1, &readfds, NULL, NULL, &timeout);
+ if (!exec_ms) {
- if (sret == 0) {
+ PFATAL("Error in timed read");
- kill(afl->cmplog_fsrv_pid, SIGKILL);
-
- } else {
+ } else if (exec_ms > timeout_ms) {
+ afl->fsrv.child_timed_out = 1;
+ kill(afl->cmplog_fsrv_pid, SIGKILL);
rlen = read(afl->cmplog_fsrv_st_fd, &status, 4);
}
@@ -213,6 +210,11 @@ void init_cmplog_forkserver(afl_state_t *afl) {
/* If we have a four-byte "hello" message from the server, we're all set.
Otherwise, try to figure out what went wrong. */
+ if (afl->fsrv.child_timed_out)
+ FATAL(
+ "Timeout while initializing cmplog fork server (adjusting -t may "
+ "help)");
+
if (rlen == 4) {
OKF("All right - fork server is up.");
@@ -220,11 +222,6 @@ void init_cmplog_forkserver(afl_state_t *afl) {
}
- if (afl->fsrv.child_timed_out)
- FATAL(
- "Timeout while initializing cmplog fork server (adjusting -t may "
- "help)");
-
if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
@@ -379,16 +376,12 @@ void init_cmplog_forkserver(afl_state_t *afl) {
u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
- struct timeval it;
- int status = 0;
- int sret;
- u64 exec_ms;
+ int status = 0;
+ u32 exec_ms;
u32 tb4;
s32 res;
- fd_set readfds;
-
afl->fsrv.child_timed_out = 0;
/* After this memset, afl->fsrv.trace_bits[] are effectively volatile, so we
@@ -423,18 +416,9 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
/* Configure timeout, as requested by user, then wait for child to terminate.
*/
+ exec_ms = read_timed(afl->cmplog_fsrv_st_fd, &status, 4, timeout);
- it.tv_sec = (timeout / 1000);
- it.tv_usec = (timeout % 1000) * 1000;
-
- FD_ZERO(&readfds);
- FD_SET(afl->cmplog_fsrv_st_fd, &readfds);
- it.tv_sec = ((timeout) / 1000);
- it.tv_usec = ((timeout) % 1000) * 1000;
-
- sret = select(afl->cmplog_fsrv_st_fd + 1, &readfds, NULL, NULL, &it);
-
- if (sret == 0) {
+ if (exec_ms > timeout) {
/* If there was no response from forkserver after timeout seconds,
we kill the child. The forkserver should inform us afterwards */
@@ -442,9 +426,12 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
kill(afl->cmplog_child_pid, SIGKILL);
afl->fsrv.child_timed_out = 1;
+ /* After killing the child, the forkserver should tell us */
+ if (!read(afl->cmplog_fsrv_st_fd, &status, 4)) exec_ms = 0;
+
}
- if ((res = read(afl->cmplog_fsrv_st_fd, &status, 4)) != 4) {
+ if (!exec_ms) { // Something went wrong.
if (afl->stop_soon) return 0;
SAYF("\n" cLRD "[-] " cRST
@@ -467,12 +454,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
if (!WIFSTOPPED(status)) afl->cmplog_child_pid = 0;
- exec_ms = (u64)timeout - (it.tv_sec * 1000 + it.tv_usec / 1000);
if (afl->slowest_exec_ms < exec_ms) afl->slowest_exec_ms = exec_ms;
- it.tv_sec = 0;
- it.tv_usec = 0;
-
++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
@@ -527,8 +510,13 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
if (afl->post_handler) {
- out_buf = afl->post_handler(out_buf, &len);
- if (!out_buf || !len) return 0;
+ u8 *post_buf = NULL;
+
+ size_t post_len =
+ afl->post_handler(afl->post_data, out_buf, len, &post_buf);
+ if (!post_buf || !post_len) return 0;
+ out_buf = post_buf;
+ len = post_len;
}
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 038c4393..e2495524 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -76,21 +76,16 @@ void bind_to_free_cpu(afl_state_t *afl) {
while ((de = readdir(d))) {
- u8 * fn;
+ u8 fn[PATH_MAX];
FILE *f;
u8 tmp[MAX_LINE];
u8 has_vmsize = 0;
if (!isdigit(de->d_name[0])) continue;
- fn = alloc_printf("/proc/%s/status", de->d_name);
+ snprintf(fn, PATH_MAX, "/proc/%s/status", de->d_name);
- if (!(f = fopen(fn, "r"))) {
-
- ck_free(fn);
- continue;
-
- }
+ if (!(f = fopen(fn, "r"))) { continue; }
while (fgets(tmp, MAX_LINE, f)) {
@@ -111,7 +106,6 @@ void bind_to_free_cpu(afl_state_t *afl) {
}
- ck_free(fn);
fclose(f);
}
@@ -276,7 +270,9 @@ void setup_post(afl_state_t *afl) {
void *dh;
u8 * fn = afl->afl_env.afl_post_library;
+ u8 tbuf[6];
u32 tlen = 6;
+ strncpy(tbuf, "hello", tlen);
if (!fn) return;
@@ -287,10 +283,20 @@ void setup_post(afl_state_t *afl) {
afl->post_handler = dlsym(dh, "afl_postprocess");
if (!afl->post_handler) FATAL("Symbol 'afl_postprocess' not found.");
+ afl->post_init = dlsym(dh, "afl_postprocess_init");
+ if (!afl->post_init) FATAL("Symbol 'afl_postprocess_init' not found.");
+ afl->post_deinit = dlsym(dh, "afl_postprocess_deinit");
+ if (!afl->post_deinit) FATAL("Symbol 'afl_postprocess_deinit' not found.");
/* Do a quick test. It's better to segfault now than later =) */
- afl->post_handler("hello", &tlen);
+ u8 *post_buf = NULL;
+ afl->post_data = afl->post_init(afl);
+ if (!afl->post_data) FATAL("Could not initialize post handler.");
+
+ size_t post_len = afl->post_handler(afl->post_data, tbuf, tlen, &post_buf);
+ if (!post_len || !post_buf)
+ SAYF("Empty return in test post handler for buf=\"hello\\0\".");
OKF("Postprocessor installed successfully.");
@@ -369,9 +375,10 @@ void read_testcases(afl_state_t *afl) {
struct stat st;
+ u8 dfn[PATH_MAX];
+ snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir,
+ nl[i]->d_name);
u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name);
- u8 *dfn = alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir,
- nl[i]->d_name);
u8 passed_det = 0;
@@ -385,7 +392,6 @@ void read_testcases(afl_state_t *afl) {
if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) {
ck_free(fn2);
- ck_free(dfn);
continue;
}
@@ -401,7 +407,6 @@ void read_testcases(afl_state_t *afl) {
and probably very time-consuming. */
if (!access(dfn, F_OK)) passed_det = 1;
- ck_free(dfn);
add_to_queue(afl, fn2, st.st_size, passed_det);
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 0ded4ba1..754b2190 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -7,6 +7,7 @@
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
Andrea Fioraldi <andreafioraldi@gmail.com>
+ Dominik Maier <mail@dmnk.co>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
@@ -78,8 +79,15 @@ void destroy_custom_mutator(afl_state_t *afl) {
afl->mutator->afl_custom_deinit(afl->mutator->data);
- if (afl->mutator->dh)
- dlclose(afl->mutator->dh);
+ if (afl->mutator->dh) dlclose(afl->mutator->dh);
+
+ if (afl->mutator->pre_save_buf) {
+
+ ck_free(afl->mutator->pre_save_buf);
+ afl->mutator->pre_save_buf = NULL;
+ afl->mutator->pre_save_size = 0;
+
+ }
ck_free(afl->mutator);
afl->mutator = NULL;
@@ -92,6 +100,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
void *dh;
afl->mutator = ck_alloc(sizeof(struct custom_mutator));
+ afl->mutator->pre_save_buf = NULL;
+ afl->mutator->pre_save_size = 0;
afl->mutator->name = fn;
ACTF("Loading custom mutator library from '%s'...", fn);
@@ -103,11 +113,13 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Mutator */
/* "afl_custom_init", required */
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
- if (!afl->mutator->afl_custom_init) FATAL("Symbol 'afl_custom_init' not found.");
+ if (!afl->mutator->afl_custom_init)
+ FATAL("Symbol 'afl_custom_init' not found.");
/* "afl_custom_deinit", required */
afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
- if (!afl->mutator->afl_custom_deinit) FATAL("Symbol 'afl_custom_deinit' not found.");
+ if (!afl->mutator->afl_custom_deinit)
+ FATAL("Symbol 'afl_custom_deinit' not found.");
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
@@ -181,7 +193,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Initialize the custom mutator */
if (afl->mutator->afl_custom_init)
- afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
+ afl->mutator->data =
+ afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
}
@@ -198,24 +211,28 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Initialize trimming in the custom mutator */
afl->stage_cur = 0;
- afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
-
+ afl->stage_max =
+ afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
+ if (unlikely(afl->stage_max) < 0)
+ FATAL("custom_init_trim error ret: %d", afl->stage_max);
if (afl->not_on_tty && afl->debug)
SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max,
q->len);
while (afl->stage_cur < afl->stage_max) {
- sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec));
+ u8 *retbuf = NULL;
- u32 cksum;
+ sprintf(afl->stage_name_buf, "ptrim %s",
+ u_stringify_int(val_buf, trim_exec));
- u8 * retbuf = NULL;
- size_t retlen = 0;
+ u32 cksum;
- afl->mutator->afl_custom_trim(afl, &retbuf, &retlen);
+ size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
- if (retlen > orig_len)
+ if (unlikely(!retbuf))
+ FATAL("custom_trim failed (ret %zd)", retlen);
+ else if (unlikely(retlen > orig_len))
FATAL(
"Trimmed data returned by custom mutator is larger than original "
"data");
@@ -225,12 +242,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
fault = run_target(afl, afl->fsrv.exec_tmout);
++afl->trim_execs;
- if (afl->stop_soon || fault == FAULT_ERROR) {
-
- ck_free(retbuf);
- goto abort_trimming;
-
- }
+ if (afl->stop_soon || fault == FAULT_ERROR) { goto abort_trimming; }
cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST);
@@ -250,7 +262,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
}
/* Tell the custom mutator that the trimming was successful */
- afl->stage_cur = afl->mutator->afl_custom_post_trim(afl, 1);
+ afl->stage_cur =
+ afl->mutator->afl_custom_post_trim(afl->mutator->data, 1);
if (afl->not_on_tty && afl->debug)
SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)",
@@ -259,15 +272,16 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
} else {
/* Tell the custom mutator that the trimming was unsuccessful */
- afl->stage_cur = afl->mutator->afl_custom_post_trim(afl, 0);
+ afl->stage_cur =
+ afl->mutator->afl_custom_post_trim(afl->mutator->data, 0);
+ if (unlikely(afl->stage_cur < 0))
+ FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
if (afl->not_on_tty && afl->debug)
SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur,
afl->stage_max);
}
- ck_free(retbuf);
-
/* Since this can be slow, update the screen every now and then. */
if (!(trim_exec++ % afl->stats_update_freq)) show_stats(afl);
@@ -304,3 +318,4 @@ abort_trimming:
return fault;
}
+
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index cc150cfe..b20bde90 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -347,6 +347,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
u8 a_collect[MAX_AUTO_EXTRA];
u32 a_len = 0;
+/* Not pretty, but saves a lot of writing */
+#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
+
#ifdef IGNORE_FINDS
/* In IGNORE_FINDS mode, skip any entries that weren't in the
@@ -360,7 +363,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* The custom mutator will decide to skip this test case or not. */
- if (!afl->mutator->afl_custom_queue_get(afl, afl->queue_cur->fname))
+ if (!afl->mutator->afl_custom_queue_get(afl->mutator->data,
+ afl->queue_cur->fname))
return 1;
}
@@ -426,7 +430,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
single byte anyway, so it wouldn't give us any performance or memory usage
benefits. */
- out_buf = ck_alloc_nozero(len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
afl->subseq_tmouts = 0;
@@ -718,7 +722,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* Initialize effector map for the next step (see comments below). Always
flag first and last byte as doing something. */
- eff_map = ck_alloc(EFF_ALEN(len));
+ eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
@@ -1442,7 +1446,7 @@ skip_interest:
orig_hit_cnt = new_hit_cnt;
- ex_tmp = ck_alloc(len + MAX_DICT_FILE);
+ ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE);
for (i = 0; i <= len; ++i) {
@@ -1465,7 +1469,6 @@ skip_interest:
if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) {
- ck_free(ex_tmp);
goto abandon_entry;
}
@@ -1479,8 +1482,6 @@ skip_interest:
}
- ck_free(ex_tmp);
-
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt;
@@ -1606,18 +1607,23 @@ custom_mutator_stage:
/* Read the additional testcase into a new buffer. */
fd = open(target->fname, O_RDONLY);
if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname);
- new_buf = ck_alloc_nozero(target->len);
+
+ new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len);
ck_read(fd, new_buf, target->len, target->fname);
close(fd);
+ u8 *mutated_buf = NULL;
+
size_t mutated_size = afl->mutator->afl_custom_fuzz(
- afl, &out_buf, len, new_buf, target->len, max_seed_size);
+ afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len,
+ max_seed_size);
- ck_free(new_buf);
+ if (unlikely(!mutated_buf))
+ FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
if (mutated_size > 0) {
- if (common_fuzz_stuff(afl, out_buf, (u32)mutated_size)) {
+ if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
goto abandon_entry;
@@ -1641,7 +1647,8 @@ custom_mutator_stage:
}
- if (mutated_size < len) out_buf = ck_realloc(out_buf, len);
+ /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */
+ /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. */
memcpy(out_buf, in_buf, len);
}
@@ -1702,7 +1709,7 @@ havoc_stage:
if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) {
stacked_custom_prob =
- afl->mutator->afl_custom_havoc_mutation_probability(afl);
+ afl->mutator->afl_custom_havoc_mutation_probability(afl->mutator->data);
if (stacked_custom_prob > 100)
FATAL(
"The probability returned by afl_custom_havoc_mutation_propability "
@@ -1723,8 +1730,22 @@ havoc_stage:
if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) {
- temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf,
- temp_len, MAX_FILE);
+ u8 * custom_havoc_buf = NULL;
+ size_t new_len = afl->mutator->afl_custom_havoc_mutation(
+ afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
+ if (unlikely(!custom_havoc_buf))
+ FATAL("Error in custom_havoc (return %zd)", new_len);
+ if (likely(new_len > 0 && custom_havoc_buf)) {
+
+ temp_len = new_len;
+ if (out_buf != custom_havoc_buf) {
+
+ ck_maybe_grow(BUF_PARAMS(out), temp_len);
+ memcpy(out_buf, custom_havoc_buf, temp_len);
+
+ }
+
+ }
}
@@ -1954,7 +1975,8 @@ havoc_stage:
clone_to = rand_below(afl, temp_len);
- new_buf = ck_alloc_nozero(temp_len + clone_len);
+ new_buf =
+ ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len);
/* Head */
@@ -1974,8 +1996,9 @@ havoc_stage:
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
- ck_free(out_buf);
+ swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
+ new_buf = NULL;
temp_len += clone_len;
}
@@ -2068,7 +2091,8 @@ havoc_stage:
if (temp_len + extra_len >= MAX_FILE) break;
- new_buf = ck_alloc_nozero(temp_len + extra_len);
+ new_buf =
+ ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
/* Head */
memcpy(new_buf, out_buf, insert_at);
@@ -2084,7 +2108,8 @@ havoc_stage:
if (temp_len + extra_len >= MAX_FILE) break;
- new_buf = ck_alloc_nozero(temp_len + extra_len);
+ new_buf =
+ ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
/* Head */
memcpy(new_buf, out_buf, insert_at);
@@ -2098,8 +2123,9 @@ havoc_stage:
memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,
temp_len - insert_at);
- ck_free(out_buf);
+ swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
+ new_buf = NULL;
temp_len += extra_len;
break;
@@ -2115,7 +2141,7 @@ havoc_stage:
/* out_buf might have been mangled a bit, so let's restore it to its
original size and shape. */
- if (temp_len < len) out_buf = ck_realloc(out_buf, len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
temp_len = len;
memcpy(out_buf, in_buf, len);
@@ -2177,7 +2203,6 @@ retry_splicing:
if (in_buf != orig_in) {
- ck_free(in_buf);
in_buf = orig_in;
len = afl->queue_cur->len;
@@ -2221,7 +2246,7 @@ retry_splicing:
if (unlikely(fd < 0)) PFATAL("Unable to open '%s'", target->fname);
- new_buf = ck_alloc_nozero(target->len);
+ new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len);
ck_read(fd, new_buf, target->len, target->fname);
@@ -2233,12 +2258,7 @@ retry_splicing:
locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff);
- if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) {
-
- ck_free(new_buf);
- goto retry_splicing;
-
- }
+ if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; }
/* Split somewhere between the first and last differing byte. */
@@ -2248,10 +2268,10 @@ retry_splicing:
len = target->len;
memcpy(new_buf, in_buf, split_at);
+ swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch));
in_buf = new_buf;
- ck_free(out_buf);
- out_buf = ck_alloc_nozero(len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
memcpy(out_buf, in_buf, len);
goto custom_mutator_stage;
@@ -2279,12 +2299,14 @@ radamsa_stage:
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
- /* Read the additional testcase into a new buffer. */
- u8 *save_buf = ck_alloc_nozero(len);
+ /* Read the additional testcase.
+ We'll reuse in_scratch, as it is free at this point.
+ */
+ u8 *save_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), len);
memcpy(save_buf, out_buf, len);
u32 max_len = len + choose_block_len(afl, HAVOC_BLK_XL);
- u8 *new_buf = ck_alloc_nozero(max_len);
+ u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), max_len);
u8 *tmp_buf;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -2304,19 +2326,10 @@ radamsa_stage:
}
- if (common_fuzz_stuff(afl, tmp_buf, temp_len)) {
-
- ck_free(save_buf);
- ck_free(new_buf);
- goto abandon_entry;
-
- }
+ if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; }
}
- ck_free(save_buf);
- ck_free(new_buf);
-
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_RADAMSA] += new_hit_cnt - orig_hit_cnt;
@@ -2346,10 +2359,6 @@ abandon_entry:
munmap(orig_in, afl->queue_cur->len);
- if (in_buf != orig_in) ck_free(in_buf);
- ck_free(out_buf);
- ck_free(eff_map);
-
return ret_val;
#undef FLIP_BIT
@@ -2448,7 +2457,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
single byte anyway, so it wouldn't give us any performance or memory usage
benefits. */
- out_buf = ck_alloc_nozero(len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
afl->subseq_tmouts = 0;
@@ -2727,7 +2736,7 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
/* Initialize effector map for the next step (see comments below). Always
flag first and last byte as doing something. */
- eff_map = ck_alloc(EFF_ALEN(len));
+ eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
@@ -3451,7 +3460,7 @@ skip_interest:
orig_hit_cnt = new_hit_cnt;
- ex_tmp = ck_alloc(len + MAX_DICT_FILE);
+ ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE);
for (i = 0; i <= len; ++i) {
@@ -3474,7 +3483,6 @@ skip_interest:
if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) {
- ck_free(ex_tmp);
goto abandon_entry;
}
@@ -3488,8 +3496,6 @@ skip_interest:
} /* for i = 0; i <= len */
- ck_free(ex_tmp);
-
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt;
@@ -3893,7 +3899,8 @@ pacemaker_fuzzing:
clone_to = rand_below(afl, temp_len);
- new_buf = ck_alloc_nozero(temp_len + clone_len);
+ new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch),
+ temp_len + clone_len);
/* Head */
@@ -3914,7 +3921,7 @@ pacemaker_fuzzing:
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
- ck_free(out_buf);
+ swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
temp_len += clone_len;
MOpt_globals.cycles_v2[STAGE_Clone75] += 1;
@@ -3967,7 +3974,7 @@ pacemaker_fuzzing:
/* out_buf might have been mangled a bit, so let's restore it to its
original size and shape. */
- if (temp_len < len) out_buf = ck_realloc(out_buf, len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
temp_len = len;
memcpy(out_buf, in_buf, len);
@@ -4045,7 +4052,6 @@ pacemaker_fuzzing:
if (in_buf != orig_in) {
- ck_free(in_buf);
in_buf = orig_in;
len = afl->queue_cur->len;
@@ -4090,7 +4096,7 @@ pacemaker_fuzzing:
if (fd < 0) PFATAL("Unable to open '%s'", target->fname);
- new_buf = ck_alloc_nozero(target->len);
+ new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len);
ck_read(fd, new_buf, target->len, target->fname);
@@ -4104,7 +4110,6 @@ pacemaker_fuzzing:
if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) {
- ck_free(new_buf);
goto retry_splicing_puppet;
}
@@ -4117,9 +4122,9 @@ pacemaker_fuzzing:
len = target->len;
memcpy(new_buf, in_buf, split_at);
+ swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch));
in_buf = new_buf;
- ck_free(out_buf);
- out_buf = ck_alloc_nozero(len);
+ out_buf = ck_maybe_grow(BUF_PARAMS(out), len);
memcpy(out_buf, in_buf, len);
goto havoc_stage_puppet;
@@ -4154,10 +4159,6 @@ pacemaker_fuzzing:
munmap(orig_in, afl->queue_cur->len);
- if (in_buf != orig_in) ck_free(in_buf);
- ck_free(out_buf);
- ck_free(eff_map);
-
if (afl->key_puppet == 1) {
if (unlikely(
@@ -4379,18 +4380,13 @@ u8 fuzz_one(afl_state_t *afl) {
int key_val_lv = 0;
#ifdef _AFL_DOCUMENT_MUTATIONS
- if (afl->do_document == 0) {
-
- char *fn = alloc_printf("%s/mutations", afl->out_dir);
- if (fn) {
- afl->do_document = mkdir(fn, 0700); // if it exists we do not care
- afl->do_document = 1;
- ck_free(fn);
-
- } else
+ u8 path_buf[PATH_MAX];
+ if (afl->do_document == 0) {
- PFATAL("malloc()");
+ snprintf(path_buf, PATH_MAX, "%s/mutations", afl->out_dir);
+ afl->do_document = mkdir(path_buf, 0700); // if it exists we do not care
+ afl->do_document = 1;
} else {
@@ -4418,5 +4414,7 @@ u8 fuzz_one(afl_state_t *afl) {
return key_val_lv;
+#undef BUF_PARAMS
+
}
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index d3027d2b..12c3a09d 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -29,19 +29,28 @@
#ifdef USE_PYTHON
static void *unsupported(afl_state_t *afl, unsigned int seed) {
+
FATAL("Python Mutator cannot be called twice yet");
return NULL;
+
}
-size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf,
- size_t add_buf_size, size_t max_size) {
+/* sorry for this makro...
+it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
+#define BUF_PARAMS(name) \
+ (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,
+ u8 *add_buf, size_t add_buf_size, size_t max_size) {
size_t mutated_size;
PyObject *py_args, *py_value;
py_args = PyTuple_New(3);
+ py_mutator_t *py = (py_mutator_t *)py_mutator;
/* buf */
- py_value = PyByteArray_FromStringAndSize(*buf, buf_size);
+ py_value = PyByteArray_FromStringAndSize(buf, buf_size);
if (!py_value) {
Py_DECREF(py_args);
@@ -77,29 +86,29 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf,
PyTuple_SetItem(py_args, 2, py_value);
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args);
+ py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
mutated_size = PyByteArray_Size(py_value);
- if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size);
- memcpy(*buf, PyByteArray_AsString(py_value), mutated_size);
+ *out_buf = ck_maybe_grow(BUF_PARAMS(fuzz), mutated_size);
+
+ memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size);
Py_DECREF(py_value);
return mutated_size;
} else {
PyErr_Print();
- FATAL("Call failed");
+ FATAL("python custom fuzz: call failed");
}
}
-
static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
if (!module_name) return NULL;
@@ -124,8 +133,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
if (py_module != NULL) {
u8 py_notrim = 0, py_idx;
+ /* init, required */
py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init");
- py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
py_functions[PY_FUNC_PRE_SAVE] =
PyObject_GetAttrString(py_module, "pre_save");
@@ -142,6 +151,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
PyObject_GetAttrString(py_module, "queue_get");
py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
PyObject_GetAttrString(py_module, "queue_new_entry");
+ py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) {
@@ -223,7 +233,8 @@ void finalize_py_module(void *py_mutator) {
}
-static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int seed) {
+static void init_py(afl_state_t *afl, py_mutator_t *py_mutator,
+ unsigned int seed) {
PyObject *py_args, *py_value;
@@ -244,7 +255,8 @@ static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int see
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
+ py_value =
+ PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
Py_DECREF(py_args);
@@ -283,15 +295,16 @@ void deinit_py(void *py_mutator) {
void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
afl->mutator = ck_alloc(sizeof(struct custom_mutator));
+ afl->mutator->pre_save_buf = NULL;
+ afl->mutator->pre_save_size = 0;
afl->mutator->name = module_name;
ACTF("Loading Python mutator library from '%s'...", module_name);
py_mutator_t *py_mutator;
py_mutator = init_py_module(afl, module_name);
- if (!py_mutator) {
- FATAL("Failed to load python mutator.");
- }
+ afl->mutator->data = py_mutator;
+ if (!py_mutator) { FATAL("Failed to load python mutator."); }
PyObject **py_functions = py_mutator->py_functions;
@@ -334,44 +347,50 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
}
-
size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) {
- size_t out_buf_size;
- PyObject *py_args, *py_value;
+ size_t py_out_buf_size;
+ PyObject * py_args, *py_value;
+ py_mutator_t *py = (py_mutator_t *)py_mutator;
+
py_args = PyTuple_New(1);
py_value = PyByteArray_FromStringAndSize(buf, buf_size);
if (!py_value) {
Py_DECREF(py_args);
- FATAL("Failed to convert arguments");
+ FATAL("Failed to convert arguments in custom pre_save");
}
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
- out_buf_size = PyByteArray_Size(py_value);
- *out_buf = malloc(out_buf_size);
- memcpy(*out_buf, PyByteArray_AsString(py_value), out_buf_size);
+ py_out_buf_size = PyByteArray_Size(py_value);
+
+ ck_maybe_grow(BUF_PARAMS(pre_save), py_out_buf_size);
+
+ memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size);
Py_DECREF(py_value);
- return out_buf_size;
+
+ *out_buf = py->pre_save_buf;
+ return py_out_buf_size;
} else {
PyErr_Print();
- FATAL("Call failed");
+ FATAL("Python custom mutator: pre_save call failed.");
}
}
-u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
+s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
PyObject *py_args, *py_value;
@@ -386,7 +405,8 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -408,7 +428,7 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
}
-u32 post_trim_py(void *py_mutator, u8 success) {
+s32 post_trim_py(void *py_mutator, u8 success) {
PyObject *py_args, *py_value;
@@ -424,7 +444,8 @@ u32 post_trim_py(void *py_mutator, u8 success) {
PyTuple_SetItem(py_args, 0, py_value);
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -446,19 +467,21 @@ u32 post_trim_py(void *py_mutator, u8 success) {
}
-void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) {
+size_t trim_py(void *py_mutator, u8 **out_buf) {
PyObject *py_args, *py_value;
+ size_t ret;
py_args = PyTuple_New(0);
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
- *out_buf_size = PyByteArray_Size(py_value);
- *out_buf = malloc(*out_buf_size);
- memcpy(*out_buf, PyByteArray_AsString(py_value), *out_buf_size);
+ ret = PyByteArray_Size(py_value);
+ *out_buf = ck_maybe_grow(BUF_PARAMS(trim), ret);
+ memcpy(*out_buf, PyByteArray_AsString(py_value), ret);
Py_DECREF(py_value);
} else {
@@ -468,17 +491,19 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) {
}
+ return ret;
+
}
-size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size,
- size_t max_size) {
+size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size,
+ u8 **out_buf, size_t max_size) {
size_t mutated_size;
PyObject *py_args, *py_value;
py_args = PyTuple_New(2);
/* buf */
- py_value = PyByteArray_FromStringAndSize(*buf, buf_size);
+ py_value = PyByteArray_FromStringAndSize(buf, buf_size);
if (!py_value) {
Py_DECREF(py_args);
@@ -503,17 +528,28 @@ size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size,
PyTuple_SetItem(py_args, 1, py_value);
- py_value =
- PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION],
+ py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
mutated_size = PyByteArray_Size(py_value);
- if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size);
+ if (mutated_size <= buf_size) {
- memcpy(*buf, PyByteArray_AsString(py_value), mutated_size);
+ /* We reuse the input buf here. */
+ *out_buf = buf;
+
+ } else {
+
+ /* A new buf is needed... */
+ *out_buf = ck_maybe_grow(BUF_PARAMS(havoc), mutated_size);
+
+ }
+
+ memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size);
Py_DECREF(py_value);
return mutated_size;
@@ -533,7 +569,9 @@ u8 havoc_mutation_probability_py(void *py_mutator) {
py_args = PyTuple_New(0);
py_value = PyObject_CallObject(
- ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args);
+ ((py_mutator_t *)py_mutator)
+ ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY],
+ py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -573,7 +611,8 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) {
PyTuple_SetItem(py_args, 0, py_value);
// Call Python function
- py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
Py_DECREF(py_args);
if (py_value != NULL) {
@@ -642,8 +681,9 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
PyTuple_SetItem(py_args, 1, py_value);
// Call
- py_value =
- PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args);
+ py_value = PyObject_CallObject(
+ ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY],
+ py_args);
Py_DECREF(py_args);
if (py_value == NULL) {
@@ -655,5 +695,7 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
}
+#undef BUF_PARAMS
+
#endif /* USE_PYTHON */
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index f49e1f1e..92cbab6f 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -30,18 +30,16 @@
void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
- u8 *fn = strrchr(q->fname, '/');
+ u8 fn[PATH_MAX];
s32 fd;
- fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir,
- fn + 1);
+ snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
+ strrchr(q->fname, '/') + 1);
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0) PFATAL("Unable to create '%s'", fn);
close(fd);
- ck_free(fn);
-
q->passed_det = 1;
}
@@ -51,10 +49,13 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
- u8 *fn = strrchr(q->fname, '/') + 1, *ldest;
+ u8 fn[PATH_MAX];
+ u8 ldest[PATH_MAX];
+
+ u8 *fn_name = strrchr(q->fname, '/') + 1;
- ldest = alloc_printf("../../%s", fn);
- fn = alloc_printf("%s/queue/.state/variable_behavior/%s", afl->out_dir, fn);
+ sprintf(ldest, "../../%s", fn_name);
+ sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name);
if (symlink(ldest, fn)) {
@@ -64,9 +65,6 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
}
- ck_free(ldest);
- ck_free(fn);
-
q->var_behavior = 1;
}
@@ -76,14 +74,14 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
- u8 *fn;
+ u8 fn[PATH_MAX];
if (state == q->fs_redundant) return;
q->fs_redundant = state;
- fn = strrchr(q->fname, '/');
- fn = alloc_printf("%s/queue/.state/redundant_edges/%s", afl->out_dir, fn + 1);
+ sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir,
+ strrchr(q->fname, '/') + 1);
if (state) {
@@ -99,8 +97,6 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
}
- ck_free(fn);
-
}
/* Append new test case to the queue. */
@@ -114,6 +110,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
q->depth = afl->cur_depth + 1;
q->passed_det = passed_det;
q->n_fuzz = 1;
+ q->trace_mini = NULL;
if (q->depth > afl->max_depth) afl->max_depth = q->depth;
@@ -147,7 +144,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
/* At the initialization stage, queue_cur is NULL */
if (afl->queue_cur) fname_orig = afl->queue_cur->fname;
- afl->mutator->afl_custom_queue_new_entry(afl, fname, fname_orig);
+ afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname,
+ fname_orig);
}
@@ -186,9 +184,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u32 i;
u64 fav_factor;
- u64 fuzz_p2 = next_p2(q->n_fuzz);
+ u64 fuzz_p2 = next_pow2(q->n_fuzz);
- if (afl->schedule == MMOPT || afl->schedule == RARE)
+ if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed))
fav_factor = q->len << 2;
else
fav_factor = q->exec_us * q->len;
@@ -203,9 +201,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
/* Faster-executing or smaller test cases are favored. */
u64 top_rated_fav_factor;
- u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
+ u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
- if (afl->schedule == MMOPT || afl->schedule == RARE)
+ if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed))
top_rated_fav_factor = afl->top_rated[i]->len << 2;
else
top_rated_fav_factor =
@@ -216,8 +214,17 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
else if (fuzz_p2 == top_rated_fuzz_p2)
if (fav_factor > top_rated_fav_factor) continue;
- if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
- continue;
+ if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) {
+
+ if (fav_factor > afl->top_rated[i]->len << 2)
+ continue;
+
+ } else {
+
+ if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
+ continue;
+
+ }
/* Looks like we're going to win. Decrease ref count for the
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
@@ -332,7 +339,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh
- if (afl->schedule != MMOPT && afl->schedule != RARE) {
+ if (afl->schedule != MMOPT && afl->schedule != RARE && likely(!afl->fixed_seed)) {
if (q->exec_us * 0.1 > avg_exec_us)
perf_score = 10;
@@ -442,7 +449,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
if (q->fuzz_level < 16)
factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
else
- factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_p2(fuzz));
+ factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz));
break;
case LIN: factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz); break;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index b069fa77..4acc204b 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -529,9 +529,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
if (!afl->shm.cmp_map->headers[k].hits) continue;
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS)
- afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_H);
+ afl->stage_max += MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_H);
else
- afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H);
+ afl->stage_max +=
+ MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H);
}
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 8c4b5941..5875eb68 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -33,13 +33,10 @@
u8 run_target(afl_state_t *afl, u32 timeout) {
s32 res;
- int sret;
+ u32 exec_ms;
- fd_set readfds;
-
- struct timeval it;
- int status = 0;
- u32 tb4;
+ int status = 0;
+ u32 tb4;
afl->fsrv.child_timed_out = 0;
@@ -70,26 +67,20 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)");
- /* use select to monitor the forkserver for timeouts. */
-
- FD_ZERO(&readfds);
- FD_SET(afl->fsrv.fsrv_st_fd, &readfds);
- it.tv_sec = ((timeout) / 1000);
- it.tv_usec = ((timeout) % 1000) * 1000;
-
- sret = select(afl->fsrv.fsrv_st_fd + 1, &readfds, NULL, NULL, &it);
+ exec_ms = read_timed(afl->fsrv.fsrv_st_fd, &status, 4, timeout);
- if (sret == 0) {
+ if (exec_ms > timeout) {
/* If there was no response from forkserver after timeout seconds,
we kill the child. The forkserver should inform us afterwards */
kill(afl->fsrv.child_pid, SIGKILL);
afl->fsrv.child_timed_out = 1;
+ if (read(afl->fsrv.fsrv_st_fd, &status, 4) < 4) exec_ms = 0;
}
- if ((res = read(afl->fsrv.fsrv_st_fd, &status, 4)) != 4) {
+ if (!exec_ms) {
if (afl->stop_soon) return 0;
SAYF("\n" cLRD "[-] " cRST
@@ -176,20 +167,16 @@ 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 = alloc_printf("%s/mutations/%09u:%s", afl->out_dir,
+ 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));
- if (fn != NULL) {
-
- if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
-
- if (write(doc_fd, mem, len) != len)
- PFATAL("write to mutation file failed: %s", fn);
- close(doc_fd);
- }
+ if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
- ck_free(fn);
+ if (write(doc_fd, mem, len) != len)
+ PFATAL("write to mutation file failed: %s", fn);
+ close(doc_fd);
}
@@ -214,16 +201,22 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
lseek(fd, 0, SEEK_SET);
- if (afl->mutator && afl->mutator->afl_custom_pre_save) {
+ if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) {
+
+ u8 *new_buf = NULL;
+
+ size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
+ len, &new_buf);
- u8 * new_data;
- size_t new_size =
- afl->mutator->afl_custom_pre_save(afl, mem, len, &new_data);
- ck_write(fd, new_data, new_size, afl->fsrv.out_file);
- ck_free(new_data);
+ if (unlikely(!new_buf))
+ 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);
} else {
+ /* boring uncustom. */
ck_write(fd, mem, len, afl->fsrv.out_file);
}
@@ -505,8 +498,8 @@ void sync_fuzzers(afl_state_t *afl) {
afl->stage_cur = 0;
afl->stage_max = 0;
- /* For every file queued by this fuzzer, parse ID and see if we have looked
- at it before; exec a test case if not. */
+ /* For every file queued by this fuzzer, parse ID and see if we have
+ looked at it before; exec a test case if not. */
while ((qd_ent = readdir(qd))) {
@@ -615,7 +608,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Select initial chunk len, starting with large steps. */
- len_p2 = next_p2(q->len);
+ len_p2 = next_pow2(q->len);
remove_len = MAX(len_p2 / TRIM_START_STEPS, TRIM_MIN_BYTES);
@@ -627,8 +620,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
u32 remove_pos = remove_len;
sprintf(afl->stage_name_buf, "trim %s/%s",
- u_stringify_int(val_bufs[0], remove_len),
- u_stringify_int(val_bufs[1], remove_len));
+ u_stringify_int(val_bufs[0], remove_len),
+ u_stringify_int(val_bufs[1], remove_len));
afl->stage_cur = 0;
afl->stage_max = q->len / remove_len;
@@ -645,7 +638,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
if (afl->stop_soon || fault == FAULT_ERROR) goto abort_trimming;
- /* Note that we don't keep track of crashes or hangs here; maybe TODO? */
+ /* Note that we don't keep track of crashes or hangs here; maybe TODO?
+ */
cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST);
@@ -659,7 +653,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
u32 move_tail = q->len - remove_pos - trim_avail;
q->len -= trim_avail;
- len_p2 = next_p2(q->len);
+ len_p2 = next_pow2(q->len);
memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail,
move_tail);
@@ -734,8 +728,13 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
if (afl->post_handler) {
- out_buf = afl->post_handler(out_buf, &len);
- if (!out_buf || !len) return 0;
+ u8 *post_buf = NULL;
+
+ size_t post_len =
+ afl->post_handler(afl->post_data, out_buf, len, &post_buf);
+ if (!post_buf || !post_len) return 0;
+ out_buf = post_buf;
+ len = post_len;
}
diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-state.c
index 88633a1b..80176a10 100644
--- a/src/afl-fuzz-globals.c
+++ b/src/afl-fuzz-state.c
@@ -34,8 +34,6 @@ char *power_names[POWER_SCHEDULES_NUM] = {
"explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
-u8 *doc_path = NULL; /* gath to documentation dir */
-
/* Initialize MOpt "globals" for this afl state */
static void init_mopt_globals(afl_state_t *afl) {
@@ -79,6 +77,8 @@ list_t afl_states = {.element_prealloc_count = 0};
void afl_state_init(afl_state_t *afl) {
+ /* thanks to this memset, growing vars like out_buf
+ and out_size are NULL/0 by default. */
memset(afl, 0, sizeof(afl_state_t));
afl->w_init = 0.9;
@@ -347,6 +347,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
void afl_state_deinit(afl_state_t *afl) {
+ if (afl->post_deinit) afl->post_deinit(afl->post_data);
+
+ free(afl->out_buf);
+ free(afl->out_scratch_buf);
+ free(afl->eff_buf);
+ free(afl->in_buf);
+ free(afl->in_scratch_buf);
+ free(afl->ex_buf);
+
list_remove(&afl_states, afl);
}
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index dc16df8f..77bbe023 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -33,16 +33,17 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
struct rusage rus;
unsigned long long int cur_time = get_cur_time();
- u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
+ u8 fn[PATH_MAX];
s32 fd;
FILE * f;
+ uint32_t t_bytes = count_non_255_bytes(afl->virgin_bits);
+
+ snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir);
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0) PFATAL("Unable to create '%s'", fn);
- ck_free(fn);
-
f = fdopen(fd, "w");
if (!f) PFATAL("fdopen() failed");
@@ -95,8 +96,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"last_hang : %llu\n"
"execs_since_crash : %llu\n"
"exec_timeout : %u\n"
- "slowest_exec_ms : %llu\n"
+ "slowest_exec_ms : %u\n"
"peak_rss_mb : %lu\n"
+ "var_byte_count : %u\n"
+ "found_edges : %u\n"
"afl_banner : %s\n"
"afl_version : " VERSION
"\n"
@@ -119,9 +122,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
#else
(unsigned long int)(rus.ru_maxrss >> 10),
#endif
- afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
- afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "",
- afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
+ afl->var_byte_count, t_bytes, afl->use_banner,
+ afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "",
+ afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "",
+ afl->crash_mode ? "crash " : "",
afl->persistent_mode ? "persistent " : "",
afl->deferred_mode ? "deferred " : "",
(afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode ||
@@ -257,7 +261,7 @@ void show_stats(afl_state_t *afl) {
t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE;
if (t_bytes)
- stab_ratio = 100 - ((double)afl->var_byte_count) * 100 / t_bytes;
+ stab_ratio = 100 - (((double)afl->var_byte_count) * 100) / t_bytes;
else
stab_ratio = 100;
@@ -406,8 +410,7 @@ void show_stats(afl_state_t *afl) {
(afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
afl->in_bitmap || afl->crash_mode)) {
- u_stringify_time_diff(time_tmp, cur_ms,
- afl->last_path_time);
+ u_stringify_time_diff(time_tmp, cur_ms, afl->last_path_time);
SAYF(bV bSTOP " last new path : " cRST "%-33s ", time_tmp);
} else {
@@ -533,24 +536,21 @@ void show_stats(afl_state_t *afl) {
if (afl->stats_avg_exec < 100) {
- sprintf(tmp, "%s/sec (%s)",
- u_stringify_float(IB(0), afl->stats_avg_exec),
- afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
+ sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
+ afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp);
} else {
- sprintf(tmp, "%s/sec",
- u_stringify_float(IB(0), afl->stats_avg_exec));
+ sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec));
SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp);
}
- sprintf(tmp, "%s (%s%s unique)",
- u_stringify_int(IB(0), afl->total_tmouts),
- u_stringify_int(IB(1), afl->unique_tmouts),
- (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
+ sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_tmouts),
+ u_stringify_int(IB(1), afl->unique_tmouts),
+ (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
@@ -567,12 +567,12 @@ void show_stats(afl_state_t *afl) {
} else {
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]),
- u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP4]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4]));
}
@@ -582,12 +582,12 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]),
- u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP
" pending : " cRST "%-10s" bSTG bV "\n",
@@ -595,12 +595,12 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]),
- u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
" pend fav : " cRST "%-10s" bSTG bV "\n",
@@ -621,25 +621,26 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
- u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
" imported : " cRST "%-10s" bSTG bV "\n",
tmp,
- afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) : (u8 *)"n/a");
+ afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
+ : (u8 *)"n/a");
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
- u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
- u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
- u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]),
- u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
- u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
+ u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
+ u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
+ u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]),
+ u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
+ u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
@@ -660,14 +661,14 @@ void show_stats(afl_state_t *afl) {
if (afl->shm.cmplog_mode) {
sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
- u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]),
- u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]),
- u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]),
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]),
+ u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]),
+ u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS]));
SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp);
@@ -675,10 +676,10 @@ void show_stats(afl_state_t *afl) {
} else {
sprintf(tmp, "%s/%s, %s/%s",
- u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
- u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
- u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
- u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
+ u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
+ u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]),
+ u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
+ u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index ba56ff67..ad4f5b6b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -25,8 +25,6 @@
#include "afl-fuzz.h"
-u8 be_quiet = 0;
-
static u8 *get_libradamsa_path(u8 *own_loc) {
u8 *tmp, *cp, *rsl, *own_copy;
@@ -693,6 +691,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->fixed_seed) OKF("Running with fixed seed: %u", (u32)afl->init_seed);
srandom((u32)afl->init_seed);
+ srand((u32)afl->init_seed); // in case it is a different implementation
if (afl->use_radamsa) {
@@ -723,6 +722,16 @@ int main(int argc, char **argv_orig, char **envp) {
}
+#if defined(__SANITIZE_ADDRESS__)
+ if (afl->fsrv.mem_limit) {
+
+ WARNF("in the ASAN build we disable all memory limits");
+ afl->fsrv.mem_limit = 0;
+
+ }
+
+#endif
+
setup_signal_handlers();
check_asan_opts();
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index caacefe4..f8a38c36 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -59,13 +59,10 @@
#include <sys/types.h>
#include <sys/resource.h>
-u8 be_quiet;
-
char *stdin_file; /* stdin file */
u8 *in_dir, /* input folder */
- *doc_path, /* Path to docs */
- *at_file = NULL; /* Substitution string for @@ */
+ *at_file = NULL; /* Substitution string for @@ */
static u8 *in_data; /* Input data */
@@ -224,26 +221,6 @@ static u32 write_results(afl_forkserver_t *fsrv) {
}
-/* Write output file. */
-
-static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
-
- s32 ret;
-
- unlink(path); /* Ignore errors */
-
- ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
-
- if (ret < 0) PFATAL("Unable to create '%s'", path);
-
- ck_write(ret, mem, len, path);
-
- lseek(ret, 0, SEEK_SET);
-
- return ret;
-
-}
-
/* 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. */
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 2275aef5..30e76d42 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -61,8 +61,7 @@
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
u8 *in_file, /* Minimizer input test case */
- *output_file, /* Minimizer output file */
- *doc_path; /* Path to docs */
+ *output_file; /* Minimizer output file */
static u8 *in_data; /* Input data for trimming */
@@ -77,8 +76,7 @@ u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */
exit_crash, /* Treat non-zero exit as crash? */
edges_only, /* Ignore hit counts? */
- exact_mode, /* Require path match for crashes? */
- be_quiet;
+ exact_mode; /* Require path match for crashes? */
static volatile u8 stop_soon; /* Ctrl-C pressed? */
@@ -406,17 +404,6 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
}
-/* Find first power of two greater or equal to val. */
-
-static u32 next_p2(u32 val) {
-
- u32 ret = 1;
- while (val > ret)
- ret <<= 1;
- return ret;
-
-}
-
/* Actually minimize! */
static void minimize(afl_forkserver_t *fsrv, char **argv) {
@@ -434,7 +421,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
* BLOCK NORMALIZATION *
***********************/
- set_len = next_p2(in_len / TMIN_SET_STEPS);
+ set_len = next_pow2(in_len / TMIN_SET_STEPS);
set_pos = 0;
if (set_len < TMIN_SET_MIN_SIZE) set_len = TMIN_SET_MIN_SIZE;
@@ -484,7 +471,7 @@ next_pass:
* BLOCK DELETION *
******************/
- del_len = next_p2(in_len / TRIM_START_STEPS);
+ del_len = next_pow2(in_len / TRIM_START_STEPS);
stage_o_len = in_len;
ACTF(cBRI "Stage #1: " cRST "Removing blocks of data...");
diff --git a/src/third_party/libradamsa/libradamsa.c b/src/third_party/libradamsa/libradamsa.c
index f3677fa7..fe91594e 100644
--- a/src/third_party/libradamsa/libradamsa.c
+++ b/src/third_party/libradamsa/libradamsa.c
@@ -30815,7 +30815,7 @@ size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
lispval = G(lispval, 2); // list = cdr(list)
}
if (lispval != INULL && max == 0) {
- printf("ERROR: lisp return value was not a proper list. Trailing %lu\n", lispval);
+ printf("ERROR: lisp return value was not a proper list. Trailing %lu\n", (unsigned long)lispval);
}
return n;
}