This commit is contained in:
Dominik Maier
2021-02-15 14:07:10 +01:00
27 changed files with 201 additions and 71 deletions

View File

@ -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

View File

@ -11,6 +11,8 @@ LABEL "about"="AFLplusplus docker image"
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
env NO_ARCH_OPT 1
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install --no-install-suggests --no-install-recommends \ apt-get -y install --no-install-suggests --no-install-recommends \
automake \ 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 LLVM_CONFIG=llvm-config-12
ENV AFL_SKIP_CPUFREQ=1 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 .. RUN cd /afl-cov && make install && cd ..
COPY . /AFLplusplus COPY . /AFLplusplus
WORKDIR /AFLplusplus WORKDIR /AFLplusplus
RUN export REAL_CXX=g++-10 && export CC=gcc-10 && \ RUN export CC=gcc-10 && export CXX=g++-10 && make clean && \
export CXX=g++-10 && make clean && \ make distrib && make install && make clean
make distrib CFLAGS="-O3 -funroll-loops -D_FORTIFY_SOURCE=2" && make install && make clean
RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc
RUN echo 'export PS1="[afl++]$PS1"' >> ~/.bashrc RUN echo 'export PS1="[afl++]$PS1"' >> ~/.bashrc

View File

@ -57,8 +57,6 @@ ifdef MSAN_BUILD
override LDFLAGS += -fsanitize=memory override LDFLAGS += -fsanitize=memory
endif endif
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" "" 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" 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 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 SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
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" #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 # ifndef SOURCE_DATE_EPOCH
HAVE_MARCHNATIVE = 1 # HAVE_MARCHNATIVE = 1
CFLAGS_OPT += -march=native # CFLAGS_OPT += -march=native
endif # endif
endif #endif
ifneq "$(shell uname)" "Darwin" ifneq "$(shell uname)" "Darwin"
ifeq "$(HAVE_MARCHNATIVE)" "1" #ifeq "$(HAVE_MARCHNATIVE)" "1"
SPECIAL_PERFORMANCE += -march=native # SPECIAL_PERFORMANCE += -march=native
endif #endif
# OS X does not like _FORTIFY_SOURCE=2 # OS X does not like _FORTIFY_SOURCE=2
ifndef DEBUG ifndef DEBUG
CFLAGS_OPT += -D_FORTIFY_SOURCE=2 CFLAGS_OPT += -D_FORTIFY_SOURCE=2
@ -366,6 +364,7 @@ help:
@echo NO_PYTHON - disable python support @echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing @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 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 "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)"
@echo "==========================================" @echo "=========================================="
@echo e.g.: make ASAN_BUILD=1 @echo e.g.: make ASAN_BUILD=1

View File

@ -43,7 +43,8 @@ endif
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' ) 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_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_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_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_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 ) 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 endif
ifeq "$(LLVM_UNSUPPORTED)" "1" 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 endif
LLVM_TOO_OLD=1 LLVM_TOO_OLD=1

View File

@ -2,8 +2,6 @@
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo"> <img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo">
![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable)
Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases) Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases)
Github Version: 3.01a Github Version: 3.01a
@ -55,7 +53,7 @@ behaviours and defaults:
* a caching of testcases can now be performed and can be modified by * 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 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). `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/ * examples/ got renamed to utils/
* libtokencap/ libdislocator/ and qdbi_mode/ were moved 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 * 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_PYTHON - disable python support
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing * NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
* AFL_NO_X86 - if compiling on non-intel/amd platforms * 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) * LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)
e.g.: make ASAN_BUILD=1 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` * 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. 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 ## 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 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). the speed compared to qemu_mode (but slower than persistent mode).
Note that several other binary rewriters exist, all with their advantages and 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 caveats.
recommended approach!
### Unicorn ### Unicorn

View File

