From 49b77207dd870bc2e2e1b283f46504e27fce432f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 11:11:30 +0200 Subject: aflpp driver cpp -> c --- examples/aflpp_driver/aflpp_driver.c | 292 +++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 examples/aflpp_driver/aflpp_driver.c (limited to 'examples/aflpp_driver/aflpp_driver.c') diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c new file mode 100644 index 00000000..65fea404 --- /dev/null +++ b/examples/aflpp_driver/aflpp_driver.c @@ -0,0 +1,292 @@ +//===- 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 +#include +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef _DEBUG +#include "hash.h" +#endif + +// 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 + +int __afl_sharedmem_fuzzing = 1; +extern unsigned int *__afl_fuzz_len; +extern unsigned char *__afl_fuzz_ptr; + +// libFuzzer interface is thin, so we don't include any libFuzzer headers. +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##"; +int __afl_persistent_loop(unsigned int); + +// Notify AFL about deferred forkserver. +static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; +void __afl_manual_init(); + +// 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)) 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; + +// 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((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. +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) { + unsigned char *buf = malloc(MAX_FILE); + for (int i = 1; i < argc; i++) { + int fd = open(argv[i], O_RDONLY); + if (fd == -1) continue; + ssize_t length = read(fd, buf, MAX_FILE); + if (length > 0) { + printf("Reading %zu bytes from %s\n", length, argv[i]); + LLVMFuzzerTestOneInput(buf, length); + printf("Execution successful.\n"); + } + } + free(buf); + 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]); + + output_file = stderr; + maybe_duplicate_stderr(); + maybe_close_fd_mask(); + if (LLVMFuzzerInitialize) + LLVMFuzzerInitialize(&argc, &argv); + + // Do any other expensive one-time initialization here. + + uint8_t dummy_input[64] = {0}; + memcpy(dummy_input, (void*)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); + memcpy(dummy_input + 32, (void*)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR)); + int N = INT_MAX; + 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) { +// if (!getenv("AFL_DRIVER_DONT_DEFER")) { + __afl_sharedmem_fuzzing = 0; + __afl_manual_init(); +// } + return ExecuteFilesOnyByOne(argc, argv); + exit(0); + } + + assert(N > 0); + +// if (!getenv("AFL_DRIVER_DONT_DEFER")) + __afl_manual_init(); + + // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization + // on the first execution of LLVMFuzzerTestOneInput is ignored. + LLVMFuzzerTestOneInput(dummy_input, 1); + + int num_runs = 0; + while (__afl_persistent_loop(N)) { +#ifdef _DEBUG + fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len); + fprintf(stderr, "RECV:"); + for (int i = 0; i < *__afl_fuzz_len; i++) + fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); + fprintf(stderr,"\n"); +#endif + if (*__afl_fuzz_len) { + num_runs++; + LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len); + } + } + Printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); +} -- cgit 1.4.1 From fe39e4dfdf90ab36342786bfb37503b53a6a358e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 11:30:37 +0200 Subject: remove unneeded stuff --- examples/aflpp_driver/GNUmakefile | 12 ++++++------ examples/aflpp_driver/aflpp_driver.c | 18 +++--------------- 2 files changed, 9 insertions(+), 21 deletions(-) (limited to 'examples/aflpp_driver/aflpp_driver.c') diff --git a/examples/aflpp_driver/GNUmakefile b/examples/aflpp_driver/GNUmakefile index 2a61f743..b118a8b5 100644 --- a/examples/aflpp_driver/GNUmakefile +++ b/examples/aflpp_driver/GNUmakefile @@ -7,25 +7,25 @@ ifneq "" "$(LLVM_BINDIR)" LLVM_BINDIR := $(LLVM_BINDIR)/ endif -FLAGS=-O3 -funroll-loops -g +CFLAGS := -O3 -funroll-loops -g all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so aflpp_driver.o: aflpp_driver.c - $(LLVM_BINDIR)clang -I. -I../../include $(FLAGS) -c aflpp_driver.c + $(LLVM_BINDIR)clang -I. -I../../include $(CFLAGS) -c aflpp_driver.c libAFLDriver.a: aflpp_driver.o ar ru libAFLDriver.a aflpp_driver.o debug: - $(LLVM_BINDIR)clang -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c + $(LLVM_BINDIR)clang -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c $(LLVM_BINDIR)clang -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c - #$(LLVM_BINDIR)clang -S -emit-llvm -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c + #$(LLVM_BINDIR)clang -S -emit-llvm -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c #$(LLVM_BINDIR)clang -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c ar ru libAFLDriver.a afl-performance.o aflpp_driver.o aflpp_qemu_driver.o: aflpp_qemu_driver.c - $(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c + $(LLVM_BINDIR)clang $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c libAFLQemuDriver.a: aflpp_qemu_driver.o ar ru libAFLQemuDriver.a aflpp_qemu_driver.o @@ -34,7 +34,7 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - $(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c + $(LLVM_BINDIR)clang -fPIC $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c test: debug #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c index 65fea404..eca3dcd1 100644 --- a/examples/aflpp_driver/aflpp_driver.c +++ b/examples/aflpp_driver/aflpp_driver.c @@ -111,10 +111,6 @@ int __afl_persistent_loop(unsigned int); static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; void __afl_manual_init(); -// 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)) void __sanitizer_set_report_fd(void *); @@ -181,14 +177,6 @@ static void dup_and_close_stderr() { 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"); @@ -226,7 +214,7 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { } int main(int argc, char **argv) { - Printf( + printf( "======================= INFO =========================\n" "This binary is built for AFL-fuzz.\n" "To run the target function on individual input(s) execute this:\n" @@ -255,7 +243,7 @@ int main(int argc, char **argv) { 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); + printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); else if (argc > 1) { // if (!getenv("AFL_DRIVER_DONT_DEFER")) { __afl_sharedmem_fuzzing = 0; @@ -288,5 +276,5 @@ int main(int argc, char **argv) { LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len); } } - Printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); + printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); } -- cgit 1.4.1 From ea9ba53cdbc6d175f3f055c9a308668ebaacda1e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 17:09:22 +0200 Subject: fix oob reads, code-format --- examples/aflpp_driver/aflpp_driver.c | 168 ++++++++++++++++++------------ examples/aflpp_driver/aflpp_driver_test.c | 16 +-- src/afl-fuzz-queue.c | 55 +++++----- src/afl-fuzz-redqueen.c | 3 +- test/test-floatingpoint.c | 8 +- 5 files changed, 146 insertions(+), 104 deletions(-) (limited to 'examples/aflpp_driver/aflpp_driver.c') diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c index eca3dcd1..86c7a69f 100644 --- a/examples/aflpp_driver/aflpp_driver.c +++ b/examples/aflpp_driver/aflpp_driver.c @@ -14,12 +14,15 @@ cat << EOF > test_fuzzer.cc #include #include 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 @@ -57,46 +60,46 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both. #include "config.h" #ifdef _DEBUG -#include "hash.h" + #include "hash.h" #endif // 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 + #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 + #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 + #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 + #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 + #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" + #error "Support for your platform has not been implemented" #endif -int __afl_sharedmem_fuzzing = 1; -extern unsigned int *__afl_fuzz_len; +int __afl_sharedmem_fuzzing = 1; +extern unsigned int * __afl_fuzz_len; extern unsigned char *__afl_fuzz_ptr; // libFuzzer interface is thin, so we don't include any libFuzzer headers. @@ -105,11 +108,11 @@ __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); // Notify AFL about persistent mode. static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; -int __afl_persistent_loop(unsigned int); +int __afl_persistent_loop(unsigned int); // Notify AFL about deferred forkserver. static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; -void __afl_manual_init(); +void __afl_manual_init(); // Use this optionally defined function to output sanitizer messages even if // user asks to close stderr. @@ -122,98 +125,121 @@ static FILE *output_file; // 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; + 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(); + if (!temp) abort(); dup2(fileno(temp), fd); fclose(temp); + } -static void close_stdout() { discard_output(STDOUT_FILENO); } +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(); + 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((void*)output_fd); + if (!new_output_file) abort(); + if (!__sanitizer_set_report_fd) return; + __sanitizer_set_report_fd((void *)output_fd); discard_output(output_fileno); + } // 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; + 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(); + 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. size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { - //assert(false && "LLVMFuzzerMutate should not be called from afl_driver"); + + // 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) { + unsigned char *buf = malloc(MAX_FILE); for (int i = 1; i < argc; i++) { + int fd = open(argv[i], O_RDONLY); if (fd == -1) continue; ssize_t length = read(fd, buf, MAX_FILE); if (length > 0) { + printf("Reading %zu bytes from %s\n", length, argv[i]); LLVMFuzzerTestOneInput(buf, length); printf("Execution successful.\n"); + } + } + free(buf); return 0; + } int main(int argc, char **argv) { + printf( "======================= INFO =========================\n" "This binary is built for AFL-fuzz.\n" @@ -226,36 +252,39 @@ int main(int argc, char **argv) { "afl-fuzz will run N iterations before " "re-spawning the process (default: 1000)\n" "======================================================\n", - argv[0], argv[0], argv[0]); + argv[0], argv[0], argv[0]); output_file = stderr; maybe_duplicate_stderr(); maybe_close_fd_mask(); - if (LLVMFuzzerInitialize) - LLVMFuzzerInitialize(&argc, &argv); + if (LLVMFuzzerInitialize) LLVMFuzzerInitialize(&argc, &argv); // Do any other expensive one-time initialization here. uint8_t dummy_input[64] = {0}; - memcpy(dummy_input, (void*)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); - memcpy(dummy_input + 32, (void*)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR)); + memcpy(dummy_input, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); + memcpy(dummy_input + 32, (void *)AFL_DEFER_FORKSVR, + sizeof(AFL_DEFER_FORKSVR)); int N = INT_MAX; 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); + 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) { -// if (!getenv("AFL_DRIVER_DONT_DEFER")) { - __afl_sharedmem_fuzzing = 0; - __afl_manual_init(); -// } + + // if (!getenv("AFL_DRIVER_DONT_DEFER")) { + + __afl_sharedmem_fuzzing = 0; + __afl_manual_init(); + // } return ExecuteFilesOnyByOne(argc, argv); exit(0); + } assert(N > 0); -// if (!getenv("AFL_DRIVER_DONT_DEFER")) + // if (!getenv("AFL_DRIVER_DONT_DEFER")) __afl_manual_init(); // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization @@ -264,17 +293,26 @@ int main(int argc, char **argv) { int num_runs = 0; while (__afl_persistent_loop(N)) { + #ifdef _DEBUG - fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len); + fprintf(stderr, "CLIENT crc: %016llx len: %u\n", + hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), + *__afl_fuzz_len); fprintf(stderr, "RECV:"); for (int i = 0; i < *__afl_fuzz_len; i++) fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); - fprintf(stderr,"\n"); + fprintf(stderr, "\n"); #endif if (*__afl_fuzz_len) { + num_runs++; LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len); + } + } + printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); + } + diff --git a/examples/aflpp_driver/aflpp_driver_test.c b/examples/aflpp_driver/aflpp_driver_test.c index 83278f5c..e4567bbf 100644 --- a/examples/aflpp_driver/aflpp_driver_test.c +++ b/examples/aflpp_driver/aflpp_driver_test.c @@ -6,18 +6,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size); - - if (Size < 5) - return 0; + fprintf(stderr, "FUNC crc: %016llx len: %lu\n", + hash64((u8 *)Data, (unsigned int)Size, + (unsigned long long int)0xa5b35705), + Size); + + if (Size < 5) return 0; if (Data[0] == 'F') if (Data[1] == 'A') if (Data[2] == '$') if (Data[3] == '$') - if (Data[4] == '$') - abort(); - + if (Data[4] == '$') abort(); + return 0; } + diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 38e95ac8..71874283 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -139,7 +139,8 @@ static u8 check_if_text(struct queue_entry *q) { // non-overlong 2-byte if (((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF)) && + len - offset > 1) { offset += 2; utf8++; @@ -149,18 +150,19 @@ static u8 check_if_text(struct queue_entry *q) { } // excluding overlongs - if ((buf[offset + 0] == 0xE0 && - (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // straight 3-byte - (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) || - buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // excluding surrogates - (buf[offset + 0] == 0xED && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF))) { + if ((len - offset > 2) && + ((buf[offset + 0] == 0xE0 && + (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && + buf[offset + 2] <= 0xBF)) || // straight 3-byte + (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) || + buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && + buf[offset + 2] <= 0xBF)) || // excluding surrogates + (buf[offset + 0] == 0xED && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF)))) { offset += 3; utf8++; @@ -170,19 +172,20 @@ static u8 check_if_text(struct queue_entry *q) { } // planes 1-3 - if ((buf[offset + 0] == 0xF0 && - (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && - buf[offset + 3] <= 0xBF)) || // planes 4-15 - ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16 - (buf[offset + 0] == 0xF4 && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF))) { + if ((len - offset > 3) && + ((buf[offset + 0] == 0xF0 && + (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && + buf[offset + 3] <= 0xBF)) || // planes 4-15 + ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16 + (buf[offset + 0] == 0xF4 && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)))) { offset += 4; utf8++; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 57e60c3d..a2e8f992 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -269,8 +269,7 @@ static long long strntoll(const char *str, size_t sz, char **end, int base) { long long ret; const char *beg = str; - for (; beg && sz && *beg == ' '; beg++, sz--) - ; + for (; beg && sz && *beg == ' '; beg++, sz--) {}; if (!sz || sz >= sizeof(buf)) { diff --git a/test/test-floatingpoint.c b/test/test-floatingpoint.c index d1709b90..3a699595 100644 --- a/test/test-floatingpoint.c +++ b/test/test-floatingpoint.c @@ -17,10 +17,10 @@ int main(void) { int len = __AFL_FUZZ_TESTCASE_LEN; if (len != sizeof(float)) return 1; - /* 15 + 1/2 = 15.5 */ - /* 15 + 1/2 + 1/8 = 15.625 */ - /* 15 + 1/2 + 1/8 + 1/32 = 15.65625 */ - /* 15 + 1/2 + 1/8 + 1/32 + 1/128 = 15.6640625 */ + /* 15 + 1/2 = 15.5 */ + /* 15 + 1/2 + 1/8 = 15.625 */ + /* 15 + 1/2 + 1/8 + 1/32 = 15.65625 */ + /* 15 + 1/2 + 1/8 + 1/32 + 1/128 = 15.6640625 */ if ((-*magic == 15.0 + 0.5 + 0.125 + 0.03125 + 0.0078125)) abort(); } -- cgit 1.4.1