mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 04:54:05 -05:00
Remove libfuzzer / afl based builds in favor of go 1.18 fuzz testing (#10065)
* Remove libfuzzer / afl based builds in favor of go 1.18 fuzz testing * rm beacon-fuzz archive Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
80
third_party/afl/BUILD.bazel
vendored
80
third_party/afl/BUILD.bazel
vendored
@@ -1,80 +0,0 @@
|
||||
package(
|
||||
default_testonly = True,
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
# Note: these libraries only compile with llvm.
|
||||
|
||||
cc_library(
|
||||
name = "comm_hdr",
|
||||
hdrs = [
|
||||
"alloc-inl.h",
|
||||
"config.h",
|
||||
"debug.h",
|
||||
"hash.h",
|
||||
"types.h",
|
||||
],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
CFLAGS = [
|
||||
"-O3 -funroll-loops",
|
||||
"-Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign",
|
||||
"-DAFL_PATH=\\\"/usr/local/lib/afl\\\"",
|
||||
"-DDOC_PATH=\\\"/usr/local/share/doc/afl\\\"",
|
||||
"-DBIN_PATH=\\\"/usr/local/bin\\\"",
|
||||
]
|
||||
|
||||
LDFLAGS = ["-ldl"]
|
||||
|
||||
cc_library(
|
||||
name = "lib-afl-fuzz",
|
||||
srcs = ["afl-fuzz.c"],
|
||||
copts = CFLAGS,
|
||||
linkopts = LDFLAGS,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [":comm_hdr"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "lib-afl-showmap",
|
||||
srcs = ["afl-showmap.c"],
|
||||
copts = CFLAGS,
|
||||
linkopts = LDFLAGS,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [":comm_hdr"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "afl-llvm-rt",
|
||||
srcs = ["llvm_mode/afl-llvm-rt.o.c"],
|
||||
copts = ["-Wno-pointer-sign -O3"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [":comm_hdr"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fuzzing_engine",
|
||||
srcs = ["afl_driver.cpp"],
|
||||
copts = ["-fsanitize=address -O3"],
|
||||
linkopts = ["-fsanitize=address"],
|
||||
tags = ["manual"],
|
||||
deps = [":afl-llvm-rt"],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "libs",
|
||||
srcs = [
|
||||
":lib-afl-fuzz",
|
||||
":lib-afl-showmap",
|
||||
],
|
||||
outs = [
|
||||
"afl-fuzz",
|
||||
"afl-showmap",
|
||||
],
|
||||
cmd = """
|
||||
cp $(locations :lib-afl-fuzz) .
|
||||
cp $(locations :lib-afl-showmap) .
|
||||
mv liblib-afl-fuzz.a $(location afl-fuzz)
|
||||
mv liblib-afl-showmap.a $(location afl-showmap)
|
||||
""",
|
||||
)
|
||||
BIN
third_party/afl/afl-fuzz
vendored
BIN
third_party/afl/afl-fuzz
vendored
Binary file not shown.
8099
third_party/afl/afl-fuzz.c
vendored
8099
third_party/afl/afl-fuzz.c
vendored
File diff suppressed because it is too large
Load Diff
780
third_party/afl/afl-showmap.c
vendored
780
third_party/afl/afl-showmap.c
vendored
@@ -1,780 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - map display utility
|
||||
----------------------------------------
|
||||
|
||||
Written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
A very simple tool that runs the targeted binary and displays
|
||||
the contents of the trace bitmap in a human-readable form. Useful in
|
||||
scripts to eliminate redundant inputs and perform other checks.
|
||||
|
||||
Exit code is 2 if the target program crashes; 1 if it times out or
|
||||
there is a problem executing it; or 0 if execution is successful.
|
||||
|
||||
*/
|
||||
|
||||
#define AFL_MAIN
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
#include "alloc-inl.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
static s32 child_pid; /* PID of the tested program */
|
||||
|
||||
static u8* trace_bits; /* SHM with instrumentation bitmap */
|
||||
|
||||
static u8 *out_file, /* Trace output file */
|
||||
*doc_path, /* Path to docs */
|
||||
*target_path, /* Path to target binary */
|
||||
*at_file; /* Substitution string for @@ */
|
||||
|
||||
static u32 exec_tmout; /* Exec timeout (ms) */
|
||||
|
||||
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
||||
|
||||
static s32 shm_id; /* ID of the SHM region */
|
||||
|
||||
static u8 quiet_mode, /* Hide non-essential messages? */
|
||||
edges_only, /* Ignore hit counts? */
|
||||
cmin_mode, /* Generate output in afl-cmin mode? */
|
||||
binary_mode, /* Write output as a binary map */
|
||||
keep_cores; /* Allow coredumps? */
|
||||
|
||||
static volatile u8
|
||||
stop_soon, /* Ctrl-C pressed? */
|
||||
child_timed_out, /* Child timed out? */
|
||||
child_crashed; /* Child crashed? */
|
||||
|
||||
/* Classify tuple counts. Instead of mapping to individual bits, as in
|
||||
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
|
||||
|
||||
static const u8 count_class_human[256] = {
|
||||
|
||||
[0] = 0,
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 3,
|
||||
[4 ... 7] = 4,
|
||||
[8 ... 15] = 5,
|
||||
[16 ... 31] = 6,
|
||||
[32 ... 127] = 7,
|
||||
[128 ... 255] = 8
|
||||
|
||||
};
|
||||
|
||||
static const u8 count_class_binary[256] = {
|
||||
|
||||
[0] = 0,
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 4,
|
||||
[4 ... 7] = 8,
|
||||
[8 ... 15] = 16,
|
||||
[16 ... 31] = 32,
|
||||
[32 ... 127] = 64,
|
||||
[128 ... 255] = 128
|
||||
|
||||
};
|
||||
|
||||
static void classify_counts(u8* mem, const u8* map) {
|
||||
|
||||
u32 i = MAP_SIZE;
|
||||
|
||||
if (edges_only) {
|
||||
|
||||
while (i--) {
|
||||
if (*mem) *mem = 1;
|
||||
mem++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
while (i--) {
|
||||
*mem = map[*mem];
|
||||
mem++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Get rid of shared memory (atexit handler). */
|
||||
|
||||
static void remove_shm(void) {
|
||||
|
||||
shmctl(shm_id, IPC_RMID, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Configure shared memory. */
|
||||
|
||||
static void setup_shm(void) {
|
||||
|
||||
u8* shm_str;
|
||||
|
||||
shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
|
||||
|
||||
if (shm_id < 0) PFATAL("shmget() failed");
|
||||
|
||||
atexit(remove_shm);
|
||||
|
||||
shm_str = alloc_printf("%d", shm_id);
|
||||
|
||||
setenv(SHM_ENV_VAR, shm_str, 1);
|
||||
|
||||
ck_free(shm_str);
|
||||
|
||||
trace_bits = shmat(shm_id, NULL, 0);
|
||||
|
||||
if (!trace_bits) PFATAL("shmat() failed");
|
||||
|
||||
}
|
||||
|
||||
/* Write results. */
|
||||
|
||||
static u32 write_results(void) {
|
||||
|
||||
s32 fd;
|
||||
u32 i, ret = 0;
|
||||
|
||||
u8 cco = !!getenv("AFL_CMIN_CRASHES_ONLY"),
|
||||
caa = !!getenv("AFL_CMIN_ALLOW_ANY");
|
||||
|
||||
if (!strncmp(out_file, "/dev/", 5)) {
|
||||
|
||||
fd = open(out_file, O_WRONLY, 0600);
|
||||
if (fd < 0) PFATAL("Unable to open '%s'", out_file);
|
||||
|
||||
} else if (!strcmp(out_file, "-")) {
|
||||
|
||||
fd = dup(1);
|
||||
if (fd < 0) PFATAL("Unable to open stdout");
|
||||
|
||||
} else {
|
||||
|
||||
unlink(out_file); /* Ignore errors */
|
||||
fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
if (fd < 0) PFATAL("Unable to create '%s'", out_file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (binary_mode) {
|
||||
|
||||
for (i = 0; i < MAP_SIZE; i++)
|
||||
if (trace_bits[i]) ret++;
|
||||
|
||||
ck_write(fd, trace_bits, MAP_SIZE, out_file);
|
||||
close(fd);
|
||||
|
||||
} else {
|
||||
|
||||
FILE* f = fdopen(fd, "w");
|
||||
|
||||
if (!f) PFATAL("fdopen() failed");
|
||||
|
||||
for (i = 0; i < MAP_SIZE; i++) {
|
||||
|
||||
if (!trace_bits[i]) continue;
|
||||
ret++;
|
||||
|
||||
if (cmin_mode) {
|
||||
|
||||
if (child_timed_out) break;
|
||||
if (!caa && child_crashed != cco) break;
|
||||
|
||||
fprintf(f, "%u%u\n", trace_bits[i], i);
|
||||
|
||||
} else fprintf(f, "%06u:%u\n", i, trace_bits[i]);
|
||||
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Handle timeout signal. */
|
||||
|
||||
static void handle_timeout(int sig) {
|
||||
|
||||
child_timed_out = 1;
|
||||
if (child_pid > 0) kill(child_pid, SIGKILL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Execute target application. */
|
||||
|
||||
static void run_target(char** argv) {
|
||||
|
||||
static struct itimerval it;
|
||||
int status = 0;
|
||||
|
||||
if (!quiet_mode)
|
||||
SAYF("-- Program output begins --\n" cRST);
|
||||
|
||||
MEM_BARRIER();
|
||||
|
||||
child_pid = fork();
|
||||
|
||||
if (child_pid < 0) PFATAL("fork() failed");
|
||||
|
||||
if (!child_pid) {
|
||||
|
||||
struct rlimit r;
|
||||
|
||||
if (quiet_mode) {
|
||||
|
||||
s32 fd = open("/dev/null", O_RDWR);
|
||||
|
||||
if (fd < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) {
|
||||
*(u32*)trace_bits = EXEC_FAIL_SIG;
|
||||
PFATAL("Descriptor initialization failed");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
if (mem_limit) {
|
||||
|
||||
r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;
|
||||
|
||||
#ifdef RLIMIT_AS
|
||||
|
||||
setrlimit(RLIMIT_AS, &r); /* Ignore errors */
|
||||
|
||||
#else
|
||||
|
||||
setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
|
||||
|
||||
#endif /* ^RLIMIT_AS */
|
||||
|
||||
}
|
||||
|
||||
if (!keep_cores) r.rlim_max = r.rlim_cur = 0;
|
||||
else r.rlim_max = r.rlim_cur = RLIM_INFINITY;
|
||||
|
||||
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
|
||||
|
||||
if (!getenv("LD_BIND_LAZY")) setenv("LD_BIND_NOW", "1", 0);
|
||||
|
||||
setsid();
|
||||
|
||||
execv(target_path, argv);
|
||||
|
||||
*(u32*)trace_bits = EXEC_FAIL_SIG;
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
/* Configure timeout, wait for child, cancel timeout. */
|
||||
|
||||
if (exec_tmout) {
|
||||
|
||||
child_timed_out = 0;
|
||||
it.it_value.tv_sec = (exec_tmout / 1000);
|
||||
it.it_value.tv_usec = (exec_tmout % 1000) * 1000;
|
||||
|
||||
}
|
||||
|
||||
setitimer(ITIMER_REAL, &it, NULL);
|
||||
|
||||
if (waitpid(child_pid, &status, 0) <= 0) FATAL("waitpid() failed");
|
||||
|
||||
child_pid = 0;
|
||||
it.it_value.tv_sec = 0;
|
||||
it.it_value.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &it, NULL);
|
||||
|
||||
MEM_BARRIER();
|
||||
|
||||
/* Clean up bitmap, analyze exit condition, etc. */
|
||||
|
||||
if (*(u32*)trace_bits == EXEC_FAIL_SIG)
|
||||
FATAL("Unable to execute '%s'", argv[0]);
|
||||
|
||||
classify_counts(trace_bits, binary_mode ?
|
||||
count_class_binary : count_class_human);
|
||||
|
||||
if (!quiet_mode)
|
||||
SAYF(cRST "-- Program output ends --\n");
|
||||
|
||||
if (!child_timed_out && !stop_soon && WIFSIGNALED(status))
|
||||
child_crashed = 1;
|
||||
|
||||
if (!quiet_mode) {
|
||||
|
||||
if (child_timed_out)
|
||||
SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
|
||||
else if (stop_soon)
|
||||
SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
|
||||
else if (child_crashed)
|
||||
SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST, WTERMSIG(status));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Handle Ctrl-C and the like. */
|
||||
|
||||
static void handle_stop_sig(int sig) {
|
||||
|
||||
stop_soon = 1;
|
||||
|
||||
if (child_pid > 0) kill(child_pid, SIGKILL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Do basic preparations - persistent fds, filenames, etc. */
|
||||
|
||||
static void set_up_environment(void) {
|
||||
|
||||
setenv("ASAN_OPTIONS", "abort_on_error=1:"
|
||||
"detect_leaks=0:"
|
||||
"symbolize=0:"
|
||||
"allocator_may_return_null=1", 0);
|
||||
|
||||
setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
|
||||
"symbolize=0:"
|
||||
"abort_on_error=1:"
|
||||
"allocator_may_return_null=1:"
|
||||
"msan_track_origins=0", 0);
|
||||
|
||||
if (getenv("AFL_PRELOAD")) {
|
||||
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
|
||||
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Setup signal handlers, duh. */
|
||||
|
||||
static void setup_signal_handlers(void) {
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
sa.sa_handler = NULL;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_sigaction = NULL;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
/* Various ways of saying "stop". */
|
||||
|
||||
sa.sa_handler = handle_stop_sig;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
/* Exec timeout notifications. */
|
||||
|
||||
sa.sa_handler = handle_timeout;
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Detect @@ in args. */
|
||||
|
||||
static void detect_file_args(char** argv) {
|
||||
|
||||
u32 i = 0;
|
||||
u8* cwd = getcwd(NULL, 0);
|
||||
|
||||
if (!cwd) PFATAL("getcwd() failed");
|
||||
|
||||
while (argv[i]) {
|
||||
|
||||
u8* aa_loc = strstr(argv[i], "@@");
|
||||
|
||||
if (aa_loc) {
|
||||
|
||||
u8 *aa_subst, *n_arg;
|
||||
|
||||
if (!at_file) FATAL("@@ syntax is not supported by this tool.");
|
||||
|
||||
/* Be sure that we're always using fully-qualified paths. */
|
||||
|
||||
if (at_file[0] == '/') aa_subst = at_file;
|
||||
else aa_subst = alloc_printf("%s/%s", cwd, at_file);
|
||||
|
||||
/* Construct a replacement argv value. */
|
||||
|
||||
*aa_loc = 0;
|
||||
n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
|
||||
argv[i] = n_arg;
|
||||
*aa_loc = '@';
|
||||
|
||||
if (at_file[0] != '/') ck_free(aa_subst);
|
||||
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
free(cwd); /* not tracked */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Show banner. */
|
||||
|
||||
static void show_banner(void) {
|
||||
|
||||
SAYF(cCYA "afl-showmap " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
|
||||
|
||||
}
|
||||
|
||||
/* Display usage hints. */
|
||||
|
||||
static void usage(u8* argv0) {
|
||||
|
||||
show_banner();
|
||||
|
||||
SAYF("\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
|
||||
|
||||
"Required parameters:\n\n"
|
||||
|
||||
" -o file - file to write the trace data to\n\n"
|
||||
|
||||
"Execution control settings:\n\n"
|
||||
|
||||
" -t msec - timeout for each run (none)\n"
|
||||
" -m megs - memory limit for child process (%u MB)\n"
|
||||
" -Q - use binary-only instrumentation (QEMU mode)\n\n"
|
||||
|
||||
"Other settings:\n\n"
|
||||
|
||||
" -q - sink program's output and don't show messages\n"
|
||||
" -e - show edge coverage only, ignore hit counts\n"
|
||||
" -c - allow core dumps\n\n"
|
||||
|
||||
"This tool displays raw tuple data captured by AFL instrumentation.\n"
|
||||
"For additional help, consult %s/README.\n\n" cRST,
|
||||
|
||||
argv0, MEM_LIMIT, doc_path);
|
||||
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Fix up argv for QEMU. */
|
||||
|
||||
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
||||
|
||||
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
||||
u8 *tmp, *cp, *rsl, *own_copy;
|
||||
|
||||
/* Workaround for a QEMU stability glitch. */
|
||||
|
||||
setenv("QEMU_LOG", "nochain", 1);
|
||||
|
||||
memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
|
||||
|
||||
new_argv[2] = target_path;
|
||||
new_argv[1] = "--";
|
||||
|
||||
/* Now we need to actually find qemu for argv[0]. */
|
||||
|
||||
tmp = getenv("AFL_PATH");
|
||||
|
||||
if (tmp) {
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
||||
|
||||
if (access(cp, X_OK))
|
||||
FATAL("Unable to find '%s'", tmp);
|
||||
|
||||
target_path = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", own_copy);
|
||||
ck_free(own_copy);
|
||||
|
||||
if (!access(cp, X_OK)) {
|
||||
|
||||
target_path = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
} else ck_free(own_copy);
|
||||
|
||||
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
||||
|
||||
target_path = new_argv[0] = BIN_PATH "/afl-qemu-trace";
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
FATAL("Unable to find 'afl-qemu-trace'.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Main entry point */
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
s32 opt;
|
||||
u8 mem_limit_given = 0, timeout_given = 0, qemu_mode = 0;
|
||||
u32 tcnt;
|
||||
char** use_argv;
|
||||
|
||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||
|
||||
while ((opt = getopt(argc,argv,"+o:m:t:A:eqZQbc")) > 0)
|
||||
|
||||
switch (opt) {
|
||||
|
||||
case 'o':
|
||||
|
||||
if (out_file) FATAL("Multiple -o options not supported");
|
||||
out_file = optarg;
|
||||
break;
|
||||
|
||||
case 'm': {
|
||||
|
||||
u8 suffix = 'M';
|
||||
|
||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
||||
mem_limit_given = 1;
|
||||
|
||||
if (!strcmp(optarg, "none")) {
|
||||
|
||||
mem_limit = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
|
||||
optarg[0] == '-') FATAL("Bad syntax used for -m");
|
||||
|
||||
switch (suffix) {
|
||||
|
||||
case 'T': mem_limit *= 1024 * 1024; break;
|
||||
case 'G': mem_limit *= 1024; break;
|
||||
case 'k': mem_limit /= 1024; break;
|
||||
case 'M': break;
|
||||
|
||||
default: FATAL("Unsupported suffix or bad syntax for -m");
|
||||
|
||||
}
|
||||
|
||||
if (mem_limit < 5) FATAL("Dangerously low value of -m");
|
||||
|
||||
if (sizeof(rlim_t) == 4 && mem_limit > 2000)
|
||||
FATAL("Value of -m out of range on 32-bit systems");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
|
||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
||||
timeout_given = 1;
|
||||
|
||||
if (strcmp(optarg, "none")) {
|
||||
exec_tmout = atoi(optarg);
|
||||
|
||||
if (exec_tmout < 20 || optarg[0] == '-')
|
||||
FATAL("Dangerously low value of -t");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
|
||||
if (edges_only) FATAL("Multiple -e options not supported");
|
||||
edges_only = 1;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
|
||||
if (quiet_mode) FATAL("Multiple -q options not supported");
|
||||
quiet_mode = 1;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
|
||||
/* This is an undocumented option to write data in the syntax expected
|
||||
by afl-cmin. Nobody else should have any use for this. */
|
||||
|
||||
cmin_mode = 1;
|
||||
quiet_mode = 1;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
|
||||
/* Another afl-cmin specific feature. */
|
||||
at_file = optarg;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
|
||||
if (qemu_mode) FATAL("Multiple -Q options not supported");
|
||||
if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;
|
||||
|
||||
qemu_mode = 1;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
|
||||
/* Secret undocumented mode. Writes output in raw binary format
|
||||
similar to that dumped by afl-fuzz in <out_dir/queue/fuzz_bitmap. */
|
||||
|
||||
binary_mode = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
|
||||
if (keep_cores) FATAL("Multiple -c options not supported");
|
||||
keep_cores = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
usage(argv[0]);
|
||||
|
||||
}
|
||||
|
||||
if (optind == argc || !out_file) usage(argv[0]);
|
||||
|
||||
setup_shm();
|
||||
setup_signal_handlers();
|
||||
|
||||
set_up_environment();
|
||||
|
||||
find_binary(argv[optind]);
|
||||
|
||||
if (!quiet_mode) {
|
||||
show_banner();
|
||||
ACTF("Executing '%s'...\n", target_path);
|
||||
}
|
||||
|
||||
detect_file_args(argv + optind);
|
||||
|
||||
if (qemu_mode)
|
||||
use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);
|
||||
else
|
||||
use_argv = argv + optind;
|
||||
|
||||
run_target(use_argv);
|
||||
|
||||
tcnt = write_results();
|
||||
|
||||
if (!quiet_mode) {
|
||||
|
||||
if (!tcnt) FATAL("No instrumentation detected" cRST);
|
||||
OKF("Captured %u tuples in '%s'." cRST, tcnt, out_file);
|
||||
|
||||
}
|
||||
|
||||
exit(child_crashed * 2 + child_timed_out);
|
||||
|
||||
}
|
||||
277
third_party/afl/afl_driver.cpp
vendored
277
third_party/afl/afl_driver.cpp
vendored
@@ -1,277 +0,0 @@
|
||||
//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* This file allows to fuzz libFuzzer-style target functions
|
||||
(LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode.
|
||||
|
||||
Usage:
|
||||
################################################################################
|
||||
cat << EOF > test_fuzzer.cc
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
if (size > 0 && data[0] == 'H')
|
||||
if (size > 1 && data[1] == 'I')
|
||||
if (size > 2 && data[2] == '!')
|
||||
__builtin_trap();
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
|
||||
clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c
|
||||
# Build afl-llvm-rt.o.c from the AFL distribution.
|
||||
clang -c -w $AFL_HOME/llvm_mode/afl-llvm-rt.o.c
|
||||
# Build this file, link it with afl-llvm-rt.o.o and the target code.
|
||||
clang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o
|
||||
# Run AFL:
|
||||
rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
|
||||
$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
|
||||
################################################################################
|
||||
AFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file
|
||||
specified. If the file does not exist, it is created. This is useful for getting
|
||||
stack traces (when using ASAN for example) or original error messages on hard
|
||||
to reproduce bugs. Note that any content written to stderr will be written to
|
||||
this file instead of stderr's usual location.
|
||||
|
||||
AFL_DRIVER_CLOSE_FD_MASK: Similar to libFuzzer's -close_fd_mask behavior option.
|
||||
If 1, close stdout at startup. If 2 close stderr; if 3 close both.
|
||||
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Platform detection. Copied from FuzzerInternal.h
|
||||
#ifdef __linux__
|
||||
#define LIBFUZZER_LINUX 1
|
||||
#define LIBFUZZER_APPLE 0
|
||||
#define LIBFUZZER_NETBSD 0
|
||||
#define LIBFUZZER_FREEBSD 0
|
||||
#define LIBFUZZER_OPENBSD 0
|
||||
#elif __APPLE__
|
||||
#define LIBFUZZER_LINUX 0
|
||||
#define LIBFUZZER_APPLE 1
|
||||
#define LIBFUZZER_NETBSD 0
|
||||
#define LIBFUZZER_FREEBSD 0
|
||||
#define LIBFUZZER_OPENBSD 0
|
||||
#elif __NetBSD__
|
||||
#define LIBFUZZER_LINUX 0
|
||||
#define LIBFUZZER_APPLE 0
|
||||
#define LIBFUZZER_NETBSD 1
|
||||
#define LIBFUZZER_FREEBSD 0
|
||||
#define LIBFUZZER_OPENBSD 0
|
||||
#elif __FreeBSD__
|
||||
#define LIBFUZZER_LINUX 0
|
||||
#define LIBFUZZER_APPLE 0
|
||||
#define LIBFUZZER_NETBSD 0
|
||||
#define LIBFUZZER_FREEBSD 1
|
||||
#define LIBFUZZER_OPENBSD 0
|
||||
#elif __OpenBSD__
|
||||
#define LIBFUZZER_LINUX 0
|
||||
#define LIBFUZZER_APPLE 0
|
||||
#define LIBFUZZER_NETBSD 0
|
||||
#define LIBFUZZER_FREEBSD 0
|
||||
#define LIBFUZZER_OPENBSD 1
|
||||
#else
|
||||
#error "Support for your platform has not been implemented"
|
||||
#endif
|
||||
|
||||
// libFuzzer interface is thin, so we don't include any libFuzzer headers.
|
||||
extern "C" {
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
|
||||
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
|
||||
}
|
||||
|
||||
// Notify AFL about persistent mode.
|
||||
static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
|
||||
extern "C" int __afl_persistent_loop(unsigned int);
|
||||
static volatile char suppress_warning2 = AFL_PERSISTENT[0];
|
||||
|
||||
// Notify AFL about deferred forkserver.
|
||||
static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##";
|
||||
extern "C" void __afl_manual_init();
|
||||
static volatile char suppress_warning1 = AFL_DEFER_FORKSVR[0];
|
||||
|
||||
// Input buffer.
|
||||
static const size_t kMaxAflInputSize = 1 << 20;
|
||||
static uint8_t AflInputBuf[kMaxAflInputSize];
|
||||
|
||||
// Use this optionally defined function to output sanitizer messages even if
|
||||
// user asks to close stderr.
|
||||
__attribute__((weak)) extern "C" void __sanitizer_set_report_fd(void *);
|
||||
|
||||
// Keep track of where stderr content is being written to, so that
|
||||
// dup_and_close_stderr can use the correct one.
|
||||
static FILE *output_file = stderr;
|
||||
|
||||
// Experimental feature to use afl_driver without AFL's deferred mode.
|
||||
// Needs to run before __afl_auto_init.
|
||||
__attribute__((constructor(0))) static void __decide_deferred_forkserver(void) {
|
||||
if (getenv("AFL_DRIVER_DONT_DEFER")) {
|
||||
if (unsetenv("__AFL_DEFER_FORKSRV")) {
|
||||
perror("Failed to unset __AFL_DEFER_FORKSRV");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the user asks us to duplicate stderr, then do it.
|
||||
static void maybe_duplicate_stderr() {
|
||||
char *stderr_duplicate_filename =
|
||||
getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME");
|
||||
|
||||
if (!stderr_duplicate_filename)
|
||||
return;
|
||||
|
||||
FILE *stderr_duplicate_stream =
|
||||
freopen(stderr_duplicate_filename, "a+", stderr);
|
||||
|
||||
if (!stderr_duplicate_stream) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME");
|
||||
abort();
|
||||
}
|
||||
output_file = stderr_duplicate_stream;
|
||||
}
|
||||
|
||||
// Most of these I/O functions were inspired by/copied from libFuzzer's code.
|
||||
static void discard_output(int fd) {
|
||||
FILE *temp = fopen("/dev/null", "w");
|
||||
if (!temp)
|
||||
abort();
|
||||
dup2(fileno(temp), fd);
|
||||
fclose(temp);
|
||||
}
|
||||
|
||||
static void close_stdout() { discard_output(STDOUT_FILENO); }
|
||||
|
||||
// Prevent the targeted code from writing to "stderr" but allow sanitizers and
|
||||
// this driver to do so.
|
||||
static void dup_and_close_stderr() {
|
||||
int output_fileno = fileno(output_file);
|
||||
int output_fd = dup(output_fileno);
|
||||
if (output_fd <= 0)
|
||||
abort();
|
||||
FILE *new_output_file = fdopen(output_fd, "w");
|
||||
if (!new_output_file)
|
||||
abort();
|
||||
if (!__sanitizer_set_report_fd)
|
||||
return;
|
||||
__sanitizer_set_report_fd(reinterpret_cast<void *>(output_fd));
|
||||
discard_output(output_fileno);
|
||||
}
|
||||
|
||||
static void Printf(const char *Fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, Fmt);
|
||||
vfprintf(output_file, Fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(output_file);
|
||||
}
|
||||
|
||||
// Close stdout and/or stderr if user asks for it.
|
||||
static void maybe_close_fd_mask() {
|
||||
char *fd_mask_str = getenv("AFL_DRIVER_CLOSE_FD_MASK");
|
||||
if (!fd_mask_str)
|
||||
return;
|
||||
int fd_mask = atoi(fd_mask_str);
|
||||
if (fd_mask & 2)
|
||||
dup_and_close_stderr();
|
||||
if (fd_mask & 1)
|
||||
close_stdout();
|
||||
}
|
||||
|
||||
// Define LLVMFuzzerMutate to avoid link failures for targets that use it
|
||||
// with libFuzzer's LLVMFuzzerCustomMutator.
|
||||
extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
|
||||
assert(false && "LLVMFuzzerMutate should not be called from afl_driver");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute any files provided as parameters.
|
||||
static int ExecuteFilesOnyByOne(int argc, char **argv) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::ifstream in(argv[i], std::ios::binary);
|
||||
in.seekg(0, in.end);
|
||||
size_t length = in.tellg();
|
||||
in.seekg (0, in.beg);
|
||||
std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl;
|
||||
// Allocate exactly length bytes so that we reliably catch buffer overflows.
|
||||
std::vector<char> bytes(length);
|
||||
in.read(bytes.data(), bytes.size());
|
||||
assert(in);
|
||||
LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()),
|
||||
bytes.size());
|
||||
std::cout << "Execution successful" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Printf(
|
||||
"======================= INFO =========================\n"
|
||||
"This binary is built for AFL-fuzz.\n"
|
||||
"To run the target function on individual input(s) execute this:\n"
|
||||
" %s < INPUT_FILE\n"
|
||||
"or\n"
|
||||
" %s INPUT_FILE1 [INPUT_FILE2 ... ]\n"
|
||||
"To fuzz with afl-fuzz execute this:\n"
|
||||
" afl-fuzz [afl-flags] %s [-N]\n"
|
||||
"afl-fuzz will run N iterations before "
|
||||
"re-spawning the process (default: 1000)\n"
|
||||
"======================================================\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
|
||||
maybe_duplicate_stderr();
|
||||
maybe_close_fd_mask();
|
||||
if (LLVMFuzzerInitialize)
|
||||
LLVMFuzzerInitialize(&argc, &argv);
|
||||
// Do any other expensive one-time initialization here.
|
||||
|
||||
if (!getenv("AFL_DRIVER_DONT_DEFER"))
|
||||
__afl_manual_init();
|
||||
|
||||
int N = 1000;
|
||||
if (argc == 2 && argv[1][0] == '-')
|
||||
N = atoi(argv[1] + 1);
|
||||
else if(argc == 2 && (N = atoi(argv[1])) > 0)
|
||||
Printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N);
|
||||
else if (argc > 1)
|
||||
return ExecuteFilesOnyByOne(argc, argv);
|
||||
|
||||
assert(N > 0);
|
||||
|
||||
// Call LLVMFuzzerTestOneInput here so that coverage caused by initialization
|
||||
// on the first execution of LLVMFuzzerTestOneInput is ignored.
|
||||
uint8_t dummy_input[1] = {0};
|
||||
LLVMFuzzerTestOneInput(dummy_input, 1);
|
||||
|
||||
int num_runs = 0;
|
||||
while (__afl_persistent_loop(N)) {
|
||||
ssize_t n_read = read(0, AflInputBuf, kMaxAflInputSize);
|
||||
if (n_read > 0) {
|
||||
// Copy AflInputBuf into a separate buffer to let asan find buffer
|
||||
// overflows. Don't use unique_ptr/etc to avoid extra dependencies.
|
||||
uint8_t *copy = new uint8_t[n_read];
|
||||
memcpy(copy, AflInputBuf, n_read);
|
||||
num_runs++;
|
||||
LLVMFuzzerTestOneInput(copy, n_read);
|
||||
delete[] copy;
|
||||
}
|
||||
}
|
||||
Printf("%s: successfully executed %d input(s)\n", argv[0], num_runs);
|
||||
}
|
||||
570
third_party/afl/alloc-inl.h
vendored
570
third_party/afl/alloc-inl.h
vendored
@@ -1,570 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - error-checking, memory-zeroing alloc routines
|
||||
------------------------------------------------------------------
|
||||
|
||||
Written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2013, 2014, 2015 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This allocator is not designed to resist malicious attackers (the canaries
|
||||
are small and predictable), but provides a robust and portable way to detect
|
||||
use-after-free, off-by-one writes, stale pointers, and so on.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_ALLOC_INL_H
|
||||
#define _HAVE_ALLOC_INL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
|
||||
|
||||
#define alloc_printf(_str...) ({ \
|
||||
u8* _tmp; \
|
||||
s32 _len = snprintf(NULL, 0, _str); \
|
||||
if (_len < 0) FATAL("Whoa, snprintf() fails?!"); \
|
||||
_tmp = ck_alloc(_len + 1); \
|
||||
snprintf((char*)_tmp, _len + 1, _str); \
|
||||
_tmp; \
|
||||
})
|
||||
|
||||
/* Macro to enforce allocation limits as a last-resort defense against
|
||||
integer overflows. */
|
||||
|
||||
#define ALLOC_CHECK_SIZE(_s) do { \
|
||||
if ((_s) > MAX_ALLOC) \
|
||||
ABORT("Bad alloc request: %u bytes", (_s)); \
|
||||
} while (0)
|
||||
|
||||
/* Macro to check malloc() failures and the like. */
|
||||
|
||||
#define ALLOC_CHECK_RESULT(_r, _s) do { \
|
||||
if (!(_r)) \
|
||||
ABORT("Out of memory: can't allocate %u bytes", (_s)); \
|
||||
} while (0)
|
||||
|
||||
/* Magic tokens used to mark used / freed chunks. */
|
||||
|
||||
#define ALLOC_MAGIC_C1 0xFF00FF00 /* Used head (dword) */
|
||||
#define ALLOC_MAGIC_F 0xFE00FE00 /* Freed head (dword) */
|
||||
#define ALLOC_MAGIC_C2 0xF0 /* Used tail (byte) */
|
||||
|
||||
/* Positions of guard tokens in relation to the user-visible pointer. */
|
||||
|
||||
#define ALLOC_C1(_ptr) (((u32*)(_ptr))[-2])
|
||||
#define ALLOC_S(_ptr) (((u32*)(_ptr))[-1])
|
||||
#define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)])
|
||||
|
||||
#define ALLOC_OFF_HEAD 8
|
||||
#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)
|
||||
|
||||
/* Allocator increments for ck_realloc_block(). */
|
||||
|
||||
#define ALLOC_BLK_INC 256
|
||||
|
||||
/* Sanity-checking macros for pointers. */
|
||||
|
||||
#define CHECK_PTR(_p) do { \
|
||||
if (_p) { \
|
||||
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\
|
||||
if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \
|
||||
ABORT("Use after free."); \
|
||||
else ABORT("Corrupted head alloc canary."); \
|
||||
} \
|
||||
if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \
|
||||
ABORT("Corrupted tail alloc canary."); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_PTR_EXPR(_p) ({ \
|
||||
typeof (_p) _tmp = (_p); \
|
||||
CHECK_PTR(_tmp); \
|
||||
_tmp; \
|
||||
})
|
||||
|
||||
|
||||
/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized
|
||||
requests. */
|
||||
|
||||
static inline void* DFL_ck_alloc_nozero(u32 size) {
|
||||
|
||||
void* ret;
|
||||
|
||||
if (!size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF_TOTAL);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
|
||||
ALLOC_S(ret) = size;
|
||||
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a buffer, returning zeroed memory. */
|
||||
|
||||
static inline void* DFL_ck_alloc(u32 size) {
|
||||
|
||||
void* mem;
|
||||
|
||||
if (!size) return NULL;
|
||||
mem = DFL_ck_alloc_nozero(size);
|
||||
|
||||
return memset(mem, 0, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD
|
||||
is set, the old memory will be also clobbered with 0xFF. */
|
||||
|
||||
static inline void DFL_ck_free(void* mem) {
|
||||
|
||||
if (!mem) return;
|
||||
|
||||
CHECK_PTR(mem);
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
|
||||
/* Catch pointer issues sooner. */
|
||||
memset(mem, 0xFF, ALLOC_S(mem));
|
||||
|
||||
#endif /* DEBUG_BUILD */
|
||||
|
||||
ALLOC_C1(mem) = ALLOC_MAGIC_F;
|
||||
|
||||
free(mem - ALLOC_OFF_HEAD);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.
|
||||
With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the
|
||||
old memory is clobbered with 0xFF. */
|
||||
|
||||
static inline void* DFL_ck_realloc(void* orig, u32 size) {
|
||||
|
||||
void* ret;
|
||||
u32 old_size = 0;
|
||||
|
||||
if (!size) {
|
||||
|
||||
DFL_ck_free(orig);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if (orig) {
|
||||
|
||||
CHECK_PTR(orig);
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
ALLOC_C1(orig) = ALLOC_MAGIC_F;
|
||||
#endif /* !DEBUG_BUILD */
|
||||
|
||||
old_size = ALLOC_S(orig);
|
||||
orig -= ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_CHECK_SIZE(old_size);
|
||||
|
||||
}
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
ret = realloc(orig, size + ALLOC_OFF_TOTAL);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
#else
|
||||
|
||||
/* Catch pointer issues sooner: force relocation and make sure that the
|
||||
original buffer is wiped. */
|
||||
|
||||
ret = malloc(size + ALLOC_OFF_TOTAL);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
if (orig) {
|
||||
|
||||
memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));
|
||||
memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);
|
||||
|
||||
ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;
|
||||
|
||||
free(orig);
|
||||
|
||||
}
|
||||
|
||||
#endif /* ^!DEBUG_BUILD */
|
||||
|
||||
ret += ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
|
||||
ALLOC_S(ret) = size;
|
||||
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
|
||||
|
||||
if (size > old_size)
|
||||
memset(ret + old_size, 0, size - old_size);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up
|
||||
repeated small reallocs without complicating the user code). */
|
||||
|
||||
static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
if (orig) {
|
||||
|
||||
CHECK_PTR(orig);
|
||||
|
||||
if (ALLOC_S(orig) >= size) return orig;
|
||||
|
||||
size += ALLOC_BLK_INC;
|
||||
|
||||
}
|
||||
|
||||
#endif /* !DEBUG_BUILD */
|
||||
|
||||
return DFL_ck_realloc(orig, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */
|
||||
|
||||
static inline u8* DFL_ck_strdup(u8* str) {
|
||||
|
||||
void* ret;
|
||||
u32 size;
|
||||
|
||||
if (!str) return NULL;
|
||||
|
||||
size = strlen((char*)str) + 1;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF_TOTAL);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
|
||||
ALLOC_S(ret) = size;
|
||||
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
|
||||
|
||||
return memcpy(ret, str, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized
|
||||
or NULL inputs. */
|
||||
|
||||
static inline void* DFL_ck_memdup(void* mem, u32 size) {
|
||||
|
||||
void* ret;
|
||||
|
||||
if (!mem || !size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF_TOTAL);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
|
||||
ALLOC_S(ret) = size;
|
||||
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
|
||||
|
||||
return memcpy(ret, mem, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Create a buffer with a block of text, appending a NUL terminator at the end.
|
||||
Returns NULL for zero-sized or NULL inputs. */
|
||||
|
||||
static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
|
||||
|
||||
u8* ret;
|
||||
|
||||
if (!mem || !size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF_TOTAL + 1);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF_HEAD;
|
||||
|
||||
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
|
||||
ALLOC_S(ret) = size;
|
||||
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
|
||||
|
||||
memcpy(ret, mem, size);
|
||||
ret[size] = 0;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
/* In non-debug mode, we just do straightforward aliasing of the above functions
|
||||
to user-visible names such as ck_alloc(). */
|
||||
|
||||
#define ck_alloc DFL_ck_alloc
|
||||
#define ck_alloc_nozero DFL_ck_alloc_nozero
|
||||
#define ck_realloc DFL_ck_realloc
|
||||
#define ck_realloc_block DFL_ck_realloc_block
|
||||
#define ck_strdup DFL_ck_strdup
|
||||
#define ck_memdup DFL_ck_memdup
|
||||
#define ck_memdup_str DFL_ck_memdup_str
|
||||
#define ck_free DFL_ck_free
|
||||
|
||||
#define alloc_report()
|
||||
|
||||
#else
|
||||
|
||||
/* In debugging mode, we also track allocations to detect memory leaks, and the
|
||||
flow goes through one more layer of indirection. */
|
||||
|
||||
/* Alloc tracking data structures: */
|
||||
|
||||
#define ALLOC_BUCKETS 4096
|
||||
|
||||
struct TRK_obj {
|
||||
void *ptr;
|
||||
char *file, *func;
|
||||
u32 line;
|
||||
};
|
||||
|
||||
#ifdef AFL_MAIN
|
||||
|
||||
struct TRK_obj* TRK[ALLOC_BUCKETS];
|
||||
u32 TRK_cnt[ALLOC_BUCKETS];
|
||||
|
||||
# define alloc_report() TRK_report()
|
||||
|
||||
#else
|
||||
|
||||
extern struct TRK_obj* TRK[ALLOC_BUCKETS];
|
||||
extern u32 TRK_cnt[ALLOC_BUCKETS];
|
||||
|
||||
# define alloc_report()
|
||||
|
||||
#endif /* ^AFL_MAIN */
|
||||
|
||||
/* Bucket-assigning function for a given pointer: */
|
||||
|
||||
#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)
|
||||
|
||||
|
||||
/* Add a new entry to the list of allocated objects. */
|
||||
|
||||
static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
if (!ptr) return;
|
||||
|
||||
bucket = TRKH(ptr);
|
||||
|
||||
/* Find a free slot in the list of entries for that bucket. */
|
||||
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
|
||||
if (!TRK[bucket][i].ptr) {
|
||||
|
||||
TRK[bucket][i].ptr = ptr;
|
||||
TRK[bucket][i].file = (char*)file;
|
||||
TRK[bucket][i].func = (char*)func;
|
||||
TRK[bucket][i].line = line;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* No space available - allocate more. */
|
||||
|
||||
TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],
|
||||
(TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));
|
||||
|
||||
TRK[bucket][i].ptr = ptr;
|
||||
TRK[bucket][i].file = (char*)file;
|
||||
TRK[bucket][i].func = (char*)func;
|
||||
TRK[bucket][i].line = line;
|
||||
|
||||
TRK_cnt[bucket]++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Remove entry from the list of allocated objects. */
|
||||
|
||||
static inline void TRK_free_buf(void* ptr, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
if (!ptr) return;
|
||||
|
||||
bucket = TRKH(ptr);
|
||||
|
||||
/* Find the element on the list... */
|
||||
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
|
||||
if (TRK[bucket][i].ptr == ptr) {
|
||||
|
||||
TRK[bucket][i].ptr = 0;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)",
|
||||
func, file, line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Do a final report on all non-deallocated objects. */
|
||||
|
||||
static inline void TRK_report(void) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
fflush(0);
|
||||
|
||||
for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
if (TRK[bucket][i].ptr)
|
||||
WARNF("ALLOC: Memory never freed, created in %s (%s:%u)",
|
||||
TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Simple wrappers for non-debugging functions: */
|
||||
|
||||
static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
void* ret = DFL_ck_alloc(size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_realloc(orig, size);
|
||||
TRK_free_buf(orig, file, func, line);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_realloc_block(orig, size);
|
||||
TRK_free_buf(orig, file, func, line);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
void* ret = DFL_ck_strdup(str);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_memdup(mem, size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_memdup_str(mem, size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void TRK_ck_free(void* ptr, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
TRK_free_buf(ptr, file, func, line);
|
||||
DFL_ck_free(ptr);
|
||||
|
||||
}
|
||||
|
||||
/* Aliasing user-facing names to tracking functions: */
|
||||
|
||||
#define ck_alloc(_p1) \
|
||||
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_alloc_nozero(_p1) \
|
||||
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_realloc(_p1, _p2) \
|
||||
TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_realloc_block(_p1, _p2) \
|
||||
TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_strdup(_p1) \
|
||||
TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_memdup(_p1, _p2) \
|
||||
TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_memdup_str(_p1, _p2) \
|
||||
TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_free(_p1) \
|
||||
TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#endif /* ^!DEBUG_BUILD */
|
||||
|
||||
#endif /* ! _HAVE_ALLOC_INL_H */
|
||||
350
third_party/afl/config.h
vendored
350
third_party/afl/config.h
vendored
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - vaguely configurable bits
|
||||
----------------------------------------------
|
||||
|
||||
Written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_CONFIG_H
|
||||
#define _HAVE_CONFIG_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* Version string: */
|
||||
|
||||
#define VERSION "2.52b"
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
* Settings that may be of interest to power users: *
|
||||
* *
|
||||
******************************************************/
|
||||
|
||||
/* Comment out to disable terminal colors (note that this makes afl-analyze
|
||||
a lot less nice): */
|
||||
|
||||
#define USE_COLOR
|
||||
|
||||
/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
|
||||
|
||||
#define FANCY_BOXES
|
||||
|
||||
/* Default timeout for fuzzed code (milliseconds). This is the upper bound,
|
||||
also used for detecting hangs; the actual value is auto-scaled: */
|
||||
|
||||
#define EXEC_TIMEOUT 1000
|
||||
|
||||
/* Timeout rounding factor when auto-scaling (milliseconds): */
|
||||
|
||||
#define EXEC_TM_ROUND 20
|
||||
|
||||
/* Default memory limit for child process (MB): */
|
||||
|
||||
#ifndef __x86_64__
|
||||
# define MEM_LIMIT 25
|
||||
#else
|
||||
# define MEM_LIMIT 50
|
||||
#endif /* ^!__x86_64__ */
|
||||
|
||||
/* Default memory limit when running in QEMU mode (MB): */
|
||||
|
||||
#define MEM_LIMIT_QEMU 200
|
||||
|
||||
/* Number of calibration cycles per every new test case (and for test
|
||||
cases that show variable behavior): */
|
||||
|
||||
#define CAL_CYCLES 8
|
||||
#define CAL_CYCLES_LONG 40
|
||||
|
||||
/* Number of subsequent timeouts before abandoning an input file: */
|
||||
|
||||
#define TMOUT_LIMIT 250
|
||||
|
||||
/* Maximum number of unique hangs or crashes to record: */
|
||||
|
||||
#define KEEP_UNIQUE_HANG 500
|
||||
#define KEEP_UNIQUE_CRASH 5000
|
||||
|
||||
/* Baseline number of random tweaks during a single 'havoc' stage: */
|
||||
|
||||
#define HAVOC_CYCLES 256
|
||||
#define HAVOC_CYCLES_INIT 1024
|
||||
|
||||
/* Maximum multiplier for the above (should be a power of two, beware
|
||||
of 32-bit int overflows): */
|
||||
|
||||
#define HAVOC_MAX_MULT 16
|
||||
|
||||
/* Absolute minimum number of havoc cycles (after all adjustments): */
|
||||
|
||||
#define HAVOC_MIN 16
|
||||
|
||||
/* Maximum stacking for havoc-stage tweaks. The actual value is calculated
|
||||
like this:
|
||||
|
||||
n = random between 1 and HAVOC_STACK_POW2
|
||||
stacking = 2^n
|
||||
|
||||
In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or
|
||||
128 stacked tweaks: */
|
||||
|
||||
#define HAVOC_STACK_POW2 7
|
||||
|
||||
/* Caps on block sizes for cloning and deletion operations. Each of these
|
||||
ranges has a 33% probability of getting picked, except for the first
|
||||
two cycles where smaller blocks are favored: */
|
||||
|
||||
#define HAVOC_BLK_SMALL 32
|
||||
#define HAVOC_BLK_MEDIUM 128
|
||||
#define HAVOC_BLK_LARGE 1500
|
||||
|
||||
/* Extra-large blocks, selected very rarely (<5% of the time): */
|
||||
|
||||
#define HAVOC_BLK_XL 32768
|
||||
|
||||
/* Probabilities of skipping non-favored entries in the queue, expressed as
|
||||
percentages: */
|
||||
|
||||
#define SKIP_TO_NEW_PROB 99 /* ...when there are new, pending favorites */
|
||||
#define SKIP_NFAV_OLD_PROB 95 /* ...no new favs, cur entry already fuzzed */
|
||||
#define SKIP_NFAV_NEW_PROB 75 /* ...no new favs, cur entry not fuzzed yet */
|
||||
|
||||
/* Splicing cycle count: */
|
||||
|
||||
#define SPLICE_CYCLES 15
|
||||
|
||||
/* Nominal per-splice havoc cycle length: */
|
||||
|
||||
#define SPLICE_HAVOC 32
|
||||
|
||||
/* Maximum offset for integer addition / subtraction stages: */
|
||||
|
||||
#define ARITH_MAX 35
|
||||
|
||||
/* Limits for the test case trimmer. The absolute minimum chunk size; and
|
||||
the starting and ending divisors for chopping up the input file: */
|
||||
|
||||
#define TRIM_MIN_BYTES 4
|
||||
#define TRIM_START_STEPS 16
|
||||
#define TRIM_END_STEPS 1024
|
||||
|
||||
/* Maximum size of input file, in bytes (keep under 100MB): */
|
||||
|
||||
#define MAX_FILE (1 * 1024 * 1024)
|
||||
|
||||
/* The same, for the test case minimizer: */
|
||||
|
||||
#define TMIN_MAX_FILE (10 * 1024 * 1024)
|
||||
|
||||
/* Block normalization steps for afl-tmin: */
|
||||
|
||||
#define TMIN_SET_MIN_SIZE 4
|
||||
#define TMIN_SET_STEPS 128
|
||||
|
||||
/* Maximum dictionary token size (-x), in bytes: */
|
||||
|
||||
#define MAX_DICT_FILE 128
|
||||
|
||||
/* Length limits for auto-detected dictionary tokens: */
|
||||
|
||||
#define MIN_AUTO_EXTRA 3
|
||||
#define MAX_AUTO_EXTRA 32
|
||||
|
||||
/* Maximum number of user-specified dictionary tokens to use in deterministic
|
||||
steps; past this point, the "extras/user" step will be still carried out,
|
||||
but with proportionally lower odds: */
|
||||
|
||||
#define MAX_DET_EXTRAS 200
|
||||
|
||||
/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing
|
||||
(first value), and to keep in memory as candidates. The latter should be much
|
||||
higher than the former. */
|
||||
|
||||
#define USE_AUTO_EXTRAS 50
|
||||
#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 10)
|
||||
|
||||
/* Scaling factor for the effector map used to skip some of the more
|
||||
expensive deterministic steps. The actual divisor is set to
|
||||
2^EFF_MAP_SCALE2 bytes: */
|
||||
|
||||
#define EFF_MAP_SCALE2 3
|
||||
|
||||
/* Minimum input file length at which the effector logic kicks in: */
|
||||
|
||||
#define EFF_MIN_LEN 128
|
||||
|
||||
/* Maximum effector density past which everything is just fuzzed
|
||||
unconditionally (%): */
|
||||
|
||||
#define EFF_MAX_PERC 90
|
||||
|
||||
/* UI refresh frequency (Hz): */
|
||||
|
||||
#define UI_TARGET_HZ 5
|
||||
|
||||
/* Fuzzer stats file and plot update intervals (sec): */
|
||||
|
||||
#define STATS_UPDATE_SEC 60
|
||||
#define PLOT_UPDATE_SEC 5
|
||||
|
||||
/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */
|
||||
|
||||
#define AVG_SMOOTHING 16
|
||||
|
||||
/* Sync interval (every n havoc cycles): */
|
||||
|
||||
#define SYNC_INTERVAL 5
|
||||
|
||||
/* Output directory reuse grace period (minutes): */
|
||||
|
||||
#define OUTPUT_GRACE 25
|
||||
|
||||
/* Uncomment to use simple file names (id_NNNNNN): */
|
||||
|
||||
// #define SIMPLE_FILES
|
||||
|
||||
/* List of interesting values to use in fuzzing. */
|
||||
|
||||
#define INTERESTING_8 \
|
||||
-128, /* Overflow signed 8-bit when decremented */ \
|
||||
-1, /* */ \
|
||||
0, /* */ \
|
||||
1, /* */ \
|
||||
16, /* One-off with common buffer size */ \
|
||||
32, /* One-off with common buffer size */ \
|
||||
64, /* One-off with common buffer size */ \
|
||||
100, /* One-off with common buffer size */ \
|
||||
127 /* Overflow signed 8-bit when incremented */
|
||||
|
||||
#define INTERESTING_16 \
|
||||
-32768, /* Overflow signed 16-bit when decremented */ \
|
||||
-129, /* Overflow signed 8-bit */ \
|
||||
128, /* Overflow signed 8-bit */ \
|
||||
255, /* Overflow unsig 8-bit when incremented */ \
|
||||
256, /* Overflow unsig 8-bit */ \
|
||||
512, /* One-off with common buffer size */ \
|
||||
1000, /* One-off with common buffer size */ \
|
||||
1024, /* One-off with common buffer size */ \
|
||||
4096, /* One-off with common buffer size */ \
|
||||
32767 /* Overflow signed 16-bit when incremented */
|
||||
|
||||
#define INTERESTING_32 \
|
||||
-2147483648LL, /* Overflow signed 32-bit when decremented */ \
|
||||
-100663046, /* Large negative number (endian-agnostic) */ \
|
||||
-32769, /* Overflow signed 16-bit */ \
|
||||
32768, /* Overflow signed 16-bit */ \
|
||||
65535, /* Overflow unsig 16-bit when incremented */ \
|
||||
65536, /* Overflow unsig 16 bit */ \
|
||||
100663045, /* Large positive number (endian-agnostic) */ \
|
||||
2147483647 /* Overflow signed 32-bit when incremented */
|
||||
|
||||
/***********************************************************
|
||||
* *
|
||||
* Really exotic stuff you probably don't want to touch: *
|
||||
* *
|
||||
***********************************************************/
|
||||
|
||||
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
|
||||
|
||||
#define RESEED_RNG 10000
|
||||
|
||||
/* Maximum line length passed from GCC to 'as' and used for parsing
|
||||
configuration files: */
|
||||
|
||||
#define MAX_LINE 8192
|
||||
|
||||
/* Environment variable used to pass SHM ID to the called program. */
|
||||
|
||||
#define SHM_ENV_VAR "__AFL_SHM_ID"
|
||||
|
||||
/* Other less interesting, internal-only variables. */
|
||||
|
||||
#define CLANG_ENV_VAR "__AFL_CLANG_MODE"
|
||||
#define AS_LOOP_ENV_VAR "__AFL_AS_LOOPCHECK"
|
||||
#define PERSIST_ENV_VAR "__AFL_PERSISTENT"
|
||||
#define DEFER_ENV_VAR "__AFL_DEFER_FORKSRV"
|
||||
|
||||
/* In-code signatures for deferred and persistent mode. */
|
||||
|
||||
#define PERSIST_SIG "##SIG_AFL_PERSISTENT##"
|
||||
#define DEFER_SIG "##SIG_AFL_DEFER_FORKSRV##"
|
||||
|
||||
/* Distinctive bitmap signature used to indicate failed execution: */
|
||||
|
||||
#define EXEC_FAIL_SIG 0xfee1dead
|
||||
|
||||
/* Distinctive exit code used to indicate MSAN trip condition: */
|
||||
|
||||
#define MSAN_ERROR 86
|
||||
|
||||
/* Designated file descriptors for forkserver commands (the application will
|
||||
use FORKSRV_FD and FORKSRV_FD + 1): */
|
||||
|
||||
#define FORKSRV_FD 198
|
||||
|
||||
/* Fork server init timeout multiplier: we'll wait the user-selected
|
||||
timeout plus this much for the fork server to spin up. */
|
||||
|
||||
#define FORK_WAIT_MULT 10
|
||||
|
||||
/* Calibration timeout adjustments, to be a bit more generous when resuming
|
||||
fuzzing sessions or trying to calibrate already-added internal finds.
|
||||
The first value is a percentage, the other is in milliseconds: */
|
||||
|
||||
#define CAL_TMOUT_PERC 125
|
||||
#define CAL_TMOUT_ADD 50
|
||||
|
||||
/* Number of chances to calibrate a case before giving up: */
|
||||
|
||||
#define CAL_CHANCES 3
|
||||
|
||||
/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than
|
||||
2; you probably want to keep it under 18 or so for performance reasons
|
||||
(adjusting AFL_INST_RATIO when compiling is probably a better way to solve
|
||||
problems with complex programs). You need to recompile the target binary
|
||||
after changing this - otherwise, SEGVs may ensue. */
|
||||
|
||||
#define MAP_SIZE_POW2 16
|
||||
#define MAP_SIZE (1 << MAP_SIZE_POW2)
|
||||
|
||||
/* Maximum allocator request size (keep well under INT_MAX): */
|
||||
|
||||
#define MAX_ALLOC 0x40000000
|
||||
|
||||
/* A made-up hashing seed: */
|
||||
|
||||
#define HASH_CONST 0xa5b35705
|
||||
|
||||
/* Constants for afl-gotcpu to control busy loop timing: */
|
||||
|
||||
#define CTEST_TARGET_MS 5000
|
||||
#define CTEST_CORE_TRG_MS 1000
|
||||
#define CTEST_BUSY_CYCLES (10 * 1000 * 1000)
|
||||
|
||||
/* Uncomment this to use inferior block-coverage-based instrumentation. Note
|
||||
that you need to recompile the target binary for this to have any effect: */
|
||||
|
||||
// #define COVERAGE_ONLY
|
||||
|
||||
/* Uncomment this to ignore hit counts and output just one bit per tuple.
|
||||
As with the previous setting, you will need to recompile the target
|
||||
binary: */
|
||||
|
||||
// #define SKIP_COUNTS
|
||||
|
||||
/* Uncomment this to use instrumentation data to record newly discovered paths,
|
||||
but do not use them as seeds for fuzzing. This is useful for conveniently
|
||||
measuring coverage that could be attained by a "dumb" fuzzing algorithm: */
|
||||
|
||||
// #define IGNORE_FINDS
|
||||
|
||||
#endif /* ! _HAVE_CONFIG_H */
|
||||
251
third_party/afl/debug.h
vendored
251
third_party/afl/debug.h
vendored
@@ -1,251 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - debug / error handling macros
|
||||
--------------------------------------------------
|
||||
|
||||
Written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_DEBUG_H
|
||||
#define _HAVE_DEBUG_H
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
|
||||
/*******************
|
||||
* Terminal colors *
|
||||
*******************/
|
||||
|
||||
#ifdef USE_COLOR
|
||||
|
||||
# define cBLK "\x1b[0;30m"
|
||||
# define cRED "\x1b[0;31m"
|
||||
# define cGRN "\x1b[0;32m"
|
||||
# define cBRN "\x1b[0;33m"
|
||||
# define cBLU "\x1b[0;34m"
|
||||
# define cMGN "\x1b[0;35m"
|
||||
# define cCYA "\x1b[0;36m"
|
||||
# define cLGR "\x1b[0;37m"
|
||||
# define cGRA "\x1b[1;90m"
|
||||
# define cLRD "\x1b[1;91m"
|
||||
# define cLGN "\x1b[1;92m"
|
||||
# define cYEL "\x1b[1;93m"
|
||||
# define cLBL "\x1b[1;94m"
|
||||
# define cPIN "\x1b[1;95m"
|
||||
# define cLCY "\x1b[1;96m"
|
||||
# define cBRI "\x1b[1;97m"
|
||||
# define cRST "\x1b[0m"
|
||||
|
||||
# define bgBLK "\x1b[40m"
|
||||
# define bgRED "\x1b[41m"
|
||||
# define bgGRN "\x1b[42m"
|
||||
# define bgBRN "\x1b[43m"
|
||||
# define bgBLU "\x1b[44m"
|
||||
# define bgMGN "\x1b[45m"
|
||||
# define bgCYA "\x1b[46m"
|
||||
# define bgLGR "\x1b[47m"
|
||||
# define bgGRA "\x1b[100m"
|
||||
# define bgLRD "\x1b[101m"
|
||||
# define bgLGN "\x1b[102m"
|
||||
# define bgYEL "\x1b[103m"
|
||||
# define bgLBL "\x1b[104m"
|
||||
# define bgPIN "\x1b[105m"
|
||||
# define bgLCY "\x1b[106m"
|
||||
# define bgBRI "\x1b[107m"
|
||||
|
||||
#else
|
||||
|
||||
# define cBLK ""
|
||||
# define cRED ""
|
||||
# define cGRN ""
|
||||
# define cBRN ""
|
||||
# define cBLU ""
|
||||
# define cMGN ""
|
||||
# define cCYA ""
|
||||
# define cLGR ""
|
||||
# define cGRA ""
|
||||
# define cLRD ""
|
||||
# define cLGN ""
|
||||
# define cYEL ""
|
||||
# define cLBL ""
|
||||
# define cPIN ""
|
||||
# define cLCY ""
|
||||
# define cBRI ""
|
||||
# define cRST ""
|
||||
|
||||
# define bgBLK ""
|
||||
# define bgRED ""
|
||||
# define bgGRN ""
|
||||
# define bgBRN ""
|
||||
# define bgBLU ""
|
||||
# define bgMGN ""
|
||||
# define bgCYA ""
|
||||
# define bgLGR ""
|
||||
# define bgGRA ""
|
||||
# define bgLRD ""
|
||||
# define bgLGN ""
|
||||
# define bgYEL ""
|
||||
# define bgLBL ""
|
||||
# define bgPIN ""
|
||||
# define bgLCY ""
|
||||
# define bgBRI ""
|
||||
|
||||
#endif /* ^USE_COLOR */
|
||||
|
||||
/*************************
|
||||
* Box drawing sequences *
|
||||
*************************/
|
||||
|
||||
#ifdef FANCY_BOXES
|
||||
|
||||
# define SET_G1 "\x1b)0" /* Set G1 for box drawing */
|
||||
# define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
|
||||
# define bSTART "\x0e" /* Enter G1 drawing mode */
|
||||
# define bSTOP "\x0f" /* Leave G1 drawing mode */
|
||||
# define bH "q" /* Horizontal line */
|
||||
# define bV "x" /* Vertical line */
|
||||
# define bLT "l" /* Left top corner */
|
||||
# define bRT "k" /* Right top corner */
|
||||
# define bLB "m" /* Left bottom corner */
|
||||
# define bRB "j" /* Right bottom corner */
|
||||
# define bX "n" /* Cross */
|
||||
# define bVR "t" /* Vertical, branch right */
|
||||
# define bVL "u" /* Vertical, branch left */
|
||||
# define bHT "v" /* Horizontal, branch top */
|
||||
# define bHB "w" /* Horizontal, branch bottom */
|
||||
|
||||
#else
|
||||
|
||||
# define SET_G1 ""
|
||||
# define RESET_G1 ""
|
||||
# define bSTART ""
|
||||
# define bSTOP ""
|
||||
# define bH "-"
|
||||
# define bV "|"
|
||||
# define bLT "+"
|
||||
# define bRT "+"
|
||||
# define bLB "+"
|
||||
# define bRB "+"
|
||||
# define bX "+"
|
||||
# define bVR "+"
|
||||
# define bVL "+"
|
||||
# define bHT "+"
|
||||
# define bHB "+"
|
||||
|
||||
#endif /* ^FANCY_BOXES */
|
||||
|
||||
/***********************
|
||||
* Misc terminal codes *
|
||||
***********************/
|
||||
|
||||
#define TERM_HOME "\x1b[H"
|
||||
#define TERM_CLEAR TERM_HOME "\x1b[2J"
|
||||
#define cEOL "\x1b[0K"
|
||||
#define CURSOR_HIDE "\x1b[?25l"
|
||||
#define CURSOR_SHOW "\x1b[?25h"
|
||||
|
||||
/************************
|
||||
* Debug & error macros *
|
||||
************************/
|
||||
|
||||
/* Just print stuff to the appropriate stream. */
|
||||
|
||||
#ifdef MESSAGES_TO_STDOUT
|
||||
# define SAYF(x...) printf(x)
|
||||
#else
|
||||
# define SAYF(x...) fprintf(stderr, x)
|
||||
#endif /* ^MESSAGES_TO_STDOUT */
|
||||
|
||||
/* Show a prefixed warning. */
|
||||
|
||||
#define WARNF(x...) do { \
|
||||
SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \
|
||||
SAYF(cRST "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Show a prefixed "doing something" message. */
|
||||
|
||||
#define ACTF(x...) do { \
|
||||
SAYF(cLBL "[*] " cRST x); \
|
||||
SAYF(cRST "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Show a prefixed "success" message. */
|
||||
|
||||
#define OKF(x...) do { \
|
||||
SAYF(cLGN "[+] " cRST x); \
|
||||
SAYF(cRST "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Show a prefixed fatal error message (not used in afl). */
|
||||
|
||||
#define BADF(x...) do { \
|
||||
SAYF(cLRD "\n[-] " cRST x); \
|
||||
SAYF(cRST "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Die with a verbose non-OS fatal error message. */
|
||||
|
||||
#define FATAL(x...) do { \
|
||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \
|
||||
cBRI x); \
|
||||
SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
/* Die by calling abort() to provide a core dump. */
|
||||
|
||||
#define ABORT(x...) do { \
|
||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \
|
||||
cBRI x); \
|
||||
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
/* Die while also including the output of perror(). */
|
||||
|
||||
#define PFATAL(x...) do { \
|
||||
fflush(stdout); \
|
||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] SYSTEM ERROR : " \
|
||||
cBRI x); \
|
||||
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
/* Die with FAULT() or PFAULT() depending on the value of res (used to
|
||||
interpret different failure modes for read(), write(), etc). */
|
||||
|
||||
#define RPFATAL(res, x...) do { \
|
||||
if (res < 0) PFATAL(x); else FATAL(x); \
|
||||
} while (0)
|
||||
|
||||
/* Error-checking versions of read() and write() that call RPFATAL() as
|
||||
appropriate. */
|
||||
|
||||
#define ck_write(fd, buf, len, fn) do { \
|
||||
u32 _len = (len); \
|
||||
s32 _res = write(fd, buf, _len); \
|
||||
if (_res != _len) RPFATAL(_res, "Short write to %s", fn); \
|
||||
} while (0)
|
||||
|
||||
#define ck_read(fd, buf, len, fn) do { \
|
||||
u32 _len = (len); \
|
||||
s32 _res = read(fd, buf, _len); \
|
||||
if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
|
||||
} while (0)
|
||||
|
||||
#endif /* ! _HAVE_DEBUG_H */
|
||||
104
third_party/afl/hash.h
vendored
104
third_party/afl/hash.h
vendored
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - hashing function
|
||||
-------------------------------------
|
||||
|
||||
The hash32() function is a variant of MurmurHash3, a good
|
||||
non-cryptosafe hashing function developed by Austin Appleby.
|
||||
|
||||
For simplicity, this variant does *NOT* accept buffer lengths
|
||||
that are not divisible by 8 bytes. The 32-bit version is otherwise
|
||||
similar to the original; the 64-bit one is a custom hack with
|
||||
mostly-unproven properties.
|
||||
|
||||
Austin's original code is public domain.
|
||||
|
||||
Other code written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2016 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_HASH_H
|
||||
#define _HAVE_HASH_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
|
||||
|
||||
static inline u32 hash32(const void* key, u32 len, u32 seed) {
|
||||
|
||||
const u64* data = (u64*)key;
|
||||
u64 h1 = seed ^ len;
|
||||
|
||||
len >>= 3;
|
||||
|
||||
while (len--) {
|
||||
|
||||
u64 k1 = *data++;
|
||||
|
||||
k1 *= 0x87c37b91114253d5ULL;
|
||||
k1 = ROL64(k1, 31);
|
||||
k1 *= 0x4cf5ad432745937fULL;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = ROL64(h1, 27);
|
||||
h1 = h1 * 5 + 0x52dce729;
|
||||
|
||||
}
|
||||
|
||||
h1 ^= h1 >> 33;
|
||||
h1 *= 0xff51afd7ed558ccdULL;
|
||||
h1 ^= h1 >> 33;
|
||||
h1 *= 0xc4ceb9fe1a85ec53ULL;
|
||||
h1 ^= h1 >> 33;
|
||||
|
||||
return h1;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
|
||||
|
||||
static inline u32 hash32(const void* key, u32 len, u32 seed) {
|
||||
|
||||
const u32* data = (u32*)key;
|
||||
u32 h1 = seed ^ len;
|
||||
|
||||
len >>= 2;
|
||||
|
||||
while (len--) {
|
||||
|
||||
u32 k1 = *data++;
|
||||
|
||||
k1 *= 0xcc9e2d51;
|
||||
k1 = ROL32(k1, 15);
|
||||
k1 *= 0x1b873593;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = ROL32(h1, 13);
|
||||
h1 = h1 * 5 + 0xe6546b64;
|
||||
|
||||
}
|
||||
|
||||
h1 ^= h1 >> 16;
|
||||
h1 *= 0x85ebca6b;
|
||||
h1 ^= h1 >> 13;
|
||||
h1 *= 0xc2b2ae35;
|
||||
h1 ^= h1 >> 16;
|
||||
|
||||
return h1;
|
||||
|
||||
}
|
||||
|
||||
#endif /* ^__x86_64__ */
|
||||
|
||||
#endif /* !_HAVE_HASH_H */
|
||||
306
third_party/afl/llvm_mode/afl-llvm-rt.o.c
vendored
306
third_party/afl/llvm_mode/afl-llvm-rt.o.c
vendored
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - LLVM instrumentation bootstrap
|
||||
---------------------------------------------------
|
||||
|
||||
Written by Laszlo Szekeres <lszekeres@google.com> and
|
||||
Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
LLVM integration design comes from Laszlo Szekeres.
|
||||
|
||||
Copyright 2015, 2016 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is the rewrite of afl-as.h's main_payload.
|
||||
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include "../types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode.
|
||||
Basically, we need to make sure that the forkserver is initialized after
|
||||
the LLVM-generated runtime initialization pass, not before. */
|
||||
|
||||
#ifdef USE_TRACE_PC
|
||||
# define CONST_PRIO 5
|
||||
#else
|
||||
# define CONST_PRIO 0
|
||||
#endif /* ^USE_TRACE_PC */
|
||||
|
||||
|
||||
/* Globals needed by the injected instrumentation. The __afl_area_initial region
|
||||
is used for instrumentation output before __afl_map_shm() has a chance to run.
|
||||
It will end up as .comm, so it shouldn't be too wasteful. */
|
||||
|
||||
u8 __afl_area_initial[MAP_SIZE];
|
||||
u8* __afl_area_ptr = __afl_area_initial;
|
||||
|
||||
__thread u32 __afl_prev_loc;
|
||||
|
||||
|
||||
/* Running in persistent mode? */
|
||||
|
||||
static u8 is_persistent;
|
||||
|
||||
|
||||
/* SHM setup. */
|
||||
|
||||
static void __afl_map_shm(void) {
|
||||
|
||||
u8 *id_str = getenv(SHM_ENV_VAR);
|
||||
|
||||
/* If we're running under AFL, attach to the appropriate region, replacing the
|
||||
early-stage __afl_area_initial region that is needed to allow some really
|
||||
hacky .init code to work correctly in projects such as OpenSSL. */
|
||||
|
||||
if (id_str) {
|
||||
|
||||
u32 shm_id = atoi(id_str);
|
||||
|
||||
__afl_area_ptr = shmat(shm_id, NULL, 0);
|
||||
|
||||
/* Whooooops. */
|
||||
|
||||
if (__afl_area_ptr == (void *)-1) _exit(1);
|
||||
|
||||
/* Write something into the bitmap so that even with low AFL_INST_RATIO,
|
||||
our parent doesn't give up on us. */
|
||||
|
||||
__afl_area_ptr[0] = 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Fork server logic. */
|
||||
|
||||
static void __afl_start_forkserver(void) {
|
||||
|
||||
static u8 tmp[4];
|
||||
s32 child_pid;
|
||||
|
||||
u8 child_stopped = 0;
|
||||
|
||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
||||
assume we're not running in forkserver mode and just execute program. */
|
||||
|
||||
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
|
||||
|
||||
while (1) {
|
||||
|
||||
u32 was_killed;
|
||||
int status;
|
||||
|
||||
/* Wait for parent by reading from the pipe. Abort if read fails. */
|
||||
|
||||
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
|
||||
|
||||
/* If we stopped the child in persistent mode, but there was a race
|
||||
condition and afl-fuzz already issued SIGKILL, write off the old
|
||||
process. */
|
||||
|
||||
if (child_stopped && was_killed) {
|
||||
child_stopped = 0;
|
||||
if (waitpid(child_pid, &status, 0) < 0) _exit(1);
|
||||
}
|
||||
|
||||
if (!child_stopped) {
|
||||
|
||||
/* Once woken up, create a clone of our process. */
|
||||
|
||||
child_pid = fork();
|
||||
if (child_pid < 0) _exit(1);
|
||||
|
||||
/* In child process: close fds, resume execution. */
|
||||
|
||||
if (!child_pid) {
|
||||
|
||||
close(FORKSRV_FD);
|
||||
close(FORKSRV_FD + 1);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Special handling for persistent mode: if the child is alive but
|
||||
currently stopped, simply restart it with SIGCONT. */
|
||||
|
||||
kill(child_pid, SIGCONT);
|
||||
child_stopped = 0;
|
||||
|
||||
}
|
||||
|
||||
/* In parent process: write PID to pipe, then wait for child. */
|
||||
|
||||
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1);
|
||||
|
||||
if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0)
|
||||
_exit(1);
|
||||
|
||||
/* In persistent mode, the child stops itself with SIGSTOP to indicate
|
||||
a successful run. In this case, we want to wake it up without forking
|
||||
again. */
|
||||
|
||||
if (WIFSTOPPED(status)) child_stopped = 1;
|
||||
|
||||
/* Relay wait status to pipe, then loop back. */
|
||||
|
||||
if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* A simplified persistent mode handler, used as explained in README.llvm. */
|
||||
|
||||
int __afl_persistent_loop(unsigned int max_cnt) {
|
||||
|
||||
static u8 first_pass = 1;
|
||||
static u32 cycle_cnt;
|
||||
|
||||
if (first_pass) {
|
||||
|
||||
/* Make sure that every iteration of __AFL_LOOP() starts with a clean slate.
|
||||
On subsequent calls, the parent will take care of that, but on the first
|
||||
iteration, it's our job to erase any trace of whatever happened
|
||||
before the loop. */
|
||||
|
||||
if (is_persistent) {
|
||||
|
||||
memset(__afl_area_ptr, 0, MAP_SIZE);
|
||||
__afl_area_ptr[0] = 1;
|
||||
__afl_prev_loc = 0;
|
||||
}
|
||||
|
||||
cycle_cnt = max_cnt;
|
||||
first_pass = 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
if (is_persistent) {
|
||||
|
||||
if (--cycle_cnt) {
|
||||
|
||||
raise(SIGSTOP);
|
||||
|
||||
__afl_area_ptr[0] = 1;
|
||||
__afl_prev_loc = 0;
|
||||
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
|
||||
/* When exiting __AFL_LOOP(), make sure that the subsequent code that
|
||||
follows the loop is not traced. We do that by pivoting back to the
|
||||
dummy output region. */
|
||||
|
||||
__afl_area_ptr = __afl_area_initial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* This one can be called from user code when deferred forkserver mode
|
||||
is enabled. */
|
||||
|
||||
void __afl_manual_init(void) {
|
||||
|
||||
static u8 init_done;
|
||||
|
||||
if (!init_done) {
|
||||
|
||||
__afl_map_shm();
|
||||
__afl_start_forkserver();
|
||||
init_done = 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Proper initialization routine. */
|
||||
|
||||
__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
|
||||
|
||||
is_persistent = !!getenv(PERSIST_ENV_VAR);
|
||||
|
||||
if (getenv(DEFER_ENV_VAR)) return;
|
||||
|
||||
__afl_manual_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard.
|
||||
It remains non-operational in the traditional, plugin-backed LLVM mode.
|
||||
For more info about 'trace-pc-guard', see README.llvm.
|
||||
|
||||
The first function (__sanitizer_cov_trace_pc_guard) is called back on every
|
||||
edge (as opposed to every basic block). */
|
||||
|
||||
void __sanitizer_cov_trace_pc_guard(uint32_t* guard) {
|
||||
__afl_area_ptr[*guard]++;
|
||||
}
|
||||
|
||||
|
||||
/* Init callback. Populates instrumentation IDs. Note that we're using
|
||||
ID of 0 as a special value to indicate non-instrumented bits. That may
|
||||
still touch the bitmap, but in a fairly harmless way. */
|
||||
|
||||
void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {
|
||||
|
||||
u32 inst_ratio = 100;
|
||||
u8* x;
|
||||
|
||||
if (start == stop || *start) return;
|
||||
|
||||
x = getenv("AFL_INST_RATIO");
|
||||
if (x) inst_ratio = atoi(x);
|
||||
|
||||
if (!inst_ratio || inst_ratio > 100) {
|
||||
fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Make sure that the first element in the range is always set - we use that
|
||||
to avoid duplicate calls (which can happen as an artifact of the underlying
|
||||
implementation in LLVM). */
|
||||
|
||||
*(start++) = R(MAP_SIZE - 1) + 1;
|
||||
|
||||
while (start < stop) {
|
||||
|
||||
if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1;
|
||||
else *start = 0;
|
||||
|
||||
start++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
86
third_party/afl/types.h
vendored
86
third_party/afl/types.h
vendored
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop - type definitions and minor macros
|
||||
------------------------------------------------------
|
||||
|
||||
Written and maintained by Michal Zalewski <lcamtuf@google.com>
|
||||
|
||||
Copyright 2013, 2014, 2015 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_TYPES_H
|
||||
#define _HAVE_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
||||
/*
|
||||
|
||||
Ugh. There is an unintended compiler / glibc #include glitch caused by
|
||||
combining the u64 type an %llu in format strings, necessitating a workaround.
|
||||
|
||||
In essence, the compiler is always looking for 'unsigned long long' for %llu.
|
||||
On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to
|
||||
'unsigned long long' in <bits/types.h>, so everything checks out.
|
||||
|
||||
But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.
|
||||
Now, it only happens in circumstances where the type happens to have the
|
||||
expected bit width, *but* the compiler does not know that... and complains
|
||||
about 'unsigned long' being unsafe to pass to %llu.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long long u64;
|
||||
#else
|
||||
typedef uint64_t u64;
|
||||
#endif /* ^__x86_64__ */
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))
|
||||
# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))
|
||||
#endif /* !MIN */
|
||||
|
||||
#define SWAP16(_x) ({ \
|
||||
u16 _ret = (_x); \
|
||||
(u16)((_ret << 8) | (_ret >> 8)); \
|
||||
})
|
||||
|
||||
#define SWAP32(_x) ({ \
|
||||
u32 _ret = (_x); \
|
||||
(u32)((_ret << 24) | (_ret >> 24) | \
|
||||
((_ret << 8) & 0x00FF0000) | \
|
||||
((_ret >> 8) & 0x0000FF00)); \
|
||||
})
|
||||
|
||||
#ifdef AFL_LLVM_PASS
|
||||
# define AFL_R(x) (random() % (x))
|
||||
#else
|
||||
# define R(x) (random() % (x))
|
||||
#endif /* ^AFL_LLVM_PASS */
|
||||
|
||||
#define STRINGIFY_INTERNAL(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
|
||||
|
||||
#define MEM_BARRIER() \
|
||||
__asm__ volatile("" ::: "memory")
|
||||
|
||||
#define likely(_x) __builtin_expect(!!(_x), 1)
|
||||
#define unlikely(_x) __builtin_expect(!!(_x), 0)
|
||||
|
||||
#endif /* ! _HAVE_TYPES_H */
|
||||
60
third_party/beacon-fuzz/corpora.BUILD
vendored
60
third_party/beacon-fuzz/corpora.BUILD
vendored
@@ -1,60 +0,0 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "all",
|
||||
srcs = glob(["**"]),
|
||||
)
|
||||
|
||||
# See: https://github.com/sigp/beacon-fuzz-corpora
|
||||
|
||||
current_version = "0_11_0"
|
||||
|
||||
alias(
|
||||
name = "current_mainnet_attestation",
|
||||
actual = ":" + current_version + "_mainnet_attestation",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "current_mainnet_attester_slashing",
|
||||
actual = ":" + current_version + "_mainnet_attester_slashing",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "current_mainnet_block_header",
|
||||
actual = ":" + current_version + "_mainnet_block_header",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "current_mainnet_beaconstate",
|
||||
actual = ":" + current_version + "_mainnet_beaconstate",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "current_mainnet_proposer_slashing",
|
||||
actual = ":" + current_version + "_mainnet_proposer_slashing",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "0_11_0_mainnet_attestation",
|
||||
srcs = glob(["0-11-0/mainnet/attestation/*"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "0_11_0_mainnet_attester_slashing",
|
||||
srcs = glob(["0-11-0/mainnet/attester_slashing/*"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "0_11_0_mainnet_block_header",
|
||||
srcs = glob(["0-11-0/mainnet/block_header/*"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "0_11_0_mainnet_beaconstate",
|
||||
srcs = glob(["0-11-0/mainnet/beaconstate/*"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "0_11_0_mainnet_proposer_slashing",
|
||||
srcs = glob(["0-11-0/mainnet/proposer_slashing/*"]),
|
||||
)
|
||||
1
third_party/herumi/bls_eth_go_binary.BUILD
vendored
1
third_party/herumi/bls_eth_go_binary.BUILD
vendored
@@ -154,7 +154,6 @@ go_library(
|
||||
"@com_github_wealdtech_go_eth2_types_v2//:__pkg__",
|
||||
],
|
||||
clinkopts = select({
|
||||
"@prysm//testing/fuzz:fuzzing_enabled": ["-Wl,--unresolved-symbols=ignore-all", "-fsanitize=address"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user