@ -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) 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 { } else {
print " Processing "in_count" files (forkserver mode)..." 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" </dev/null" # print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -A \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null"
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" </dev/null") retval = system( AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -A \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
} }
if (retval && !AFL_CMIN_CRASHES_ONLY) { if (retval && !AFL_CMIN_CRASHES_ONLY) {

View File

@ -48,6 +48,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
support (less performant than our own), GCC for old afl-gcc and support (less performant than our own), GCC for old afl-gcc and
CLANG for old afl-clang CLANG for old afl-clang
- fixed a potential crash in the LAF feature - 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 - qemuafl
- QASan (address sanitizer for Qemu) ported to qemuafl! - QASan (address sanitizer for Qemu) ported to qemuafl!
See qemu_mode/libqasan/README.md See qemu_mode/libqasan/README.md
@ -58,8 +60,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Substantial speed gains in python bindings for certain use cases - Substantial speed gains in python bindings for certain use cases
- Improved rust bindings - Improved rust bindings
- Added a new example harness to compare python, c, and 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 - 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/ - added dummy Makefile to instrumentation/
- Updated utils/afl_frida to be 5% faster, 7% on x86_x64 - Updated utils/afl_frida to be 5% faster, 7% on x86_x64
- Added AFL_KILL_SIGNAL env variable (thanks @v-p-b) - Added AFL_KILL_SIGNAL env variable (thanks @v-p-b)

View File

@ -5,6 +5,10 @@
users or for some types of custom fuzzing setups. See [README.md](README.md) for the general users or for some types of custom fuzzing setups. See [README.md](README.md) for the general
instruction manual. 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 ## 1) Settings for all compilers
Starting with afl++ 3.0 there is only one compiler: afl-cc 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` `MODE` can be one of `LTO` (afl-clang-lto*), `LLVM` (afl-clang-fast*), `GCC_PLUGIN`
(afl-g*-fast) or `GCC` (afl-gcc/afl-g++). (afl-g*-fast) or `GCC` (afl-gcc/afl-g++).
Because (with the exception of the --afl-MODE command line option) the Because (with the exception of the --afl-MODE command line option) the
compile-time tools do not accept afl specific command-line options, they compile-time tools do not accept afl specific command-line options, they
make fairly broad use of environmental variables instead: 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`. `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`). `afl_version` corresponds to the currently running afl version (e.g `++3.0c`).
Default (empty/non present) will add no tags to the metrics. 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. - Setting `AFL_CRASH_EXITCODE` sets the exit code afl treats as crash.
For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting

View File

@ -16,6 +16,7 @@ static char *afl_environment_deprecated[] = {
static char *afl_environment_variables[] = { static char *afl_environment_variables[] = {
"_AFL_LTO_COMPILE",
"AFL_ALIGNED_ALLOC", "AFL_ALIGNED_ALLOC",
"AFL_ALLOW_TMP", "AFL_ALLOW_TMP",
"AFL_ANALYZE_HEX", "AFL_ANALYZE_HEX",
@ -61,6 +62,7 @@ static char *afl_environment_variables[] = {
"AFL_FORKSRV_INIT_TMOUT", "AFL_FORKSRV_INIT_TMOUT",
"AFL_HARDEN", "AFL_HARDEN",
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
"AFL_IGNORE_UNKNOWN_ENVS",
"AFL_IMPORT_FIRST", "AFL_IMPORT_FIRST",
"AFL_INST_LIBS", "AFL_INST_LIBS",
"AFL_INST_RATIO", "AFL_INST_RATIO",

View File

@ -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) { [](const Constant *A, const Constant *B) {
return cast<ConstantInt>(A)->getLimitedValue() < return cast<ConstantInt>(A)->getLimitedValue() <
@ -1136,10 +1136,10 @@ void ModuleSanitizerCoverage::InjectTraceForGep(
for (auto GEP : GepTraceTargets) { for (auto GEP : GepTraceTargets) {
IRBuilder<> IRB(GEP); IRBuilder<> IRB(GEP);
for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I) for (Use &Idx : GEP->indices())
if (!isa<ConstantInt>(*I) && (*I)->getType()->isIntegerTy()) if (!isa<ConstantInt>(Idx) && Idx->getType()->isIntegerTy())
IRB.CreateCall(SanCovTraceGepFunction, IRB.CreateCall(SanCovTraceGepFunction,
{IRB.CreateIntCast(*I, IntptrTy, true)}); {IRB.CreateIntCast(Idx, IntptrTy, true)});
} }

View File

@ -1171,7 +1171,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
fprintf(stderr, fprintf(stderr,
"Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n", "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n",
start, stop, stop - start); start, stop, (unsigned long)(stop - start));
} }

View File

@ -113,6 +113,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C); IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
IntegerType *Int128Ty = IntegerType::getInt128Ty(C); IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
char *is_lto = getenv("_AFL_LTO_COMPILE");
#if LLVM_VERSION_MAJOR < 9 #if LLVM_VERSION_MAJOR < 9
Constant * Constant *
#else #else
@ -265,10 +267,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size; unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size;
unsigned char do_cast = 0; 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"; if (max_size % 8) {
continue;
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; max_size = 128;
do_cast = 1; do_cast = 1;
@ -301,6 +314,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
cast_size = max_size; cast_size = max_size;
break; break;
default: default:
if (is_lto) { continue; } // LTO cannot bitcast _ExtInt() :(
cast_size = 128; cast_size = 128;
do_cast = 1; 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) { 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; max_size = 128;
do_cast = 1; do_cast = 1;
@ -568,6 +598,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
cast_size = max_size; cast_size = max_size;
break; break;
default: default:
if (is_lto) { continue; } // LTO cannot bitcast from _ExtInt() :(
cast_size = 128; cast_size = 128;
do_cast = 1; do_cast = 1;

View File

@ -1 +1 @@
47722f64e4 213f3b27dd

View File

@ -233,7 +233,6 @@ QEMU_CONF_FLAGS=" \
--disable-xen \ --disable-xen \
--disable-xen-pci-passthrough \ --disable-xen-pci-passthrough \
--disable-xfsctl \ --disable-xfsctl \
--enable-pie \
--python=${PYTHONBIN} \ --python=${PYTHONBIN} \
--target-list="${CPU_TARGET}-linux-user" \ --target-list="${CPU_TARGET}-linux-user" \
--without-default-devices \ --without-default-devices \
@ -241,7 +240,7 @@ QEMU_CONF_FLAGS=" \
if [ -n "${CROSS_PREFIX}" ]; then 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 fi
@ -249,10 +248,15 @@ if [ "$STATIC" = "1" ]; then
echo Building STATIC binary echo Building STATIC binary
QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--static \ --static \
--extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \ --extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \
" "
else
QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} --enable-pie "
fi fi
if [ "$DEBUG" = "1" ]; then if [ "$DEBUG" = "1" ]; then
@ -262,7 +266,7 @@ if [ "$DEBUG" = "1" ]; then
# --enable-gcov might go here but incurs a mesonbuild error on meson # --enable-gcov might go here but incurs a mesonbuild error on meson
# versions prior to 0.56: # versions prior to 0.56:
# https://github.com/qemu/meson/commit/903d5dd8a7dc1d6f8bef79e66d6ebc07c # https://github.com/qemu/meson/commit/903d5dd8a7dc1d6f8bef79e66d6ebc07c
QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--disable-strip \ --disable-strip \
--enable-debug \ --enable-debug \
--enable-debug-info \ --enable-debug-info \
@ -275,7 +279,7 @@ if [ "$DEBUG" = "1" ]; then
else else
QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--disable-debug-info \ --disable-debug-info \
--disable-debug-mutex \ --disable-debug-mutex \
--disable-debug-tcg \ --disable-debug-tcg \
@ -290,7 +294,7 @@ if [ "$PROFILING" = "1" ]; then
echo Building PROFILED binary echo Building PROFILED binary
QEMU_CONF_FLAGS="${QEMU_CONF_FLAGS} \ QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--enable-gprof \ --enable-gprof \
--enable-profiler \ --enable-profiler \
" "
@ -298,7 +302,7 @@ if [ "$PROFILING" = "1" ]; then
fi fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
./configure ${QEMU_CONF_FLAGS} || exit 1 ./configure $QEMU_CONF_FLAGS || exit 1
echo "[+] Configuration complete." echo "[+] Configuration complete."

View File

@ -29,6 +29,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include "types.h" #include "types.h"
#include "config.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; size_t i;
if (debug_fd != 1) { if (debug_fd != 1) {
char debugbuf[4096]; 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, v0 == NULL ? "(null)" : (char *)v0,
v1 == NULL ? "(null)" : (char *)v1, n); v1 == NULL ? "(null)" : (char *)v1, n);
write(debug_fd, debugbuf, strlen(debugbuf)); write(debug_fd, debugbuf, strlen(debugbuf));
@ -206,7 +209,7 @@ int strcmp(const char *str1, const char *str2) {
if (n <= MAX_CMP_LENGTH) { 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 = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1; 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) { 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 = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1; cur_loc &= MAP_SIZE - 1;
@ -265,7 +268,7 @@ int strcasecmp(const char *str1, const char *str2) {
if (n <= MAX_CMP_LENGTH) { 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 = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1; 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) { 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 = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1; 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) { 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 = (cur_loc >> 4) ^ (cur_loc << 8);
cur_loc &= MAP_SIZE - 1; cur_loc &= MAP_SIZE - 1;

View File

@ -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 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.

View File

@ -3916,6 +3916,11 @@ static void internal_malloc_stats(mstate m) {
clear_smallmap(M, I); \ clear_smallmap(M, I); \
\ \
} else if (RTCHECK(B == smallbin_at(M, I) || \ } else if (RTCHECK(B == smallbin_at(M, I) || \
<<<<<<< HEAD
=======
\
\
>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
(ok_address(M, B) && B->fd == P))) { \ (ok_address(M, B) && B->fd == P))) { \
\ \
F->bk = B; \ F->bk = B; \
@ -4126,6 +4131,11 @@ static void internal_malloc_stats(mstate m) {
XP->child[1] = R; \ XP->child[1] = R; \
\ \
} else \ } else \
<<<<<<< HEAD
=======
\
\
>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \ CORRUPTION_ERROR_ACTION(M); \
if (R != 0) { \ if (R != 0) { \
\ \
@ -4141,6 +4151,11 @@ static void internal_malloc_stats(mstate m) {
C0->parent = R; \ C0->parent = R; \
\ \
} else \ } else \
<<<<<<< HEAD
=======
\
\
>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \ CORRUPTION_ERROR_ACTION(M); \
\ \
} \ } \
@ -4152,11 +4167,21 @@ static void internal_malloc_stats(mstate m) {
C1->parent = R; \ C1->parent = R; \
\ \
} else \ } else \
<<<<<<< HEAD
=======
\
\
>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \ CORRUPTION_ERROR_ACTION(M); \
\ \
} \ } \
\ \
} else \ } else \
<<<<<<< HEAD
=======
\
\
>>>>>>> e3a5c31307f323452dc4b5288e0d19a02b596a33
CORRUPTION_ERROR_ACTION(M); \ CORRUPTION_ERROR_ACTION(M); \
\ \
} \ } \

