diff --git a/.github/workflows/build_aflplusplus_docker.yaml b/.github/workflows/build_aflplusplus_docker.yaml
new file mode 100644
index 00000000..be8d795d
--- /dev/null
+++ b/.github/workflows/build_aflplusplus_docker.yaml
@@ -0,0 +1,27 @@
+name: Publish Docker Images
+on:
+ push:
+ branches: [ stable ]
+ paths:
+ - Dockerfile
+ pull_request:
+ branches: [ stable ]
+ paths:
+ - Dockerfile
+jobs:
+ push_to_registry:
+ name: Push Docker images to Dockerhub
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: Login to Dockerhub
+ uses: docker/login-action@v1
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_TOKEN }}
+ - name: Publish aflpp to Registry
+ uses: docker/build-push-action@v2
+ with:
+ context: .
+ push: true
+ tags: aflplusplus/aflplusplus:latest
diff --git a/Dockerfile b/Dockerfile
index 8779fee5..1cb00d5d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,6 +11,8 @@ LABEL "about"="AFLplusplus docker image"
ARG DEBIAN_FRONTEND=noninteractive
+env NO_ARCH_OPT 1
+
RUN apt-get update && \
apt-get -y install --no-install-suggests --no-install-recommends \
automake \
@@ -48,16 +50,16 @@ RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 0
ENV LLVM_CONFIG=llvm-config-12
ENV AFL_SKIP_CPUFREQ=1
+ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
-RUN git clone https://github.com/vanhauser-thc/afl-cov /afl-cov
+RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov /afl-cov
RUN cd /afl-cov && make install && cd ..
COPY . /AFLplusplus
WORKDIR /AFLplusplus
-RUN export REAL_CXX=g++-10 && export CC=gcc-10 && \
- export CXX=g++-10 && make clean && \
- make distrib CFLAGS="-O3 -funroll-loops -D_FORTIFY_SOURCE=2" && make install && make clean
+RUN export CC=gcc-10 && export CXX=g++-10 && make clean && \
+ make distrib && make install && make clean
RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc
RUN echo 'export PS1="[afl++]$PS1"' >> ~/.bashrc
diff --git a/GNUmakefile b/GNUmakefile
index 4ba5d3b3..0420cdfc 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -57,8 +57,6 @@ ifdef MSAN_BUILD
override LDFLAGS += -fsanitize=memory
endif
-
-
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
CFLAGS_FLTO ?= -flto=full
@@ -77,17 +75,17 @@ ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -
SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
endif
-ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- ifndef SOURCE_DATE_EPOCH
- HAVE_MARCHNATIVE = 1
- CFLAGS_OPT += -march=native
- endif
-endif
+#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+# ifndef SOURCE_DATE_EPOCH
+# HAVE_MARCHNATIVE = 1
+# CFLAGS_OPT += -march=native
+# endif
+#endif
ifneq "$(shell uname)" "Darwin"
- ifeq "$(HAVE_MARCHNATIVE)" "1"
- SPECIAL_PERFORMANCE += -march=native
- endif
+ #ifeq "$(HAVE_MARCHNATIVE)" "1"
+ # SPECIAL_PERFORMANCE += -march=native
+ #endif
# OS X does not like _FORTIFY_SOURCE=2
ifndef DEBUG
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
@@ -366,6 +364,7 @@ help:
@echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
+ @echo NO_ARCH_OPT - builds afl++ without machine architecture optimizations
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)"
@echo "=========================================="
@echo e.g.: make ASAN_BUILD=1
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index d3691658..cc332f6c 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -43,7 +43,8 @@ endif
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
-LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^1[3-9]' && echo 1 || echo 0 )
+LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^[0-2]\.' && echo 1 || echo 0 )
+LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[3-9]' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]' && echo 1 || echo 0 )
@@ -58,7 +59,11 @@ ifeq "$(LLVMVER)" ""
endif
ifeq "$(LLVM_UNSUPPORTED)" "1"
- $(warning llvm_mode only supports llvm versions 3.4 up to 12)
+ $(error llvm_mode only supports llvm from version 3.4 onwards)
+endif
+
+ifeq "$(LLVM_TOO_NEW)" "1"
+ $(warning you are using an in-development llvm version - this might break llvm_mode!)
endif
LLVM_TOO_OLD=1
diff --git a/README.md b/README.md
index 4f49bf99..00095390 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,6 @@
- 
-
Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases)
Github Version: 3.01a
@@ -55,7 +53,7 @@ behaviours and defaults:
* a caching of testcases can now be performed and can be modified by
editing config.h for TESTCASE_CACHE or by specifying the env variable
`AFL_TESTCACHE_SIZE` (in MB). Good values are between 50-500 (default: 50).
- * -M mains does not perform trimming
+ * -M mains do not perform trimming
* examples/ got renamed to utils/
* libtokencap/ libdislocator/ and qdbi_mode/ were moved to utils/
* afl-cmin/afl-cmin.bash now search first in PATH and last in AFL_PATH
@@ -219,6 +217,7 @@ These build options exist:
* NO_PYTHON - disable python support
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
* AFL_NO_X86 - if compiling on non-intel/amd platforms
+* NO_ARCH_OPT - builds afl++ without machine architecture optimizations
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)
e.g.: make ASAN_BUILD=1
@@ -752,6 +751,8 @@ campaigns as these are much shorter runnings.
* for CMPLOG targets, 60% for `-l 2`, 40% for `-l 3`
4. Do *not* run any `-M` modes, just running `-S` modes is better for CI fuzzing.
+ `-M` enables deterministic fuzzing, old queue handling etc. which is good for
+ a fuzzing campaign but not good for short CI runs.
## Fuzzing binary-only targets
@@ -789,8 +790,7 @@ If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for
your binary, then you can use afl-fuzz normally and it will have twice
the speed compared to qemu_mode (but slower than persistent mode).
Note that several other binary rewriters exist, all with their advantages and
-caveats. As rewriting a binary is much faster than Qemu this is a highly
-recommended approach!
+caveats.
### Unicorn
diff --git a/afl-cmin b/afl-cmin
index 31d7ddad..4ee79a79 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -411,8 +411,8 @@ BEGIN {
retval = system( AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
} else {
print " Processing "in_count" files (forkserver mode)..."
-# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string" .
support (less performant than our own), GCC for old afl-gcc and
CLANG for old afl-clang
- fixed a potential crash in the LAF feature
+ - workaround for llvm 13
+ - workaround for llvm internal lto bug that lets not bitcast from _ExtInt()
- qemuafl
- QASan (address sanitizer for Qemu) ported to qemuafl!
See qemu_mode/libqasan/README.md
@@ -58,8 +60,10 @@ sending a mail to .
- Substantial speed gains in python bindings for certain use cases
- Improved rust bindings
- Added a new example harness to compare python, c, and rust bindings
+ - afl-cmin and afl-showmap now support the -f option
- changed default: no memory limit for afl-cmin and afl-cmin.bash
- - warn on any _AFL and __AFL env vars
+ - warn on any _AFL and __AFL env vars.
+ - set AFL_IGNORE_UNKNOWN_ENVS to not warn on unknown AFL_... env vars.
- added dummy Makefile to instrumentation/
- Updated utils/afl_frida to be 5% faster, 7% on x86_x64
- Added AFL_KILL_SIGNAL env variable (thanks @v-p-b)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 886669ad..f6ed12d0 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -5,6 +5,10 @@
users or for some types of custom fuzzing setups. See [README.md](README.md) for the general
instruction manual.
+ Note that most tools will warn on any unknown AFL environment variables.
+ This is for warning on typos that can happen. If you want to disable this
+ check then set the `AFL_IGNORE_UNKNOWN_ENVS` environment variable.
+
## 1) Settings for all compilers
Starting with afl++ 3.0 there is only one compiler: afl-cc
@@ -18,7 +22,6 @@ To select the different instrumentation modes this can be done by
`MODE` can be one of `LTO` (afl-clang-lto*), `LLVM` (afl-clang-fast*), `GCC_PLUGIN`
(afl-g*-fast) or `GCC` (afl-gcc/afl-g++).
-
Because (with the exception of the --afl-MODE command line option) the
compile-time tools do not accept afl specific command-line options, they
make fairly broad use of environmental variables instead:
@@ -448,6 +451,7 @@ checks or alter some of the more exotic semantics of the tool:
`banner` corresponds to the name of the fuzzer provided through `-M/-S`.
`afl_version` corresponds to the currently running afl version (e.g `++3.0c`).
Default (empty/non present) will add no tags to the metrics.
+ See [rpc_statsd.md](rpc_statsd.md) for more information.
- Setting `AFL_CRASH_EXITCODE` sets the exit code afl treats as crash.
For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting
diff --git a/include/envs.h b/include/envs.h
index 210b34a6..36667ebc 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -16,6 +16,7 @@ static char *afl_environment_deprecated[] = {
static char *afl_environment_variables[] = {
+ "_AFL_LTO_COMPILE",
"AFL_ALIGNED_ALLOC",
"AFL_ALLOW_TMP",
"AFL_ANALYZE_HEX",
@@ -61,6 +62,7 @@ static char *afl_environment_variables[] = {
"AFL_FORKSRV_INIT_TMOUT",
"AFL_HARDEN",
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
+ "AFL_IGNORE_UNKNOWN_ENVS",
"AFL_IMPORT_FIRST",
"AFL_INST_LIBS",
"AFL_INST_RATIO",
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 5d6d6703..9b1351b0 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -1088,7 +1088,7 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch(
}
- llvm::sort(Initializers.begin() + 2, Initializers.end(),
+ llvm::sort(drop_begin(Initializers, 2),
[](const Constant *A, const Constant *B) {
return cast(A)->getLimitedValue() <
@@ -1136,10 +1136,10 @@ void ModuleSanitizerCoverage::InjectTraceForGep(
for (auto GEP : GepTraceTargets) {
IRBuilder<> IRB(GEP);
- for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I)
- if (!isa(*I) && (*I)->getType()->isIntegerTy())
+ for (Use &Idx : GEP->indices())
+ if (!isa(Idx) && Idx->getType()->isIntegerTy())
IRB.CreateCall(SanCovTraceGepFunction,
- {IRB.CreateIntCast(*I, IntptrTy, true)});
+ {IRB.CreateIntCast(Idx, IntptrTy, true)});
}
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 3a9e3e0e..5fb715e2 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1171,7 +1171,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
fprintf(stderr,
"Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n",
- start, stop, stop - start);
+ start, stop, (unsigned long)(stop - start));
}
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index b5cc1882..6b071b48 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -113,6 +113,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
+ char *is_lto = getenv("_AFL_LTO_COMPILE");
+
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
@@ -265,10 +267,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size;
unsigned char do_cast = 0;
- if (!SI->getNumCases() || max_size < 16 || max_size % 8) {
+ if (!SI->getNumCases() || max_size < 16) { continue; }
- // if (!be_quiet) errs() << "skip trivial switch..\n";
- continue;
+ if (max_size % 8) {
+
+ if (is_lto) {
+
+ continue; // LTO cannot bitcast from _ExtInt() :(
+
+ } else {
+
+ max_size = (((max_size / 8) + 1) * 8);
+ do_cast = 1;
+
+ }
}
@@ -285,6 +297,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
+ if (is_lto) { continue; } // LTO cannot bitcast _ExtInt() :(
max_size = 128;
do_cast = 1;
@@ -301,6 +314,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
cast_size = max_size;
break;
default:
+ if (is_lto) { continue; } // LTO cannot bitcast _ExtInt() :(
cast_size = 128;
do_cast = 1;
@@ -540,7 +554,22 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
- if (!max_size || max_size % 8 || max_size < 16) { continue; }
+ if (!max_size || max_size < 16) { continue; }
+
+ if (max_size % 8) {
+
+ if (is_lto) {
+
+ continue; // LTO cannot bitcast from _ExtInt() :(
+
+ } else {
+
+ max_size = (((max_size / 8) + 1) * 8);
+ do_cast = 1;
+
+ }
+
+ }
if (max_size > 128) {
@@ -552,6 +581,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
+ if (is_lto) { continue; } // LTO cannot bitcast from _ExtInt() :(
max_size = 128;
do_cast = 1;
@@ -568,6 +598,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
cast_size = max_size;
break;
default:
+ if (is_lto) { continue; } // LTO cannot bitcast from _ExtInt() :(
cast_size = 128;
do_cast = 1;
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index d9f0ec33..b0d4fd45 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-47722f64e4
+213f3b27dd
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index a161cc43..50e5d4e8 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -233,7 +233,6 @@ QEMU_CONF_FLAGS=" \
--disable-xen \
--disable-xen-pci-passthrough \
--disable-xfsctl \
- --enable-pie \
--python=${PYTHONBIN} \
--target-list="${CPU_TARGET}-linux-user" \
--without-default-devices \
@@ -241,7 +240,7 @@ QEMU_CONF_FLAGS=" \
if [ -n "${CROSS_PREFIX}" ]; then
- QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} --cross-prefix=${CROSS_PREFIX}"
+ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS --cross-prefix=$CROSS_PREFIX"
fi
@@ -249,10 +248,15 @@ if [ "$STATIC" = "1" ]; then
echo Building STATIC binary
- QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \
+ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--static \
--extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \
"
+
+else
+
+ QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} --enable-pie "
+
fi
if [ "$DEBUG" = "1" ]; then
@@ -262,7 +266,7 @@ if [ "$DEBUG" = "1" ]; then
# --enable-gcov might go here but incurs a mesonbuild error on meson
# versions prior to 0.56:
# https://github.com/qemu/meson/commit/903d5dd8a7dc1d6f8bef79e66d6ebc07c
- QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \
+ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--disable-strip \
--enable-debug \
--enable-debug-info \
@@ -275,7 +279,7 @@ if [ "$DEBUG" = "1" ]; then
else
- QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \
+ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--disable-debug-info \
--disable-debug-mutex \
--disable-debug-tcg \
@@ -290,7 +294,7 @@ if [ "$PROFILING" = "1" ]; then
echo Building PROFILED binary
- QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \
+ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--enable-gprof \
--enable-profiler \
"
@@ -298,7 +302,7 @@ if [ "$PROFILING" = "1" ]; then
fi
# shellcheck disable=SC2086
-./configure ${QEMU_CONF_FLAGS} || exit 1
+./configure $QEMU_CONF_FLAGS || exit 1
echo "[+] Configuration complete."
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index 23f465a4..4fc84e62 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -29,6 +29,8 @@
#include
#include
#include
+#include
+#include
#include "types.h"
#include "config.h"
@@ -159,14 +161,15 @@ static void __compcov_load(void) {
}
-static void __compcov_trace(u64 cur_loc, const u8 *v0, const u8 *v1, size_t n) {
+static void __compcov_trace(uintptr_t cur_loc, const u8 *v0, const u8 *v1,
+ size_t n) {
size_t i;
if (debug_fd != 1) {
char debugbuf[4096];
- snprintf(debugbuf, sizeof(debugbuf), "0x%llx %s %s %zu\n", cur_loc,
+ snprintf(debugbuf, sizeof(debugbuf), "0x%" PRIxPTR " %s %s %zu\n", cur_loc,
v0 == NULL ? "(null)" : (char *)v0,
v1 == NULL ? "(null)" : (char *)v1, n);
write(debug_fd, debugbuf, strlen(debugbuf));
@@ -206,7 +209,7 @@ int strcmp(const char *str1, const char *str2) {
if (n <= MAX_CMP_LENGTH) {
- u64 cur_loc = (u64)retaddr;
+ uintptr_t cur_loc = (uintptr_t)retaddr;
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1;
@@ -235,7 +238,7 @@ int strncmp(const char *str1, const char *str2, size_t len) {
if (n <= MAX_CMP_LENGTH) {
- u64 cur_loc = (u64)retaddr;
+ uintptr_t cur_loc = (uintptr_t)retaddr;
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1;
@@ -265,7 +268,7 @@ int strcasecmp(const char *str1, const char *str2) {
if (n <= MAX_CMP_LENGTH) {
- u64 cur_loc = (u64)retaddr;
+ uintptr_t cur_loc = (uintptr_t)retaddr;
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1;
@@ -296,7 +299,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
if (n <= MAX_CMP_LENGTH) {
- u64 cur_loc = (u64)retaddr;
+ uintptr_t cur_loc = (uintptr_t)retaddr;
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1;
@@ -324,7 +327,7 @@ int memcmp(const void *mem1, const void *mem2, size_t len) {
if (n <= MAX_CMP_LENGTH) {
- u64 cur_loc = (u64)retaddr;
+ uintptr_t cur_loc = (uintptr_t)retaddr;
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1;
diff --git a/qemu_mode/libqasan/README.md b/qemu_mode/libqasan/README.md
index 83fb2442..4a241233 100644
--- a/qemu_mode/libqasan/README.md
+++ b/qemu_mode/libqasan/README.md
@@ -4,16 +4,25 @@ This library is the injected runtime used by QEMU AddressSanitizer (QASan).
The original repository is [here](https://github.com/andreafioraldi/qasan).
-The version embedded in qemuafl is an updated version of just the usermode part and this runtime is injected via LD_PRELOAD (so works just for dynamically linked binaries).
+The version embedded in qemuafl is an updated version of just the usermode part
+and this runtime is injected via LD_PRELOAD (so works just for dynamically
+linked binaries).
-The usage is super simple, just set the env var `AFL_USE_QASAN=1` when fuzzing in qemu mode (-Q). afl-fuzz will automatically set AFL_PRELOAD to load this library and enable the QASan instrumentation in afl-qemu-trace.
+The usage is super simple, just set the env var `AFL_USE_QASAN=1` when fuzzing
+in qemu mode (-Q). afl-fuzz will automatically set AFL_PRELOAD to load this
+library and enable the QASan instrumentation in afl-qemu-trace.
-For debugging purposes, we still suggest to run the original QASan as the stacktrace support for ARM (just a debug feature, it does not affect the bug finding capabilities during fuzzing) is WIP.
+For debugging purposes, we still suggest to run the original QASan as the
+stacktrace support for ARM (just a debug feature, it does not affect the bug
+finding capabilities during fuzzing) is WIP.
-### When I should use QASan?
+### When should I use QASan?
-If your target binary is PIC x86_64, you should also give a try to [retrowrite](https://github.com/HexHive/retrowrite) for static rewriting.
+If your target binary is PIC x86_64, you should also give a try to
+[retrowrite](https://github.com/HexHive/retrowrite) for static rewriting.
-If it fails, or if your binary is for another architecture, or you want to use persistent and snapshot mode, AFL++ QASan mode is what you want/have to use.
+If it fails, or if your binary is for another architecture, or you want to use
+persistent and snapshot mode, AFL++ QASan mode is what you want/have to use.
-Note that the overhead of libdislocator when combined with QEMU mode is much lower but it can catch less bugs. This is a short blanket, take your choice.
+Note that the overhead of libdislocator when combined with QEMU mode is much
+lower but it can catch less bugs. This is a short blanket, take your choice.
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index 71cafd9d..74b05e15 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -3916,6 +3916,11 @@ static void internal_malloc_stats(mstate m) {
clear_smallmap(M, I); \
\
} else if (RTCHECK(B == smallbin_at(M, I) || \
+<<<<<<< HEAD
+=======
+ \
+ \
+>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
(ok_address(M, B) && B->fd == P))) { \
\
F->bk = B; \
@@ -4126,6 +4131,11 @@ static void internal_malloc_stats(mstate m) {
XP->child[1] = R; \
\
} else \
+<<<<<<< HEAD
+=======
+ \
+ \
+>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \
if (R != 0) { \
\
@@ -4141,6 +4151,11 @@ static void internal_malloc_stats(mstate m) {
C0->parent = R; \
\
} else \
+<<<<<<< HEAD
+=======
+ \
+ \
+>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \
\
} \
@@ -4152,11 +4167,21 @@ static void internal_malloc_stats(mstate m) {
C1->parent = R; \
\
} else \
+<<<<<<< HEAD
+=======
+ \
+ \
+>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \
\
} \
\
} else \
+<<<<<<< HEAD
+=======
+ \
+ \
+>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \
\
} \
diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c
index 3bb4cc42..405dddae 100644
--- a/qemu_mode/libqasan/hooks.c
+++ b/qemu_mode/libqasan/hooks.c
@@ -174,7 +174,9 @@ char *fgets(char *s, int size, FILE *stream) {
QASAN_DEBUG("%14p: fgets(%p, %d, %p)\n", rtv, s, size, stream);
QASAN_STORE(s, size);
+#ifndef __ANDROID__
QASAN_LOAD(stream, sizeof(FILE));
+#endif
char *r = __lq_libc_fgets(s, size, stream);
QASAN_DEBUG("\t\t = %p\n", r);
diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c
index 11b50270..9fc4ef7a 100644
--- a/qemu_mode/libqasan/libqasan.c
+++ b/qemu_mode/libqasan/libqasan.c
@@ -72,7 +72,7 @@ void __libqasan_print_maps(void) {
QASAN_LOG("QEMU-AddressSanitizer (v%s)\n", QASAN_VERSTR);
QASAN_LOG(
- "Copyright (C) 2019-2020 Andrea Fioraldi \n");
+ "Copyright (C) 2019-2021 Andrea Fioraldi \n");
QASAN_LOG("\n");
if (__qasan_log) __libqasan_print_maps();
diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c
index 4be01279..c850463b 100644
--- a/qemu_mode/libqasan/string.c
+++ b/qemu_mode/libqasan/string.c
@@ -271,7 +271,7 @@ void *__libqasan_memmem(const void *haystack, size_t haystack_len,
}
- } while (++h <= end);
+ } while (h++ <= end);
return 0;
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 47722f64..9a258d5b 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 47722f64e4c1662bad97dc25f3e4cc63959ff5f3
+Subproject commit 9a258d5b7a38c045a6e385fcfcf80a746a60e557
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 0ae401e7..959c9a6f 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -554,6 +554,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
+#if LLVM_MAJOR >= 13
+ // fuck you llvm 13
+ cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
+#endif
+
if (lto_mode && !have_c) {
u8 *ld_path = strdup(AFL_REAL_LD);
@@ -1582,6 +1587,7 @@ int main(int argc, char **argv, char **envp) {
"libtokencap.so)\n"
" AFL_PATH: path to instrumenting pass and runtime "
"(afl-compiler-rt.*o)\n"
+ " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
" AFL_INST_RATIO: percentage of branches to instrument\n"
" AFL_QUIET: suppress verbose output\n"
" AFL_HARDEN: adds code hardening to catch memory bugs\n"
@@ -1869,6 +1875,8 @@ int main(int argc, char **argv, char **envp) {
edit_params(argc, argv, envp);
+ if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); }
+
if (debug) {
DEBUGF("cd '%s';", getthecwd());
diff --git a/src/afl-common.c b/src/afl-common.c
index 1cc7f462..589aac71 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -523,7 +523,7 @@ void check_environment_vars(char **envp) {
if (be_quiet) { return; }
int index = 0, issue_detected = 0;
- char *env, *val;
+ char *env, *val, *ignore = getenv("AFL_IGNORE_UNKNOWN_ENVS");
while ((env = envp[index++]) != NULL) {
if (strncmp(env, "ALF_", 4) == 0 || strncmp(env, "_ALF", 4) == 0 ||
@@ -582,7 +582,7 @@ void check_environment_vars(char **envp) {
}
- if (match == 0) {
+ if (match == 0 && !ignore) {
WARNF("Mistyped AFL environment variable: %s", env);
issue_detected = 1;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index deaddc56..cf65d3c1 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1512,11 +1512,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
struct cmp_header *h = &afl->shm.cmp_map->headers[key];
struct tainted * t;
u32 i, j, idx, taint_len, loggeds;
- u32 have_taint = 1, is_n = 0;
+ u32 have_taint = 1;
u8 status = 0, found_one = 0;
/* loop cmps are useless, detect and ignore them */
#ifdef WORD_SIZE_64
+ u32 is_n = 0;
u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0;
#endif
u64 s_v0, s_v1;
@@ -1534,6 +1535,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
+#ifdef WORD_SIZE_64
switch (SHAPE_BYTES(h->shape)) {
case 1:
@@ -1546,6 +1548,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
+#endif
+
for (i = 0; i < loggeds; ++i) {
struct cmp_operands *o = &afl->shm.cmp_map->log[key][i];
@@ -2620,8 +2624,8 @@ exit_its:
}
#else
- u32 *v = (u64 *)afl->virgin_bits;
- u32 *s = (u64 *)virgin_save;
+ u32 *v = (u32 *)afl->virgin_bits;
+ u32 *s = (u32 *)virgin_save;
u32 i;
for (i = 0; i < (afl->shm.map_size >> 2); i++) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e79671e0..8eb3625b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -198,6 +198,7 @@ static void usage(u8 *argv0, int more_help) {
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
+ "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index c424cdf3..b40527d3 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1013,7 +1013,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (in_dir) {
- if (at_file) { PFATAL("Options -A and -i are mutually exclusive"); }
detect_file_args(argv + optind, "", &fsrv->use_stdin);
} else {
@@ -1169,8 +1168,9 @@ int main(int argc, char **argv_orig, char **envp) {
}
- stdin_file =
- alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid());
+ stdin_file = at_file ? strdup(at_file)
+ : (char *)alloc_printf("%s/.afl-showmap-temp-%u",
+ use_dir, (u32)getpid());
unlink(stdin_file);
atexit(at_exit_handler);
fsrv->out_file = stdin_file;
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 132610c0..b4bb9df2 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -7,7 +7,7 @@ AFL_GCC=afl-gcc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "i386" && {
test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
- ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
+ ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"
@@ -39,7 +39,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
$ECHO "$RED[!] ${AFL_GCC} failed"
echo CUT------------------------------------------------------------------CUT
uname -a
- ../${AFL_GCC} -o test-instr.plain ../test-instr.c
+ ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c
echo CUT------------------------------------------------------------------CUT
CODE=1
}
@@ -128,7 +128,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
SKIP=
test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
- ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
+ ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"