Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus

This commit is contained in:
Andrea Fioraldi 2019-10-31 16:19:26 +01:00
commit 58fe2f2c76
15 changed files with 184 additions and 37 deletions

View File

@ -1,11 +1,20 @@
dist: bionic
language: c
env:
- AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1
- AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1
- AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1
# TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes
- AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1
before_install:
- sudo apt update
- sudo apt install -y libtool libtool-bin automake bison libglib2.0 build-essential clang gcc-8 gcc-8-plugin-dev libc++-8-dev
# libc++-7-dev
script:
- make
- ./afl-gcc ./test-instr.c -o test-instr
- mkdir seeds; mkdir out
- echo "" > seeds/nil_seed
- timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-instr
- gcc -v
- clang -v
- make distrib
- make tests
- make clean

View File

@ -13,6 +13,19 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>.
----------------------
Version ++2.58d (dev):
----------------------
- afl-analyze: added AFL_SKIP_BIN_CHECK support
- better random numbers for gcc_plugin and llvm_mode (thanks to devnexen)
- afl-fuzz: CPU affinity support for DragonFly
- llvm_mode: float splitting is now configured via AFL_LLVM_LAF_SPLIT_FLOATS
- libtokencap: support for *BSD/OSX added
- libcompcov floating point splitting support for qemu and unicorn
- removed unnecessary warnings
--------------------------
Version ++2.58c (release):
--------------------------

View File