View File

@ -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_DEBUG("%14p: fgets(%p, %d, %p)\n", rtv, s, size, stream);
QASAN_STORE(s, size); QASAN_STORE(s, size);
#ifndef __ANDROID__
QASAN_LOAD(stream, sizeof(FILE)); QASAN_LOAD(stream, sizeof(FILE));
#endif
char *r = __lq_libc_fgets(s, size, stream); char *r = __lq_libc_fgets(s, size, stream);
QASAN_DEBUG("\t\t = %p\n", r); QASAN_DEBUG("\t\t = %p\n", r);

View File

@ -72,7 +72,7 @@ void __libqasan_print_maps(void) {
QASAN_LOG("QEMU-AddressSanitizer (v%s)\n", QASAN_VERSTR); QASAN_LOG("QEMU-AddressSanitizer (v%s)\n", QASAN_VERSTR);
QASAN_LOG( QASAN_LOG(
"Copyright (C) 2019-2020 Andrea Fioraldi <andreafioraldi@gmail.com>\n"); "Copyright (C) 2019-2021 Andrea Fioraldi <andreafioraldi@gmail.com>\n");
QASAN_LOG("\n"); QASAN_LOG("\n");
if (__qasan_log) __libqasan_print_maps(); if (__qasan_log) __libqasan_print_maps();

View File

@ -271,7 +271,7 @@ void *__libqasan_memmem(const void *haystack, size_t haystack_len,
} }
} while (++h <= end); } while (h++ <= end);
return 0; return 0;

