From ad7a7fcf075c617e09cb516da000b244be161093 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 1 Mar 2021 15:30:55 +0100 Subject: ASan-compatible area_is_mapped() --- instrumentation/afl-compiler-rt.o.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index ecb94cab..dab06177 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -34,6 +34,7 @@ #include #include +#include #ifndef __HAIKU__ #include #endif @@ -1551,15 +1552,22 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { } +__attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) { + return NULL; +} + // POSIX shenanigan to see if an area is mapped. // If it is mapped as X-only, we have a problem, so maybe we should add a check // to avoid to call it on .text addresses static int area_is_mapped(void *ptr, size_t len) { + if (__asan_region_is_poisoned(ptr, len) == NULL) + return 1; + char *p = (char *)ptr; char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); - int r = msync(page, (p - page) + len, MS_ASYNC); + int r = syscall(SYS_msync, page, (p - page) + len, MS_ASYNC); if (r < 0) return errno != ENOMEM; return 1; -- cgit 1.4.1 From 75d6a8b7011699c22e6d7c7ad9869b9a850e053b Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 1 Mar 2021 15:33:28 +0100 Subject: fix last commit --- instrumentation/afl-compiler-rt.o.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index dab06177..1151cd52 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1559,10 +1559,10 @@ __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) { // POSIX shenanigan to see if an area is mapped. // If it is mapped as X-only, we have a problem, so maybe we should add a check // to avoid to call it on .text addresses -static int area_is_mapped(void *ptr, size_t len) { +static int area_is_valid(void *ptr, size_t len) { - if (__asan_region_is_poisoned(ptr, len) == NULL) - return 1; + if (__asan_region_is_poisoned(ptr, len)) + return 0; char *p = (char *)ptr; char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); @@ -1577,7 +1577,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { /* u32 i; - if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return; + if (!area_is_valid(ptr1, 32) || !area_is_valid(ptr2, 32)) return; fprintf(stderr, "rtn arg0="); for (i = 0; i < 24; i++) fprintf(stderr, "%02x", ptr1[i]); @@ -1589,7 +1589,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return; + if (!area_is_valid(ptr1, 32) || !area_is_valid(ptr2, 32)) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (k >> 4) ^ (k << 8); @@ -1666,7 +1666,7 @@ static u8 *get_llvm_stdstring(u8 *string) { void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_mapped(stdstring, 32) || !area_is_mapped(cstring, 32)) return; + if (!area_is_valid(stdstring, 32) || !area_is_valid(cstring, 32)) return; __cmplog_rtn_hook(get_gcc_stdstring(stdstring), cstring); @@ -1675,7 +1675,7 @@ void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) { void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_mapped(stdstring1, 32) || !area_is_mapped(stdstring2, 32)) + if (!area_is_valid(stdstring1, 32) || !area_is_valid(stdstring2, 32)) return; __cmplog_rtn_hook(get_gcc_stdstring(stdstring1), @@ -1686,7 +1686,7 @@ void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_mapped(stdstring, 32) || !area_is_mapped(cstring, 32)) return; + if (!area_is_valid(stdstring, 32) || !area_is_valid(cstring, 32)) return; __cmplog_rtn_hook(get_llvm_stdstring(stdstring), cstring); @@ -1695,7 +1695,7 @@ void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) { void __cmplog_rtn_llvm_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_mapped(stdstring1, 32) || !area_is_mapped(stdstring2, 32)) + if (!area_is_valid(stdstring1, 32) || !area_is_valid(stdstring2, 32)) return; __cmplog_rtn_hook(get_llvm_stdstring(stdstring1), -- cgit 1.4.1 From a29b360d55026b43989ab653958bfd86fc854927 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 1 Mar 2021 17:16:34 +0100 Subject: area_is_valid with write --- instrumentation/afl-compiler-rt.o.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 1151cd52..15bc823a 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -123,6 +123,10 @@ static u8 is_persistent; static u8 _is_sancov; +/* Dummy pipe for area_is_valid() */ + +static int dummy_pipe; + /* ensure we kill the child on termination */ void at_exit(int signal) { @@ -476,6 +480,11 @@ static void __afl_map_shm(void) { } if (id_str) { + + if (pipe(dummy_pipe) < 0) { + perror("pipe() failed\n"); + exit(1); + } #ifdef USEMMAP const char * shm_file_path = id_str; @@ -1567,9 +1576,8 @@ static int area_is_valid(void *ptr, size_t len) { char *p = (char *)ptr; char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); - int r = syscall(SYS_msync, page, (p - page) + len, MS_ASYNC); - if (r < 0) return errno != ENOMEM; - return 1; + int r = syscall(dummy_pipe[1], SYS_write, page, (p - page) + len); + return errno != EFAULT; } -- cgit 1.4.1 From 05e2f577f6f510f848661073fcd19c1ef6b9a517 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 1 Mar 2021 17:21:27 +0100 Subject: fix area_is_valid with write --- instrumentation/afl-compiler-rt.o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 15bc823a..1694def6 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -125,7 +125,7 @@ static u8 _is_sancov; /* Dummy pipe for area_is_valid() */ -static int dummy_pipe; +static int dummy_pipe[2]; /* ensure we kill the child on termination */ -- cgit 1.4.1 From 14fd4771475ede994f5731faf0ce19bebfd4034f Mon Sep 17 00:00:00 2001 From: aflpp Date: Mon, 1 Mar 2021 19:03:25 +0100 Subject: better fix for asan? --- instrumentation/afl-compiler-rt.o.c | 95 ++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 27 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 1694def6..15832793 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -34,7 +34,7 @@ #include #include -#include +#include #ifndef __HAIKU__ #include #endif @@ -125,7 +125,7 @@ static u8 _is_sancov; /* Dummy pipe for area_is_valid() */ -static int dummy_pipe[2]; +static int __afl_dummy_fd[2] = {2, 2}; /* ensure we kill the child on termination */ @@ -480,10 +480,11 @@ static void __afl_map_shm(void) { } if (id_str) { - - if (pipe(dummy_pipe) < 0) { - perror("pipe() failed\n"); - exit(1); + + if ((__afl_dummy_fd[0] = open("/dev/null", O_WRONLY)) < 0) { + + if (pipe(__afl_dummy_fd) < 0) { __afl_dummy_fd[0] = 1; } + } #ifdef USEMMAP @@ -1562,7 +1563,9 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { } __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) { + return NULL; + } // POSIX shenanigan to see if an area is mapped. @@ -1570,14 +1573,47 @@ __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) { // to avoid to call it on .text addresses static int area_is_valid(void *ptr, size_t len) { - if (__asan_region_is_poisoned(ptr, len)) - return 0; + void *ret_ptr = __asan_region_is_poisoned(ptr, len); + + if (ret_ptr) { // region is poisoned + + ssize_t ret_diff = ret_ptr - ptr; + + if (ret_diff <= 0) { + + return 0; + + } else { + + return ret_diff; // only partially poisoned + + } + + } - char *p = (char *)ptr; - char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); + int r = syscall(__afl_dummy_fd[0], SYS_write, ptr, len); - int r = syscall(dummy_pipe[1], SYS_write, page, (p - page) + len); - return errno != EFAULT; + if (r <= 0) { // maybe this is going over an asan boundary + + char *p = (char *)ptr; + long page_size = sysconf(_SC_PAGE_SIZE); + char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size; + if (page < p + len) { return 0; } + len -= (p + len - page); + r = syscall(__afl_dummy_fd[0], SYS_write, p, len); + + } + + // partial writes - we return what was written. + if (r > 0) { + + return r; + + } else { + + return 0; + + } } @@ -1585,19 +1621,22 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { /* u32 i; - if (!area_is_valid(ptr1, 32) || !area_is_valid(ptr2, 32)) return; + if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return; fprintf(stderr, "rtn arg0="); - for (i = 0; i < 24; i++) + for (i = 0; i < 32; i++) fprintf(stderr, "%02x", ptr1[i]); fprintf(stderr, " arg1="); - for (i = 0; i < 24; i++) + for (i = 0; i < 32; i++) fprintf(stderr, "%02x", ptr2[i]); fprintf(stderr, "\n"); */ if (unlikely(!__afl_cmp_map)) return; - - if (!area_is_valid(ptr1, 32) || !area_is_valid(ptr2, 32)) return; + int l1, l2; + if ((l1 = area_is_valid(ptr1, 32)) <= 0 || + (l2 = area_is_valid(ptr2, 32)) <= 0) + return; + int len = MIN(l1, l2); uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (k >> 4) ^ (k << 8); @@ -1608,17 +1647,17 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) { __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; - hits = 0; __afl_cmp_map->headers[k].hits = 1; - __afl_cmp_map->headers[k].shape = 31; + __afl_cmp_map->headers[k].shape = len - 1; + hits = 0; } else { hits = __afl_cmp_map->headers[k].hits++; - if (__afl_cmp_map->headers[k].shape < 31) { + if (__afl_cmp_map->headers[k].shape < len) { - __afl_cmp_map->headers[k].shape = 31; + __afl_cmp_map->headers[k].shape = len; } @@ -1626,9 +1665,9 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { hits &= CMP_MAP_RTN_H - 1; __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, - ptr1, 32); + ptr1, len); __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, - ptr2, 32); + ptr2, len); } @@ -1674,7 +1713,8 @@ static u8 *get_llvm_stdstring(u8 *string) { void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_valid(stdstring, 32) || !area_is_valid(cstring, 32)) return; + if (area_is_valid(stdstring, 32) <= 0 || area_is_valid(cstring, 32) <= 0) + return; __cmplog_rtn_hook(get_gcc_stdstring(stdstring), cstring); @@ -1683,7 +1723,7 @@ void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) { void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_valid(stdstring1, 32) || !area_is_valid(stdstring2, 32)) + if (area_is_valid(stdstring1, 32) <= 0 || area_is_valid(stdstring2, 32) <= 0) return; __cmplog_rtn_hook(get_gcc_stdstring(stdstring1), @@ -1694,7 +1734,8 @@ void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_valid(stdstring, 32) || !area_is_valid(cstring, 32)) return; + if (area_is_valid(stdstring, 32) <= 0 || area_is_valid(cstring, 32) <= 0) + return; __cmplog_rtn_hook(get_llvm_stdstring(stdstring), cstring); @@ -1703,7 +1744,7 @@ void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) { void __cmplog_rtn_llvm_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) { if (unlikely(!__afl_cmp_map)) return; - if (!area_is_valid(stdstring1, 32) || !area_is_valid(stdstring2, 32)) + if (area_is_valid(stdstring1, 32) <= 0 || area_is_valid(stdstring2, 32) <= 0) return; __cmplog_rtn_hook(get_llvm_stdstring(stdstring1), -- cgit 1.4.1 From d0a61279b8306ea74de6f4a4a9cebbc7f559a4e1 Mon Sep 17 00:00:00 2001 From: aflpp Date: Mon, 1 Mar 2021 19:15:58 +0100 Subject: write to correct pipe end --- instrumentation/afl-compiler-rt.o.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 15832793..1b21eea1 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -481,9 +481,9 @@ static void __afl_map_shm(void) { if (id_str) { - if ((__afl_dummy_fd[0] = open("/dev/null", O_WRONLY)) < 0) { + if ((__afl_dummy_fd[1] = open("/dev/null", O_WRONLY)) < 0) { - if (pipe(__afl_dummy_fd) < 0) { __afl_dummy_fd[0] = 1; } + if (pipe(__afl_dummy_fd) < 0) { __afl_dummy_fd[1] = 1; } } @@ -1591,7 +1591,7 @@ static int area_is_valid(void *ptr, size_t len) { } - int r = syscall(__afl_dummy_fd[0], SYS_write, ptr, len); + int r = syscall(__afl_dummy_fd[1], SYS_write, ptr, len); if (r <= 0) { // maybe this is going over an asan boundary @@ -1600,7 +1600,7 @@ static int area_is_valid(void *ptr, size_t len) { char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size; if (page < p + len) { return 0; } len -= (p + len - page); - r = syscall(__afl_dummy_fd[0], SYS_write, p, len); + r = syscall(__afl_dummy_fd[1], SYS_write, p, len); } -- cgit 1.4.1 From c269c3977ccb96710a2488b19c72bae51832a827 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 2 Mar 2021 11:38:12 +0100 Subject: fix llvm for unicode strings (hopefully) --- instrumentation/SanitizerCoverageLTO.so.cc | 4 ++-- instrumentation/afl-llvm-dict2file.so.cc | 5 +++-- instrumentation/afl-llvm-lto-instrumentation.so.cc | 4 ++-- instrumentation/compare-transform-pass.so.cc | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 3026abc8..942d5357 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -733,7 +733,7 @@ bool ModuleSanitizerCoverage::instrumentModule( Var->getInitializer())) { HasStr2 = true; - Str2 = Array->getAsString().str(); + Str2 = Array->getRawDataValues().str(); } @@ -809,7 +809,7 @@ bool ModuleSanitizerCoverage::instrumentModule( Var->getInitializer())) { HasStr1 = true; - Str1 = Array->getAsString().str(); + Str1 = Array->getRawDataValues().str(); } diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 19ef15f7..1c365da8 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -357,6 +357,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { StringRef TmpStr; bool HasStr1; getConstantStringInfo(Str1P, TmpStr); + if (TmpStr.empty()) { HasStr1 = false; @@ -403,7 +404,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { dyn_cast(Var->getInitializer())) { HasStr2 = true; - Str2 = Array->getAsString().str(); + Str2 = Array->getRawDataValues().str(); } @@ -479,7 +480,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { dyn_cast(Var->getInitializer())) { HasStr1 = true; - Str1 = Array->getAsString().str(); + Str1 = Array->getRawDataValues().str(); } diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 137bae2c..1f21b917 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -519,7 +519,7 @@ bool AFLLTOPass::runOnModule(Module &M) { Var->getInitializer())) { HasStr2 = true; - Str2 = Array->getAsString().str(); + Str2 = Array->getRawDataValues().str(); } @@ -595,7 +595,7 @@ bool AFLLTOPass::runOnModule(Module &M) { Var->getInitializer())) { HasStr1 = true; - Str1 = Array->getAsString().str(); + Str1 = Array->getRawDataValues().str(); } diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index bd524a69..84301493 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -229,9 +229,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, dyn_cast(Var->getInitializer())) { HasStr2 = true; - Str2 = Array->getAsString(); + Str2 = Array->getRawDataValues(); valueMap[Str2P] = new std::string(Str2.str()); - fprintf(stderr, "glo2 %s\n", Str2.str().c_str()); + // fprintf(stderr, "glo2 %s\n", Str2.str().c_str()); } @@ -254,7 +254,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, Var->getInitializer())) { HasStr1 = true; - Str1 = Array->getAsString(); + Str1 = Array->getRawDataValues(); valueMap[Str1P] = new std::string(Str1.str()); // fprintf(stderr, "glo1 %s\n", Str1.str().c_str()); -- cgit 1.4.1 From 333509bb0a56be9bd2e236f0e2f37d4af2dd7d59 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 2 Mar 2021 16:24:43 +0100 Subject: better unicode support --- docs/Changelog.md | 3 ++- instrumentation/SanitizerCoverageLTO.so.cc | 14 +++++++++----- instrumentation/afl-llvm-dict2file.so.cc | 14 +++++++++----- instrumentation/afl-llvm-lto-instrumentation.so.cc | 14 +++++++++----- instrumentation/compare-transform-pass.so.cc | 11 +++++++++-- 5 files changed, 38 insertions(+), 18 deletions(-) (limited to 'instrumentation') diff --git a/docs/Changelog.md b/docs/Changelog.md index f5742d24..01240b2a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,7 +10,8 @@ sending a mail to . ### Version ++3.11a (dev) - afl-cc - - fixed for a crash that can occur with ASAN + CMPLOG together + - fixed for a crash that can occur with ASAN + CMPLOG together plus + better support for unicode (thanks to @stbergmann for reporting!) ### Version ++3.10c (release) - Mac OS ARM64 support diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 942d5357..849b6eef 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -872,17 +872,21 @@ bool ModuleSanitizerCoverage::instrumentModule( // was not already added if (!isMemcmp) { - if (addedNull == false) { + if (addedNull == false && thestring[optLen - 1] != '\0') { thestring.append("\0", 1); // add null byte optLen++; } - // ensure we do not have garbage - size_t offset = thestring.find('\0', 0); - if (offset + 1 < optLen) optLen = offset + 1; - thestring = thestring.substr(0, optLen); + if (!isStdString) { + + // ensure we do not have garbage + size_t offset = thestring.find('\0', 0); + if (offset + 1 < optLen) optLen = offset + 1; + thestring = thestring.substr(0, optLen); + + } } diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 1c365da8..885aa035 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -543,17 +543,21 @@ bool AFLdict2filePass::runOnModule(Module &M) { // was not already added if (!isMemcmp) { - if (addedNull == false) { + if (addedNull == false && thestring[optLen - 1] != '\0') { thestring.append("\0", 1); // add null byte optLen++; } - // ensure we do not have garbage - size_t offset = thestring.find('\0', 0); - if (offset + 1 < optLen) optLen = offset + 1; - thestring = thestring.substr(0, optLen); + if (!isStdString) { + + // ensure we do not have garbage + size_t offset = thestring.find('\0', 0); + if (offset + 1 < optLen) optLen = offset + 1; + thestring = thestring.substr(0, optLen); + + } } diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 1f21b917..ef270a1f 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -658,17 +658,21 @@ bool AFLLTOPass::runOnModule(Module &M) { // was not already added if (!isMemcmp) { - if (addedNull == false) { + if (addedNull == false && thestring[optLen - 1] != '\0') { thestring.append("\0", 1); // add null byte optLen++; } - // ensure we do not have garbage - size_t offset = thestring.find('\0', 0); - if (offset + 1 < optLen) optLen = offset + 1; - thestring = thestring.substr(0, optLen); + if (!isStdString) { + + // ensure we do not have garbage + size_t offset = thestring.find('\0', 0); + if (offset + 1 < optLen) optLen = offset + 1; + thestring = thestring.substr(0, optLen); + + } } diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 84301493..a85522a2 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -421,14 +421,21 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } // add null termination character implicit in c strings - TmpConstStr.append("\0", 1); + if (TmpConstStr[TmpConstStr.length() - 1] != 0) { + + TmpConstStr.append("\0", 1); + + } // in the unusual case the const str has embedded null // characters, the string comparison functions should terminate // at the first null - if (!isMemcmp) + if (!isMemcmp) { + TmpConstStr.assign(TmpConstStr, 0, TmpConstStr.find('\0') + 1); + } + constStrLen = TmpConstStr.length(); // prefer use of StringRef (in comparison to std::string a StringRef has // built-in runtime bounds checking, which makes debugging easier) -- cgit 1.4.1 From 0e736276e6421162da0070e98d17d25b9a679de0 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 11:00:54 +0100 Subject: restore correct CTX behaviour in llvm mode --- instrumentation/afl-llvm-pass.so.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 16fd9c94..87267e35 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -354,7 +354,8 @@ bool AFLCoverage::runOnModule(Module &M) { // if yes we store a context ID for this function in the global var if (has_calls) { - ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); + Value *NewCtx = IRB.CreateXor( + PrevCtx, ConstantInt::get(Int32Ty, AFL_R(map_size))); StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); StoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -- cgit 1.4.1 From 1e76079e93f5b4a9729367dd982d632013669bc5 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 11:32:32 +0100 Subject: llvm mode CALLER mode --- instrumentation/README.ctx.md | 22 +++++++++++++++++++--- instrumentation/afl-llvm-pass.so.cc | 18 ++++++++++-------- src/afl-cc.c | 37 +++++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 23 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.ctx.md b/instrumentation/README.ctx.md index caf2c09a..ffcce0a9 100644 --- a/instrumentation/README.ctx.md +++ b/instrumentation/README.ctx.md @@ -4,14 +4,19 @@ This is an LLVM-based implementation of the context sensitive branch coverage. -Basically every function gets its own ID and that ID is combined with the -edges of the called functions. +Basically every function gets its own ID and, every time that an edge is logged, +all the IDs in the callstack are hashed and combined with the edge transition +hash to augment the classic edge coverage with the information about the +calling context. So if both function A and function B call a function C, the coverage collected in C will be different. In math the coverage is collected as follows: -`map[current_location_ID ^ previous_location_ID >> 1 ^ previous_callee_ID] += 1` +`map[current_location_ID ^ previous_location_ID >> 1 ^ hash_callstack_IDs] += 1` + +The callstack hash is produced XOR-ing the function IDs to avoid explosion with +recusrsive functions. ## Usage @@ -20,3 +25,14 @@ Set the `AFL_LLVM_INSTRUMENT=CTX` or `AFL_LLVM_CTX=1` environment variable. It is highly recommended to increase the MAP_SIZE_POW2 definition in config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur. + +## Caller Branch Coverage + +If the context sensitive coverage introduces too may collisions becoming +decremental, the user can choose to augment edge coverage with just the +called function ID, instead of the entire callstack hash. + +In math the coverage is collected as follows: +`map[current_location_ID ^ previous_location_ID >> 1 ^ previous_callee_ID] += 1` + +Set the `AFL_LLVM_INSTRUMENT=CALLER` or `AFL_LLVM_CALLER=1` environment variable. diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 87267e35..d06d3201 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -84,7 +84,7 @@ class AFLCoverage : public ModulePass { uint32_t ngram_size = 0; uint32_t map_size = MAP_SIZE; uint32_t function_minimum_size = 1; - char * ctx_str = NULL, *skip_nozero = NULL; + char * ctx_str = NULL, *caller_str = NULL, *skip_nozero = NULL; }; @@ -187,6 +187,7 @@ bool AFLCoverage::runOnModule(Module &M) { char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); ctx_str = getenv("AFL_LLVM_CTX"); + caller_str = getenv("AFL_LLVM_CALLER"); #ifdef AFL_HAVE_VECTOR_INTRINSICS /* Decide previous location vector size (must be a power of two) */ @@ -240,7 +241,7 @@ bool AFLCoverage::runOnModule(Module &M) { GlobalVariable *AFLPrevLoc; GlobalVariable *AFLContext = NULL; - if (ctx_str) + if (ctx_str || caller_str) #if defined(__ANDROID__) || defined(__HAIKU__) AFLContext = new GlobalVariable( M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx"); @@ -318,7 +319,7 @@ bool AFLCoverage::runOnModule(Module &M) { IRBuilder<> IRB(&(*IP)); // Context sensitive coverage - if (ctx_str && &BB == &F.getEntryBlock()) { + if ((ctx_str || caller_str) && &BB == &F.getEntryBlock()) { // load the context ID of the previous function and write to to a local // variable on the stack @@ -354,8 +355,9 @@ bool AFLCoverage::runOnModule(Module &M) { // if yes we store a context ID for this function in the global var if (has_calls) { - Value *NewCtx = IRB.CreateXor( - PrevCtx, ConstantInt::get(Int32Ty, AFL_R(map_size))); + Value *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); + if (ctx_str) + NewCtx = IRB.CreateXor(PrevCtx, NewCtx); StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); StoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); @@ -412,7 +414,7 @@ bool AFLCoverage::runOnModule(Module &M) { // in CTX mode we have to restore the original context for the caller - // she might be calling other functions which need the correct CTX - if (ctx_str && has_calls) { + if ((ctx_str || caller_str) && has_calls) { Instruction *Inst = BB.getTerminator(); if (isa(Inst) || isa(Inst)) { @@ -459,7 +461,7 @@ bool AFLCoverage::runOnModule(Module &M) { #endif PrevLocTrans = PrevLoc; - if (ctx_str) + if (ctx_str || caller_str) PrevLocTrans = IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty); else @@ -546,7 +548,7 @@ bool AFLCoverage::runOnModule(Module &M) { // in CTX mode we have to restore the original context for the caller - // she might be calling other functions which need the correct CTX. // Currently this is only needed for the Ubuntu clang-6.0 bug - if (ctx_str && has_calls) { + if ((ctx_str || caller_str) && has_calls) { Instruction *Inst = BB.getTerminator(); if (isa(Inst) || isa(Inst)) { diff --git a/src/afl-cc.c b/src/afl-cc.c index c3910e6d..9cf02059 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -73,7 +73,8 @@ enum { INSTRUMENT_GCC = 6, INSTRUMENT_CLANG = 7, INSTRUMENT_OPT_CTX = 8, - INSTRUMENT_OPT_NGRAM = 16 + INSTRUMENT_OPT_NGRAM = 16, + INSTRUMENT_OPT_CALLER = 32, }; @@ -1273,7 +1274,8 @@ int main(int argc, char **argv, char **envp) { } if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; - + if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + if (getenv("AFL_LLVM_NGRAM_SIZE")) { instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; @@ -1387,6 +1389,13 @@ int main(int argc, char **argv, char **envp) { setenv("AFL_LLVM_CTX", "1", 1); } + + if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) { + + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + setenv("AFL_LLVM_CALLER", "1", 1); + + } if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { @@ -1420,6 +1429,11 @@ int main(int argc, char **argv, char **envp) { } } + + if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && + (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) { + FATAL("you cannot set CTX and CALLER together"); + } if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && (compiler_mode == LLVM || compiler_mode == UNSET)) { @@ -1770,7 +1784,7 @@ int main(int argc, char **argv, char **envp) { } if (instrument_opt_mode && compiler_mode != LLVM) - FATAL("CTX and NGRAM can only be used in LLVM mode"); + FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode"); if (!instrument_opt_mode) { @@ -1780,15 +1794,14 @@ int main(int argc, char **argv, char **envp) { } else { - if (instrument_opt_mode == INSTRUMENT_OPT_CTX) - - ptr = alloc_printf("%s + CTX", instrument_mode_string[instrument_mode]); - else if (instrument_opt_mode == INSTRUMENT_OPT_NGRAM) - ptr = alloc_printf("%s + NGRAM-%u", - instrument_mode_string[instrument_mode], ngram_size); - else - ptr = alloc_printf("%s + CTX + NGRAM-%u", - instrument_mode_string[instrument_mode], ngram_size); + char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); + ptr = alloc_printf("%s%s%s%s", instrument_mode_string[instrument_mode], + (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", + (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", + (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "" + ); + + ck_free(ptr2); } -- cgit 1.4.1 From 8f538e77ed75256466e8b97d43d0c32948cb9931 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 11:33:51 +0100 Subject: code format --- instrumentation/afl-llvm-pass.so.cc | 5 ++--- src/afl-cc.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index d06d3201..33898aec 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -356,9 +356,8 @@ bool AFLCoverage::runOnModule(Module &M) { if (has_calls) { Value *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); - if (ctx_str) - NewCtx = IRB.CreateXor(PrevCtx, NewCtx); - StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); + if (ctx_str) NewCtx = IRB.CreateXor(PrevCtx, NewCtx); + StoreInst *StoreCtx = IRB.CreateStore(NewCtx, AFLContext); StoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); diff --git a/src/afl-cc.c b/src/afl-cc.c index 9cf02059..0c689286 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1275,7 +1275,7 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER; - + if (getenv("AFL_LLVM_NGRAM_SIZE")) { instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; @@ -1389,7 +1389,7 @@ int main(int argc, char **argv, char **envp) { setenv("AFL_LLVM_CTX", "1", 1); } - + if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) { instrument_opt_mode |= INSTRUMENT_OPT_CALLER; @@ -1429,10 +1429,12 @@ int main(int argc, char **argv, char **envp) { } } - + if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) { + FATAL("you cannot set CTX and CALLER together"); + } if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && @@ -1795,12 +1797,12 @@ int main(int argc, char **argv, char **envp) { } else { char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); - ptr = alloc_printf("%s%s%s%s", instrument_mode_string[instrument_mode], + ptr = alloc_printf( + "%s%s%s%s", instrument_mode_string[instrument_mode], (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", - (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "" - ); - + (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : ""); + ck_free(ptr2); } -- cgit 1.4.1 From 02f33192560a972f02fad72e051b9f884635d7ff Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 12:23:19 +0100 Subject: only initialize afl-compiler-rt once --- instrumentation/afl-compiler-rt.o.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 1b21eea1..c9577a55 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -242,6 +242,10 @@ static void __afl_map_shm_fuzz() { static void __afl_map_shm(void) { + static u32 __afl_already_initialized_shm = 0; + if (__afl_already_initialized_shm) return; + __afl_already_initialized_shm = 1; + // if we are not running in afl ensure the map exists if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; } @@ -742,6 +746,10 @@ static void __afl_start_snapshots(void) { static void __afl_start_forkserver(void) { + static u32 __afl_already_initialized_forkserver = 0; + if (__afl_already_initialized_forkserver) return; + __afl_already_initialized_forkserver = 1; + struct sigaction orig_action; sigaction(SIGTERM, NULL, &orig_action); old_sigterm_handler = orig_action.sa_handler; @@ -1071,6 +1079,10 @@ __attribute__((constructor(CTOR_PRIO))) void __afl_auto_early(void) { __attribute__((constructor(1))) void __afl_auto_second(void) { + static u32 __afl_already_initialized_second = 0; + if (__afl_already_initialized_second) return; + __afl_already_initialized_second = 1; + if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; u8 *ptr; @@ -1102,6 +1114,10 @@ __attribute__((constructor(1))) void __afl_auto_second(void) { __attribute__((constructor(0))) void __afl_auto_first(void) { + static u32 __afl_already_initialized_first = 0; + if (__afl_already_initialized_first) return; + __afl_already_initialized_first = 1; + if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; u8 *ptr; -- cgit 1.4.1 From 96c526cb78512737a980726dd32c95593edb8cd1 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 14:04:40 +0100 Subject: fix caller/ctx change, support dlopen in afl-compiler-rt --- docs/Changelog.md | 10 ++++ instrumentation/LLVMInsTrim.so.cc | 29 ++++----- instrumentation/afl-compiler-rt.o.c | 114 +++++++++++++++++++++++++++++++----- src/afl-cc.c | 31 ++++++---- 4 files changed, 144 insertions(+), 40 deletions(-) (limited to 'instrumentation') diff --git a/docs/Changelog.md b/docs/Changelog.md index 1be41267..6fe3517a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,16 @@ sending a mail to . - afl-cc - fixed a crash that can occur with ASAN + CMPLOG together plus better support for unicode (thanks to @stbergmann for reporting!) + - handle erroneous setups in which multiple afl-compiler-rt are + compiled into the target. This now also supports dlopen instrumented + libs loaded before the forkserver. + - Renamed CTX to CALLER, added correct/real CTX implemenation to CLASSIC + - qemu_mode + - added AFL_QEMU_EXCLUDE_RANGES env by @realmadsci, thanks! + - if no new/updated checkout is wanted, build with: + NO_CHECKOUT=1 ./build_qemu_support.sh + - we no longer perform a "git drop" + ### Version ++3.10c (release) - Mac OS ARM64 support diff --git a/instrumentation/LLVMInsTrim.so.cc b/instrumentation/LLVMInsTrim.so.cc index 948f8f3a..f0de6536 100644 --- a/instrumentation/LLVMInsTrim.so.cc +++ b/instrumentation/LLVMInsTrim.so.cc @@ -135,7 +135,7 @@ struct InsTrim : public ModulePass { unsigned int PrevLocSize = 0; char * ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); - char *ctx_str = getenv("AFL_LLVM_CTX"); + char *caller_str = getenv("AFL_LLVM_CALLER"); #ifdef AFL_HAVE_VECTOR_INTRINSICS unsigned int ngram_size = 0; @@ -197,9 +197,9 @@ struct InsTrim : public ModulePass { GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); GlobalVariable *AFLPrevLoc; GlobalVariable *AFLContext = NULL; - LoadInst * PrevCtx = NULL; // for CTX sensitive coverage + LoadInst * PrevCaller = NULL; // for CALLER sensitive coverage - if (ctx_str) + if (caller_str) #if defined(__ANDROID__) || defined(__HAIKU__) AFLContext = new GlobalVariable( M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx"); @@ -398,11 +398,11 @@ struct InsTrim : public ModulePass { unsigned int cur_loc; // Context sensitive coverage - if (ctx_str && &BB == &F.getEntryBlock()) { + if (caller_str && &BB == &F.getEntryBlock()) { - PrevCtx = IRB.CreateLoad(AFLContext); - PrevCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); + PrevCaller = IRB.CreateLoad(AFLContext); + PrevCaller->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); // does the function have calls? and is any of the calls larger than // one basic block? @@ -441,7 +441,7 @@ struct InsTrim : public ModulePass { } - } // END of ctx_str + } // END of caller_str if (MarkSetOpt && MS.find(&BB) == MS.end()) { continue; } @@ -485,9 +485,9 @@ struct InsTrim : public ModulePass { #endif PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty()); - if (ctx_str) + if (caller_str) PrevLocTrans = - IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty); + IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCaller), Int32Ty); /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); @@ -535,16 +535,17 @@ struct InsTrim : public ModulePass { IRB.CreateStore(Incr, MapPtrIdx) ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - if (ctx_str && has_calls) { + if (caller_str && has_calls) { - // in CTX mode we have to restore the original context for the + // in CALLER mode we have to restore the original context for the // caller - she might be calling other functions which need the - // correct CTX + // correct CALLER Instruction *Inst = BB.getTerminator(); if (isa(Inst) || isa(Inst)) { IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + StoreInst * RestoreCtx = + Post_IRB.CreateStore(PrevCaller, AFLContext); RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c9577a55..e3aa787f 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -123,6 +123,17 @@ static u8 is_persistent; static u8 _is_sancov; +/* Debug? */ + +static u32 __afl_debug; + +/* Already initialized markers */ + +static u32 __afl_already_initialized_shm; +static u32 __afl_already_initialized_forkserver; +static u32 __afl_already_initialized_first; +static u32 __afl_already_initialized_second; + /* Dummy pipe for area_is_valid() */ static int __afl_dummy_fd[2] = {2, 2}; @@ -176,7 +187,7 @@ static void __afl_map_shm_fuzz() { char *id_str = getenv(SHM_FUZZ_ENV_VAR); - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "DEBUG: fuzzcase shmem %s\n", id_str ? id_str : "none"); @@ -222,7 +233,7 @@ static void __afl_map_shm_fuzz() { __afl_fuzz_len = (u32 *)map; __afl_fuzz_ptr = map + sizeof(u32); - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "DEBUG: successfully got fuzzing shared memory\n"); @@ -242,7 +253,6 @@ static void __afl_map_shm_fuzz() { static void __afl_map_shm(void) { - static u32 __afl_already_initialized_shm = 0; if (__afl_already_initialized_shm) return; __afl_already_initialized_shm = 1; @@ -303,7 +313,7 @@ static void __afl_map_shm(void) { 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 (getenv("AFL_DEBUG")) + if (__afl_debug) fprintf(stderr, "DEBUG: id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_map_addr 0x%llx, MAP_SIZE %u, __afl_final_loc %u, " @@ -359,17 +369,18 @@ static void __afl_map_shm(void) { } + close(shm_fd); + if (shm_base == MAP_FAILED) { - close(shm_fd); shm_fd = -1; - fprintf(stderr, "mmap() failed\n"); + perror("mmap for map"); + if (__afl_map_addr) send_forkserver_error(FS_ERROR_MAP_ADDR); else send_forkserver_error(FS_ERROR_MMAP); - perror("mmap for map"); exit(2); @@ -476,7 +487,7 @@ static void __afl_map_shm(void) { id_str = getenv(CMPLOG_SHM_ENV_VAR); - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "DEBUG: cmplog id_str %s\n", id_str == NULL ? "" : id_str); @@ -541,6 +552,58 @@ static void __afl_map_shm(void) { } +/* unmap SHM. */ + +static void __afl_unmap_shm(void) { + + if (!__afl_already_initialized_shm) return; + + char *id_str = getenv(SHM_ENV_VAR); + + if (id_str) { + +#ifdef USEMMAP + + munmap((void *)__afl_area_ptr, __afl_map_size); + +#else + + shmdt((void *)__afl_area_ptr); + +#endif + + } else if ((!__afl_area_ptr || __afl_area_ptr == __afl_area_initial) && + + __afl_map_addr) { + + munmap((void *)__afl_map_addr, __afl_map_size); + + } + + __afl_area_ptr = __afl_area_ptr_dummy; + + id_str = getenv(CMPLOG_SHM_ENV_VAR); + + if (id_str) { + +#ifdef USEMMAP + + munmap((void *)__afl_cmp_map, __afl_map_size); + +#else + + shmdt((void *)__afl_cmp_map); + +#endif + + __afl_cmp_map = NULL; + + } + + __afl_already_initialized_shm = 0; + +} + #ifdef __linux__ static void __afl_start_snapshots(void) { @@ -569,7 +632,7 @@ static void __afl_start_snapshots(void) { if (read(FORKSRV_FD, &was_killed, 4) != 4) { _exit(1); } - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "target forkserver recv: %08x\n", was_killed); @@ -746,7 +809,6 @@ static void __afl_start_snapshots(void) { static void __afl_start_forkserver(void) { - static u32 __afl_already_initialized_forkserver = 0; if (__afl_already_initialized_forkserver) return; __afl_already_initialized_forkserver = 1; @@ -800,7 +862,7 @@ static void __afl_start_forkserver(void) { if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "target forkserver recv: %08x\n", was_killed); @@ -1035,7 +1097,7 @@ void __afl_manual_init(void) { __afl_sharedmem_fuzzing = 0; if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_ptr_dummy; - if (getenv("AFL_DEBUG")) + if (__afl_debug) fprintf(stderr, "DEBUG: disabled instrumentation because of " "AFL_DISABLE_LLVM_INSTRUMENTATION\n"); @@ -1079,10 +1141,11 @@ __attribute__((constructor(CTOR_PRIO))) void __afl_auto_early(void) { __attribute__((constructor(1))) void __afl_auto_second(void) { - static u32 __afl_already_initialized_second = 0; if (__afl_already_initialized_second) return; __afl_already_initialized_second = 1; + if (getenv("AFL_DEBUG")) { __afl_debug = 1; } + if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; u8 *ptr; @@ -1114,7 +1177,6 @@ __attribute__((constructor(1))) void __afl_auto_second(void) { __attribute__((constructor(0))) void __afl_auto_first(void) { - static u32 __afl_already_initialized_first = 0; if (__afl_already_initialized_first) return; __afl_already_initialized_first = 1; @@ -1198,7 +1260,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { _is_sancov = 1; - if (getenv("AFL_DEBUG")) { + if (__afl_debug) { fprintf(stderr, "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n", @@ -1235,6 +1297,28 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { } + if (__afl_debug) { + + fprintf(stderr, + "Done __sanitizer_cov_trace_pc_guard_init: __afl_final_loc = %u\n", + __afl_final_loc); + + } + + if (__afl_already_initialized_shm && __afl_final_loc > __afl_map_size) { + + if (__afl_debug) { + + fprintf(stderr, "Reinit shm necessary (+%u)\n", + __afl_final_loc - __afl_map_size); + + } + + __afl_unmap_shm(); + __afl_map_shm(); + + } + } ///// CmpLog instrumentation diff --git a/src/afl-cc.c b/src/afl-cc.c index 0c689286..ab794877 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -89,7 +89,7 @@ char instrument_mode_string[18][18] = { "GCC", "CLANG", "CTX", - "", + "CALLER", "", "", "", @@ -1514,12 +1514,13 @@ int main(int argc, char **argv, char **envp) { " CLASSIC %s no yes module yes yes " "yes\n" " - NORMAL\n" + " - CALLER\n" " - CTX\n" " - NGRAM-{2-16}\n" " INSTRIM no yes module yes yes " " yes\n" " - NORMAL\n" - " - CTX\n" + " - CALLER\n" " - NGRAM-{2-16}\n" " [GCC_PLUGIN] gcc plugin: %s%s\n" " CLASSIC DEFAULT no yes no no no " @@ -1566,7 +1567,10 @@ int main(int argc, char **argv, char **envp) { NATIVE_MSG " CLASSIC: decision target instrumentation (README.llvm.md)\n" - " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" + " CALLER: CLASSIC + single callee context " + "(instrumentation/README.ctx.md)\n" + " CTX: CLASSIC + full callee context " + "(instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " "((instrumentation/README.ngram.md)\n" " INSTRIM: Dominator tree (for LLVM <= 6.0) " @@ -1660,15 +1664,17 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " "mutator)\n" " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" - " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CTX, NGRAM-2 ... " - "NGRAM-16\n" + " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, " + "NGRAM-2 ..-16\n" " You can also use the old environment variables instead:\n" " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " "(option to INSTRIM)\n" - " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " - "INSTRIM)\n" + " AFL_LLVM_CALLER: use single context sensitive coverage (for " + "CLASSIC)\n" + " AFL_LLVM_CTX: use full context sensitive coverage (for " + "CLASSIC)\n" " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " "CLASSIC & INSTRIM)\n"); @@ -1814,11 +1820,14 @@ int main(int argc, char **argv, char **envp) { "(requires LLVM 11 or higher)"); #endif - if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC && - instrument_mode != INSTRUMENT_CFG) + if (instrument_opt_mode && instrument_mode == INSTRUMENT_CFG && + instrument_opt_mode & INSTRUMENT_OPT_CTX) + FATAL("CFG instrumentation mode supports NGRAM and CALLER, but not CTX."); + else if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) + // we will drop CFG/INSTRIM in the future so do not advertise FATAL( - "CTX and NGRAM instrumentation options can only be used with LLVM and " - "CFG or CLASSIC instrumentation modes!"); + "CALLER, CTX and NGRAM instrumentation options can only be used with " + "the LLVM CLASSIC instrumentation mode."); if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) FATAL( -- cgit 1.4.1 From 79d75d8e42e5adf64e149ab6e1fe197cb1d4f303 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 14:19:00 +0100 Subject: even support dlopen instrumented libs after the forkserver --- docs/Changelog.md | 5 +++-- instrumentation/afl-compiler-rt.o.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) (limited to 'instrumentation') diff --git a/docs/Changelog.md b/docs/Changelog.md index 6fe3517a..b1c991ff 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -15,8 +15,9 @@ sending a mail to . - fixed a crash that can occur with ASAN + CMPLOG together plus better support for unicode (thanks to @stbergmann for reporting!) - handle erroneous setups in which multiple afl-compiler-rt are - compiled into the target. This now also supports dlopen instrumented - libs loaded before the forkserver. + compiled into the target. This now also supports dlopen + instrumented libs loaded before the forkserver and even after the + forkserver is started (then with collisions though) - Renamed CTX to CALLER, added correct/real CTX implemenation to CLASSIC - qemu_mode - added AFL_QEMU_EXCLUDE_RANGES env by @realmadsci, thanks! diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index e3aa787f..87bf6486 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1263,8 +1263,10 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { if (__afl_debug) { fprintf(stderr, - "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n", - start, stop, (unsigned long)(stop - start)); + "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges) " + "after_fs=%u\n", + start, stop, (unsigned long)(stop - start), + __afl_already_initialized_forkserver); } @@ -1280,6 +1282,36 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { } + /* instrumented code is loaded *after* our forkserver is up. this is a + problem. We cannot prevent collisions then :( */ + if (__afl_already_initialized_forkserver && + __afl_final_loc + 1 + stop - start > __afl_map_size) { + + if (__afl_debug) + fprintf(stderr, "Warning: new instrumneted code after the forkserver!\n"); + __afl_final_loc = 2; + + if (1 + stop - start > __afl_map_size) { + + *(start++) = ++__afl_final_loc; + + while (start < stop) { + + if (R(100) < inst_ratio) + *start = ++__afl_final_loc % __afl_map_size; + else + *start = 0; + + start++; + + } + + return; + + } + + } + /* 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). */ -- cgit 1.4.1 From 0aa93afeb82c610fd39b5dd4a3dd7482b9f86b1e Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 14:50:26 +0100 Subject: vectorial top-k CTX first implementation --- instrumentation/LLVMInsTrim.so.cc | 2 +- instrumentation/afl-compiler-rt.o.c | 4 +- instrumentation/afl-llvm-pass.so.cc | 154 ++++++++++++++++++++++++---- instrumentation/llvm-alternative-coverage.h | 21 ++++ instrumentation/llvm-ngram-coverage.h | 18 ---- src/afl-cc.c | 2 +- 6 files changed, 162 insertions(+), 39 deletions(-) create mode 100644 instrumentation/llvm-alternative-coverage.h delete mode 100644 instrumentation/llvm-ngram-coverage.h (limited to 'instrumentation') diff --git a/instrumentation/LLVMInsTrim.so.cc b/instrumentation/LLVMInsTrim.so.cc index 948f8f3a..83f11411 100644 --- a/instrumentation/LLVMInsTrim.so.cc +++ b/instrumentation/LLVMInsTrim.so.cc @@ -38,7 +38,7 @@ typedef long double max_align_t; #include "MarkNodes.h" #include "afl-llvm-common.h" -#include "llvm-ngram-coverage.h" +#include "llvm-alternative-coverage.h" #include "config.h" #include "debug.h" diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c9577a55..d583e246 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -20,7 +20,7 @@ #include "config.h" #include "types.h" #include "cmplog.h" -#include "llvm-ngram-coverage.h" +#include "llvm-alternative-coverage.h" #include #include @@ -97,10 +97,12 @@ int __afl_selective_coverage_temp = 1; #if defined(__ANDROID__) || defined(__HAIKU__) PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; +PREV_LOC_T __afl_prev_caller[CTX_MAX_K]; u32 __afl_prev_ctx; u32 __afl_cmp_counter; #else __thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; +__thread PREV_LOC_T __afl_prev_caller[CTX_MAX_K]; __thread u32 __afl_prev_ctx; __thread u32 __afl_cmp_counter; #endif diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 33898aec..c58e9d95 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -62,7 +62,7 @@ typedef long double max_align_t; #endif #include "afl-llvm-common.h" -#include "llvm-ngram-coverage.h" +#include "llvm-alternative-coverage.h" using namespace llvm; @@ -82,6 +82,7 @@ class AFLCoverage : public ModulePass { protected: uint32_t ngram_size = 0; + uint32_t ctx_k = 0; uint32_t map_size = MAP_SIZE; uint32_t function_minimum_size = 1; char * ctx_str = NULL, *caller_str = NULL, *skip_nozero = NULL; @@ -183,12 +184,17 @@ bool AFLCoverage::runOnModule(Module &M) { skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); unsigned PrevLocSize = 0; + unsigned PrevCallerSize = 0; char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); + char *ctx_k_str = getenv("AFL_LLVM_CTX_K"); + if (!ctx_k_str) ctx_k_str = getenv("AFL_CTX_K"); ctx_str = getenv("AFL_LLVM_CTX"); caller_str = getenv("AFL_LLVM_CALLER"); + bool instrument_ctx = ctx_str || caller_str; + #ifdef AFL_HAVE_VECTOR_INTRINSICS /* Decide previous location vector size (must be a power of two) */ VectorType *PrevLocTy = NULL; @@ -205,6 +211,25 @@ bool AFLCoverage::runOnModule(Module &M) { if (ngram_size) PrevLocSize = ngram_size - 1; else + PrevLocSize = 1; + + /* Decide K-ctx vector size (must be a power of two) */ + VectorType *PrevCallerTy = NULL; + + if (ctx_k_str) + if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 2 || + ctx_k > CTX_MAX_K) + FATAL("Bad value of AFL_CTX_K (must be between 2 and CTX_MAX_K (%u))", CTX_MAX_K); + + if (ctx_k == 1) { + ctx_k = 0; + instrument_ctx = true; + caller_str = ctx_k_str; // Enable CALLER instead + } + if (ctx_k) { + PrevCallerSize = ctx_k; + instrument_ctx = true; + } #else if (ngram_size_str) #ifndef LLVM_VERSION_PATCH @@ -218,8 +243,20 @@ bool AFLCoverage::runOnModule(Module &M) { "%d.%d.%d!", LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH); #endif + if (ctx_k_str) + #ifndef LLVM_VERSION_PATCH + FATAL( + "Sorry, K-CTX branch coverage is not supported with llvm version " + "%d.%d.%d!", + LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0); + #else + FATAL( + "Sorry, K-CTX branch coverage is not supported with llvm version " + "%d.%d.%d!", + LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH); + #endif + PrevLocSize = 1; #endif - PrevLocSize = 1; #ifdef AFL_HAVE_VECTOR_INTRINSICS int PrevLocVecSize = PowerOf2Ceil(PrevLocSize); @@ -232,6 +269,17 @@ bool AFLCoverage::runOnModule(Module &M) { ); #endif +#ifdef AFL_HAVE_VECTOR_INTRINSICS + int PrevCallerVecSize = PowerOf2Ceil(PrevCallerSize); + if (ctx_k) + PrevCallerTy = VectorType::get(IntLocTy, PrevCallerVecSize + #if LLVM_VERSION_MAJOR >= 12 + , + false + #endif + ); +#endif + /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -239,6 +287,7 @@ bool AFLCoverage::runOnModule(Module &M) { new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); GlobalVariable *AFLPrevLoc; + GlobalVariable *AFLPrevCaller; GlobalVariable *AFLContext = NULL; if (ctx_str || caller_str) @@ -275,6 +324,30 @@ bool AFLCoverage::runOnModule(Module &M) { GlobalVariable::GeneralDynamicTLSModel, 0, false); #endif +#ifdef AFL_HAVE_VECTOR_INTRINSICS + if (ctx_k) + #if defined(__ANDROID__) || defined(__HAIKU__) + AFLPrevCaller = new GlobalVariable( + M, PrevCallerTy, /* isConstant */ false, GlobalValue::ExternalLinkage, + /* Initializer */ nullptr, "__afl_prev_caller"); + #else + AFLPrevCaller = new GlobalVariable( + M, PrevCallerTy, /* isConstant */ false, GlobalValue::ExternalLinkage, + /* Initializer */ nullptr, "__afl_prev_caller", + /* InsertBefore */ nullptr, GlobalVariable::GeneralDynamicTLSModel, + /* AddressSpace */ 0, /* IsExternallyInitialized */ false); + #endif + else +#endif +#if defined(__ANDROID__) || defined(__HAIKU__) + AFLPrevCaller = new GlobalVariable( + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller"); +#else + AFLPrevCaller = new GlobalVariable( + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller", 0, + GlobalVariable::GeneralDynamicTLSModel, 0, false); +#endif + #ifdef AFL_HAVE_VECTOR_INTRINSICS /* Create the vector shuffle mask for updating the previous block history. Note that the first element of the vector will store cur_loc, so just set @@ -289,13 +362,24 @@ bool AFLCoverage::runOnModule(Module &M) { PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize)); Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle); + + SmallVector PrevCallerShuffle = {UndefValue::get(Int32Ty)}; + + for (unsigned I = 0; I < PrevCallerSize - 1; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); + + for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); + + Constant *PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); #endif // other constants we need ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *One = ConstantInt::get(Int8Ty, 1); - LoadInst *PrevCtx = NULL; // CTX sensitive coverage + Value *PrevCtx = NULL; // CTX sensitive coverage + LoadInst *PrevCaller = NULL; // K-CTX coverage /* Instrument all the things! */ @@ -319,12 +403,21 @@ bool AFLCoverage::runOnModule(Module &M) { IRBuilder<> IRB(&(*IP)); // Context sensitive coverage - if ((ctx_str || caller_str) && &BB == &F.getEntryBlock()) { + if (instrument_ctx && &BB == &F.getEntryBlock()) { - // load the context ID of the previous function and write to to a local - // variable on the stack - PrevCtx = IRB.CreateLoad(AFLContext); - PrevCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); +#ifdef AFL_HAVE_VECTOR_INTRINSICS + if (ctx_k) { + PrevCaller = IRB.CreateLoad(AFLPrevCaller); + PrevCaller->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + PrevCtx = IRB.CreateZExt(IRB.CreateXorReduce(PrevCaller), IRB.getInt32Ty()); + } else +#endif + { + // load the context ID of the previous function and write to to a local variable on the stack + LoadInst* PrevCtxLoad = IRB.CreateLoad(AFLContext); + PrevCtxLoad->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + PrevCtx = PrevCtxLoad; + } // does the function have calls? and is any of the calls larger than one // basic block? @@ -356,10 +449,22 @@ bool AFLCoverage::runOnModule(Module &M) { if (has_calls) { Value *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); - if (ctx_str) NewCtx = IRB.CreateXor(PrevCtx, NewCtx); - StoreInst *StoreCtx = IRB.CreateStore(NewCtx, AFLContext); - StoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); +#ifdef AFL_HAVE_VECTOR_INTRINSICS + if (ctx_k) { + Value *ShuffledPrevCaller = IRB.CreateShuffleVector( + PrevCaller, UndefValue::get(PrevCallerTy), PrevCallerShuffleMask); + Value *UpdatedPrevCaller = IRB.CreateInsertElement(ShuffledPrevCaller, NewCtx, (uint64_t)0); + + StoreInst * Store = IRB.CreateStore(UpdatedPrevCaller, AFLPrevCaller); + Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + } else +#endif + { + if (ctx_str) NewCtx = IRB.CreateXor(PrevCtx, NewCtx); + StoreInst *StoreCtx = IRB.CreateStore(NewCtx, AFLContext); + StoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + } } @@ -413,16 +518,22 @@ bool AFLCoverage::runOnModule(Module &M) { // in CTX mode we have to restore the original context for the caller - // she might be calling other functions which need the correct CTX - if ((ctx_str || caller_str) && has_calls) { + if (instrument_ctx && has_calls) { Instruction *Inst = BB.getTerminator(); if (isa(Inst) || isa(Inst)) { IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + + StoreInst * RestoreCtx; +#ifdef AFL_HAVE_VECTOR_INTRINSICS + if (ctx_k) + RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller); + else +#endif + RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - } } @@ -460,7 +571,7 @@ bool AFLCoverage::runOnModule(Module &M) { #endif PrevLocTrans = PrevLoc; - if (ctx_str || caller_str) + if (instrument_ctx) PrevLocTrans = IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty); else @@ -547,13 +658,20 @@ bool AFLCoverage::runOnModule(Module &M) { // in CTX mode we have to restore the original context for the caller - // she might be calling other functions which need the correct CTX. // Currently this is only needed for the Ubuntu clang-6.0 bug - if ((ctx_str || caller_str) && has_calls) { + if (instrument_ctx && has_calls) { Instruction *Inst = BB.getTerminator(); if (isa(Inst) || isa(Inst)) { IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + + StoreInst * RestoreCtx; +#ifdef AFL_HAVE_VECTOR_INTRINSICS + if (ctx_k) + RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller); + else +#endif + RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); diff --git a/instrumentation/llvm-alternative-coverage.h b/instrumentation/llvm-alternative-coverage.h new file mode 100644 index 00000000..0d7b3957 --- /dev/null +++ b/instrumentation/llvm-alternative-coverage.h @@ -0,0 +1,21 @@ +#ifndef AFL_NGRAM_CONFIG_H +#define AFL_NGRAM_CONFIG_H + +#include "types.h" + +#if (MAP_SIZE_POW2 <= 16) +typedef u16 PREV_LOC_T; +#elif (MAP_SIZE_POW2 <= 32) +typedef u32 PREV_LOC_T; +#else +typedef u64 PREV_LOC_T; +#endif + +/* Maximum ngram size */ +#define NGRAM_SIZE_MAX 16U + +/* Maximum K for top-K context sensitivity */ +#define CTX_MAX_K 32U + +#endif + diff --git a/instrumentation/llvm-ngram-coverage.h b/instrumentation/llvm-ngram-coverage.h deleted file mode 100644 index 666839c8..00000000 --- a/instrumentation/llvm-ngram-coverage.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef AFL_NGRAM_CONFIG_H -#define AFL_NGRAM_CONFIG_H - -#include "types.h" - -#if (MAP_SIZE_POW2 <= 16) -typedef u16 PREV_LOC_T; -#elif (MAP_SIZE_POW2 <= 32) -typedef u32 PREV_LOC_T; -#else -typedef u64 PREV_LOC_T; -#endif - -/* Maximum ngram size */ -#define NGRAM_SIZE_MAX 16U - -#endif - diff --git a/src/afl-cc.c b/src/afl-cc.c index 0c689286..3c96beac 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -22,7 +22,7 @@ #include "types.h" #include "debug.h" #include "alloc-inl.h" -#include "llvm-ngram-coverage.h" +#include "llvm-alternative-coverage.h" #include #include -- cgit 1.4.1 From be5274d4a9c7fb835530be5054132253d2559ade Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 15:12:08 +0100 Subject: fix kctx compilation hang --- include/envs.h | 1 + instrumentation/afl-llvm-pass.so.cc | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'instrumentation') diff --git a/include/envs.h b/include/envs.h index 26f4de90..e8595ef7 100644 --- a/include/envs.h +++ b/include/envs.h @@ -81,6 +81,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX", + "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRIM_LOOPHEAD", diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index c58e9d95..fbf55f81 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -363,15 +363,18 @@ bool AFLCoverage::runOnModule(Module &M) { Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle); + Constant *PrevCallerShuffleMask = NULL; SmallVector PrevCallerShuffle = {UndefValue::get(Int32Ty)}; - for (unsigned I = 0; I < PrevCallerSize - 1; ++I) - PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); + if (ctx_k) { + for (unsigned I = 0; I < PrevCallerSize - 1; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); - for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I) - PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); + for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); - Constant *PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); + PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); + } #endif // other constants we need -- cgit 1.4.1 From 3342aa751d8e9102449e1739b38a25c40ab18e81 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 10:05:43 +0100 Subject: fix laf string transform crash --- docs/Changelog.md | 1 + instrumentation/SanitizerCoverageLTO.so.cc | 3 +++ instrumentation/afl-llvm-dict2file.so.cc | 4 ++++ instrumentation/afl-llvm-lto-instrumentation.so.cc | 3 +++ instrumentation/compare-transform-pass.so.cc | 11 +++++++++-- 5 files changed, 20 insertions(+), 2 deletions(-) (limited to 'instrumentation') diff --git a/docs/Changelog.md b/docs/Changelog.md index b1c991ff..c5b275de 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,7 @@ sending a mail to . - afl-cc - fixed a crash that can occur with ASAN + CMPLOG together plus better support for unicode (thanks to @stbergmann for reporting!) + - fixed a crash in LAF transform for empty strings - handle erroneous setups in which multiple afl-compiler-rt are compiled into the target. This now also supports dlopen instrumented libs loaded before the forkserver and even after the diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 849b6eef..13a5e5fd 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -849,15 +849,18 @@ bool ModuleSanitizerCoverage::instrumentModule( thestring = Str2; optLen = thestring.length(); + if (optLen < 2 || (optLen == 2 && !thestring[1])) { continue; } if (isMemcmp || isStrncmp || isStrncasecmp) { Value * op2 = callInst->getArgOperand(2); ConstantInt *ilen = dyn_cast(op2); + if (ilen) { uint64_t literalLength = optLen; optLen = ilen->getZExtValue(); + if (optLen < 2) { continue; } if (literalLength + 1 == optLen) { // add null byte thestring.append("\0", 1); addedNull = true; diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 885aa035..c954054b 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -521,14 +521,18 @@ bool AFLdict2filePass::runOnModule(Module &M) { optLen = thestring.length(); + if (optLen < 2 || (optLen == 2 && !thestring[1])) { continue; } + if (isMemcmp || isStrncmp || isStrncasecmp) { Value * op2 = callInst->getArgOperand(2); ConstantInt *ilen = dyn_cast(op2); + if (ilen) { uint64_t literalLength = optLen; optLen = ilen->getZExtValue(); + if (optLen < 2) { continue; } if (literalLength + 1 == optLen) { // add null byte thestring.append("\0", 1); addedNull = true; diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index ef270a1f..50306224 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -635,15 +635,18 @@ bool AFLLTOPass::runOnModule(Module &M) { thestring = Str2; optLen = thestring.length(); + if (optLen < 2 || (optLen == 2 && !thestring[1])) { continue; } if (isMemcmp || isStrncmp || isStrncasecmp) { Value * op2 = callInst->getArgOperand(2); ConstantInt *ilen = dyn_cast(op2); + if (ilen) { uint64_t literalLength = optLen; optLen = ilen->getZExtValue(); + if (optLen < 2) { continue; } if (literalLength + 1 == optLen) { // add null byte thestring.append("\0", 1); addedNull = true; diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index a85522a2..3ecba4e6 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -316,7 +316,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, uint64_t len = ilen->getZExtValue(); // if len is zero this is a pointless call but allow real // implementation to worry about that - if (!len) continue; + if (len < 2) continue; if (isMemcmp) { @@ -420,8 +420,15 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } + if (TmpConstStr.length() < 2 || + (TmpConstStr.length() == 2 && !TmpConstStr[1])) { + + continue; + + } + // add null termination character implicit in c strings - if (TmpConstStr[TmpConstStr.length() - 1] != 0) { + if (!isMemcmp && TmpConstStr[TmpConstStr.length() - 1]) { TmpConstStr.append("\0", 1); -- cgit 1.4.1 From 3e5ac0af5237bbd01abc30538add248ee0bf1735 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 10:21:28 +0100 Subject: no static for rt initialized markers --- instrumentation/afl-compiler-rt.o.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 87bf6486..664c942d 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -129,10 +129,10 @@ static u32 __afl_debug; /* Already initialized markers */ -static u32 __afl_already_initialized_shm; -static u32 __afl_already_initialized_forkserver; -static u32 __afl_already_initialized_first; -static u32 __afl_already_initialized_second; +u32 __afl_already_initialized_shm; +u32 __afl_already_initialized_forkserver; +u32 __afl_already_initialized_first; +u32 __afl_already_initialized_second; /* Dummy pipe for area_is_valid() */ -- cgit 1.4.1 From 41ad23041b98917e9c38873f5b296ab98e59e460 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 14:58:37 +0100 Subject: remove warnings --- instrumentation/afl-compiler-rt.o.c | 8 +++----- instrumentation/cmplog-instructions-pass.cc | 14 +++----------- instrumentation/split-compares-pass.so.cc | 19 +++++++++++++++---- 3 files changed, 21 insertions(+), 20 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 664c942d..1d8fd757 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1170,7 +1170,7 @@ __attribute__((constructor(1))) void __afl_auto_second(void) { } -} +} // ptr memleak report is a false positive /* preset __afl_area_ptr #1 - at constructor level 0 global variables have not been set */ @@ -1181,9 +1181,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) { __afl_already_initialized_first = 1; if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; - u8 *ptr; - - ptr = (u8 *)malloc(MAP_INITIAL_SIZE); + u8 *ptr = (u8 *)malloc(MAP_INITIAL_SIZE); if (ptr && (ssize_t)ptr != -1) { @@ -1192,7 +1190,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) { } -} +} // ptr memleak report is a false positive /* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard. It remains non-operational in the traditional, plugin-backed LLVM mode. diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index dbca9afa..ad334d3b 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -418,7 +418,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { IntegerType * intTyOp0 = NULL; IntegerType * intTyOp1 = NULL; unsigned max_size = 0, cast_size = 0; - unsigned char attr = 0, do_cast = 0; + unsigned char attr = 0; std::vector args; CmpInst *cmpInst = dyn_cast(selectcmpInst); @@ -484,7 +484,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { max_size = 128; attr += 8; - do_cast = 1; } else { @@ -503,12 +502,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (!max_size || max_size < 16) { continue; } - if (max_size % 8) { - - max_size = (((max_size / 8) + 1) * 8); - do_cast = 1; - - } + if (max_size % 8) { max_size = (((max_size / 8) + 1) * 8); } if (max_size > 128) { @@ -521,7 +515,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } max_size = 128; - do_cast = 1; } @@ -537,7 +530,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { break; default: cast_size = 128; - do_cast = 1; } @@ -574,7 +566,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n", - // max_size, cast_size, attr, do_cast); + // max_size, cast_size, attr); switch (cast_size) { diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 80cd90ba..d03944df 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -149,8 +149,11 @@ bool SplitComparesTransform::simplifyFPCompares(Module &M) { auto op1 = FcmpInst->getOperand(1); /* find out what the new predicate is going to be */ - auto pred = dyn_cast(FcmpInst)->getPredicate(); + auto cmp_inst = dyn_cast(FcmpInst); + if (!cmp_inst) { continue; } + auto pred = cmp_inst->getPredicate(); CmpInst::Predicate new_pred; + switch (pred) { case CmpInst::FCMP_UGE: @@ -276,8 +279,11 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { auto op1 = IcmpInst->getOperand(1); /* find out what the new predicate is going to be */ - auto pred = dyn_cast(IcmpInst)->getPredicate(); + auto cmp_inst = dyn_cast(IcmpInst); + if (!cmp_inst) { continue; } + auto pred = cmp_inst->getPredicate(); CmpInst::Predicate new_pred; + switch (pred) { case CmpInst::ICMP_UGE: @@ -412,8 +418,11 @@ bool SplitComparesTransform::simplifyIntSignedness(Module &M) { IntegerType *IntType = IntegerType::get(C, bitw); /* get the new predicate */ - auto pred = dyn_cast(IcmpInst)->getPredicate(); + auto cmp_inst = dyn_cast(IcmpInst); + if (!cmp_inst) { continue; } + auto pred = cmp_inst->getPredicate(); CmpInst::Predicate new_pred; + if (pred == CmpInst::ICMP_SGT) { new_pred = CmpInst::ICMP_UGT; @@ -1113,7 +1122,9 @@ size_t SplitComparesTransform::splitIntCompares(Module &M, unsigned bitw) { auto op0 = IcmpInst->getOperand(0); auto op1 = IcmpInst->getOperand(1); - auto pred = dyn_cast(IcmpInst)->getPredicate(); + auto cmp_inst = dyn_cast(IcmpInst); + if (!cmp_inst) { continue; } + auto pred = cmp_inst->getPredicate(); BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst)); -- cgit 1.4.1 From c429021de10cf01878bd2150cc68c6b403db9335 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 5 Mar 2021 15:27:10 +0100 Subject: fix typos and format --- instrumentation/afl-llvm-pass.so.cc | 99 ++++++++++++++++++++++++------------- src/afl-cc.c | 16 +++--- 2 files changed, 72 insertions(+), 43 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index fbf55f81..f4717345 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -212,24 +212,30 @@ bool AFLCoverage::runOnModule(Module &M) { PrevLocSize = ngram_size - 1; else PrevLocSize = 1; - + /* Decide K-ctx vector size (must be a power of two) */ VectorType *PrevCallerTy = NULL; if (ctx_k_str) - if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 2 || - ctx_k > CTX_MAX_K) - FATAL("Bad value of AFL_CTX_K (must be between 2 and CTX_MAX_K (%u))", CTX_MAX_K); + if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 2 || ctx_k > CTX_MAX_K) + FATAL("Bad value of AFL_CTX_K (must be between 2 and CTX_MAX_K (%u))", + CTX_MAX_K); if (ctx_k == 1) { + ctx_k = 0; instrument_ctx = true; - caller_str = ctx_k_str; // Enable CALLER instead + caller_str = ctx_k_str; // Enable CALLER instead + } + if (ctx_k) { + PrevCallerSize = ctx_k; instrument_ctx = true; + } + #else if (ngram_size_str) #ifndef LLVM_VERSION_PATCH @@ -274,8 +280,8 @@ bool AFLCoverage::runOnModule(Module &M) { if (ctx_k) PrevCallerTy = VectorType::get(IntLocTy, PrevCallerVecSize #if LLVM_VERSION_MAJOR >= 12 - , - false + , + false #endif ); #endif @@ -340,12 +346,13 @@ bool AFLCoverage::runOnModule(Module &M) { else #endif #if defined(__ANDROID__) || defined(__HAIKU__) - AFLPrevCaller = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller"); + AFLPrevCaller = + new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, + "__afl_prev_caller"); #else AFLPrevCaller = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller", 0, - GlobalVariable::GeneralDynamicTLSModel, 0, false); + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller", + 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); #endif #ifdef AFL_HAVE_VECTOR_INTRINSICS @@ -362,11 +369,12 @@ bool AFLCoverage::runOnModule(Module &M) { PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize)); Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle); - - Constant *PrevCallerShuffleMask = NULL; + + Constant * PrevCallerShuffleMask = NULL; SmallVector PrevCallerShuffle = {UndefValue::get(Int32Ty)}; if (ctx_k) { + for (unsigned I = 0; I < PrevCallerSize - 1; ++I) PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); @@ -374,15 +382,17 @@ bool AFLCoverage::runOnModule(Module &M) { PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); + } + #endif // other constants we need ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *One = ConstantInt::get(Int8Ty, 1); - Value *PrevCtx = NULL; // CTX sensitive coverage - LoadInst *PrevCaller = NULL; // K-CTX coverage + Value * PrevCtx = NULL; // CTX sensitive coverage + LoadInst *PrevCaller = NULL; // K-CTX coverage /* Instrument all the things! */ @@ -410,16 +420,25 @@ bool AFLCoverage::runOnModule(Module &M) { #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ctx_k) { + PrevCaller = IRB.CreateLoad(AFLPrevCaller); - PrevCaller->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - PrevCtx = IRB.CreateZExt(IRB.CreateXorReduce(PrevCaller), IRB.getInt32Ty()); - } else + PrevCaller->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + PrevCtx = + IRB.CreateZExt(IRB.CreateXorReduce(PrevCaller), IRB.getInt32Ty()); + + } else + #endif { - // load the context ID of the previous function and write to to a local variable on the stack - LoadInst* PrevCtxLoad = IRB.CreateLoad(AFLContext); - PrevCtxLoad->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + + // load the context ID of the previous function and write to to a + // local variable on the stack + LoadInst *PrevCtxLoad = IRB.CreateLoad(AFLContext); + PrevCtxLoad->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); PrevCtx = PrevCtxLoad; + } // does the function have calls? and is any of the calls larger than one @@ -454,19 +473,28 @@ bool AFLCoverage::runOnModule(Module &M) { Value *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ctx_k) { + Value *ShuffledPrevCaller = IRB.CreateShuffleVector( - PrevCaller, UndefValue::get(PrevCallerTy), PrevCallerShuffleMask); - Value *UpdatedPrevCaller = IRB.CreateInsertElement(ShuffledPrevCaller, NewCtx, (uint64_t)0); + PrevCaller, UndefValue::get(PrevCallerTy), + PrevCallerShuffleMask); + Value *UpdatedPrevCaller = IRB.CreateInsertElement( + ShuffledPrevCaller, NewCtx, (uint64_t)0); + + StoreInst *Store = + IRB.CreateStore(UpdatedPrevCaller, AFLPrevCaller); + Store->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } else - StoreInst * Store = IRB.CreateStore(UpdatedPrevCaller, AFLPrevCaller); - Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - } else #endif { + if (ctx_str) NewCtx = IRB.CreateXor(PrevCtx, NewCtx); StoreInst *StoreCtx = IRB.CreateStore(NewCtx, AFLContext); StoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + } } @@ -528,15 +556,16 @@ bool AFLCoverage::runOnModule(Module &M) { IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx; -#ifdef AFL_HAVE_VECTOR_INTRINSICS + StoreInst *RestoreCtx; + #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ctx_k) RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller); - else -#endif - RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + else + #endif + RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + } } @@ -667,14 +696,14 @@ bool AFLCoverage::runOnModule(Module &M) { if (isa(Inst) || isa(Inst)) { IRBuilder<> Post_IRB(Inst); - - StoreInst * RestoreCtx; + + StoreInst *RestoreCtx; #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ctx_k) RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller); - else + else #endif - RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); diff --git a/src/afl-cc.c b/src/afl-cc.c index 97f32b2b..e4ea66e4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1283,19 +1283,19 @@ int main(int argc, char **argv, char **envp) { ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( - "K-CTX instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " "(%u)", NGRAM_SIZE_MAX); } - + if (getenv("AFL_LLVM_CTX_K")) { instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); if (ctx_k < 1 || ctx_k > CTX_MAX_K) - FATAL( - "NGRAM instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", + CTX_MAX_K); } @@ -1393,7 +1393,7 @@ int main(int argc, char **argv, char **envp) { compiler_mode = CLANG; } - + if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0) { u8 *ptr3 = ptr2 + strlen("ctx-"); @@ -1412,7 +1412,8 @@ int main(int argc, char **argv, char **envp) { ctx_k = atoi(ptr3); if (ctx_k < 1 || ctx_k > CTX_MAX_K) FATAL( - "K-CTX instrumentation option must be between 1 and CTX_MAX_K (%u)", + "K-CTX instrumentation option must be between 1 and CTX_MAX_K " + "(%u)", CTX_MAX_K); instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); u8 *ptr4 = alloc_printf("%u", ctx_k); @@ -1855,8 +1856,7 @@ int main(int argc, char **argv, char **envp) { (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "", - (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : "" - ); + (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : ""); ck_free(ptr2); ck_free(ptr3); -- cgit 1.4.1 From 16d6f35aa6f968d6dbdd2005e8fa140955815837 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Fri, 5 Mar 2021 18:11:05 +0100 Subject: typos --- instrumentation/README.ctx.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.ctx.md b/instrumentation/README.ctx.md index ffcce0a9..577b3e5f 100644 --- a/instrumentation/README.ctx.md +++ b/instrumentation/README.ctx.md @@ -4,7 +4,7 @@ This is an LLVM-based implementation of the context sensitive branch coverage. -Basically every function gets its own ID and, every time that an edge is logged, +Basically every function gets its own ID and, every time when an edge is logged, all the IDs in the callstack are hashed and combined with the edge transition hash to augment the classic edge coverage with the information about the calling context. @@ -16,7 +16,7 @@ In math the coverage is collected as follows: `map[current_location_ID ^ previous_location_ID >> 1 ^ hash_callstack_IDs] += 1` The callstack hash is produced XOR-ing the function IDs to avoid explosion with -recusrsive functions. +recursive functions. ## Usage @@ -28,7 +28,7 @@ many map collisions occur. ## Caller Branch Coverage -If the context sensitive coverage introduces too may collisions becoming +If the context sensitive coverage introduces too may collisions and becoming decremental, the user can choose to augment edge coverage with just the called function ID, instead of the entire callstack hash. -- cgit 1.4.1 From 44be521ab8ef5d62847ae48ebdb060d84aae5e47 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 19:19:43 +0100 Subject: fix --- instrumentation/afl-compiler-rt.o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 1d8fd757..c741bc05 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -370,10 +370,10 @@ static void __afl_map_shm(void) { } close(shm_fd); + shm_fd = -1; if (shm_base == MAP_FAILED) { - shm_fd = -1; fprintf(stderr, "mmap() failed\n"); perror("mmap for map"); -- cgit 1.4.1 From 7b907e45ada18020da03b69a24bc68b64a11d1e7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 19:55:20 +0100 Subject: we do not support 80 + 128 bit FP in laf --- instrumentation/split-compares-pass.so.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index d03944df..b02a89fb 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -612,6 +612,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { if (op_size != op1->getType()->getPrimitiveSizeInBits()) { continue; } const unsigned int sizeInBits = op0->getType()->getPrimitiveSizeInBits(); + + // BUG FIXME TODO: u64 does not work for > 64 bit ... e.g. 80 and 128 bit + if (sizeInBits > 64) { continue; } + const unsigned int precision = sizeInBits == 32 ? 24 : sizeInBits == 64 ? 53 : sizeInBits == 128 ? 113 @@ -619,8 +623,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { : sizeInBits == 80 ? 65 : sizeInBits - 8; - const unsigned shiftR_exponent = precision - 1; - // BUG FIXME TODO: u64 does not work for > 64 bit ... e.g. 80 and 128 bit + const unsigned shiftR_exponent = precision - 1; const unsigned long long mask_fraction = (1ULL << (shiftR_exponent - 1)) | ((1ULL << (shiftR_exponent - 1)) - 1); const unsigned long long mask_exponent = -- cgit 1.4.1 From 9b3d8c327d33191b181219ffce411b40bdbe8902 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 6 Mar 2021 10:20:01 +0100 Subject: fix for asan compile rt --- instrumentation/afl-compiler-rt.o.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c741bc05..a702ec39 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1703,41 +1703,25 @@ __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) { // to avoid to call it on .text addresses static int area_is_valid(void *ptr, size_t len) { - void *ret_ptr = __asan_region_is_poisoned(ptr, len); + if (unlikely(__asan_region_is_poisoned(ptr, len))) { return 0; } - if (ret_ptr) { // region is poisoned + long r = syscall(__afl_dummy_fd[1], SYS_write, ptr, len); - ssize_t ret_diff = ret_ptr - ptr; - - if (ret_diff <= 0) { - - return 0; - - } else { - - return ret_diff; // only partially poisoned - - } - - } - - int r = syscall(__afl_dummy_fd[1], SYS_write, ptr, len); - - if (r <= 0) { // maybe this is going over an asan boundary + if (unlikely(r <= 0 || r > len)) { // fail - maybe hitting asan boundary? char *p = (char *)ptr; long page_size = sysconf(_SC_PAGE_SIZE); char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size; - if (page < p + len) { return 0; } + if (page < p + len) { return 0; } // no isnt, return fail len -= (p + len - page); r = syscall(__afl_dummy_fd[1], SYS_write, p, len); } // partial writes - we return what was written. - if (r > 0) { + if (likely(r >= 0 && r <= len)) { - return r; + return (int)r; } else { -- cgit 1.4.1 From 791c5c171d9e4e7391a9c3760a4a8eb4ce2b4058 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 18:44:42 +0100 Subject: fix ctx-1 --- include/envs.h | 1 + instrumentation/afl-llvm-pass.so.cc | 4 ++-- src/afl-cc.c | 29 +++++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) (limited to 'instrumentation') diff --git a/include/envs.h b/include/envs.h index 37748a56..4d4d6b0e 100644 --- a/include/envs.h +++ b/include/envs.h @@ -80,6 +80,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_BLOCKLIST", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", + "AFL_LLVM_CALLER", "AFL_LLVM_CTX", "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index f4717345..0f773aba 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -217,8 +217,8 @@ bool AFLCoverage::runOnModule(Module &M) { VectorType *PrevCallerTy = NULL; if (ctx_k_str) - if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 2 || ctx_k > CTX_MAX_K) - FATAL("Bad value of AFL_CTX_K (must be between 2 and CTX_MAX_K (%u))", + if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 1 || ctx_k > CTX_MAX_K) + FATAL("Bad value of AFL_CTX_K (must be between 1 and CTX_MAX_K (%u))", CTX_MAX_K); if (ctx_k == 1) { diff --git a/src/afl-cc.c b/src/afl-cc.c index a517124f..b9e0c101 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1298,11 +1298,21 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_CTX_K")) { - instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); if (ctx_k < 1 || ctx_k > CTX_MAX_K) FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + if (ctx_k == 1) { + + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + + } else { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; + + } } @@ -1422,9 +1432,20 @@ int main(int argc, char **argv, char **envp) { "K-CTX instrumentation option must be between 1 and CTX_MAX_K " "(%u)", CTX_MAX_K); - instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); - u8 *ptr4 = alloc_printf("%u", ctx_k); - setenv("AFL_LLVM_CTX_K", ptr4, 1); + + if (ctx_k == 1) { + + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + + } else { + + instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); + u8 *ptr4 = alloc_printf("%u", ctx_k); + setenv("AFL_LLVM_CTX_K", ptr4, 1); + + } } -- cgit 1.4.1 From 5001779984cca8667bf7fc86c92b37cf101b1aef Mon Sep 17 00:00:00 2001 From: Wyatt Neal Date: Tue, 9 Mar 2021 14:54:26 -0500 Subject: documentation correction & formatting * fixed up manual define for `__AFL_LOOP()` * added the code language formaters to the various blocks * fixed a couple of missing backticks --- instrumentation/README.persistent_mode.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.persistent_mode.md b/instrumentation/README.persistent_mode.md index 2cf76adf..24f81ea0 100644 --- a/instrumentation/README.persistent_mode.md +++ b/instrumentation/README.persistent_mode.md @@ -16,7 +16,7 @@ Examples can be found in [utils/persistent_mode](../utils/persistent_mode). ## 2) TLDR; Example `fuzz_target.c`: -``` +```c #include "what_you_need_for_your_target.h" __AFL_FUZZ_INIT(); @@ -60,14 +60,14 @@ The speed increase is usually x10 to x20. If you want to be able to compile the target without afl-clang-fast/lto then add this just after the includes: -``` +```c #ifndef __AFL_FUZZ_TESTCASE_LEN ssize_t fuzz_len; #define __AFL_FUZZ_TESTCASE_LEN fuzz_len unsigned char fuzz_buf[1024000]; #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf #define __AFL_FUZZ_INIT() void sync(void); - #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? + #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) #define __AFL_INIT() sync() #endif ``` @@ -75,7 +75,7 @@ add this just after the includes: ## 3) Deferred initialization AFL tries to optimize performance by executing the targeted binary just once, -stopping it just before main(), and then cloning this "main" process to get +stopping it just before `main()`, and then cloning this "main" process to get a steady supply of targets to fuzz. Although this approach eliminates much of the OS-, linker- and libc-level @@ -97,7 +97,7 @@ a location after: - The creation of any vital threads or child processes - since the forkserver can't clone them easily. - - The initialization of timers via setitimer() or equivalent calls. + - The initialization of timers via `setitimer()` or equivalent calls. - The creation of temporary files, network sockets, offset-sensitive file descriptors, and similar shared-state resources - but only provided that @@ -150,9 +150,9 @@ the impact of memory leaks and similar glitches; 1000 is a good starting point, and going much higher increases the likelihood of hiccups without giving you any real performance benefits. -A more detailed template is shown in ../utils/persistent_mode/. -Similarly to the previous mode, the feature works only with afl-clang-fast; #ifdef -guards can be used to suppress it when using other compilers. +A more detailed template is shown in `../utils/persistent_mode/.` +Similarly to the previous mode, the feature works only with afl-clang-fast; +`#ifdef` guards can be used to suppress it when using other compilers. Note that as with the previous mode, the feature is easy to misuse; if you do not fully reset the critical state, you may end up with false positives or @@ -161,7 +161,7 @@ wary of memory leaks and of the state of file descriptors. PS. Because there are task switches still involved, the mode isn't as fast as "pure" in-process fuzzing offered, say, by LLVM's LibFuzzer; but it is a lot -faster than the normal fork() model, and compared to in-process fuzzing, +faster than the normal `fork()` model, and compared to in-process fuzzing, should be a lot more robust. ## 5) Shared memory fuzzing @@ -174,17 +174,17 @@ Setting this up is very easy: After the includes set the following macro: -``` +```c __AFL_FUZZ_INIT(); ``` Directly at the start of main - or if you are using the deferred forkserver -with `__AFL_INIT()` then *after* `__AFL_INIT? : -``` +with `__AFL_INIT()` then *after* `__AFL_INIT()` : +```c unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; ``` Then as first line after the `__AFL_LOOP` while loop: -``` +```c int len = __AFL_FUZZ_TESTCASE_LEN; ``` and that is all! -- cgit 1.4.1 From 4131965d48c19323dc63fa1ba8a256b954695526 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 9 Mar 2021 21:59:31 +0100 Subject: md formatting --- instrumentation/README.out_of_line.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.out_of_line.md b/instrumentation/README.out_of_line.md index aad215b6..2264f91f 100644 --- a/instrumentation/README.out_of_line.md +++ b/instrumentation/README.out_of_line.md @@ -1,18 +1,16 @@ -=========================================== -Using afl++ without inlined instrumentation -=========================================== +## Using afl++ without inlined instrumentation This file describes how you can disable inlining of instrumentation. By default, the GCC plugin will duplicate the effects of calling -__afl_trace (see afl-gcc-rt.o.c) in instrumented code, instead of +`__afl_trace` (see `afl-gcc-rt.o.c`) in instrumented code, instead of issuing function calls. The calls are presumed to be slower, more so because the rt file itself is not optimized by the compiler. -Setting AFL_GCC_OUT_OF_LINE=1 in the environment while compiling code +Setting `AFL_GCC_OUT_OF_LINE=1` in the environment while compiling code with the plugin will disable this inlining, issuing calls to the unoptimized runtime instead. -- cgit 1.4.1 From aa12e46013f1900793adbd28d50e9d56243fefb0 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 9 Mar 2021 22:09:58 +0100 Subject: formatting and RedQueen reference added --- instrumentation/README.cmplog.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.cmplog.md b/instrumentation/README.cmplog.md index 5f855e1f..a796c7a7 100644 --- a/instrumentation/README.cmplog.md +++ b/instrumentation/README.cmplog.md @@ -1,10 +1,11 @@ # CmpLog instrumentation -The CmpLog instrumentation enables the logging of the comparisons operands in a +The CmpLog instrumentation enables logging of comparison operands in a shared memory. These values can be used by various mutators built on top of it. -At the moment we support the RedQueen mutator (input-2-state instructions only). +At the moment we support the RedQueen mutator (input-2-state instructions only), +for details see [the RedQueen paper](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf). ## Build @@ -13,7 +14,7 @@ program. The first version is built using the regular AFL++ instrumentation. -The second one, the CmpLog binary, with setting AFL_LLVM_CMPLOG during the compilation. +The second one, the CmpLog binary, is built with setting AFL_LLVM_CMPLOG during the compilation. For example: @@ -26,11 +27,12 @@ export AFL_LLVM_CMPLOG=1 ./configure --cc=~/path/to/afl-clang-fast make cp ./program ./program.cmplog +unset AFL_LLVM_CMPLOG ``` ## Use -AFL++ has the new -c option that needs to be used to specify the CmpLog binary (the second +AFL++ has the new `-c` option that needs to be used to specify the CmpLog binary (the second build). For example: -- cgit 1.4.1 From d44b650cd458d6e5032694801a7f8fd5359ee20d Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 9 Mar 2021 22:14:34 +0100 Subject: typo --- instrumentation/README.ctx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/README.ctx.md b/instrumentation/README.ctx.md index 577b3e5f..335e9921 100644 --- a/instrumentation/README.ctx.md +++ b/instrumentation/README.ctx.md @@ -29,7 +29,7 @@ many map collisions occur. ## Caller Branch Coverage If the context sensitive coverage introduces too may collisions and becoming -decremental, the user can choose to augment edge coverage with just the +detrimental, the user can choose to augment edge coverage with just the called function ID, instead of the entire callstack hash. In math the coverage is collected as follows: -- cgit 1.4.1 From b865fc608087941c679d0895c8cfcd279235493e Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 9 Mar 2021 23:04:53 +0100 Subject: typos, rewording --- instrumentation/README.gcc_plugin.md | 61 +++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 25 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.gcc_plugin.md b/instrumentation/README.gcc_plugin.md index 12449efd..230ceb73 100644 --- a/instrumentation/README.gcc_plugin.md +++ b/instrumentation/README.gcc_plugin.md @@ -3,16 +3,20 @@ See [../README.md](../README.md) for the general instruction manual. See [README.llvm.md](README.llvm.md) for the LLVM-based instrumentation. +This document describes how to build and use `afl-gcc-fast` and `afl-g++-fast`, +which instrument the target with the help of gcc plugins. + TLDR: - * `apt-get install gcc-VERSION-plugin-dev` - * `make` - * gcc and g++ must point to the gcc-VERSION you you have to set AFL_CC/AFL_CXX + * check the version of your gcc compiler: `gcc --version` + * `apt-get install gcc-VERSION-plugin-dev` or similar to install headers for gcc plugins + * `gcc` and `g++` must match the gcc-VERSION you installed headers for. You can set `AFL_CC`/`AFL_CXX` to point to these! - * just use afl-gcc-fast/afl-g++-fast normally like you would afl-clang-fast + * `make` + * just use `afl-gcc-fast`/`afl-g++-fast` normally like you would do with `afl-clang-fast` ## 1) Introduction -The code in this directory allows you to instrument programs for AFL using +The code in this directory allows to instrument programs for AFL using true compiler-level instrumentation, instead of the more crude assembly-level rewriting approach taken by afl-gcc and afl-clang. This has several interesting properties: @@ -27,10 +31,10 @@ several interesting properties: - The instrumentation is CPU-independent. At least in principle, you should be able to rely on it to fuzz programs on non-x86 architectures (after - building afl-fuzz with AFL_NOX86=1). + building `afl-fuzz` with `AFL_NOX86=1`). - Because the feature relies on the internals of GCC, it is gcc-specific - and will *not* work with LLVM (see ../llvm_mode for an alternative). + and will *not* work with LLVM (see [README.llvm.md](README.llvm.md) for an alternative). Once this implementation is shown to be sufficiently robust and portable, it will probably replace afl-gcc. For now, it can be built separately and @@ -41,29 +45,32 @@ The idea and much of the implementation comes from Laszlo Szekeres. ## 2) How to use In order to leverage this mechanism, you need to have modern enough GCC -(>= version 4.5.0) and the plugin headers installed on your system. That +(>= version 4.5.0) and the plugin development headers installed on your system. That should be all you need. On Debian machines, these headers can be acquired by installing the `gcc-VERSION-plugin-dev` packages. -To build the instrumentation itself, type 'make'. This will generate binaries -called afl-gcc-fast and afl-g++-fast in the parent directory. +To build the instrumentation itself, type `make`. This will generate binaries +called `afl-gcc-fast` and `afl-g++-fast` in the parent directory. The gcc and g++ compiler links have to point to gcc-VERSION - or set these -by pointing the environment variables AFL_CC/AFL_CXX to them. -If the CC/CXX have been overridden, those compilers will be used from -those wrappers without using AFL_CXX/AFL_CC settings. +by pointing the environment variables `AFL_CC`/`AFL_CXX` to them. +If the `CC`/`CXX` environment variables have been set, those compilers will be +preferred over those from the `AFL_CC`/`AFL_CXX` settings. Once this is done, you can instrument third-party code in a way similar to the standard operating mode of AFL, e.g.: - - CC=/path/to/afl/afl-gcc-fast ./configure [...options...] +``` + CC=/path/to/afl/afl-gcc-fast + CXX=/path/to/afl/afl-g++-fast + export CC CXX + ./configure [...options...] make +``` +Note: We also used `CXX` to set the C++ compiler to `afl-g++-fast` for C++ code. -Be sure to also include CXX set to afl-g++-fast for C++ code. - -The tool honors roughly the same environmental variables as afl-gcc (see -[env_variables.md](../docs/env_variables.md). This includes AFL_INST_RATIO, -AFL_USE_ASAN, AFL_HARDEN, and AFL_DONT_OPTIMIZE. +The tool honors roughly the same environmental variables as `afl-gcc` (see +[env_variables.md](../docs/env_variables.md). This includes `AFL_INST_RATIO`, +`AFL_USE_ASAN`, `AFL_HARDEN`, and `AFL_DONT_OPTIMIZE`. Note: if you want the GCC plugin to be installed on your system for all users, you need to build it before issuing 'make install' in the parent @@ -72,7 +79,7 @@ directory. ## 3) Gotchas, feedback, bugs This is an early-stage mechanism, so field reports are welcome. You can send bug -reports to afl@aflplus.plus +reports to afl@aflplus.plus. ## 4) Bonus feature #1: deferred initialization @@ -88,7 +95,7 @@ file before getting to the fuzzed data. In such cases, it's beneficial to initialize the forkserver a bit later, once most of the initialization work is already done, but before the binary attempts to read the fuzzed input and parse it; in some cases, this can offer a 10x+ -performance gain. You can implement delayed initialization in LLVM mode in a +performance gain. You can implement delayed initialization in GCC mode in a fairly simple way. First, locate a suitable location in the code where the delayed cloning can @@ -117,7 +124,7 @@ With the location selected, add this code in the appropriate spot: ``` You don't need the #ifdef guards, but they will make the program still work as -usual when compiled with a tool other than afl-gcc-fast/afl-clang-fast. +usual when compiled with a compiler other than afl-gcc-fast/afl-clang-fast. Finally, recompile the program with afl-gcc-fast (afl-gcc or afl-clang will *not* generate a deferred-initialization binary) - and you should be all set! @@ -127,7 +134,7 @@ Finally, recompile the program with afl-gcc-fast (afl-gcc or afl-clang will Some libraries provide APIs that are stateless, or whose state can be reset in between processing different input files. When such a reset is performed, a single long-lived process can be reused to try out multiple test cases, -eliminating the need for repeated fork() calls and the associated OS overhead. +eliminating the need for repeated `fork()` calls and the associated OS overhead. The basic structure of the program that does this would be: @@ -160,5 +167,9 @@ wary of memory leaks and the state of file descriptors. When running in this mode, the execution paths will inherently vary a bit depending on whether the input loop is being entered for the first time or executed again. To avoid spurious warnings, the feature implies -AFL_NO_VAR_CHECK and hides the "variable path" warnings in the UI. +`AFL_NO_VAR_CHECK` and hides the "variable path" warnings in the UI. + +## 6) Bonus feature #3: selective instrumentation +It can be more effective to fuzzing to only instrument parts of the code. +For details see [README.instrument_list.md](README.instrument_list.md). -- cgit 1.4.1 From 9f22a151f3a22756febe4d92443b9d5b55f0ff66 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 9 Mar 2021 23:55:22 +0100 Subject: mention added support for gcc_plugin mode --- instrumentation/README.neverzero.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/README.neverzero.md b/instrumentation/README.neverzero.md index 5c894d6e..49104e00 100644 --- a/instrumentation/README.neverzero.md +++ b/instrumentation/README.neverzero.md @@ -16,7 +16,7 @@ at a very little cost (one instruction per edge). (The alternative of saturated counters has been tested also and proved to be inferior in terms of path discovery.) -This is implemented in afl-gcc, however for llvm_mode this is optional if +This is implemented in afl-gcc and afl-gcc-fast, however for llvm_mode this is optional if the llvm version is below 9 - as there is a perfomance bug that is only fixed in version 9 and onwards. -- cgit 1.4.1 From d471fc9509159a0cec4f6a98672cc7a7d2227588 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 10 Mar 2021 00:07:33 +0100 Subject: add version dependency --- instrumentation/README.ngram.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/README.ngram.md b/instrumentation/README.ngram.md index de3ba432..da61ef32 100644 --- a/instrumentation/README.ngram.md +++ b/instrumentation/README.ngram.md @@ -10,8 +10,8 @@ by Jinghan Wang, et. al. Note that the original implementation (available [here](https://github.com/bitsecurerlab/afl-sensitive)) is built on top of AFL's QEMU mode. -This is essentially a port that uses LLVM vectorized instructions to achieve -the same results when compiling source code. +This is essentially a port that uses LLVM vectorized instructions (available from +llvm versions 4.0.1 and higher) to achieve the same results when compiling source code. In math the branch coverage is performed as follows: `map[current_location ^ prev_location[0] >> 1 ^ prev_location[1] >> 1 ^ ... up to n-1`] += 1` -- cgit 1.4.1 From bff02dae0d344cb51222b75840cc7f1a31ab03eb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 09:32:54 +0100 Subject: cmplog rtn rt fix --- instrumentation/afl-compiler-rt.o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index ff14b966..74db7089 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1773,7 +1773,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { if (__afl_cmp_map->headers[k].shape < len) { - __afl_cmp_map->headers[k].shape = len; + __afl_cmp_map->headers[k].shape = len - 1; } -- cgit 1.4.1 From b2feada293b64f6148917399e728c9b19799edf9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 10:04:45 +0100 Subject: rt debug --- instrumentation/afl-compiler-rt.o.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 74db7089..7fd982ce 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -317,16 +317,18 @@ static void __afl_map_shm(void) { if (__afl_debug) fprintf(stderr, - "DEBUG: id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_map_addr 0x%llx, MAP_SIZE %u, __afl_final_loc %u, " + "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " + "__afl_area_ptr_dummy 0x%llx, __afl_map_addr 0x%llx, MAP_SIZE %u, " + "__afl_final_loc %u, " "max_size_forkserver %u/0x%x\n", id_str == NULL ? "" : id_str, __afl_area_ptr, - __afl_area_initial, __afl_map_addr, MAP_SIZE, __afl_final_loc, - FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, + __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); if (id_str) { - if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial) { + if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial && + __afl_area_ptr != __afl_area_ptr_dummy) { if (__afl_map_addr) { @@ -457,6 +459,17 @@ static void __afl_map_shm(void) { if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; } + if (__afl_debug) + fprintf(stderr, + "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " + "__afl_area_ptr_dummy 0x%llx, __afl_map_addr 0x%llx, MAP_SIZE " + "%u, __afl_final_loc %u, " + "max_size_forkserver %u/0x%x\n", + id_str == NULL ? "" : id_str, __afl_area_ptr, + __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, + MAP_SIZE, __afl_final_loc, FS_OPT_MAX_MAPSIZE, + FS_OPT_MAX_MAPSIZE); + } __afl_area_ptr_backup = __afl_area_ptr; -- cgit 1.4.1 From d678d59372494ab971429abceaa35b0fad2860ae Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 10:07:54 +0100 Subject: fix --- instrumentation/afl-compiler-rt.o.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 7fd982ce..9480b90e 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -318,7 +318,7 @@ static void __afl_map_shm(void) { if (__afl_debug) fprintf(stderr, "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy 0x%llx, __afl_map_addr 0x%llx, MAP_SIZE %u, " + "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE %u, " "__afl_final_loc %u, " "max_size_forkserver %u/0x%x\n", id_str == NULL ? "" : id_str, __afl_area_ptr, @@ -462,7 +462,7 @@ static void __afl_map_shm(void) { if (__afl_debug) fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy 0x%llx, __afl_map_addr 0x%llx, MAP_SIZE " + "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE " "%u, __afl_final_loc %u, " "max_size_forkserver %u/0x%x\n", id_str == NULL ? "" : id_str, __afl_area_ptr, -- cgit 1.4.1 From 69f3095045f4e60a9ef4b0ca0c5032ed824cd4f4 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 10:40:52 +0100 Subject: correct debug --- instrumentation/afl-compiler-rt.o.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 9480b90e..71ef6c48 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -459,21 +459,20 @@ static void __afl_map_shm(void) { if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; } - if (__afl_debug) - fprintf(stderr, - "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE " - "%u, __afl_final_loc %u, " - "max_size_forkserver %u/0x%x\n", - id_str == NULL ? "" : id_str, __afl_area_ptr, - __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, - MAP_SIZE, __afl_final_loc, FS_OPT_MAX_MAPSIZE, - FS_OPT_MAX_MAPSIZE); - } __afl_area_ptr_backup = __afl_area_ptr; + if (__afl_debug) + fprintf(stderr, + "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " + "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE " + "%u, __afl_final_loc %u, " + "max_size_forkserver %u/0x%x\n", + id_str == NULL ? "" : id_str, __afl_area_ptr, + __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, + __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + if (__afl_selective_coverage) { if (__afl_map_size > MAP_INITIAL_SIZE) { -- cgit 1.4.1 From a0c30116733dd08e8d74a879c0e99be140b7eebb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 11:08:03 +0100 Subject: change map_size tests --- instrumentation/afl-llvm-common.cc | 6 ++++-- src/afl-forkserver.c | 8 ++++---- src/afl-fuzz.c | 30 +++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 11 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index aa54f4f7..0fd3a011 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -62,13 +62,15 @@ bool isIgnoreFunction(const llvm::Function *F) { "sancov.", "__ubsan_", "ign.", - "__afl_", + "__afl", "_fini", - "__libc_csu", + "__libc_", "__asan", "__msan", "__cmplog", "__sancov", + "__cxx_", + "_GLOBAL", "msan.", "LLVMFuzzerM", "LLVMFuzzerC", diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 82ec3069..68995388 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -821,7 +821,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - The target binary requires a large map and crashes before " "reporting.\n" - " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + " Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " "AFL_DEBUG=1 to see the\n" " message from the target binary\n\n" @@ -848,7 +848,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - The target binary requires a large map and crashes before " "reporting.\n" - " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + " Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " "AFL_DEBUG=1 to see the\n" " message from the target binary\n\n" @@ -914,7 +914,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handshake with the injected code.\n" "Most likely the target has a huge coverage map, retry with setting" " the\n" - "environment variable AFL_MAP_SIZE=4194304\n" + "environment variable AFL_MAP_SIZE=8000000\n" "Otherwise there is a horrible bug in the fuzzer.\n" "Poke for troubleshooting tips.\n"); @@ -933,7 +933,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - Most likely the target has a huge coverage map, retry with " "setting the\n" - " environment variable AFL_MAP_SIZE=4194304\n\n" + " environment variable AFL_MAP_SIZE=8000000\n\n" " - The current memory limit (%s) is too restrictive, causing an " "OOM\n" diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 065010fa..8364c1c2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1569,13 +1569,21 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->fsrv.map_size = 4194304; // dummy temporary value - setenv("AFL_MAP_SIZE", "4194304", 1); + u32 set_env = 0; + if (!getenv("AFL_MAP_SIZE")) { + + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); + set_env = 1; + + } + + u32 prev_map_size = afl->fsrv.map_size; u32 new_map_size = afl_fsrv_get_mapsize( &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != 4194304) { + if (new_map_size && new_map_size != prev_map_size) { // only reinitialize when it makes sense if (map_size < new_map_size || @@ -1607,6 +1615,7 @@ int main(int argc, char **argv_orig, char **envp) { } map_size = new_map_size; + if (set_env) { unsetenv("AFL_MAP_SIZE"); } } @@ -1624,13 +1633,22 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - afl->cmplog_fsrv.map_size = 4194304; + u32 set_env = 0; + if (!getenv("AFL_MAP_SIZE")) { + + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); + set_env = 1; + + } + + u32 prev_map_size = afl->fsrv.map_size; u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != 4194304) { + if (new_map_size && new_map_size != prev_map_size) { // only reinitialize when it needs to be larger if (map_size < new_map_size) { @@ -1667,6 +1685,8 @@ int main(int argc, char **argv_orig, char **envp) { } + if (set_env) { unsetenv("AFL_MAP_SIZE"); } + } afl->cmplog_fsrv.map_size = map_size; -- cgit 1.4.1 From 071edb1a2ddcf787680ca5096ddc1d6e28addd0b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 15:44:54 +0100 Subject: brackets make dominik happy --- instrumentation/afl-compiler-rt.o.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'instrumentation') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 71ef6c48..cca38cd0 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -315,7 +315,8 @@ static void __afl_map_shm(void) { 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 (__afl_debug) + if (__afl_debug) { + fprintf(stderr, "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE %u, " @@ -325,6 +326,8 @@ static void __afl_map_shm(void) { __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + } + if (id_str) { if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial && @@ -463,7 +466,8 @@ static void __afl_map_shm(void) { __afl_area_ptr_backup = __afl_area_ptr; - if (__afl_debug) + if (__afl_debug) { + fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE " @@ -473,6 +477,8 @@ static void __afl_map_shm(void) { __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + } + if (__afl_selective_coverage) { if (__afl_map_size > MAP_INITIAL_SIZE) { @@ -1111,11 +1117,14 @@ void __afl_manual_init(void) { __afl_sharedmem_fuzzing = 0; if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_ptr_dummy; - if (__afl_debug) + if (__afl_debug) { + fprintf(stderr, "DEBUG: disabled instrumentation because of " "AFL_DISABLE_LLVM_INSTRUMENTATION\n"); + } + } if (!init_done) { @@ -1299,8 +1308,12 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { if (__afl_already_initialized_forkserver && __afl_final_loc + 1 + stop - start > __afl_map_size) { - if (__afl_debug) - fprintf(stderr, "Warning: new instrumneted code after the forkserver!\n"); + if (__afl_debug) { + + fprintf(stderr, "Warning: new instrumented code after the forkserver!\n"); + + } + __afl_final_loc = 2; if (1 + stop - start > __afl_map_size) { -- cgit 1.4.1