@ -108,7 +108,7 @@ static void edit_params(u32 argc, char** argv) {
u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1;
u8* name;
cc_params = ck_alloc((argc + 64) * sizeof(u8*));
cc_params = ck_alloc((argc + 128) * sizeof(u8*));
name = strrchr(argv[0], '/');
if (!name)
@ -202,6 +202,19 @@ static void edit_params(u32 argc, char** argv) {
}
if (getenv("AFL_NO_BUILTIN")) {
cc_params[cc_par_cnt++] = "-fno-builtin-strcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
}
#ifdef USEMMAP
cc_params[cc_par_cnt++] = "-lrt";
#endif

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <sys/mman.h>
#include "config.h"
@ -264,6 +265,54 @@ void* realloc(void* ptr, size_t len) {
}
/* posix_memalign we mainly check the proper alignment argument
if the requested size fits within the alignment we do
a normal request */
int posix_memalign(void** ptr, size_t align, size_t len) {
if (*ptr == NULL)
return EINVAL;
if ((align % 2) || (align % sizeof(void *)))
return EINVAL;
if (len == 0) {
*ptr = NULL;
return 0;
}
if (align >= 4 * sizeof(size_t)) len += align -1;
*ptr = malloc(len);
DEBUGF("posix_memalign(%p %zu, %zu)", ptr, align, len);
return 0;
}
/* just the non-posix fashion */
void *memalign(size_t align, size_t len) {
void* ret = NULL;
if (posix_memalign(&ret, align, len)) {
DEBUGF("memalign(%zu, %zu) failed", align, len);
}
return ret;
}
/* sort of C11 alias of memalign only more severe, alignment-wise */
void *aligned_alloc(size_t align, size_t len) {
void *ret = NULL;
if ((len % align)) return NULL;
if (posix_memalign(&ret, align, len)) {
DEBUGF("aligned_alloc(%zu, %zu) failed", align, len);
}
return ret;
}
__attribute__((constructor)) void __dislocator_init(void) {
u8* tmp = getenv("AFL_LD_LIMIT_MB");

View File

@ -33,6 +33,9 @@ endif
ifeq "$(shell uname)" "OpenBSD"
TARGETS = libtokencap.so
endif
ifeq "$(shell uname)" "NetBSD"
TARGETS = libtokencap.so
endif
all: $(TARGETS)
libtokencap.so: libtokencap.so.c ../config.h

View File

@ -23,6 +23,7 @@
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include "../types.h"
#include "../config.h"
@ -49,7 +50,7 @@ static struct mapping { void *st, *en; } __tokencap_ro[MAX_MAPPINGS];
static u32 __tokencap_ro_cnt;
static u8 __tokencap_ro_loaded;
static FILE* __tokencap_out_file;
static int __tokencap_out_file = -1;
/* Identify read-only regions in memory. Only parameters that fall into these
ranges are worth dumping when passed to strcmp() and so on. Read-write
@ -114,7 +115,7 @@ static void __tokencap_load_mappings(void) {
#elif defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__
#if defined __FreeBSD__
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, -1};
#elif defined __OpenBSD__
int mib[] = {CTL_KERN, KERN_PROC_VMMAP, getpid()};
#elif defined __NetBSD__
@ -133,9 +134,7 @@ static void __tokencap_load_mappings(void) {
#endif
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!buf) {
return;
}
if (buf == MAP_FAILED) return;
if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) {
@ -211,7 +210,7 @@ static void __tokencap_dump(const u8* ptr, size_t len, u8 is_text) {
u32 i;
u32 pos = 0;
if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA || !__tokencap_out_file)
if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA || __tokencap_out_file == -1)
return;
for (i = 0; i < len; i++) {
@ -237,7 +236,9 @@ static void __tokencap_dump(const u8* ptr, size_t len, u8 is_text) {
buf[pos] = 0;
fprintf(__tokencap_out_file, "\"%s\"\n", buf);
int wrt_ok = ( 1 == write(__tokencap_out_file, "\"", 1));
wrt_ok &= (pos == write(__tokencap_out_file, buf, pos));
wrt_ok &= (2 == write(__tokencap_out_file, "\"\n", 2));
}
@ -253,7 +254,7 @@ int strcmp(const char* str1, const char* str2) {
while (1) {
unsigned char c1 = *str1, c2 = *str2;
const unsigned char c1 = *str1, c2 = *str2;
if (c1 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0;
@ -295,7 +296,7 @@ int strcasecmp(const char* str1, const char* str2) {
while (1) {
unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
if (c1 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0;
@ -315,7 +316,7 @@ int strncasecmp(const char* str1, const char* str2, size_t len) {
while (len--) {
unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
if (!c1) return 0;
if (c1 != c2) return (c1 > c2) ? 1 : -1;
@ -335,12 +336,15 @@ int memcmp(const void* mem1, const void* mem2, size_t len) {
if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0);
if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0);
const char *strmem1 = (const char *)mem1;
const char *strmem2 = (const char *)mem2;
while (len--) {
unsigned char c1 = *(const char*)mem1, c2 = *(const char*)mem2;
const unsigned char c1 = *strmem1, c2 = *strmem2;
if (c1 != c2) return (c1 > c2) ? 1 : -1;
mem1++;
mem2++;
strmem1++;
strmem2++;
}
@ -348,6 +352,28 @@ int memcmp(const void* mem1, const void* mem2, size_t len) {
}
#undef bcmp
int bcmp(const void* mem1, const void* mem2, size_t len) {
if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0);
if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0);
const char *strmem1 = (const char *)mem1;
const char *strmem2 = (const char *)mem2;
while (len--) {
int diff = *strmem1 ^ *strmem2;
if (diff != 0) return 1;
strmem1++;
strmem2++;
}
return 0;
}
#undef strstr
char* strstr(const char* haystack, const char* needle) {
@ -403,8 +429,13 @@ char* strcasestr(const char* haystack, const char* needle) {
__attribute__((constructor)) void __tokencap_init(void) {
u8* fn = getenv("AFL_TOKEN_FILE");
if (fn) __tokencap_out_file = fopen(fn, "a");
if (!__tokencap_out_file) __tokencap_out_file = stderr;
if (fn) __tokencap_out_file = open(fn, O_RDWR | O_CREAT | O_APPEND, 0655);
if (__tokencap_out_file == -1) __tokencap_out_file = STDERR_FILENO;
}
/* closing as best as we can the tokens file */
__attribute__((destructor)) void __tokencap_shutdown(void) {
if (__tokencap_out_file != STDERR_FILENO) close(__tokencap_out_file);
}

View File

@ -158,6 +158,7 @@ struct InsTrim : public ModulePass {
bool instrumentBlock = false;
DebugLoc Loc;
StringRef instFilename;
unsigned int instLine = 0;
for (auto &BB : F) {
@ -171,7 +172,7 @@ struct InsTrim : public ModulePass {
DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
unsigned int instLine = cDILoc->getLine();
instLine = cDILoc->getLine();
instFilename = cDILoc->getFilename();
if (instFilename.str().empty()) {
@ -217,11 +218,13 @@ struct InsTrim : public ModulePass {
* not whitelisted, so we skip instrumentation. */
if (!instrumentBlock) {
if (!instFilename.str().empty())
SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s ...\n",
instFilename.str().c_str());
else
SAYF(cYEL "[!] " cBRI "No filename information found, skipping it");
if (!be_quiet) {
if (!instFilename.str().empty())
SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n",
instFilename.str().c_str(), instLine);
else
SAYF(cYEL "[!] " cBRI "No filename information found, skipping it");
}
continue;
}

View File

@ -52,7 +52,7 @@ endif
CFLAGS ?= -O3 -funroll-loops
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I ../include/ \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DVERSION=\"$(VERSION)\"
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\"
ifdef AFL_TRACE_PC
CFLAGS += -DUSE_TRACE_PC=1
endif

View File

@ -32,11 +32,13 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
static u8* obj_path; /* Path to runtime libraries */
static u8** cc_params; /* Parameters passed to the real CC */
static u32 cc_par_cnt = 1; /* Param count, including argv0 */
static u8 llvm_fullpath[PATH_MAX];
/* Try to find the runtime libraries. If that fails, abort. */
@ -104,6 +106,7 @@ static void find_obj(u8* argv0) {
static void edit_params(u32 argc, char** argv) {
u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0;
u8 has_llvm_config = 0;
u8* name;
cc_params = ck_alloc((argc + 128) * sizeof(u8*));
@ -114,15 +117,21 @@ static void edit_params(u32 argc, char** argv) {
else
++name;
has_llvm_config = (strlen(LLVM_BINDIR) > 0);
if (!strcmp(name, "afl-clang-fast++")) {
u8* alt_cxx = getenv("AFL_CXX");
cc_params[0] = alt_cxx ? alt_cxx : (u8*)"clang++";
if (has_llvm_config) snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++", LLVM_BINDIR);
else sprintf(llvm_fullpath, "clang++");
cc_params[0] = alt_cxx ? alt_cxx : (u8*)llvm_fullpath;
} else {
u8* alt_cc = getenv("AFL_CC");
cc_params[0] = alt_cc ? alt_cc : (u8*)"clang";
if (has_llvm_config) snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang", LLVM_BINDIR);
else sprintf(llvm_fullpath, "clang");
cc_params[0] = alt_cc ? alt_cc : (u8*)llvm_fullpath;
}
@ -273,6 +282,9 @@ static void edit_params(u32 argc, char** argv) {
cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
}

View File

@ -190,6 +190,8 @@ bool AFLCoverage::runOnModule(Module &M) {
}
(void)instLine;
/* Continue only if we know where we actually are */
if (!instFilename.str().empty()) {

View File

@ -234,6 +234,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
sizedLen = ilen->getZExtValue();
} else {
sizedLen = 0;
}
if (HasStr1) {

View File

@ -118,6 +118,8 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
/* this is probably not needed but we do it anyway */
if (TyOp0 != TyOp1) { continue; }
if (TyOp0->isArrayTy() || TyOp0->isVectorTy()) { continue; }
fcomps.push_back(selectcmpInst);
}

View File

@ -987,7 +987,7 @@ int main(int argc, char** argv) {
if (child_timed_out)
FATAL("Target binary times out (adjusting -t may help).");
if (!anything_set()) FATAL("No instrumentation detected.");
if (getenv("AFL_SKIP_BIN_CHECK") == NULL && !anything_set()) FATAL("No instrumentation detected.");
analyze(use_argv);

View File

@ -320,6 +320,7 @@ static void edit_params(u32 argc, char** argv) {
cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";

View File

@ -26,6 +26,7 @@ test -z "$ECHO" && { printf Error: printf command does not support octal charact
export AFL_EXIT_WHEN_DONE=1
export AFL_SKIP_CPUFREQ=1
export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
unset AFL_QUIET
unset AFL_DEBUG
unset AFL_HARDEN
@ -87,7 +88,7 @@ test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
# now we want to be sure that afl-fuzz is working
# make sure core_pattern is set to core on linux
(test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
$ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
true
}) ||
# make sure crash reporter is disabled on Mac OS X
@ -143,7 +144,7 @@ test -e ../afl-clang-fast && {
} || $ECHO "$RED[!] llvm_mode hardened mode compilation failed"
# now we want to be sure that afl-fuzz is working
(test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
$ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
true
}) ||
# make sure crash reporter is disabled on Mac OS X
@ -226,7 +227,7 @@ test -e ../afl-gcc-fast && {
} || $ECHO "$RED[!] gcc_plugin hardened mode compilation failed"
# now we want to be sure that afl-fuzz is working
(test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
$ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
true
}) ||
# make sure crash reporter is disabled on Mac OS X
@ -372,11 +373,15 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
test -d ../unicorn_mode/unicorn && {
test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
{
# travis workaround
PY=`which python2.7`
test "$PY" = "/opt/pyenv/shims/python2.7" -a -x /usr/bin/python2.7 && PY=/usr/bin/python2.7
mkdir -p in
echo 0 > in/in
$ECHO "$GREY[*] Using python binary $PY"
$ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 20 seconds"
{
../afl-fuzz -V20 -U -i in -o out -d -- python ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
../afl-fuzz -V20 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode"
@ -391,7 +396,7 @@ test -d ../unicorn_mode/unicorn && {
$ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 25 seconds"
{
export AFL_COMPCOV_LEVEL=2
../afl-fuzz -V25 -U -i in -o out -d -- python ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/queue/id:000001* 2> /dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode compcov"