View File

@ -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) { if (lto_mode && !have_c) {
u8 *ld_path = strdup(AFL_REAL_LD); u8 *ld_path = strdup(AFL_REAL_LD);
@ -1582,6 +1587,7 @@ int main(int argc, char **argv, char **envp) {
"libtokencap.so)\n" "libtokencap.so)\n"
" AFL_PATH: path to instrumenting pass and runtime " " AFL_PATH: path to instrumenting pass and runtime "
"(afl-compiler-rt.*o)\n" "(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_INST_RATIO: percentage of branches to instrument\n"
" AFL_QUIET: suppress verbose output\n" " AFL_QUIET: suppress verbose output\n"
" AFL_HARDEN: adds code hardening to catch memory bugs\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); edit_params(argc, argv, envp);
if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); }
if (debug) { if (debug) {
DEBUGF("cd '%s';", getthecwd()); DEBUGF("cd '%s';", getthecwd());

View File

@ -523,7 +523,7 @@ void check_environment_vars(char **envp) {
if (be_quiet) { return; } if (be_quiet) { return; }
int index = 0, issue_detected = 0; int index = 0, issue_detected = 0;
char *env, *val; char *env, *val, *ignore = getenv("AFL_IGNORE_UNKNOWN_ENVS");
while ((env = envp[index++]) != NULL) { while ((env = envp[index++]) != NULL) {
if (strncmp(env, "ALF_", 4) == 0 || strncmp(env, "_ALF", 4) == 0 || 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); WARNF("Mistyped AFL environment variable: %s", env);
issue_detected = 1; issue_detected = 1;

View File

@ -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 cmp_header *h = &afl->shm.cmp_map->headers[key];
struct tainted * t; struct tainted * t;
u32 i, j, idx, taint_len, loggeds; u32 i, j, idx, taint_len, loggeds;
u32 have_taint = 1, is_n = 0; u32 have_taint = 1;
u8 status = 0, found_one = 0; u8 status = 0, found_one = 0;
/* loop cmps are useless, detect and ignore them */ /* loop cmps are useless, detect and ignore them */
#ifdef WORD_SIZE_64 #ifdef WORD_SIZE_64
u32 is_n = 0;
u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0;
#endif #endif
u64 s_v0, s_v1; 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)) { switch (SHAPE_BYTES(h->shape)) {
case 1: 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) { for (i = 0; i < loggeds; ++i) {
struct cmp_operands *o = &afl->shm.cmp_map->log[key][i]; struct cmp_operands *o = &afl->shm.cmp_map->log[key][i];
@ -2620,8 +2624,8 @@ exit_its:
} }
#else #else
u32 *v = (u64 *)afl->virgin_bits; u32 *v = (u32 *)afl->virgin_bits;
u32 *s = (u64 *)virgin_save; u32 *s = (u32 *)virgin_save;
u32 i; u32 i;
for (i = 0; i < (afl->shm.map_size >> 2); i++) { for (i = 0; i < (afl->shm.map_size >> 2); i++) {

View File

@ -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_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
"AFL_HANG_TMOUT: override timeout value (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_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_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_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" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"

View File

@ -1013,7 +1013,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (in_dir) { if (in_dir) {
if (at_file) { PFATAL("Options -A and -i are mutually exclusive"); }
detect_file_args(argv + optind, "", &fsrv->use_stdin); detect_file_args(argv + optind, "", &fsrv->use_stdin);
} else { } else {
@ -1169,8 +1168,9 @@ int main(int argc, char **argv_orig, char **envp) {
} }
stdin_file = stdin_file = at_file ? strdup(at_file)
alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); : (char *)alloc_printf("%s/.afl-showmap-temp-%u",
use_dir, (u32)getpid());
unlink(stdin_file); unlink(stdin_file);
atexit(at_exit_handler); atexit(at_exit_handler);
fsrv->out_file = stdin_file; fsrv->out_file = stdin_file;

View File

@ -7,7 +7,7 @@ AFL_GCC=afl-gcc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin" $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 "$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 && { 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 AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
test -e test-instr.plain && { test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded" $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 "$RED[!] ${AFL_GCC} failed"
echo CUT------------------------------------------------------------------CUT echo CUT------------------------------------------------------------------CUT
uname -a uname -a
../${AFL_GCC} -o test-instr.plain ../test-instr.c ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c
echo CUT------------------------------------------------------------------CUT echo CUT------------------------------------------------------------------CUT
CODE=1 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" $ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
SKIP= SKIP=
test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && { 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 AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
test -e test-instr.plain && { test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded" $ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"