diff options
Diffstat (limited to 'src/afl-common.c')
-rw-r--r-- | src/afl-common.c | 160 |
1 files changed, 144 insertions, 16 deletions
diff --git a/src/afl-common.c b/src/afl-common.c index 73b3fa8a..6ef7a195 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -37,9 +37,14 @@ #include <unistd.h> #endif #include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> u8 be_quiet = 0; u8 *doc_path = ""; +u8 last_intr = 0; char *afl_environment_variables[] = { @@ -58,15 +63,16 @@ char *afl_environment_variables[] = { "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX", "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", + "AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", - "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", + "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_NO_X86", // not really an env but we dont want to warn on it - "AFL_PATH", "AFL_PERFORMANCE_FILE", + "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE", //"AFL_PERSISTENT", // not implemented anymore, so warn additionally "AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV", "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", @@ -139,7 +145,7 @@ void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { char **argv_cpy_dup(int argc, char **argv) { - u32 i = 0; + int i = 0; char **ret = ck_alloc((argc + 1) * sizeof(char *)); @@ -216,10 +222,12 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } - } else + } else { ck_free(own_copy); + } + if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) { if (cp) ck_free(cp); @@ -233,7 +241,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { "Oops, unable to find the 'afl-qemu-trace' binary. The binary must be " "built\n" " separately by following the instructions in " - "afl->qemu_mode/README.md. " + "qemu_mode/README.md. " "If you\n" " already have the binary installed, you may need to specify " "AFL_PATH in the\n" @@ -290,11 +298,10 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { *rsl = 0; cp = alloc_printf("%s/afl-qemu-trace", own_copy); - ck_free(own_copy); - if (!access(cp, X_OK)) { + if (cp && !access(cp, X_OK)) { - if (cp != NULL) ck_free(cp); + ck_free(cp); cp = alloc_printf("%s/afl-wine-trace", own_copy); @@ -307,10 +314,14 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } - } else + ck_free(own_copy); + + } else { ck_free(own_copy); + } + u8 *ncp = BIN_PATH "/afl-qemu-trace"; if (!access(ncp, X_OK)) { @@ -330,7 +341,7 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { "Oops, unable to find the '%s' binary. The binary must be " "built\n" " separately by following the instructions in " - "afl->qemu_mode/README.md. " + "qemu_mode/README.md. " "If you\n" " already have the binary installed, you may need to specify " "AFL_PATH in the\n" @@ -348,12 +359,85 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } +/* Find binary, used by analyze, showmap, tmin + @returns the path, allocating the string */ + +u8 *find_binary(u8 *fname) { + + // TODO: Merge this function with check_binary of afl-fuzz-init.c + + u8 *env_path = NULL; + u8 *target_path = NULL; + + struct stat st; + + if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { + + target_path = ck_strdup(fname); + + if (stat(target_path, &st) || !S_ISREG(st.st_mode) || + !(st.st_mode & 0111) || st.st_size < 4) { + + free(target_path); + FATAL("Program '%s' not found or not executable", fname); + + } + + } else { + + while (env_path) { + + u8 *cur_elem, *delim = strchr(env_path, ':'); + + if (delim) { + + cur_elem = ck_alloc(delim - env_path + 1); + memcpy(cur_elem, env_path, delim - env_path); + delim++; + + } else { + + cur_elem = ck_strdup(env_path); + + } + + env_path = delim; + + if (cur_elem[0]) { + + target_path = alloc_printf("%s/%s", cur_elem, fname); + + } else { + + target_path = ck_strdup(fname); + + } + + ck_free(cur_elem); + + if (!stat(target_path, &st) && S_ISREG(st.st_mode) && + (st.st_mode & 0111) && st.st_size >= 4) + break; + + ck_free(target_path); + target_path = NULL; + + } + + if (!target_path) FATAL("Program '%s' not found or not executable", fname); + + } + + return target_path; + +} + void check_environment_vars(char **envp) { if (be_quiet) return; int index = 0, found = 0; - char *env; + char *env, *val; while ((env = envp[index++]) != NULL) { if (strncmp(env, "ALF_", 4) == 0) { @@ -367,10 +451,21 @@ void check_environment_vars(char **envp) { while (match == 0 && afl_environment_variables[i] != NULL) if (strncmp(env, afl_environment_variables[i], strlen(afl_environment_variables[i])) == 0 && - env[strlen(afl_environment_variables[i])] == '=') + env[strlen(afl_environment_variables[i])] == '=') { + match = 1; - else + if ((val = getenv(afl_environment_variables[i])) && !*val) + WARNF( + "AFL environment variable %s defined but is empty, this can " + "lead to unexpected consequences", + afl_environment_variables[i]); + + } else { + i++; + + } + if (match == 0) { WARNF("Mistyped AFL environment variable: %s", env); @@ -398,6 +493,20 @@ char *get_afl_env(char *env) { } +/* Read mask bitmap from file. This is for the -B option. */ + +void read_bitmap(u8 *fname, u8 *map, size_t len) { + + s32 fd = open(fname, O_RDONLY); + + if (fd < 0) PFATAL("Unable to open '%s'", fname); + + ck_read(fd, map, len, fname); + + close(fd); + +} + u64 get_cur_time(void) { struct timeval tv; @@ -743,7 +852,8 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { 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) { +u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms, + volatile u8 *stop_soon_p) { struct timeval timeout; fd_set readfds; @@ -768,8 +878,8 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { } else if (sret < 0) { - // perror("sret malloc"); - // TODO: catch other (errno == EINTR) than ctrl+c? + /* Retry select for all signals other than than ctrl+c */ + if (errno == EINTR && !*stop_soon_p) { continue; } return 0; } @@ -788,3 +898,21 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) { } +u32 get_map_size() { + + uint32_t map_size = MAP_SIZE; + char * ptr; + + if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { + + map_size = atoi(ptr); + if (map_size < 8 || map_size > (1 << 29)) + FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size); + if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3); + + } + + return map_size; + +} + |