Merge pull request #426 from AFLplusplus/dev

Dev
This commit is contained in:
van Hauser 2020-06-29 18:19:35 +02:00 committed by GitHub
commit 8f1b78f49e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 69783 additions and 31707 deletions

4
.gitignore vendored
View File

@ -18,6 +18,7 @@ afl-gcc-fast
afl-g++-fast
afl-gotcpu
afl-ld
afl-ld-lto
afl-qemu-trace
afl-showmap
afl-tmin
@ -45,9 +46,12 @@ ld
qemu_mode/qemu-*
unicorn_mode/samples/*/\.test-*
unicorn_mode/samples/*/output/
unicorn_mode/unicornafl
core\.*
test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable
test/unittests/unit_list
test/unittests/unit_rand
test/unittests/unit_hash
examples/afl_network_proxy/afl-network-server
examples/afl_network_proxy/afl-network-client

View File

@ -9,9 +9,9 @@ branches:
matrix:
include:
- os: linux
dist: focal
env: NAME="focal-amd64" MODERN="yes" GCC="9"
# - os: linux # focal errors every run with a timeout while installing packages
# dist: focal
# env: NAME="focal-amd64" MODERN="yes" GCC="9"
- os: linux
dist: bionic
env: NAME="bionic-amd64" MODERN="yes" GCC="7"

View File

@ -50,19 +50,30 @@ else
endif
endif
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
endif
ifneq "$(shell uname)" "Darwin"
#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"
# CFLAGS_OPT += -march=native
#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"
#CFLAGS_OPT += -march=native
SPECIAL_PERFORMANCE += -march=native
endif
# OS X does not like _FORTIFY_SOURCE=2
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
endif
ifeq "$(shell uname)" "SunOS"
CFLAGS_OPT += -Wno-format-truncation
LDFLAGS=-lkstat
endif
ifdef STATIC
$(info Compiling static version of binaries)
$(info Compiling static version of binaries, disabling python though)
# Disable python for static compilation to simplify things
PYTHON_OK=0
PYFLAGS=
PYTHON_INCLUDE=/
CFLAGS_OPT += -static
LDFLAGS += -lm -lpthread -lz -lutil
@ -86,7 +97,7 @@ endif
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
ifeq "$(shell uname -s)" "FreeBSD"
@ -109,6 +120,13 @@ ifeq "$(shell uname -s)" "NetBSD"
LDFLAGS += -L /usr/pkg/lib/
endif
ifeq "$(shell uname -s)" "Haiku"
SHMAT_OK=0
override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fPIC
LDFLAGS += -Wno-deprecated-declarations -lgnu
SPECIAL_PERFORMANCE += -DUSEMMAP=1
endif
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
ifneq "$(shell command -v python3m 2>/dev/null)" ""
@ -182,12 +200,12 @@ ifneq "$(filter Linux GNU%,$(shell uname))" ""
endif
ifneq "$(findstring FreeBSD, $(shell uname))" ""
CFLAGS += -pthread
override CFLAGS += -pthread
LDFLAGS += -lpthread
endif
ifneq "$(findstring NetBSD, $(shell uname))" ""
CFLAGS += -pthread
override CFLAGS += -pthread
LDFLAGS += -lpthread
endif
@ -227,7 +245,7 @@ endif
ifdef ASAN_BUILD
$(info Compiling ASAN version of binaries)
CFLAGS+=$(ASAN_CFLAGS)
override CFLAGS+=$(ASAN_CFLAGS)
LDFLAGS+=$(ASAN_LDFLAGS)
endif
@ -235,14 +253,14 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
SHMAT_OK=1
else
SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations
override CFLAGS+=-DUSEMMAP=1
LDFLAGS += -Wno-deprecated-declarations -lrt
endif
ifeq "$(TEST_MMAP)" "1"
ifdef TEST_MMAP
SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations
override CFLAGS += -DUSEMMAP=1
LDFLAGS += -Wno-deprecated-declarations -lrt
endif
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done
@ -265,8 +283,8 @@ help:
@echo "HELP --- the following make targets exist:"
@echo "=========================================="
@echo "all: just the main afl++ binaries"
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa"
@echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa"
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap"
@echo "distrib: everything (for both binary-only and source code fuzzing)"
@echo "man: creates simple man pages from the help option of the programs"
@echo "install: installs everything you have compiled with the build option above"
@ -294,6 +312,8 @@ ifndef AFL_NO_X86
test_x86:
@echo "[*] Checking for the default compiler cc..."
@type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC=<yourCcompiler>'."; echo; exit 1 )
@echo "[*] Testing the PATH environment variable..."
@test "$${PATH}" != "$${PATH#.:}" && { echo "Please remove current directory '.' from PATH to avoid recursion of 'as', thanks!"; echo; exit 1; } || :
@echo "[*] Checking for the ability to compile x86 code..."
@echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 )
@rm -f .test1
@ -345,6 +365,9 @@ afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
ln -sf afl-as as
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
$(CC) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
@ -354,42 +377,47 @@ src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
radamsa: src/third_party/libradamsa/libradamsa.so
cp src/third_party/libradamsa/libradamsa.so .
src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h
$(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)"
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS)
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS)
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS)
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
# document all mutations and only do one run (use with only one input file!)
document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
$(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-performance.o | test_x86
$(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_maybe_alloc
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_hash
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_rand
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
@ -397,8 +425,8 @@ unit_list: test/unittests/unit_list.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_list
test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
unit_preallocable: test/unittests/unit_preallocable.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
@ -409,7 +437,7 @@ unit_clean:
ifneq "$(shell uname)" "Darwin"
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
else
@ -429,6 +457,8 @@ code-format:
./.custom-format.py -i gcc_plugin/*.c
#./.custom-format.py -i gcc_plugin/*.h
./.custom-format.py -i gcc_plugin/*.cc
./.custom-format.py -i custom_mutators/*/*.c
./.custom-format.py -i custom_mutators/*/*.h
./.custom-format.py -i examples/*/*.c
./.custom-format.py -i examples/*/*.h
./.custom-format.py -i test/*.c
@ -481,7 +511,6 @@ clean:
$(MAKE) -C examples/argv_fuzzing clean
$(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C src/third_party/libradamsa/ clean
rm -rf qemu_mode/qemu-3.1.1
ifeq "$(IN_REPO)" "1"
test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
@ -495,7 +524,7 @@ deepclean: clean
rm -rf unicorn_mode/unicornafl
git reset --hard >/dev/null 2>&1 || true
distrib: all radamsa
distrib: all
-$(MAKE) -C llvm_mode
-$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator
@ -504,18 +533,18 @@ distrib: all radamsa
$(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
binary-only: all radamsa
binary-only: all
$(MAKE) -C libdislocator
$(MAKE) -C libtokencap
$(MAKE) -C examples/afl_network_proxy
$(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
source-only: all radamsa
source-only: all
-$(MAKE) -C llvm_mode
-$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator
@ -554,7 +583,6 @@ install: all $(MANPAGES)
if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi
if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi

View File

@ -54,7 +54,7 @@
* Win32 PE binary-only fuzzing with QEMU and Wine
* Radamsa mutator (enable with `-R` to add or `-RR` to run it exclusively).
* Radamsa mutator (as a custom mutator).
* QBDI mode to fuzz android native libraries via QBDI framework
@ -167,8 +167,8 @@ is what you should choose.
These build targets exist:
* all: just the main afl++ binaries
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap, radamsa
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap
* distrib: everything (for both binary-only and source code fuzzing)
* man: creates simple man pages from the help option of the programs
* install: installs everything you have compiled with the build options above
@ -371,14 +371,15 @@ therefore may increase the code coverage.
The available schedules are:
- explore (default)
- fast
- coe
- quad
- lin
- exploit
- mmopt (experimental)
- rare (experimental)
- explore (default, original AFL)
- exploit (original AFL)
- fast (AFLfast)
- coe (AFLfast)
- quad (AFLfast)
- lin (AFLfast)
- rare (afl++ experimental)
- mmopt (afl++ experimental)
- seek (afl++ experimental)
In parallel mode (-M/-S, several instances with the shared queue), we suggest to
run the main node using the explore or fast schedule (-p explore) and the secondary

11
TODO.md
View File

@ -3,13 +3,9 @@
## Roadmap 2.65+
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
- random crc32 HASH_CONST per run? because with 65536 paths we have collisions
- namespace for targets? e.g. network
- libradamsa as a custom module?
- learn from honggfuzz
- for persistent mode, have a functionality that transports the test case
via shared memory (and the int write to the FD from afl-fuzz is the size)
- CPU affinity for many cores?
- learn from honggfuzz (mutations, maybe ptrace?)
- CPU affinity for many cores? There seems to be an issue > 96 cores
## Further down the road
@ -18,9 +14,10 @@ afl-fuzz:
- setting min_len/max_len/start_offset/end_offset limits for mutation output
llvm_mode:
- better whitelist solution for LTO
- LTO - imitate sancov
gcc_plugin:
- (wait for submission then decide)
- laf-intel
- better instrumentation (seems to be better with gcc-9+)

View File

@ -134,7 +134,6 @@ Environment variables used:
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
AFL_PATH: path for the afl-showmap binary
AFL_SKIP_BIN_CHECK: skip check for target binary
AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp
_EOF_
exit 1
fi
@ -142,29 +141,29 @@ fi
# Do a sanity check to discourage the use of /tmp, since we can't really
# handle this safely from a shell script.
if [ "$AFL_ALLOW_TMP" = "" ]; then
echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
T1="$?"
echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
T2="$?"
echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
T3="$?"
echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
T4="$?"
echo "$PWD" | grep -qE '^(/var)?/tmp/'
T5="$?"
if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
exit 1
fi
fi
#if [ "$AFL_ALLOW_TMP" = "" ]; then
#
# echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
# T1="$?"
#
# echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
# T2="$?"
#
# echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
# T3="$?"
#
# echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
# T4="$?"
#
# echo "$PWD" | grep -qE '^(/var)?/tmp/'
# T5="$?"
#
# if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
# echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
# exit 1
# fi
#
#fi
# If @@ is specified, but there's no -f, let's come up with a temporary input
# file name.
@ -246,7 +245,7 @@ if [ ! "$STDIN_FILE" = "" ]; then
fi
if [ "$AFL_PATH" = "" ]; then
SHOWMAP="${0%/afl-cmin}/afl-showmap"
SHOWMAP="${0%/afl-cmin.bash}/afl-showmap"
else
SHOWMAP="$AFL_PATH/afl-showmap"
fi

View File

@ -15,6 +15,10 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
get_abs_path() {
echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`"
}
echo "progress plotting utility for afl-fuzz by Michal Zalewski"
echo
@ -31,40 +35,40 @@ an empty directory where this tool can write the resulting plots to.
The program will put index.html and three PNG images in the output directory;
you should be able to view it with any web browser of your choice.
Environment variables used:
AFL_ALLOW_TMP: allow /var/tmp or /tmp for input and output directories
_EOF_
exit 1
fi
if [ "$AFL_ALLOW_TMP" = "" ]; then
inputdir=`get_abs_path "$1"`
outputdir=`get_abs_path "$2"`
echo "$1" | grep -qE '^(/var)?/tmp/'
T1="$?"
#if [ "$AFL_ALLOW_TMP" = "" ]; then
#
# echo "$inputdir" | grep -qE '^(/var)?/tmp/'
# T1="$?"
#
# echo "$outputdir" | grep -qE '^(/var)?/tmp/'
# T2="$?"
#
# if [ "$T1" = "0" -o "$T2" = "0" ]; then
#
# echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
# exit 1
#
# fi
#
#fi
echo "$2" | grep -qE '^(/var)?/tmp/'
T2="$?"
if [ "$T1" = "0" -o "$T2" = "0" ]; then
echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
exit 1
fi
fi
if [ ! -f "$1/plot_data" ]; then
if [ ! -f "$inputdir/plot_data" ]; then
echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
exit 1
fi
BANNER="`cat "$1/fuzzer_stats" | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
test "$BANNER" = "" && BANNER="(none)"
@ -77,17 +81,17 @@ if [ "$GNUPLOT" = "" ]; then
fi
mkdir "$2" 2>/dev/null
mkdir "$outputdir" 2>/dev/null
if [ ! -d "$2" ]; then
if [ ! -d "$outputdir" ]; then
echo "[-] Error: unable to create the output directory - pick another location." 1>&2
exit 1
fi
rm -f "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png"
mv -f "$2/index.html" "$2/index.html.orig" 2>/dev/null
rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png"
mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null
echo "[*] Generating plots..."
@ -96,7 +100,7 @@ echo "[*] Generating plots..."
cat <<_EOF_
set terminal png truecolor enhanced size 1000,300 butt
set output '$2/high_freq.png'
set output '$outputdir/high_freq.png'
set xdata time
set timefmt '%s'
@ -114,31 +118,31 @@ set key outside
set autoscale xfixmin
set autoscale xfixmax
plot '$1/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
'' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
'' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\
'' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3
set terminal png truecolor enhanced size 1000,200 butt
set output '$2/low_freq.png'
set output '$outputdir/low_freq.png'
plot '$1/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
'' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\
'' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3
set terminal png truecolor enhanced size 1000,200 butt
set output '$2/exec_speed.png'
set output '$outputdir/exec_speed.png'
plot '$1/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
'$1/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
'$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
_EOF_
) | gnuplot
if [ ! -s "$2/exec_speed.png" ]; then
if [ ! -s "$outputdir/exec_speed.png" ]; then
echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2
exit 1
@ -147,10 +151,10 @@ fi
echo "[*] Generating index.html..."
cat >"$2/index.html" <<_EOF_
cat >"$outputdir/index.html" <<_EOF_
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr>
<tr><td><b>Directory:</b></td><td>$1</td></tr>
<tr><td><b>Directory:</b></td><td>$inputdir</td></tr>
<tr><td><b>Generated on:</b></td><td>`date`</td></tr>
</table>
<p>
@ -164,8 +168,8 @@ _EOF_
# served by Apache or other HTTP daemon. Since the plots aren't horribly
# sensitive, this seems like a reasonable trade-off.
chmod 755 "$2"
chmod 644 "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" "$2/index.html"
chmod 755 "$outputdir"
chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/index.html"
echo "[+] All done - enjoy your charts!"

12
custom_mutators/README.md Normal file
View File

@ -0,0 +1,12 @@
# production ready custom mutators
This directory holds ready to use custom mutators.
Just type "make" in the individual subdirectories.
Use with e.g.
`AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/radamsa/radamsa-mutator.so afl-fuzz ....`
and add `AFL_CUSTOM_MUTATOR_ONLY=1` if you only want to use the custom mutator.
Multiple custom mutators can be used by separating their paths with `:` in the environment variable.

View File

@ -1,15 +1,15 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
all: libradamsa.so
all: radamsa-mutator.so
# These can be overriden:
CFLAGS ?= -march=native $(CFLAGS_FLTO)
CFLAGS ?= $(CFLAGS_FLTO)
# These are required: (otherwise radamsa gets very very slooooow)
CFLAGS += -O3 -funroll-loops
libradamsa.so: libradamsa.a
$(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
#libradamsa.so: libradamsa.a
# $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************"
@ -17,10 +17,14 @@ libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************"
$(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c
radamsa-mutator.so: radamsa-mutator.c libradamsa.a
$(CC) $(CFLAGS) -g -I. -I../../include -shared -fPIC -c radamsa-mutator.c
$(CC) $(CFLAGS) -shared -fPIC -o radamsa-mutator.so radamsa-mutator.o libradamsa.a
test: libradamsa.a libradamsa-test.c
$(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
./libradamsa-test libradamsa-test.c | grep "library test passed"
rm /tmp/libradamsa-*.fuzz
clean:
rm -f libradamsa.a libradamsa.so libradamsa-test
rm -f radamsa-mutator.so libradamsa.a libradamsa-test *.o *~ core

View File

@ -1,4 +1,4 @@
# libradamsa
# custum mutator: libradamsa
Pretranslated radamsa library. This code belongs to the radamsa author.

View File

@ -0,0 +1,342 @@
#ifndef CUSTOM_MUTATOR_HELPERS
#define CUSTOM_MUTATOR_HELPERS
#include "config.h"
#include "types.h"
#include <stdlib.h>
#define INITIAL_GROWTH_SIZE (64)
#define RAND_BELOW(limit) (rand() % (limit))
/* Use in a struct: creates a name_buf and a name_size variable. */
#define BUF_VAR(type, name) \
type * name##_buf; \
size_t name##_size;
/* this filles in `&structptr->something_buf, &structptr->something_size`. */
#define BUF_PARAMS(struct, name) \
(void **)&struct->name##_buf, &struct->name##_size
typedef struct {
} afl_t;
static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) {
static s8 interesting_8[] = {INTERESTING_8};
static s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
static s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
switch (RAND_BELOW(12)) {
case 0: {
/* Flip a single bit somewhere. Spooky! */
s32 bit_idx = ((RAND_BELOW(end - begin) + begin) << 3) + RAND_BELOW(8);
out_buf[bit_idx >> 3] ^= 128 >> (bit_idx & 7);
break;
}
case 1: {
/* Set byte to interesting value. */
u8 val = interesting_8[RAND_BELOW(sizeof(interesting_8))];
out_buf[(RAND_BELOW(end - begin) + begin)] = val;
break;
}
case 2: {
/* Set word to interesting value, randomly choosing endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
switch (RAND_BELOW(2)) {
case 0:
*(u16 *)(out_buf + byte_idx) =
interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)];
break;
case 1:
*(u16 *)(out_buf + byte_idx) =
SWAP16(interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)]);
break;
}
break;
}
case 3: {
/* Set dword to interesting value, randomly choosing endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
switch (RAND_BELOW(2)) {
case 0:
*(u32 *)(out_buf + byte_idx) =
interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)];
break;
case 1:
*(u32 *)(out_buf + byte_idx) =
SWAP32(interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]);
break;
}
break;
}
case 4: {
/* Set qword to interesting value, randomly choosing endian. */
if (end - begin < 8) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 7) break;
switch (RAND_BELOW(2)) {
case 0:
*(u64 *)(out_buf + byte_idx) =
(s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)];
break;
case 1:
*(u64 *)(out_buf + byte_idx) = SWAP64(
(s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]);
break;
}
break;
}
case 5: {
/* Randomly subtract from byte. */
out_buf[(RAND_BELOW(end - begin) + begin)] -= 1 + RAND_BELOW(ARITH_MAX);
break;
}
case 6: {
/* Randomly add to byte. */
out_buf[(RAND_BELOW(end - begin) + begin)] += 1 + RAND_BELOW(ARITH_MAX);
break;
}
case 7: {
/* Randomly subtract from word, random endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
if (RAND_BELOW(2)) {
*(u16 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX);
} else {
u16 num = 1 + RAND_BELOW(ARITH_MAX);
*(u16 *)(out_buf + byte_idx) =
SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) - num);
}
break;
}
case 8: {
/* Randomly add to word, random endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
if (RAND_BELOW(2)) {
*(u16 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX);
} else {
u16 num = 1 + RAND_BELOW(ARITH_MAX);
*(u16 *)(out_buf + byte_idx) =
SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) + num);
}
break;
}
case 9: {
/* Randomly subtract from dword, random endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
if (RAND_BELOW(2)) {
*(u32 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX);
} else {
u32 num = 1 + RAND_BELOW(ARITH_MAX);
*(u32 *)(out_buf + byte_idx) =
SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) - num);
}
break;
}
case 10: {
/* Randomly add to dword, random endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
if (RAND_BELOW(2)) {
*(u32 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX);
} else {
u32 num = 1 + RAND_BELOW(ARITH_MAX);
*(u32 *)(out_buf + byte_idx) =
SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) + num);
}
break;
}
case 11: {
/* Just set a random byte to a random value. Because,
why not. We use XOR with 1-255 to eliminate the
possibility of a no-op. */
out_buf[(RAND_BELOW(end - begin) + begin)] ^= 1 + RAND_BELOW(255);
break;
}
}
}
/* This function calculates the next power of 2 greater or equal its argument.
@return The rounded up power of 2 (if no overflow) or 0 on overflow.
*/
static inline size_t next_pow2(size_t in) {
if (in == 0 || in > (size_t)-1)
return 0; /* avoid undefined behaviour under-/overflow */
size_t out = in - 1;
out |= out >> 1;
out |= out >> 2;
out |= out >> 4;
out |= out >> 8;
out |= out >> 16;
return out + 1;
}
/* This function makes sure *size is > size_needed after call.
It will realloc *buf otherwise.
*size will grow exponentially as per:
https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/
Will return NULL and free *buf if size_needed is <1 or realloc failed.
@return For convenience, this function returns *buf.
*/
static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) {
/* No need to realloc */
if (likely(size_needed && *size >= size_needed)) return *buf;
/* No initial size was set */
if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
/* grow exponentially */
size_t next_size = next_pow2(size_needed);
/* handle overflow */
if (!next_size) { next_size = size_needed; }
/* alloc */
*buf = realloc(*buf, next_size);
*size = *buf ? next_size : 0;
return *buf;
}
/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */
static inline void swap_bufs(void **buf1, size_t *size1, void **buf2,
size_t *size2) {
void * scratch_buf = *buf1;
size_t scratch_size = *size1;
*buf1 = *buf2;
*size1 = *size2;
*buf2 = scratch_buf;
*size2 = scratch_size;
}
#undef INITIAL_GROWTH_SIZE
#endif

View File

@ -0,0 +1,81 @@
#include <radamsa.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
size_t filesize(char *filename) {
struct stat st;
stat(filename, &st);
return st.st_size;
}
#define BUFSIZE 1024 * 1024
void fail(char *why) {
printf("fail: %s\n", why);
exit(1);
}
void write_output(char *data, size_t len, int num) {
char path[32];
int fd;
int wrote;
sprintf(path, "/tmp/libradamsa-%d.fuzz", num);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("Opened %s -> %d\n", path, fd);
if (fd < 0) { fail("failed to open output file"); }
wrote = write(fd, data, len);
printf("wrote %d of %zu bytes\n", wrote, len);
if (wrote != len) { fail("failed to write all of output at once"); }
close(fd);
printf("Wrote %zu bytes to %s\n", len, path);
}
int main(int nargs, char **argv) {
char * spath = argv[1];
int fd = open(spath, O_RDONLY, 0);
size_t len;
char * input;
char * output;
int seed = 0;
if (fd < 0) { fail("cannot open input file"); }
len = filesize(spath);
input = malloc(len);
output = malloc(BUFSIZE);
if (!input || !output) { fail("failed to allocate buffers\n"); }
radamsa_init();
if (len != read(fd, input, len)) {
fail("failed to read the entire sample at once");
}
while (seed++ < 100) {
size_t n;
n = radamsa((uint8_t *)input, len, (uint8_t *)output, BUFSIZE, seed);
write_output(output, n, seed);
printf("Fuzzed %zu -> %zu bytes\n", len, n);
}
printf("library test passed\n");
free(output);
free(input);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
// This simple example just creates random buffer <= 100 filled with 'A'
// needs -I /path/to/AFLplusplus/include
//#include "custom_mutator_helpers.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "radamsa.h"
#include "custom_mutator_helpers.h"
typedef struct my_mutator {
afl_t *afl;
u8 *mutator_buf;
unsigned int seed;
} my_mutator_t;
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
srand(seed);
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
if (!data) {
perror("afl_custom_init alloc");
return NULL;
}
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
perror("mutator_buf alloc");
return NULL;
}
data->afl = afl;
data->seed = seed;
radamsa_init();
return data;
}
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
size_t max_size) {
*out_buf = data->mutator_buf;
return radamsa(buf, buf_size, data->mutator_buf, max_size, data->seed++);
}
/**
* Deinitialize everything
*
* @param data The data ptr from afl_custom_init
*/
void afl_custom_deinit(my_mutator_t *data) {
free(data->mutator_buf);
free(data);
}

View File

@ -0,0 +1,10 @@
#include <inttypes.h>
#include <stddef.h>
void radamsa_init(void);
size_t radamsa(uint8_t *ptr, size_t len, uint8_t *target, size_t max,
unsigned int seed);
size_t radamsa_inplace(uint8_t *ptr, size_t len, size_t max, unsigned int seed);

124
dictionaries/ftp.dict Normal file
View File

@ -0,0 +1,124 @@
# from https://github.com/antonio-morales/Fuzzing/Dictionaries/FTP/Example.dict.txt
#Parameters
#tls = {0,1,2,3}
#Input1
"user"
"pass"
"syst"
"acct"
"feat"
"noop"
"help"
"stat"
"stru"
"adat"
"site"
#Input2
"mkd"
"cwd"
"pwd"
"cdup"
#Input3
"port"
"list"
"mlst"
"nlst"
"mlsd"
#Input4
"rmd"
#Input5
"stor"
#Input6
"retr"
#Input7
"dele"
#Input8
"pasv"
#Input9
"epsv"
#Input10
"type"
"size"
#Input11
"mode"
#Input12
"rnfr"
"rnto"
#Input13
"appe"
#Input14
"allo"
"quit"
#Input15
"connect"
#Input16
"esta"
"estp"
#Input17
"mdtm"
"opts"
"eprt"
#Input18
"mfmt"
"pret"
"stou"
"rest"
#-------------------------------------
"\x00"
"\x0d\x0a"
"\x0d"
"\x0a"
"-"
"-a "
"-C "
"-d "
"-F "
"-l "
"-r "
"-R "
"-S "
"-t"
" "
"fuzzing"
"test"
"teste"
".txt"
"test.txt"
" UTC"
"C"
"E"
"P"
"S"
"abor"
#ifdef WITH_TLS
"pbsz"
"auth"
"prot"
"ccc"
#ifdef DEBUG
"xdbg"
# ifdef WITH_DIRALIASES
"alias"

View File

@ -71,7 +71,7 @@
"Location"
"Max-Forwards"
"Origin"
"P3P "
"P3P"
"Pragma"
"Proxy-Authenticate"
"Proxy-Authorization"

View File

@ -373,7 +373,7 @@
"ALT "
"AMH "
"ANG "
"APPH"
"APPH"
"ARA "
"ARG "
"ARI "
@ -394,9 +394,9 @@
"BAR "
"BAU "
"BBC "
"BBR "
"BBR "
"BCH "
"BCR "
"BCR "
"BDY "
"BEL "
"BEM "
@ -416,7 +416,7 @@
"BLN "
"BLT "
"BMB "
"BML "
"BML "
"BOS "
"BPY "
"BRE "
@ -521,7 +521,7 @@
"GAE "
"GAG "
"GAL "
"GAR "
"GAR "
"GAW "
"GEZ "
"GIH "
@ -725,7 +725,7 @@
"MOK "
"MOL "
"MON "
"MOR "
"MOR "
"MOS "
"MRI "
"MTH "
@ -751,7 +751,7 @@
"NEP "
"NEW "
"NGA "
"NGR "
"NGR "
"NHC "
"NIS "
"NIU "
@ -930,7 +930,7 @@
"VIT "
"VOL "
"VRO "
"WA "
"WA "
"WAG "
"WAR "
"WCR "
@ -949,7 +949,7 @@
"YAP "
"YBA "
"YCR "
"YIC "
"YIC "
"YIM "
"ZEA "
"ZGH "

View File

@ -11,21 +11,32 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++2.65d (dev)
- afl-fuzz:
- -S secondary nodes now only sync from the main node to increase performance,
the -M main node still syncs from everyone. Added checks that ensure
exactly one main node is present and warn otherwise
- If no main node is present at a sync one secondary node automatically becomes
a temporary main node until a real main nodes shows up
- -S secondary nodes now only sync from the main node to increase
performance, the -M main node still syncs from everyone. Added checks
that ensure exactly one main node is present and warn otherwise
- Add -D after -S to force a secondary to perform deterministic fuzzing
- If no main node is present at a sync one secondary node automatically
becomes a temporary main node until a real main nodes shows up
- Fixed a mayor performance issue we inherited from AFLfast
- switched murmur2 hashing and random() for xxh3 and xoshiro256**,
resulting in an up to 5.5% speed increase
- Resizing the window does not crash afl-fuzz anymore
- Ensure that the targets are killed on exit
- fix/update to MOpt (thanks to arnow117)
- added MOpt dictionary support from repo
- added experimental SEEK power schedule. It is EXPLORE with ignoring
the runtime and less focus on the length of the test case
- llvm_mode:
- the default instrumentation is now PCGUARD, as it is faster and provides
better coverage. The original afl instrumentation can be set via
AFL_LLVM_INSTRUMENT=AFL. This is automatically done when the WHITELIST
feature is used.
- some targets want a ld variant for LD that is not gcc/clang but ld, added
afl-ld-lto to solve this
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim,
which needs 3.8.0)
- the default instrumentation is now PCGUARD if the llvm version is >= 7,
as it is faster and provides better coverage. The original afl
instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is
automatically done when the WHITELIST feature is used.
- PCGUARD mode is now even better because we made it collision free - plus
it has a fixed map size, so it is also faster! :)
- some targets want a ld variant for LD that is not gcc/clang but ld,
added afl-ld-lto to solve this
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which
needs 3.8.0)
- WHITELIST feature now supports wildcards (thanks to sirmc)
- small change to cmplog to make it work with current llvm 11-dev
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
@ -37,16 +48,23 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- enable snapshot lkm also for persistent mode
- Unicornafl
- Added powerPC support from unicorn/next
- rust bindings!
- CMPLOG/Redqueen now also works for MMAP sharedmem
- ensure shmem is released on errors
- we moved radamsa to be a custom mutator in ./custom_mutators/. It is not
compiled by default anymore.
- allow running in /tmp (only unsafe with umask 0)
- persistent mode shared memory testcase handover (instead of via
files/stdin) - 10-100% performance increase
- General support for 64 bit PowerPC, RiscV, Sparc etc.
- fix afl-cmin.bash
- slightly better performance compilation options for afl++ and targets
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in
the same second
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
- added former post_library examples to examples/custom_mutators/
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and gcc 10
so afl-clang-lto can be build
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and
gcc 10 so afl-clang-lto can be build
### Version ++2.65c (release):

View File

@ -1,9 +0,0 @@
# libradamsa
Pretranslated radamsa library. This code belongs to the radamsa author.
> Original repository: https://gitlab.com/akihe/radamsa
> Source commit: 7b2cc2d0
> The code here is adapted for AFL++ with minor changes respect the original version

View File

@ -6,7 +6,7 @@ for future AFL++ versions.
For GSOC2020 interested students please see
[https://github.com/AFLplusplus/AFLplusplus/issues/208](https://github.com/AFLplusplus/AFLplusplus/issues/208)
## Flexible Grammar Mutator
## Flexible Grammar Mutator (currently in development)
Currently, AFL++'s mutation does not have deeper knowledge about the fuzzed
binary, apart from feedback, even though the developer may have insights
@ -25,41 +25,21 @@ various results.
Mentor: andreafioraldi
## Expand on the MOpt mutator
Work on the MOpt mutator that is already in AFL++.
This is an excellent mutations scheduler based on Particle Swarm
Optimization but the current implementation schedule only the mutations
that were present on AFL.
AFL++ added a lot of optional mutators like the Input-2-State one based
on Redqueen, the Radamsa mutator, the Custom mutator (the user can define
its own mutator) and the work is to generalize MOpt for all the current
and future mutators.
Mentor: vanhauser-thc or andreafioraldi
## perf-fuzz Linux Kernel Module
Either Port the patch to the upcoming Ubuntu LTS 20.04 default kernel
and provide a qemu-kvm image or find a different userspace snapshot
solution that has a good performance and is reliable, e.g. with docker.
[perf-fuzz](https://gts3.org/assets/papers/2017/xu:os-fuzz.pdf)
The perf-fuzz kernel can be found at [https://github.com/sslab-gatech/perf-fuzz](https://github.com/sslab-gatech/perf-fuzz)
There also is/was a FreeBSD project at [https://github.com/veracode-research/freebsd-perf-fuzz](https://github.com/veracode-research/freebsd-perf-fuzz)
This enables snapshot fuzzing on Linux with an incredible performance!
Expand on [snapshot LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
To make it thread safe, can snapshot several processes at once and increase
overall performance.
Mentor: any
Idea/Issue tracker: [https://github.com/AFLplusplus/AFLplusplus/issues/248](https://github.com/AFLplusplus/AFLplusplus/issues/248)
## QEMU 4-based Instrumentation
## QEMU 5-based Instrumentation
First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior
changed, which vastly decreases fuzzing speeds.
This is the cause why, right now, we cannot switch to QEMU 4.2.
In this task test if QEMU 5 performs better and port the afl++ QEMU 3.1
patches to QEMU 5.
Understanding the current instrumentation and fixing the current caching
issues will be needed.
@ -86,7 +66,7 @@ Either improve a single mutator thorugh learning of many different bugs
Mentor: domenukk
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library (currently in development)
Right now, afl-fuzz is single threaded, cannot safely be embedded in tools,
and not multi-threaded. It makes use of a large number of globals, must always

View File

@ -21,6 +21,7 @@ We find that AFL's exploitation-based constant schedule assigns **too much energ
| `-p exploit` (AFL) | ![LIN](http://latex.codecogs.com/gif.latex?p%28i%29%20%3D%20%5Calpha%28i%29) |
| `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries |
| `-p rare` | Experimental: `rare` puts focus on queue entries that hit rare edges |
| `-p seek` | Experimental: `seek` is EXPLORE but ignoring the runtime of the queue input and less focus on the size |
where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path.
More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).

View File

@ -7,20 +7,22 @@ ifneq "" "$(LLVM_BINDIR)"
LLVM_BINDIR := $(LLVM_BINDIR)/
endif
FLAGS=-O3 -funroll-loops
FLAGS=-O3 -funroll-loops -g
all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
aflpp_driver.o: aflpp_driver.cpp
$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -std=c++11 -c aflpp_driver.cpp
libAFLDriver.a: aflpp_driver.o
ar ru libAFLDriver.a aflpp_driver.o
debug:
$(LLVM_BINDIR)clang++ -D_DEBUG=\"1\" $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
ar ru libAFLDriver.a aflpp_driver.o
$(LLVM_BINDIR)clang++ -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c
$(LLVM_BINDIR)clang++ -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
#$(LLVM_BINDIR)clang++ -S -emit-llvm -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c
#$(LLVM_BINDIR)clang++ -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
ar ru libAFLDriver.a afl-performance.o aflpp_driver.o
aflpp_qemu_driver.o: aflpp_qemu_driver.c
$(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c
@ -34,8 +36,9 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o
aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c
$(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c
test: libAFLDriver.a aflpp_driver_test.cpp
afl-clang-fast++ -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a
test: debug
#clang++ -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test.ll aflpp_driver_test.cpp
afl-clang-fast++ -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a
clean:
rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test

View File

@ -54,6 +54,10 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
#include <iostream>
#include <vector>
#ifdef _DEBUG
#include "hash.h"
#endif
// Platform detection. Copied from FuzzerInternal.h
#ifdef __linux__
#define LIBFUZZER_LINUX 1
@ -273,7 +277,11 @@ int main(int argc, char **argv) {
int num_runs = 0;
while (__afl_persistent_loop(N)) {
#ifdef _DEBUG
fprintf(stderr, "len: %u\n", *__afl_fuzz_len);
fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len);
fprintf(stderr, "RECV:");
for (int i = 0; i < *__afl_fuzz_len; i++)
fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
fprintf(stderr,"\n");
#endif
if (*__afl_fuzz_len) {
num_runs++;

View File

@ -1,19 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "hash.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
fprintf(stderr, "Received size %lu\n", Size);
fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size);
if (Size < 4)
if (Size < 5)
return 0;
if (Data[0] == 'F')
if (Data[1] == 'A')
if (Data[2] == '$')
if (Data[3] == '$')
abort();
if (Data[4] == '$')
abort();
return 0;

View File

@ -49,9 +49,13 @@ int main(int argc, char **argv) {
len = __AFL_FUZZ_TESTCASE_LEN;
fprintf(stderr, "input: %zd \"%s\"\n", len, buf);
/* do we have enough data? */
if (len < 8) continue;
if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n");
if (buf[0] == 'f') {
printf("one\n");

View File

@ -28,11 +28,12 @@ MAN_PATH ?= $(PREFIX)/man/man8
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CFLAGS = -Wall -I../include -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
-Wno-unused-function
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CFLAGS_SAFE := -Wall -I../include -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
-Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CXXEFLAGS := $(CXXFLAGS) -Wall
@ -60,13 +61,15 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
SHMAT_OK=1
else
SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1
LDFLAGS += -lrt
override CFLAGS += -DUSEMMAP=1
endif
ifeq "$(TEST_MMAP)" "1"
SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1
override CFLAGS += -DUSEMMAP=1
endif
ifneq "$(shell uname -s)" "Haiku"
LDFLAGS += -lrt
endif
@ -111,7 +114,7 @@ afl-common.o: ../src/afl-common.c
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps
$(CC) $(CFLAGS) -fPIC -c $< -o $@
$(CC) $(CFLAGS_SAFE) -fPIC -c $< -o $@
test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..."

View File

@ -231,7 +231,7 @@ static void edit_params(u32 argc, char **argv) {
}
#ifdef USEMMAP
#if defined(USEMMAP) && !defined(__HAIKU__)
cc_params[cc_par_cnt++] = "-lrt";
#endif

View File

@ -35,7 +35,9 @@
#include <assert.h>
#include <sys/mman.h>
#include <sys/shm.h>
#ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/wait.h>
#include <sys/types.h>

View File

@ -49,6 +49,7 @@
#include "sharedmem.h"
#include "forkserver.h"
#include "common.h"
#include "hash.h"
#include <stdio.h>
#include <unistd.h>
@ -66,7 +67,9 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
@ -83,7 +86,7 @@
can hope... */
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__DragonFly__)
defined(__DragonFly__) || defined(__sun)
#define HAVE_AFFINITY 1
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <sys/param.h>
@ -96,6 +99,11 @@
#define cpu_set_t cpuset_t
#elif defined(__NetBSD__)
#include <pthread.h>
#elif defined(__sun)
#include <sys/types.h>
#include <kstat.h>
#include <sys/sysinfo.h>
#include <sys/pset.h>
#endif
#endif /* __linux__ */
@ -134,13 +142,13 @@ struct queue_entry {
fully_colorized; /* Do not run redqueen stage again */
u32 bitmap_size, /* Number of bits set in bitmap */
fuzz_level, /* Number of fuzzing iterations */
exec_cksum; /* Checksum of the execution trace */
fuzz_level; /* Number of fuzzing iterations */
u64 exec_us, /* Execution time (us) */
handicap, /* Number of queue cycles behind */
n_fuzz, /* Number of fuzz, does not overflow */
depth; /* Path depth */
n_fuzz, /* Number of fuzz, does not overflow*/
depth, /* Path depth */
exec_cksum; /* Checksum of the execution trace */
u8 *trace_mini; /* Trace bytes, if kept */
u32 tc_ref; /* Trace bytes ref count */
@ -180,10 +188,11 @@ enum {
/* 15 */ STAGE_HAVOC,
/* 16 */ STAGE_SPLICE,
/* 17 */ STAGE_PYTHON,
/* 18 */ STAGE_RADAMSA,
/* 19 */ STAGE_CUSTOM_MUTATOR,
/* 20 */ STAGE_COLORIZATION,
/* 21 */ STAGE_ITS,
/* 18 */ STAGE_CUSTOM_MUTATOR,
/* 19 */ STAGE_COLORIZATION,
/* 20 */ STAGE_ITS,
STAGE_NUM_MAX
};
@ -197,7 +206,7 @@ enum {
};
#define operator_num 16
#define operator_num 18
#define swarm_num 5
#define period_core 500000
@ -211,18 +220,21 @@ enum {
#define STAGE_DELETEBYTE 13
#define STAGE_Clone75 14
#define STAGE_OverWrite75 15
#define STAGE_OverWriteExtra 16
#define STAGE_InsertExtra 17
#define period_pilot 50000
enum {
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
/* 01 */ FAST, /* Exponential schedule */
/* 02 */ COE, /* Cut-Off Exponential schedule */
/* 03 */ LIN, /* Linear schedule */
/* 04 */ QUAD, /* Quadratic schedule */
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
/* 06 */ MMOPT, /* Modified MOPT schedule */
/* 07 */ RARE, /* Rare edges */
/* 01 */ EXPLOIT, /* AFL's exploitation-based const. */
/* 02 */ FAST, /* Exponential schedule */
/* 03 */ COE, /* Cut-Off Exponential schedule */
/* 04 */ LIN, /* Linear schedule */
/* 05 */ QUAD, /* Quadratic schedule */
/* 06 */ RARE, /* Rare edges */
/* 07 */ MMOPT, /* Modified MOPT schedule */
/* 08 */ SEEK, /* EXPLORE that ignores timings */
POWER_SCHEDULES_NUM
@ -416,9 +428,6 @@ typedef struct afl_state {
u8 schedule; /* Power schedule (default: EXPLORE)*/
u8 havoc_max_mult;
u8 use_radamsa;
size_t (*radamsa_mutate_ptr)(u8 *, size_t, u8 *, size_t, u32);
u8 skip_deterministic, /* Skip deterministic stages? */
use_splicing, /* Recombine input files? */
non_instrumented_mode, /* Run in non-instrumented mode? */
@ -515,11 +524,9 @@ typedef struct afl_state {
u64 stage_finds[32], /* Patterns found per fuzz stage */
stage_cycles[32]; /* Execs per fuzz stage */
#ifndef HAVE_ARC4RANDOM
u32 rand_cnt; /* Random number counter */
#endif
u32 rand_seed[2];
u64 rand_seed[4];
s64 init_seed;
u64 total_cal_us, /* Total calibration time (us) */
@ -937,7 +944,10 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
/* RedQueen */
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
u32 exec_cksum);
u64 exec_cksum);
/* xoshiro256** */
uint64_t rand_next(afl_state_t *afl);
/**** Inline routines ****/
@ -946,34 +956,31 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
#ifdef HAVE_ARC4RANDOM
if (unlikely(afl->fixed_seed)) { return random() % limit; }
/* The boundary not being necessarily a power of 2,
we need to ensure the result uniformity. */
return arc4random_uniform(limit);
#else
if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
"/dev/urandom");
srandom(afl->rand_seed[0]);
// srandom(afl->rand_seed[0]);
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
}
return random() % limit;
#endif
return rand_next(afl) % limit;
}
static inline u32 get_rand_seed(afl_state_t *afl) {
static inline s64 rand_get_seed(afl_state_t *afl) {
if (unlikely(afl->fixed_seed)) { return (u32)afl->init_seed; }
if (unlikely(afl->fixed_seed)) { return afl->init_seed; }
return afl->rand_seed[0];
}
/* initialize randomness with a given seed. Can be called again at any time. */
void rand_set_seed(afl_state_t *afl, s64 init_seed);
/* Find first power of two greater or equal to val (assuming val under
2^63). */

View File

@ -60,7 +60,7 @@ typedef enum prealloc_status {
\
if ((prealloc_counter) >= (prealloc_size)) { \
\
el_ptr = malloc(sizeof(*el_ptr)); \
el_ptr = (void *)malloc(sizeof(*el_ptr)); \
if (!el_ptr) { FATAL("error in list.h -> out of memory for element!"); } \
el_ptr->pre_status = PRE_STATUS_MALLOC; \
\

View File

@ -170,10 +170,10 @@ static inline u8 *DFL_ck_strdup(u8 *str) {
size = strlen((char *)str) + 1;
ALLOC_CHECK_SIZE(size);
ret = malloc(size);
ret = (u8 *)malloc(size);
ALLOC_CHECK_RESULT(ret, size);
return memcpy(ret, str, size);
return (u8 *)memcpy(ret, str, size);
}
@ -204,7 +204,7 @@ static inline u8 *DFL_ck_memdup_str(u8 *mem, u32 size) {
if (!mem || !size) { return NULL; }
ALLOC_CHECK_SIZE(size);
ret = malloc(size + 1);
ret = (u8 *)malloc(size + 1);
ALLOC_CHECK_RESULT(ret, size);
memcpy(ret, mem, size);

View File

@ -293,7 +293,7 @@
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
#define RESEED_RNG 10000
#define RESEED_RNG 100000
/* Maximum line length passed from GCC to 'as' and used for parsing
configuration files: */
@ -397,12 +397,5 @@
// #define IGNORE_FINDS
/* for *BSD: use ARC4RANDOM and save a file descriptor */
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#ifndef HAVE_ARC4RANDOM
#define HAVE_ARC4RANDOM 1
#endif
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
#endif /* ! _HAVE_CONFIG_H */

View File

@ -262,7 +262,7 @@
\
} while (0)
/* Die with FAULT() or PFAULT() depending on the value of res (used to
/* Die with FATAL() or PFATAL() depending on the value of res (used to
interpret different failure modes for read(), write(), etc). */
#define RPFATAL(res, x...) \

View File

@ -47,9 +47,8 @@ typedef struct afl_forkserver {
out_dir_fd; /* FD of the lock file */
s32 out_fd, /* Persistent fd for fsrv->out_file */
#ifndef HAVE_ARC4RANDOM
dev_urandom_fd, /* Persistent fd for /dev/urandom */
#endif
dev_null_fd, /* Persistent fd for /dev/null */
fsrv_ctl_fd, /* Fork server control pipe (write) */
fsrv_st_fd; /* Fork server status pipe (read) */

View File

@ -30,11 +30,18 @@
#include "types.h"
#ifdef __x86_64__
u32 hash32(u8 *key, u32 len, u32 seed);
u64 hash64(u8 *key, u32 len, u64 seed);
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
#if 0
static inline u32 hash32(const void *key, u32 len, u32 seed) {
The following code is disabled because xxh3 is 30% faster
#ifdef __x86_64__
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
static inline u32 hash32(u8 *key, u32 len, u32 seed) {
const u64 *data = (u64 *)key;
u64 h1 = seed ^ len;
@ -65,9 +72,9 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
}
#else
#else
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
static inline u32 hash32(const void *key, u32 len, u32 seed) {
@ -100,7 +107,8 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
}
#endif /* ^__x86_64__ */
#endif /* ^__x86_64__ */
#endif
#endif /* !_HAVE_HASH_H */

View File

@ -38,6 +38,8 @@ typedef struct sharedmem {
/* ================ Proteas ================ */
int g_shm_fd;
char g_shm_file_path[L_tmpnam];
int cmplog_g_shm_fd;
char cmplog_g_shm_file_path[L_tmpnam];
/* ========================================= */
#else
s32 shm_id; /* ID of the SHM region */

3187
include/xxh3.h Normal file

File diff suppressed because it is too large Load Diff

2442
include/xxhash.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -37,9 +37,12 @@
#include <sys/param.h>
#endif
#if defined(__linux__) && !defined(__ANDROID__)
#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__HAIKU__)
#include <unistd.h>
#include <sys/syscall.h>
#ifdef __linux__
#include <sys/syscall.h>
#include <malloc.h>
#endif
#ifdef __NR_getrandom
#define arc4random_buf(p, l) \
do { \

View File

@ -35,10 +35,11 @@ _UNIQ=_QINU_
_____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=)
______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl")
_OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ))
__OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ))
___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ))
____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=)
_OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ))
__OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ))
___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ))
____OS_TARGET = $(___OS_TARGET:$(_UNIQ)Haiku=$(_UNIQ))
_____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=)
TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so)

View File

@ -33,8 +33,9 @@
#include "../types.h"
#include "../config.h"
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ && \
!defined(__HAIKU__)
#error "Sorry, this library is unsupported in this platform for now!"
#endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \
!__NetBSD__*/
@ -49,6 +50,8 @@
#include <sys/user.h>
#endif
#include <sys/mman.h>
#elif defined __HAIKU__
#include <kernel/image.h>
#endif
#include <dlfcn.h>
@ -230,6 +233,19 @@ static void __tokencap_load_mappings(void) {
}
munmap(buf, len);
#elif defined __HAIKU__
image_info ii;
int32_t group = 0;
while (get_next_image_info(0, &group, &ii) == B_OK) {
__tokencap_ro[__tokencap_ro_cnt].st = ii.text;
__tokencap_ro[__tokencap_ro_cnt].en = ((char *)ii.text) + ii.text_size;
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
}
#endif
}
@ -357,7 +373,7 @@ int strcasecmp(const char *str1, const char *str2) {
while (1) {
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
if (c1 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0;
@ -381,7 +397,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
while (len--) {
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
if (c1 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0;
@ -495,7 +511,7 @@ char *strcasestr(const char *haystack, const char *needle) {
const char *n = needle;
const char *h = haystack;
while (*n && *h && tolower(*n) == tolower(*h))
while (*n && *h && tolower((int)*n) == tolower((int)*h))
n++, h++;
if (!*n) return (char *)haystack;

View File

@ -196,24 +196,31 @@ ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`com
endif
endif
CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
override CFLAGS += -Wall \
-g -Wno-pointer-sign -I ../include/ \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ../include/ \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
ifdef AFL_TRACE_PC
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
endif
CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
CXXFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
override CXXFLAGS += -Wall -g -I ../include/ \
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros
CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fpic $(CXXFLAGS)
ifneq "$(shell $(LLVM_CONFIG) --includedir) 2> /dev/null" ""
CLANG_CFL = -I$(shell $(LLVM_CONFIG) --includedir)
endif
ifneq "$(LLVM_CONFIG)" ""
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
endif
CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS)
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
@ -221,12 +228,12 @@ CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
ifeq "$(shell uname)" "Darwin"
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
else
CLANG_CFL += -Wl,-znodelete
CLANG_CPPFL += -Wl,-znodelete
endif
ifeq "$(shell uname)" "OpenBSD"
CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
CLANG_CFL += -mno-retpoline
CLANG_CPPFL += -mno-retpoline
CFLAGS += -mno-retpoline
# Needed for unwind symbols
LDFLAGS += -lc++abi
@ -304,7 +311,7 @@ afl-common.o: ../src/afl-common.c
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
$(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
$(CC) $(CLANG_CFL) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
ln -sf afl-clang-fast ../afl-clang-fast++
ifneq "$(AFL_CLANG_FLTO)" ""
ifeq "$(LLVM_LTO)" "1"
@ -317,17 +324,17 @@ afl-llvm-common.o: afl-llvm-common.cc afl-llvm-common.h
$(CXX) $(CFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps
-$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
-$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps
ifeq "$(LLVM_MIN_4_0_1)" "0"
$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
endif
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
endif
../afl-ld-lto: afl-ld-lto.c
@ -337,47 +344,47 @@ endif
../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
@$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
@$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
endif
../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
endif
# laf
../split-switches-pass.so: split-switches-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../compare-transform-pass.so: compare-transform-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../split-compares-pass.so: split-compares-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
# /laf
../cmplog-routines-pass.so: cmplog-routines-pass.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../cmplog-instructions-pass.so: cmplog-instructions-pass.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
document:
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -fPIC -c $< -o $@
$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c $< -o $@
../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..."

View File

@ -103,6 +103,7 @@ struct InsTrim : public ModulePass {
bool runOnModule(Module &M) override {
char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {

View File

@ -39,6 +39,8 @@
#include <limits.h>
#include <assert.h>
#include "llvm/Config/llvm-config.h"
static u8 * obj_path; /* Path to runtime libraries */
static u8 **cc_params; /* Parameters passed to the real CC */
static u32 cc_par_cnt = 1; /* Param count, including argv0 */
@ -464,7 +466,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
#ifdef USEMMAP
#if defined(USEMMAP) && !defined(__HAIKU__)
cc_params[cc_par_cnt++] = "-lrt";
#endif
@ -500,7 +502,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
"unsigned char *__afl_fuzz_alt_ptr;";
cc_params[cc_par_cnt++] =
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
"(__afl_fuzz_alt_ptr = malloc(1 * 1024 * 1024)))";
"(__afl_fuzz_alt_ptr = (unsigned char *) malloc(1 * 1024 * 1024)))";
cc_params[cc_par_cnt++] =
"-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
"__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
@ -757,12 +759,14 @@ int main(int argc, char **argv, char **envp) {
if (instrument_mode == 0) {
#ifndef USE_TRACE_PC
#if LLVM_VERSION_MAJOR <= 6
instrument_mode = INSTRUMENT_AFL;
#else
if (getenv("AFL_LLVM_WHITELIST"))
instrument_mode = INSTRUMENT_AFL;
else
#endif
instrument_mode = INSTRUMENT_PCGUARD;
#endif
}

View File

@ -110,8 +110,11 @@ struct InsTrimLTO : public ModulePass {
bool runOnModule(Module &M) override {
char be_quiet = 0;
char *ptr;
char be_quiet = 0;
char * ptr;
uint32_t locations = 0, functions = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
@ -561,6 +564,8 @@ struct InsTrimLTO : public ModulePass {
if (F.size() < function_minimum_size) continue;
if (isBlacklisted(&F)) continue;
functions++;
// whitelist check
AttributeList Attrs = F.getAttributes();
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
@ -657,6 +662,7 @@ struct InsTrimLTO : public ModulePass {
if (PI == PE) {
L = ConstantInt::get(Int32Ty, afl_global_id++);
locations++;
} else {
@ -668,6 +674,7 @@ struct InsTrimLTO : public ModulePass {
auto It = PredMap.insert({PBB, afl_global_id++});
unsigned Label = It.first->second;
PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB);
locations++;
}
@ -885,7 +892,7 @@ struct InsTrimLTO : public ModulePass {
for (BasicBlock *Succ : successors(Pred))
if (Succ != NULL) count++;
if (count > 1) return true;
if (count > 1) would_instrument = true;
}
@ -910,11 +917,12 @@ struct InsTrimLTO : public ModulePass {
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
OKF("Instrumented %u locations (%llu, %llu) with no collisions (on "
OKF("Instrumented %u locations for %u edges in %u functions (%llu, "
"%llu) with no collisions (on "
"average %llu collisions would be in afl-gcc/afl-clang-fast for %u "
"edges) (%s mode).",
inst_blocks, total_rs, total_hs, calculateCollisions(edges), edges,
modeline);
inst_blocks, locations, functions, total_rs, total_hs,
calculateCollisions(edges), edges, modeline);
}

View File

@ -109,6 +109,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
/* Show a banner */
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
@ -162,7 +163,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
}
if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); }
if (debug) { fprintf(stderr, "map address is 0x%lx\n", map_addr); }
/* Get/set the globals for the SHM region. */

View File

@ -111,6 +111,7 @@ bool AFLwhitelist::runOnModule(Module &M) {
/* Show a banner */
char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {

View File

@ -140,6 +140,7 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Show a banner */
char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) debug = 1;

View File

@ -139,7 +139,8 @@ static void __afl_map_shm_fuzz() {
}
map = (u8 *)mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
map =
(u8 *)mmap(0, MAX_FILE + sizeof(u32), PROT_READ, MAP_SHARED, shm_fd, 0);
#else
u32 shm_id = atoi(id_str);
@ -157,7 +158,7 @@ static void __afl_map_shm_fuzz() {
}
__afl_fuzz_len = (u32 *)map;
__afl_fuzz_ptr = (u8 *)(map + sizeof(u32));
__afl_fuzz_ptr = map + sizeof(u32);
if (getenv("AFL_DEBUG")) {
@ -182,6 +183,9 @@ static void __afl_map_shm(void) {
if (__afl_final_loc) {
if (__afl_final_loc % 8)
__afl_final_loc = (((__afl_final_loc + 7) >> 3) << 3);
__afl_map_size = __afl_final_loc;
if (__afl_final_loc > MAP_SIZE) {
@ -391,7 +395,10 @@ static void __afl_start_snapshots(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) ==
if (getenv("AFL_DEBUG"))
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
__afl_map_shm_fuzz();
@ -590,6 +597,9 @@ static void __afl_start_forkserver(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if (getenv("AFL_DEBUG"))
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
@ -870,7 +880,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
while (start < stop) {
if (R(100) < inst_ratio)
*start = R(MAP_SIZE - 1) + 1;
*start = ++__afl_final_loc;
else
*start = 0;

View File

@ -237,16 +237,16 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
switch (max_size) {
case 8:
IRB.CreateCall(cmplogHookIns1, args, "tmp");
IRB.CreateCall(cmplogHookIns1, args);
break;
case 16:
IRB.CreateCall(cmplogHookIns2, args, "tmp");
IRB.CreateCall(cmplogHookIns2, args);
break;
case 32:
IRB.CreateCall(cmplogHookIns4, args, "tmp");
IRB.CreateCall(cmplogHookIns4, args);
break;
case 64:
IRB.CreateCall(cmplogHookIns8, args, "tmp");
IRB.CreateCall(cmplogHookIns8, args);
break;
default:
break;

View File

@ -169,7 +169,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
IRB.CreateCall(cmplogHookFn, args, "tmp");
IRB.CreateCall(cmplogHookFn, args);
// errs() << callInst->getCalledFunction()->getName() << "\n";

View File

@ -500,7 +500,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
load = cur_cmp_IRB.CreateZExt(load, Int32Ty);
std::vector<Value *> args;
args.push_back(load);
load = cur_cmp_IRB.CreateCall(tolowerFn, args, "tmp");
load = cur_cmp_IRB.CreateCall(tolowerFn, args);
load = cur_cmp_IRB.CreateTrunc(load, Int8Ty);
}

View File

@ -20,7 +20,8 @@ MAN_PATH ?= $(PREFIX)/man/man8
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
CFLAGS ?= -O3 -funroll-loops -I ../../include/
CFLAGS ?= -O3 -funroll-loops
CFLAGS += -I ../../include/
CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
LDFLAGS += -ldl

View File

@ -51,7 +51,9 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
@ -66,11 +68,12 @@ static u8 *in_file, /* Analyzer input test case */
static u8 *in_data; /* Input data for analysis */
static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
total_execs, /* Total number of execs */
exec_hangs, /* Total number of hangs */
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
static u64 orig_cksum; /* Original checksum */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
static s32 dev_null_fd = -1; /* FD to /dev/null */
@ -222,7 +225,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
int status = 0;
s32 prog_in_fd;
u32 cksum;
u64 cksum;
memset(trace_bits, 0, map_size);
MEM_BARRIER();
@ -321,7 +324,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
}
cksum = hash32(trace_bits, map_size, HASH_CONST);
cksum = hash64(trace_bits, map_size, HASH_CONST);
/* We don't actually care if the target is crashing or not,
except that when it does, the checksum should be different. */
@ -1046,6 +1049,9 @@ int main(int argc, char **argv, char **envp) {
check_environment_vars(envp);
sharedmem_t shm = {0};
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler);
setup_signal_handlers();

View File

@ -54,6 +54,7 @@ char *afl_environment_variables[] = {
"AFL_CMIN_CRASHES_ONLY", "AFL_CODE_END", "AFL_CODE_START",
"AFL_COMPCOV_BINNAME", "AFL_COMPCOV_LEVEL", "AFL_CUSTOM_MUTATOR_LIBRARY",
"AFL_CUSTOM_MUTATOR_ONLY", "AFL_CXX", "AFL_DEBUG", "AFL_DEBUG_CHILD_OUTPUT",
"AFL_DEBUG_GDB",
//"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally
"AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV",
"AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI",

View File

@ -32,6 +32,7 @@
#include "common.h"
#include "list.h"
#include "forkserver.h"
#include "hash.h"
#include <stdio.h>
#include <unistd.h>
@ -70,9 +71,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->out_fd = -1;
fsrv->out_dir_fd = -1;
fsrv->dev_null_fd = -1;
#ifndef HAVE_ARC4RANDOM
fsrv->dev_urandom_fd = -1;
#endif
/* Settings */
fsrv->use_stdin = 1;
fsrv->no_unlink = 0;
@ -103,9 +103,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
fsrv_to->map_size = from->map_size;
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
#ifndef HAVE_ARC4RANDOM
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
#endif
// These are forkserver specific.
fsrv_to->out_dir_fd = -1;
@ -131,7 +129,8 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
struct timeval timeout;
size_t len = 4;
int sret;
ssize_t len_read;
timeout.tv_sec = (timeout_ms / 1000);
timeout.tv_usec = (timeout_ms % 1000) * 1000;
@ -140,33 +139,52 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
#endif
/* set exceptfds as well to return when a child exited/closed the pipe. */
int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
restart_select:
sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
if (!sret) {
if (likely(sret > 0)) {
restart_read:
len_read = read(fd, (u8 *)buf, 4);
if (likely(len_read == 4)) { // for speed we put this first
#if defined(__linux__)
u32 exec_ms = MIN(
timeout_ms,
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
#else
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
#endif
// ensure to report 1 ms has passed (0 is an error)
return exec_ms > 0 ? exec_ms : 1;
} else if (unlikely(len_read == -1 && errno == EINTR)) {
goto restart_read;
} else if (unlikely(len_read < 4)) {
return 0;
}
} else if (unlikely(!sret)) {
*buf = -1;
return timeout_ms + 1;
} else if (sret < 0) {
} else if (unlikely(sret < 0)) {
if (likely(errno == EINTR)) goto restart_select;
*buf = -1;
return 0;
}
ssize_t len_read = read(fd, ((u8 *)buf), len);
if (len_read < len) { return 0; }
#if defined(__linux__)
u32 exec_ms =
MIN(timeout_ms,
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
#else
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
#endif
// ensure to report 1 ms has passed (0 is an error)
return exec_ms > 0 ? exec_ms : 1;
return 0; // not reached
}
@ -400,9 +418,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
close(fsrv->out_dir_fd);
close(fsrv->dev_null_fd);
#ifndef HAVE_ARC4RANDOM
close(fsrv->dev_urandom_fd);
#endif
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
/* This should improve performance a bit, since it stops the linker from
@ -445,6 +462,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
/* PARENT PROCESS */
char pid_buf[16];
sprintf(pid_buf, "%d", fsrv->fsrv_pid);
if (fsrv->cmplog_binary)
setenv("__AFL_TARGET_PID2", pid_buf, 1);
else
setenv("__AFL_TARGET_PID1", pid_buf, 1);
/* Close the unneeded endpoints. */
close(ctl_pipe[0]);
@ -545,7 +569,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (unlikely(tmp_map_size % 8)) {
// should not happen
WARNF("Target reported non-aligned map size of %ud", tmp_map_size);
WARNF("Target reported non-aligned map size of %u", tmp_map_size);
tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
}
@ -572,9 +596,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
// this is not afl-fuzz - we deny and return
if (fsrv->use_shmem_fuzz)
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
status = (FS_OPT_ENABLED);
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed.");
@ -586,7 +610,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
if (!be_quiet) { ACTF("Using AUTODICT feature."); }
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
if (fsrv->use_shmem_fuzz)
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed.");
@ -837,8 +866,23 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
*fsrv->shmem_fuzz_len = len;
memcpy(fsrv->shmem_fuzz, buf, len);
// printf("test case len: %u [0]:0x%02x\n", *fsrv->shmem_fuzz_len, buf[0]);
// fflush(stdout);
#ifdef _DEBUG
if (getenv("AFL_DEBUG")) {
fprintf(stderr, "FS crc: %016llx len: %u\n",
hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705),
*fsrv->shmem_fuzz_len);
fprintf(stderr, "SHM :");
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]);
fprintf(stderr, "\nORIG:");
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
fprintf(stderr, "%02x", buf[i]);
fprintf(stderr, "\n");
}
#endif
} else {

View File

@ -542,27 +542,35 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
u8 hnb = '\0';
s32 fd;
u8 keeping = 0, res;
u64 cksum = 0;
u8 fn[PATH_MAX];
/* Update path frequency. */
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
struct queue_entry *q = afl->queue;
while (q) {
/* Generating a hash on every input is super expensive. Bad idea and should
only be used for special schedules */
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
if (q->exec_cksum == cksum) {
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
q->n_fuzz = q->n_fuzz + 1;
break;
struct queue_entry *q = afl->queue;
while (q) {
if (q->exec_cksum == cksum) {
++q->n_fuzz;
break;
}
q = q->next;
}
q = q->next;
}
if (unlikely(fault == afl->crash_mode)) {
if (likely(fault == afl->crash_mode)) {
/* Keep only if there are new bits in the map, add to queue for
future fuzzing, etc. */
@ -595,7 +603,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
afl->queue_top->exec_cksum = cksum;
if (cksum)
afl->queue_top->exec_cksum = cksum;
else
afl->queue_top->exec_cksum =
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
/* Try to calibrate inline; this also calls update_bitmap_score() when
successful. */

View File

@ -37,6 +37,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
cpu_set_t c;
#elif defined(__NetBSD__)
cpuset_t * c;
#elif defined(__sun)
psetid_t c;
#endif
u8 cpu_used[4096] = {0};
@ -181,6 +183,56 @@ void bind_to_free_cpu(afl_state_t *afl) {
}
ck_free(procs);
#elif defined(__sun)
kstat_named_t *n;
kstat_ctl_t * m;
kstat_t * k;
cpu_stat_t cs;
u32 ncpus;
m = kstat_open();
if (!m) FATAL("kstat_open failed");
k = kstat_lookup(m, "unix", 0, "system_misc");
if (!k) {
kstat_close(m);
return;
}
if (kstat_read(m, k, NULL)) {
kstat_close(m);
return;
}
n = kstat_data_lookup(k, "ncpus");
ncpus = n->value.i32;
if (ncpus > sizeof(cpu_used)) ncpus = sizeof(cpu_used);
for (i = 0; i < ncpus; i++) {
k = kstat_lookup(m, "cpu_stat", i, NULL);
if (kstat_read(m, k, &cs)) {
kstat_close(m);
return;
}
if (cs.cpu_sysinfo.cpu[CPU_IDLE] > 0) continue;
if (cs.cpu_sysinfo.cpu[CPU_USER] > 0 || cs.cpu_sysinfo.cpu[CPU_KERNEL] > 0)
cpu_used[i] = 1;
}
kstat_close(m);
#else
#warning \
"For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus"
@ -189,7 +241,7 @@ void bind_to_free_cpu(afl_state_t *afl) {
size_t cpu_start = 0;
try:
#ifndef __ANDROID__
#if !defined(__ANDROID__)
for (i = cpu_start; i < afl->cpu_core_count; i++) {
if (!cpu_used[i]) { break; }
@ -228,6 +280,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
c = cpuset_create();
if (c == NULL) PFATAL("cpuset_create failed");
cpuset_set(i, c);
#elif defined(__sun)
pset_create(&c);
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
#endif
#if defined(__linux__)
@ -271,6 +326,19 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) {
}
cpuset_destroy(c);
#elif defined(__sun)
if (pset_bind(c, P_PID, getpid(), NULL)) {
if (cpu_start == afl->cpu_core_count)
PFATAL("pset_bind failed for cpu %d, exit", i);
WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i);
cpu_start++;
goto try
;
}
pset_destroy(c);
#else
// this will need something for other platforms
// TODO: Solaris/Illumos has processor_bind ... might worth a try
@ -1473,10 +1541,8 @@ void setup_dirs_fds(afl_state_t *afl) {
afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR);
if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
#ifndef HAVE_ARC4RANDOM
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
#endif
/* Gnuplot output file. */
@ -2062,14 +2128,17 @@ void check_binary(afl_state_t *afl, u8 *fname) {
/* Check for blatant user errors. */
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
!strchr(afl->fsrv.target_path + 5, '/')) ||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
!strchr(afl->fsrv.target_path + 9, '/'))) {
/* disabled. not a real-worl scenario where this is a problem.
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
!strchr(afl->fsrv.target_path + 5, '/')) ||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
!strchr(afl->fsrv.target_path + 9, '/'))) {
FATAL("Please don't keep binaries in /tmp or /var/tmp");
FATAL("Please don't keep binaries in /tmp or /var/tmp");
}
}
*/
fd = open(afl->fsrv.target_path, O_RDONLY);

View File

@ -44,7 +44,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators "
"(custom/radamsa/redqueen/...).");
"(custom/redqueen/...).");
u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
@ -89,7 +89,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL(
"MOpt and Python mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators "
"(custom/radamsa/redqueen/...).");
"(custom/redqueen/...).");
}
@ -272,7 +272,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
sprintf(afl->stage_name_buf, "ptrim %s",
u_stringify_int(val_buf, trim_exec));
u32 cksum;
u64 cksum;
size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
@ -295,7 +295,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
if (cksum == q->exec_cksum) {

View File

@ -29,10 +29,14 @@
static int select_algorithm(afl_state_t *afl) {
int i_puppet, j_puppet;
int i_puppet, j_puppet = 0, operator_number = operator_num;
if (!afl->extras_cnt && !afl->a_extras_cnt) operator_number -= 2;
double range_sele =
(double)afl->probability_now[afl->swarm_now][operator_number - 1];
double sele = ((double)(rand_below(afl, 10000) * 0.0001 * range_sele));
double sele = ((double)(rand_below(afl, 10000)) * 0.0001);
j_puppet = 0;
for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
if (unlikely(i_puppet == 0)) {
@ -52,8 +56,10 @@ static int select_algorithm(afl_state_t *afl) {
}
if (j_puppet == 1 &&
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) {
if ((j_puppet == 1 &&
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) ||
(i_puppet + 1 < operator_num &&
sele > afl->probability_now[afl->swarm_now][i_puppet + 1])) {
FATAL("error select_algorithm");
@ -364,8 +370,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
s32 len, fd, temp_len, i, j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt;
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum;
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0;
@ -488,6 +494,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
@ -548,8 +556,6 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(perf_score == 0)) { goto abandon_entry; }
if (unlikely(afl->use_radamsa > 1)) { goto radamsa_stage; }
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len,
@ -566,12 +572,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
if it has gone through deterministic testing in earlier, resumed runs
(passed_det). */
if (afl->skip_deterministic ||
((!afl->queue_cur->passed_det) &&
perf_score < (afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
? afl->queue_cur->depth * 30
: afl->havoc_max_mult * 100)) ||
afl->queue_cur->passed_det) {
if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
likely(perf_score <
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
? afl->queue_cur->depth * 30
: afl->havoc_max_mult * 100))) {
goto custom_mutator_stage;
@ -653,7 +658,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
@ -821,14 +826,14 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
u32 cksum;
u64 cksum;
/* If in non-instrumented mode or if the file is very short, just flag
everything without wasting time on checksums. */
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
} else {
@ -1680,6 +1685,7 @@ custom_mutator_stage:
retry_external_pick:
/* Pick a random other queue entry for passing to external API */
do {
tid = rand_below(afl, afl->queued_paths);
@ -1704,7 +1710,7 @@ custom_mutator_stage:
/* Make sure that the target has a reasonable length. */
while (target && (target->len < 2 || target == afl->queue_cur) &&
afl->queued_paths > 1) {
afl->queued_paths > 3) {
target = target->next;
++afl->splicing_with;
@ -2230,7 +2236,7 @@ havoc_stage:
case 16: {
u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1);
u8 *new_buf;
u8 *ptr;
/* Insert an extra. Do the same dice-rolling stuff as for the
previous case. */
@ -2239,44 +2245,27 @@ havoc_stage:
use_extra = rand_below(afl, afl->a_extras_cnt);
extra_len = afl->a_extras[use_extra].len;
if (temp_len + extra_len >= MAX_FILE) { break; }
new_buf =
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
/* Head */
memcpy(new_buf, out_buf, insert_at);
/* Inserted part */
memcpy(new_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
ptr = afl->a_extras[use_extra].data;
} else {
use_extra = rand_below(afl, afl->extras_cnt);
extra_len = afl->extras[use_extra].len;
if (temp_len + extra_len >= MAX_FILE) { break; }
new_buf =
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
/* Head */
memcpy(new_buf, out_buf, insert_at);
/* Inserted part */
memcpy(new_buf + insert_at, afl->extras[use_extra].data, extra_len);
ptr = afl->extras[use_extra].data;
}
/* Tail */
memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,
temp_len - insert_at);
if (temp_len + extra_len >= MAX_FILE) { break; }
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
/* Tail */
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
temp_len - insert_at);
/* Inserted part */
memcpy(out_buf + insert_at, ptr, extra_len);
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
new_buf = NULL;
temp_len += extra_len;
break;
@ -2438,63 +2427,6 @@ retry_splicing:
#endif /* !IGNORE_FINDS */
ret_val = 0;
goto radamsa_stage;
radamsa_stage:
if (likely(!afl->use_radamsa || !afl->radamsa_mutate_ptr)) {
goto abandon_entry;
}
afl->stage_name = "radamsa";
afl->stage_short = "radamsa";
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100)
<< afl->use_radamsa;
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
/* Read the additional testcase.
We'll reuse in_scratch, as it is free at this point.
*/
u8 *save_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), len);
memcpy(save_buf, out_buf, len);
u32 max_len = len + choose_block_len(afl, HAVOC_BLK_XL);
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), max_len);
u8 *tmp_buf;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
get_rand_seed(afl));
if (new_len) {
temp_len = new_len;
tmp_buf = new_buf;
} else {
tmp_buf = save_buf; // nope but I dont care
temp_len = len;
}
if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; }
}
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_RADAMSA] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_RADAMSA] += afl->stage_max;
ret_val = 0;
goto abandon_entry;
/* we are through with this queue entry - for this iteration */
abandon_entry:
@ -2539,8 +2471,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
s32 len, fd, temp_len, i, j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
u64 havoc_queued, orig_hit_cnt, new_hit_cnt, cur_ms_lv;
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum;
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0;
@ -2637,6 +2569,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
@ -2806,7 +2740,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
@ -2974,14 +2908,14 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
u32 cksum;
u64 cksum;
/* If in non-instrumented mode or if the file is very short, just flag
everything without wasting time on checksums. */
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
} else {
@ -4208,6 +4142,94 @@ pacemaker_fuzzing:
} /* case 15 */
/* Values 16 and 17 can be selected only if there are any extras
present in the dictionaries. */
case 16: {
/* Overwrite bytes with an extra. */
if (!afl->extras_cnt ||
(afl->a_extras_cnt && rand_below(afl, 2))) {
/* No user-specified extras or odds in our favor. Let's use an
auto-detected one. */
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
if (extra_len > temp_len) break;
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
} else {
/* No auto extras or odds in our favor. Use the dictionary. */
u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
if (extra_len > temp_len) break;
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
extra_len);
}
afl->stage_cycles_puppet_v2[afl->swarm_now]
[STAGE_OverWriteExtra] += 1;
break;
}
/* Insert an extra. */
case 17: {
u32 use_extra, extra_len,
insert_at = rand_below(afl, temp_len + 1);
u8 *ptr;
/* Insert an extra. Do the same dice-rolling stuff as for the
previous case. */
if (!afl->extras_cnt ||
(afl->a_extras_cnt && rand_below(afl, 2))) {
use_extra = rand_below(afl, afl->a_extras_cnt);
extra_len = afl->a_extras[use_extra].len;
ptr = afl->a_extras[use_extra].data;
} else {
use_extra = rand_below(afl, afl->extras_cnt);
extra_len = afl->extras[use_extra].len;
ptr = afl->extras[use_extra].data;
}
if (temp_len + extra_len >= MAX_FILE) break;
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
/* Tail */
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
temp_len - insert_at);
/* Inserted part */
memcpy(out_buf + insert_at, ptr, extra_len);
temp_len += extra_len;
afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_InsertExtra] +=
1;
break;
}
} /* switch select_algorithm() */
} /* for i=0; i < use_stacking */

View File

@ -194,10 +194,14 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u32 i;
u64 fav_factor;
u64 fuzz_p2 = next_pow2(q->n_fuzz);
u64 fuzz_p2;
if (afl->schedule == MMOPT || afl->schedule == RARE ||
unlikely(afl->fixed_seed)) {
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
fuzz_p2 = next_pow2(q->n_fuzz);
else
fuzz_p2 = q->fuzz_level;
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
fav_factor = q->len << 2;
@ -217,10 +221,13 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
/* Faster-executing or smaller test cases are favored. */
u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
u64 top_rated_fuzz_p2;
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
else
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
if (afl->schedule == MMOPT || afl->schedule == RARE ||
unlikely(afl->fixed_seed)) {
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
top_rated_fav_factor = afl->top_rated[i]->len << 2;
@ -241,8 +248,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
}
if (afl->schedule == MMOPT || afl->schedule == RARE ||
unlikely(afl->fixed_seed)) {
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
if (fav_factor > afl->top_rated[i]->len << 2) { continue; }
@ -387,8 +393,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh
if (afl->schedule != MMOPT && afl->schedule != RARE &&
likely(!afl->fixed_seed)) {
if (afl->schedule >= RARE && likely(!afl->fixed_seed)) {
if (q->exec_us * 0.1 > avg_exec_us) {
@ -500,6 +505,9 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
case EXPLORE:
break;
case SEEK:
break;
case EXPLOIT:
factor = MAX_FACTOR;
break;
@ -593,9 +601,12 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
}
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
perf_score *= factor / POWER_BETA;
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
perf_score *= factor / POWER_BETA;
}
// MOpt mode
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) {

View File

@ -89,11 +89,11 @@ static struct range *pop_biggest_range(struct range **ranges) {
}
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
*cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
*cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
return 0;
}
@ -109,7 +109,7 @@ static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
}
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
struct range *ranges = add_range(NULL, 0, len);
u8 * backup = ck_alloc_nozero(len);
@ -137,7 +137,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
memcpy(backup, buf + rng->start, s);
rand_replace(afl, buf + rng->start, s);
u32 cksum;
u64 cksum;
u64 start_us = get_cur_time_us();
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
@ -180,7 +180,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
while (ranges) {
rng = ranges;
ranges = ranges->next;
ranges = rng->next;
ck_free(rng);
rng = NULL;
@ -224,7 +224,7 @@ checksum_fail:
while (ranges) {
rng = ranges;
ranges = ranges->next;
ranges = rng->next;
ck_free(rng);
rng = NULL;
@ -695,7 +695,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
// afl->queue_cur->exec_cksum
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
u32 exec_cksum) {
u64 exec_cksum) {
u8 r = 1;
if (afl->orig_cmp_map == NULL) {

View File

@ -142,7 +142,41 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
s32 fd = afl->fsrv.out_fd;
u32 tail_len = len - skip_at - skip_len;
if (afl->fsrv.out_file) {
if (afl->fsrv.shmem_fuzz) {
if (skip_at) { memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); }
if (tail_len) {
memcpy(afl->fsrv.shmem_fuzz + skip_at, (u8 *)mem + skip_at + skip_len,
tail_len);
}
*afl->fsrv.shmem_fuzz_len = len - skip_len;
#ifdef _DEBUG
if (afl->debug) {
fprintf(
stderr, "FS crc: %16llx len: %u\n",
hash64(afl->fsrv.shmem_fuzz, *afl->fsrv.shmem_fuzz_len, 0xa5b35705),
*afl->fsrv.shmem_fuzz_len);
fprintf(stderr, "SHM :");
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
fprintf(stderr, "%02x", afl->fsrv.shmem_fuzz[i]);
fprintf(stderr, "\nORIG:");
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
fprintf(stderr, "%02x", (u8)((u8 *)mem)[i]);
fprintf(stderr, "\n");
}
#endif
return;
} else if (afl->fsrv.out_file) {
if (afl->no_unlink) {
@ -234,6 +268,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz);
afl->shm_fuzz = NULL;
@ -256,13 +291,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 cksum;
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) {
show_stats(afl);
}
u64 cksum;
write_to_testcase(afl, use_mem, q->len);
@ -281,7 +310,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
}
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
if (q->exec_cksum != cksum) {
hnb = has_new_bits(afl, afl->virgin_bits);
@ -385,7 +414,7 @@ void sync_fuzzers(afl_state_t *afl) {
DIR * sd;
struct dirent *sd_ent;
u32 sync_cnt = 0, synced = 0, entries = 0;
u8 path[PATH_MAX];
u8 path[PATH_MAX + 256];
sd = opendir(afl->sync_dir);
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
@ -399,7 +428,7 @@ void sync_fuzzers(afl_state_t *afl) {
while ((sd_ent = readdir(sd))) {
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
u32 min_accept = 0, next_min_accept;
u32 min_accept = 0, next_min_accept = 0;
s32 id_fd;
@ -438,6 +467,12 @@ void sync_fuzzers(afl_state_t *afl) {
synced++;
/* document the attempt to sync to this instance */
sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name);
id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (id_fd >= 0) close(id_fd);
/* Skip anything that doesn't have a queue/ subdirectory. */
sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name);
@ -462,14 +497,13 @@ void sync_fuzzers(afl_state_t *afl) {
if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
if (read(id_fd, &min_accept, sizeof(u32)) > 0) {
if (read(id_fd, &min_accept, sizeof(u32)) == sizeof(u32)) {
next_min_accept = min_accept;
lseek(id_fd, 0, SEEK_SET);
}
next_min_accept = min_accept;
/* Show stats */
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt);
@ -505,7 +539,7 @@ void sync_fuzzers(afl_state_t *afl) {
s32 fd;
struct stat st;
sprintf(path, "%s/%s", qd_path, namelist[o]->d_name);
snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name);
afl->syncing_case = next_min_accept;
next_min_accept++;
o--;
@ -646,7 +680,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
while (remove_pos < q->len) {
u32 trim_avail = MIN(remove_len, q->len - remove_pos);
u32 cksum;
u64 cksum;
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
@ -658,7 +692,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
*/
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
/* If the deletion had no impact on the trace, make it permanent. This
isn't perfect for variable-path inputs, but we're just making a

View File

@ -30,9 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
char *power_names[POWER_SCHEDULES_NUM] = {
"explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast",
"coe", "lin", "quad",
"rare", "mmopt", "seek"};
/* Initialize MOpt "globals" for this afl state */
@ -124,9 +124,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->stats_update_freq = 1;
#ifndef HAVE_ARC4RANDOM
afl->fsrv.dev_urandom_fd = -1;
#endif
afl->fsrv.dev_null_fd = -1;
afl->fsrv.child_pid = -1;

View File

@ -31,7 +31,9 @@
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
double eps) {
#ifndef __HAIKU__
struct rusage rus;
#endif
unsigned long long int cur_time = get_cur_time();
u8 fn[PATH_MAX];
@ -65,7 +67,9 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
}
#ifndef __HAIKU__
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
#endif
fprintf(
f,
@ -119,12 +123,21 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
afl->last_path_time / 1000, afl->last_crash_time / 1000,
afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
#ifdef __APPLE__
#ifndef __HAIKU__
#ifdef __APPLE__
(unsigned long int)(rus.ru_maxrss >> 20),
#else
#else
(unsigned long int)(rus.ru_maxrss >> 10),
#endif
#else
-1UL,
#endif
afl->cpu_aff, t_bytes, afl->var_byte_count, afl->use_banner,
#ifdef HAVE_AFFINITY
afl->cpu_aff,
#else
-1,
#endif
t_bytes, afl->var_byte_count, afl->use_banner,
afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
afl->non_instrumented_mode ? " non_instrumented " : "",
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
@ -181,7 +194,8 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
afl->plot_prev_uc == afl->unique_crashes &&
afl->plot_prev_uh == afl->unique_hangs &&
afl->plot_prev_md == afl->max_depth) ||
unlikely(!afl->queue_cycle)) {
unlikely(!afl->queue_cycle) ||
unlikely(get_cur_time() - afl->start_time <= 60)) {
return;
@ -732,15 +746,13 @@ void show_stats(afl_state_t *afl) {
afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
: (u8 *)"n/a");
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
sprintf(tmp, "%s/%s, %s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]),
u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
SAYF(bV bSTOP "havoc/splice : " cRST "%-36s " bSTG bV bSTOP, tmp);
if (t_bytes) {
@ -821,18 +833,19 @@ void show_stats(afl_state_t *afl) {
}
if (afl->custom_mutators_count) {
// if (afl->custom_mutators_count) {
sprintf(tmp, "%s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
//
// sprintf(tmp, "%s/%s",
// u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
// u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
// SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
//
//} else {
} else {
SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
}
//}
/* Provide some CPU utilization stats. */

View File

@ -26,66 +26,53 @@
#include "afl-fuzz.h"
#include "cmplog.h"
#include <limits.h>
#ifndef USEMMAP
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#ifdef PROFILING
extern u64 time_spent_working;
#endif
static u8 *get_libradamsa_path(u8 *own_loc) {
static void at_exit() {
u8 *tmp, *cp, *rsl, *own_copy;
int i;
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
char *ptr = getenv("__AFL_TARGET_PID1");
tmp = getenv("AFL_PATH");
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
if (tmp) {
ptr = getenv("__AFL_TARGET_PID2");
cp = alloc_printf("%s/libradamsa.so", tmp);
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", cp); }
i = 0;
while (list[i] != NULL) {
return cp;
ptr = getenv(list[i]);
if (ptr && *ptr) {
#ifdef USEMMAP
shm_unlink(ptr);
#else
shmctl(atoi(ptr), IPC_RMID, NULL);
#endif
}
i++;
}
own_copy = ck_strdup(own_loc);
rsl = strrchr(own_copy, '/');
if (rsl) {
*rsl = 0;
cp = alloc_printf("%s/libradamsa.so", own_copy);
ck_free(own_copy);
if (!access(cp, X_OK)) { return cp; }
} else {
ck_free(own_copy);
}
if (!access(AFL_PATH "/libradamsa.so", X_OK)) {
return ck_strdup(AFL_PATH "/libradamsa.so");
}
if (!access(BIN_PATH "/libradamsa.so", X_OK)) {
return ck_strdup(BIN_PATH "/libradamsa.so");
}
SAYF(
"\n" cLRD "[-] " cRST
"Oops, unable to find the 'libradamsa.so' binary. The binary must be "
"built\n"
" separately using 'make radamsa'. If you already have the binary "
"installed,\n you may need to specify AFL_PATH in the environment.\n");
FATAL("Failed to locate 'libradamsa.so'.");
}
/* Display usage hints. */
@ -100,12 +87,13 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
" -p schedule - power schedules recompute a seed's performance "
"score.\n"
" <explore(default), fast, coe, lin, quad, exploit, "
"mmopt, rare>\n"
" -p schedule - power schedules compute a seed's performance score. "
"<explore\n"
" (default), fast, coe, lin, quad, exploit, mmopt, "
"rare, seek>\n"
" see docs/power_schedules.md\n"
" -f file - location read by the fuzzed program (stdin)\n"
" -f file - location read by the fuzzed program (default: stdin "
"or @@)\n"
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
" -m megs - memory limit for child process (%d MB)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
@ -114,8 +102,6 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"mode)\n\n"
"Mutator settings:\n"
" -R[R] - add Radamsa as mutator, add another -R to exclusivly "
"run it\n"
" -L minutes - use MOpt(imize) mode and set the time limit for "
"entering the\n"
" pacemaker mode (minutes of no new paths). 0 = "
@ -131,7 +117,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"devices etc.!)\n"
" -d - quick & dirty mode (skips deterministic steps)\n"
" -n - fuzz without instrumentation (non-instrumented mode)\n"
" -x dir - optional fuzzer dictionary (see README.md, its really "
" -x dict_file - optional fuzzer dictionary (see README.md, its really "
"good!)\n\n"
"Testing settings:\n"
@ -144,14 +130,16 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"Other stuff:\n"
" -T text - text banner to show on the screen\n"
" -M / -S id - distributed mode (see docs/parallel_fuzzing.md)\n"
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
" use -D to force -S secondary to perform deterministic "
"fuzzing\n"
" -I command - execute this command/script when a new crash is "
"found\n"
" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap "
"file\n"
//" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
//" "file\n"
" -C - crash exploration mode (the peruvian rabbit thing)\n"
" -e ext - file extension for the temporarily generated test "
"case\n\n",
" -e ext - file extension for the fuzz test input file (if "
"needed)\n\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT);
if (more_help > 1) {
@ -231,7 +219,7 @@ static int stricmp(char const *a, char const *b) {
for (;; ++a, ++b) {
int d;
d = tolower(*a) - tolower(*b);
d = tolower((int)*a) - tolower((int)*b);
if (d != 0 || !*a) { return d; }
}
@ -274,10 +262,10 @@ int main(int argc, char **argv_orig, char **envp) {
doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz);
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
while ((opt = getopt(argc, argv,
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
"+c:i:I:o:f:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
0) {
switch (opt) {
@ -296,7 +284,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 's': {
afl->init_seed = strtoul(optarg, 0L, 10);
rand_set_seed(afl, strtoul(optarg, 0L, 10));
afl->fixed_seed = 1;
break;
@ -332,6 +320,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->schedule = RARE;
} else if (!stricmp(optarg, "seek")) {
afl->schedule = SEEK;
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
@ -369,7 +361,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->out_dir = optarg;
break;
case 'M': { /* master sync ID */
case 'M': { /* main sync ID */
u8 *c;
@ -398,7 +390,7 @@ int main(int argc, char **argv_orig, char **envp) {
break;
case 'S':
case 'S': /* secondary sync id */
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
afl->sync_id = ck_strdup(optarg);
@ -503,6 +495,11 @@ int main(int argc, char **argv_orig, char **envp) {
break;
case 'D': /* enforce deterministic */
afl->skip_deterministic = 0;
break;
case 'd': /* skip deterministic */
afl->skip_deterministic = 1;
@ -767,15 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
case 'R':
if (afl->use_radamsa) {
afl->use_radamsa = 2;
} else {
afl->use_radamsa = 1;
}
FATAL(
"Radamsa is now a custom mutator, please use that "
"(custom_mutators/radamsa/).");
break;
@ -808,8 +799,7 @@ int main(int argc, char **argv_orig, char **envp) {
WARNF(
"Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
"will "
"result in no deterministic mutations being done!");
"will result in no deterministic mutations being done!");
}
@ -819,50 +809,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
srandom((u32)afl->init_seed);
srand((u32)afl->init_seed); // in case it is a different implementation
if (afl->use_radamsa) {
if (afl->limit_time_sig > 0) {
FATAL(
"MOpt and Radamsa are mutually exclusive unless you specify -L -1. "
"We accept pull requests that integrates MOpt with the optional "
"mutators (custom/radamsa/redqueen/...).");
}
if (afl->limit_time_sig && afl->use_radamsa > 1) {
FATAL("Radamsa in radamsa-only mode can not run together with -L");
}
OKF("Using Radamsa add-on");
u8 * libradamsa_path = get_libradamsa_path(argv[0]);
void *handle = dlopen(libradamsa_path, RTLD_NOW);
ck_free(libradamsa_path);
if (!handle) { FATAL("Failed to dlopen() libradamsa"); }
void (*radamsa_init_ptr)(void) = dlsym(handle, "radamsa_init");
afl->radamsa_mutate_ptr = dlsym(handle, "radamsa");
if (!radamsa_init_ptr || !afl->radamsa_mutate_ptr) {
FATAL("Failed to dlsym() libradamsa");
}
/* radamsa_init installs some signal handlers, call it before
setup_signal_handlers so that AFL++ can then replace those signal
handlers */
radamsa_init_ptr();
}
#if defined(__SANITIZE_ADDRESS__)
if (afl->fsrv.mem_limit) {
@ -936,6 +882,9 @@ int main(int argc, char **argv_orig, char **envp) {
case RARE:
OKF("Using rare edge focus power schedule (RARE)");
break;
case SEEK:
OKF("Using seek power schedule (SEEK)");
break;
case EXPLORE:
OKF("Using exploration-based constant power schedule (EXPLORE, default)");
break;
@ -1071,6 +1020,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_crash_handling();
check_cpu_governor(afl);
atexit(at_exit);
afl->fsrv.trace_bits =
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
@ -1082,7 +1033,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->is_main_node && check_main_node_exists(afl) == 1) {
WARNF("it is wasteful to run more than one master!");
WARNF("it is wasteful to run more than one main node!");
sleep(1);
}
@ -1327,7 +1278,15 @@ int main(int argc, char **argv_orig, char **envp) {
if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) {
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
if (unlikely(afl->is_main_node)) {
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); }
} else {
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
}
}
@ -1396,10 +1355,13 @@ stop_fuzzing:
destroy_queue(afl);
destroy_extras(afl);
destroy_custom_mutators(afl);
unsetenv(SHM_ENV_VAR);
unsetenv(CMPLOG_SHM_ENV_VAR);
afl_shm_deinit(&afl->shm);
if (afl->shm_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz);

View File

@ -335,7 +335,7 @@ static void edit_params(u32 argc, char **argv) {
}
#ifdef USEMMAP
#if defined(USEMMAP) && !defined(__HAIKU__)
cc_params[cc_par_cnt++] = "-lrt";
#endif

View File

@ -54,7 +54,7 @@
#include "common.h"
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__APPLE__) || defined(__DragonFly__)
defined(__APPLE__) || defined(__DragonFly__) || defined(__sun)
#define HAVE_AFFINITY 1
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <pthread.h>
@ -70,6 +70,8 @@
#include <pthread.h>
#include <mach/thread_act.h>
#include <mach/thread_policy.h>
#elif defined(__sun)
#include <sys/pset.h>
#endif
#endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */
@ -181,6 +183,12 @@ int main(int argc, char **argv) {
if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY,
(thread_policy_t)&c, 1) != KERN_SUCCESS)
PFATAL("thread_policy_set failed");
#elif defined(__sun)
psetid_t c;
if (pset_create(&c)) PFATAL("pset_create failed");
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
@ -195,6 +203,12 @@ int main(int argc, char **argv) {
cpuset_destroy(c);
#endif
#if defined(__sun)
if (pset_bind(c, P_PID, getpid(), NULL)) PFATAL("pset_bind failed");
pset_destroy(c);
#endif
#if defined(__linux__)
if (sched_setaffinity(0, sizeof(c), &c)) {

167
src/afl-performance.c Normal file
View File

@ -0,0 +1,167 @@
/*
Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>.
This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
It has excellent (sub-ns) speed, a state (256 bits) that is large
enough for any parallel application, and it passes all tests we are
aware of.
For generating just floating-point numbers, xoshiro256+ is even faster.
The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s[].
*/
#include <stdint.h>
#include "afl-fuzz.h"
#include "types.h"
#include "xxh3.h"
/* we use xoshiro256** instead of rand/random because it is 10x faster and has
better randomness properties. */
static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
void rand_set_seed(afl_state_t *afl, s64 init_seed) {
afl->init_seed = init_seed;
afl->rand_seed[0] =
hash64((u8 *)&afl->init_seed, sizeof(afl->init_seed), HASH_CONST);
afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef;
afl->rand_seed[2] = afl->rand_seed[0] & 0x0123456789abcdef;
afl->rand_seed[3] = afl->rand_seed[0] | 0x01abcde43f567908;
}
uint64_t rand_next(afl_state_t *afl) {
const uint64_t result =
rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + afl->rand_seed[0];
const uint64_t t = afl->rand_seed[1] << 17;
afl->rand_seed[2] ^= afl->rand_seed[0];
afl->rand_seed[3] ^= afl->rand_seed[1];
afl->rand_seed[1] ^= afl->rand_seed[2];
afl->rand_seed[0] ^= afl->rand_seed[3];
afl->rand_seed[2] ^= t;
afl->rand_seed[3] = rotl(afl->rand_seed[3], 45);
return result;
}
/* This is the jump function for the generator. It is equivalent
to 2^128 calls to rand_next(); it can be used to generate 2^128
non-overlapping subsequences for parallel computations. */
void jump(afl_state_t *afl) {
static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c,
0xa9582618e03fc9aa, 0x39abdc4529b1661c};
int i, b;
uint64_t s0 = 0;
uint64_t s1 = 0;
uint64_t s2 = 0;
uint64_t s3 = 0;
for (i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for (b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
s0 ^= afl->rand_seed[0];
s1 ^= afl->rand_seed[1];
s2 ^= afl->rand_seed[2];
s3 ^= afl->rand_seed[3];
}
rand_next(afl);
}
afl->rand_seed[0] = s0;
afl->rand_seed[1] = s1;
afl->rand_seed[2] = s2;
afl->rand_seed[3] = s3;
}
/* This is the long-jump function for the generator. It is equivalent to
2^192 calls to rand_next(); it can be used to generate 2^64 starting points,
from each of which jump() will generate 2^64 non-overlapping
subsequences for parallel distributed computations. */
void long_jump(afl_state_t *afl) {
static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3,
0x77710069854ee241, 0x39109bb02acbe635};
int i, b;
uint64_t s0 = 0;
uint64_t s1 = 0;
uint64_t s2 = 0;
uint64_t s3 = 0;
for (i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
for (b = 0; b < 64; b++) {
if (LONG_JUMP[i] & UINT64_C(1) << b) {
s0 ^= afl->rand_seed[0];
s1 ^= afl->rand_seed[1];
s2 ^= afl->rand_seed[2];
s3 ^= afl->rand_seed[3];
}
rand_next(afl);
}
afl->rand_seed[0] = s0;
afl->rand_seed[1] = s1;
afl->rand_seed[2] = s2;
afl->rand_seed[3] = s3;
}
/* we switch from afl's murmur implementation to xxh3 as it is 30% faster -
and get 64 bit hashes instead of just 32 bit. Less collisions! :-) */
#ifdef _DEBUG
u32 hash32(u8 *key, u32 len, u32 seed) {
#else
u32 inline hash32(u8 *key, u32 len, u32 seed) {
#endif
return (u32)XXH64(key, len, seed);
}
#ifdef _DEBUG
u64 hash64(u8 *key, u32 len, u64 seed) {
#else
u64 inline hash64(u8 *key, u32 len, u64 seed) {
#endif
return XXH64(key, len, seed);
}

View File

@ -66,6 +66,8 @@ static list_t shm_list = {.element_prealloc_count = 0};
void afl_shm_deinit(sharedmem_t *shm) {
if (shm == NULL) return;
list_remove(&shm_list, shm);
#ifdef USEMMAP
@ -83,6 +85,38 @@ void afl_shm_deinit(sharedmem_t *shm) {
}
if (shm->g_shm_file_path[0]) {
shm_unlink(shm->g_shm_file_path);
shm->g_shm_file_path[0] = 0;
}
if (shm->cmplog_mode) {
if (shm->cmp_map != NULL) {
munmap(shm->cmp_map, shm->map_size);
shm->map = NULL;
}
if (shm->cmplog_g_shm_fd != -1) {
close(shm->cmplog_g_shm_fd);
shm->cmplog_g_shm_fd = -1;
}
if (shm->cmplog_g_shm_file_path[0]) {
shm_unlink(shm->cmplog_g_shm_file_path);
shm->cmplog_g_shm_file_path[0] = 0;
}
}
#else
shmctl(shm->shm_id, IPC_RMID, NULL);
if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); }
@ -99,13 +133,15 @@ void afl_shm_deinit(sharedmem_t *shm) {
u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
unsigned char non_instrumented_mode) {
shm->map_size = map_size;
shm->map_size = 0;
shm->map = NULL;
shm->cmp_map = NULL;
#ifdef USEMMAP
shm->g_shm_fd = -1;
shm->cmplog_g_shm_fd = -1;
/* ======
generate random file name for multi instance
@ -134,6 +170,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
close(shm->g_shm_fd);
shm->g_shm_fd = -1;
shm_unlink(shm->g_shm_file_path);
shm->g_shm_file_path[0] = 0;
PFATAL("mmap() failed");
}
@ -145,13 +183,55 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
if (shm->map == -1 || !shm->map) PFATAL("mmap() failed");
if (shm->map == (void *)-1 || !shm->map) PFATAL("mmap() failed");
if (shm->cmplog_mode) {
snprintf(shm->cmplog_g_shm_file_path, L_tmpnam, "/afl_cmplog_%d_%ld",
getpid(), random());
/* create the shared memory segment as if it was a file */
shm->cmplog_g_shm_fd =
shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */
if (ftruncate(shm->cmplog_g_shm_fd, map_size)) {
PFATAL("setup_shm(): cmplog ftruncate() failed");
}
/* map the shared memory segment to the address space of the process */
shm->cmp_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
shm->cmplog_g_shm_fd, 0);
if (shm->map == MAP_FAILED) {
close(shm->cmplog_g_shm_fd);
shm->cmplog_g_shm_fd = -1;
shm_unlink(shm->cmplog_g_shm_file_path);
shm->cmplog_g_shm_file_path[0] = 0;
PFATAL("mmap() failed");
}
/* If somebody is asking us to fuzz instrumented binaries in
non-instrumented mode, we don't want them to detect instrumentation,
since we won't be sending fork server commands. This should be replaced
with better auto-detection later on, perhaps? */
if (!non_instrumented_mode)
setenv(CMPLOG_SHM_ENV_VAR, shm->cmplog_g_shm_file_path, 1);
if (shm->cmp_map == (void *)-1 || !shm->cmp_map)
PFATAL("cmplog mmap() failed");
}
#else
u8 *shm_str;
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
if (shm->cmplog_mode) {
@ -159,7 +239,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
IPC_CREAT | IPC_EXCL | 0600);
if (shm->cmplog_shm_id < 0) { PFATAL("shmget() failed"); }
if (shm->cmplog_shm_id < 0) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
PFATAL("shmget() failed");
}
}
@ -186,7 +271,18 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shm->map = shmat(shm->shm_id, NULL, 0);
if (shm->map == (void *)-1 || !shm->map) { PFATAL("shmat() failed"); }
if (shm->map == (void *)-1 || !shm->map) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed");
}
if (shm->cmplog_mode) {
@ -194,6 +290,13 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
if (shm->cmp_map == (void *)-1 || !shm->cmp_map) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed");
}
@ -202,6 +305,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
#endif
shm->map_size = map_size;
list_append(&shm_list, shm);
return shm->map;

View File

@ -56,7 +56,9 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
@ -80,11 +82,16 @@ static u8 quiet_mode, /* Hide non-essential messages? */
raw_instr_output, /* Do not apply AFL filters */
cmin_mode, /* Generate output in afl-cmin mode? */
binary_mode, /* Write output as a binary map */
keep_cores; /* Allow coredumps? */
keep_cores, /* Allow coredumps? */
remove_shm = 1; /* remove shmem? */
static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_crashed; /* Child crashed? */
static sharedmem_t shm;
static afl_forkserver_t *fsrv;
static sharedmem_t * shm_fuzz;
/* Classify tuple counts. Instead of mapping to individual bits, as in
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
@ -139,12 +146,33 @@ static void classify_counts(afl_forkserver_t *fsrv) {
}
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
sharedmem_t * shm_fuzz) {
afl_shm_deinit(shm_fuzz);
fsrv->support_shmem_fuzz = 0;
fsrv->shmem_fuzz_len = NULL;
fsrv->shmem_fuzz = NULL;
ck_free(shm_fuzz);
return NULL;
}
/* Get rid of temp files (atexit handler). */
static void at_exit_handler(void) {
if (stdin_file) { unlink(stdin_file); }
if (remove_shm) {
if (shm.map) afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
}
afl_fsrv_killall();
}
/* Write results. */
@ -557,7 +585,7 @@ static void usage(u8 *argv0) {
"size\n"
" the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_QUIET: do not print extra informational output",
"AFL_QUIET: do not print extra informational output\n",
argv0, MEM_LIMIT, doc_path);
exit(1);
@ -577,8 +605,8 @@ int main(int argc, char **argv_orig, char **envp) {
char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var;
afl_forkserver_t fsrv_var = {0};
fsrv = &fsrv_var;
afl_fsrv_init(fsrv);
map_size = get_map_size();
fsrv->map_size = map_size;
@ -773,7 +801,19 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp);
sharedmem_t shm = {0};
if (getenv("AFL_DEBUG")) {
SAYF(cMGN "[D]" cRST);
for (i = 0; i < argc; i++)
SAYF(" %s", argv[i]);
SAYF("\n");
}
// if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
setup_signal_handlers();
@ -827,16 +867,36 @@ int main(int argc, char **argv_orig, char **envp) {
}
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */
shm_fuzz->cmplog_mode = 0;
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
#ifdef USEMMAP
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
#else
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
ck_free(shm_str);
#endif
fsrv->support_shmem_fuzz = 1;
fsrv->shmem_fuzz_len = (u32 *)map;
fsrv->shmem_fuzz = map + sizeof(u32);
if (in_dir) {
DIR * dir_in, *dir_out;
struct dirent *dir_ent;
int done = 0;
u8 infile[PATH_MAX], outfile[PATH_MAX];
u8 wait_for_gdb = 0;
#if !defined(DT_REG)
struct stat statbuf;
#endif
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = 1;
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
@ -895,6 +955,9 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
while (done == 0 && (dir_ent = readdir(dir_in))) {
if (dir_ent->d_name[0] == '.') {
@ -922,6 +985,14 @@ int main(int argc, char **argv_orig, char **envp) {
if (read_file(infile)) {
if (wait_for_gdb) {
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
kill(0, SIGSTOP);
}
showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
ck_free(in_data);
tcnt = write_results_to_file(fsrv, outfile);
@ -937,6 +1008,9 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
showmap_run_target(fsrv, use_argv);
tcnt = write_results_to_file(fsrv, out_file);
@ -958,13 +1032,16 @@ int main(int argc, char **argv_orig, char **envp) {
}
remove_shm = 0;
afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
if (fsrv->target_path) { ck_free(fsrv->target_path); }
afl_fsrv_deinit(fsrv);
if (stdin_file) { ck_free(stdin_file); }
argv_cpy_free(argv);

View File

@ -54,7 +54,9 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
@ -67,20 +69,27 @@ static u8 *in_file, /* Minimizer input test case */
static u8 *in_data; /* Input data for trimming */
static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
missed_hangs, /* Misses due to hangs */
missed_crashes, /* Misses due to crashes */
missed_paths, /* Misses due to exec path diffs */
map_size = MAP_SIZE;
static u64 orig_cksum; /* Original checksum */
static u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */
exit_crash, /* Treat non-zero exit as crash? */
edges_only, /* Ignore hit counts? */
exact_mode; /* Require path match for crashes? */
exact_mode, /* Require path match for crashes? */
remove_out_file, /* remove out_file on exit? */
remove_shm = 1; /* remove shmem on exit? */
static volatile u8 stop_soon; /* Ctrl-C pressed? */
static afl_forkserver_t *fsrv;
static sharedmem_t shm;
static sharedmem_t * shm_fuzz;
/*
* forkserver section
*/
@ -102,6 +111,18 @@ static const u8 count_class_lookup[256] = {
};
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
sharedmem_t * shm_fuzz) {
afl_shm_deinit(shm_fuzz);
fsrv->support_shmem_fuzz = 0;
fsrv->shmem_fuzz_len = NULL;
fsrv->shmem_fuzz = NULL;
ck_free(shm_fuzz);
return NULL;
}
/* Apply mask to classified bitmap (if set). */
static void apply_mask(u32 *mem, u32 *mask) {
@ -166,7 +187,15 @@ static inline u8 anything_set(afl_forkserver_t *fsrv) {
static void at_exit_handler(void) {
if (remove_shm) {
if (shm.map) afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
}
afl_fsrv_killall();
if (remove_out_file) unlink(out_file);
}
@ -300,7 +329,7 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
u64 cksum = hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
if (first_run) { orig_cksum = cksum; }
@ -620,6 +649,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid());
remove_out_file = 1;
}
@ -809,8 +839,8 @@ int main(int argc, char **argv_orig, char **envp) {
char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var;
afl_forkserver_t fsrv_var = {0};
fsrv = &fsrv_var;
afl_fsrv_init(fsrv);
map_size = get_map_size();
fsrv->map_size = map_size;
@ -1007,7 +1037,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp);
sharedmem_t shm = {0};
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler);
@ -1049,11 +1080,31 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF("\n");
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */
shm_fuzz->cmplog_mode = 0;
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
#ifdef USEMMAP
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
#else
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
ck_free(shm_str);
#endif
fsrv->support_shmem_fuzz = 1;
fsrv->shmem_fuzz_len = (u32 *)map;
fsrv->shmem_fuzz = map + sizeof(u32);
read_initial_file();
afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
@ -1107,7 +1158,9 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("We're done here. Have a nice day!\n");
remove_shm = 0;
afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
afl_fsrv_deinit(fsrv);
if (fsrv->target_path) { ck_free(fsrv->target_path); }
if (mask_bitmap) { ck_free(mask_bitmap); }

View File

@ -1,3 +0,0 @@
*.a
*.o
libradamsa-test

View File

@ -1,75 +0,0 @@
#include <radamsa.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
size_t filesize(char* filename) {
struct stat st;
stat(filename, &st);
return st.st_size;
}
#define BUFSIZE 1024*1024
void fail(char *why) {
printf("fail: %s\n", why);
exit(1);
}
void write_output(char *data, size_t len, int num) {
char path[32];
int fd;
int wrote;
sprintf(path, "/tmp/libradamsa-%d.fuzz", num);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("Opened %s -> %d\n", path, fd);
if (fd < 0) {
fail("failed to open output file");
}
wrote = write(fd, data, len);
printf("wrote %d of %zu bytes\n", wrote, len);
if (wrote != len) {
fail("failed to write all of output at once");
}
close(fd);
printf("Wrote %zu bytes to %s\n", len, path);
}
int main(int nargs, char **argv) {
char *spath = argv[1];
int fd = open(spath, O_RDONLY, 0);
size_t len;
char *input;
char *output;
int seed = 0;
if (fd < 0) {
fail("cannot open input file");
}
len = filesize(spath);
input = malloc(len);
output = malloc(BUFSIZE);
if (!input || !output) {
fail("failed to allocate buffers\n");
}
radamsa_init();
if (len != read(fd, input, len)) {
fail("failed to read the entire sample at once");
}
while(seed++ < 100) {
size_t n;
n = radamsa((uint8_t *) input, len, (uint8_t *) output, BUFSIZE, seed);
write_output(output, n, seed);
printf("Fuzzed %zu -> %zu bytes\n", len, n);
}
printf("library test passed\n");
free(output);
free(input);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +0,0 @@
#include <inttypes.h>
#include <stddef.h>
void radamsa_init(void);
size_t radamsa(uint8_t *ptr, size_t len,
uint8_t *target, size_t max,
unsigned int seed);
size_t radamsa_inplace(uint8_t *ptr,
size_t len,
size_t max,
unsigned int seed);

View File

@ -23,7 +23,7 @@ else
fi
test_compcov_binary_functionality() {
RUN="../afl-showmap -o /dev/null -- $1"
RUN="../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- $1"
$RUN 'LIBTOKENCAP' | grep 'your string was LIBTOKENCAP' \
&& $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \
&& $RUN 'BANANA' | grep 'your string started with BAN' \
@ -86,7 +86,7 @@ export AFL_LLVM_INSTRUMENT=AFL
# on OpenBSD we need to work with llvm from /usr/local/bin
test -e /usr/local/bin/opt && {
export PATH=/usr/local/bin:${PATH}
export PATH="/usr/local/bin:${PATH}"
}
# on MacOS X we prefer afl-clang over afl-gcc, because
# afl-gcc does not work there
@ -108,7 +108,7 @@ RESET="\\033[0m"
MEM_LIMIT=none
export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..."
@ -459,24 +459,23 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && {
}
rm -f test-instr.plain
# Disabled whitelist until I have a different solution -mh
# echo foobar.c > whitelist.txt
# AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1
# test -e test-compcov && {
# grep -q "No instrumentation targets found" test.out && {
# $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
# } || {
# $ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
# CODE=1
# }
# } || {
# $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
# CODE=1
# }
# rm -f test-compcov test.out whitelist.txt
echo foobar.c > whitelist.txt
AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1
test -e test-compcov && {
grep -q "No instrumentation targets found" test.out && {
$ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
} || {
$ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
CODE=1
}
} || {
$ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
CODE=1
}
rm -f test-compcov test.out whitelist.txt
../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
test -e test-persistent && {
echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && {
echo foo | ../afl-showmap -m none -o /dev/null -q -r ./test-persistent && {
$ECHO "$GREEN[+] llvm_mode LTO persistent mode feature works correctly"
} || {
$ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work"
@ -638,43 +637,43 @@ test -e ../libdislocator.so && {
INCOMPLETE=1
}
rm -f test-compcov
test -e ../libradamsa.so && {
# on FreeBSD need to set AFL_CC
test `uname -s` = 'FreeBSD' && {
if type clang >/dev/null; then
export AFL_CC=`command -v clang`
else
export AFL_CC=`$LLVM_CONFIG --bindir`/clang
fi
}
test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain && {
mkdir -p in
printf 1 > in/in
$ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds"
{
../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
} >>errors 2>&1
test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
$ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
} || {
echo CUT------------------------------------------------------------------CUT
cat errors
echo CUT------------------------------------------------------------------CUT
$ECHO "$RED[!] libradamsa failed"
CODE=1
}
rm -rf in out errors test-instr.plain
} || {
$ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
INCOMPLETE=1
}
} || {
$ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
INCOMPLETE=1
}
#test -e ../libradamsa.so && {
# # on FreeBSD need to set AFL_CC
# test `uname -s` = 'FreeBSD' && {
# if type clang >/dev/null; then
# export AFL_CC=`command -v clang`
# else
# export AFL_CC=`$LLVM_CONFIG --bindir`/clang
# fi
# }
# test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
# test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
# test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
# test -e test-instr.plain && {
# mkdir -p in
# printf 1 > in/in
# $ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds"
# {
# ../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
# } >>errors 2>&1
# test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
# $ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
# } || {
# echo CUT------------------------------------------------------------------CUT
# cat errors
# echo CUT------------------------------------------------------------------CUT
# $ECHO "$RED[!] libradamsa failed"
# CODE=1
# }
# rm -rf in out errors test-instr.plain
# } || {
# $ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
# INCOMPLETE=1
# }
#} || {
# $ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
# INCOMPLETE=1
#}
test -z "$AFL_CC" && {
if type gcc >/dev/null; then
@ -902,6 +901,9 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
test -d ../unicorn_mode/unicornafl && {
test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
{
# We want to see python errors etc. in logs, in case something doesn't work
export AFL_DEBUG_CHILD_OUTPUT=1
# some python version should be available now
PYTHONS="`command -v python3` `command -v python` `command -v python2`"
EASY_INSTALL_FOUND=0
@ -988,6 +990,9 @@ test -d ../unicorn_mode/unicornafl && {
rm -rf in out errors
}
fi
unset AFL_DEBUG_CHILD_OUTPUT
}
} || {
$ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??"
@ -1121,7 +1126,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
$ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY"
unset AFL_CC
make -C .. unit || "$CODE" = "1"
make -C .. unit || CODE=1 INCOMPLETE=1 :
$ECHO "$GREY[*] all test cases completed.$RESET"
test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed"

View File

@ -0,0 +1,75 @@
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <assert.h>
#include <cmocka.h>
/* cmocka < 1.0 didn't support these features we need */
#ifndef assert_ptr_equal
#define assert_ptr_equal(a, b) \
_assert_int_equal(cast_ptr_to_largest_integral_type(a), \
cast_ptr_to_largest_integral_type(b), \
__FILE__, __LINE__)
#define CMUnitTest UnitTest
#define cmocka_unit_test unit_test
#define cmocka_run_group_tests(t, setup, teardown) run_tests(t)
#endif
extern void mock_assert(const int result, const char* const expression,
const char * const file, const int line);
#undef assert
#define assert(expression) \
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
#include "afl-fuzz.h"
#include "hash.h"
/* remap exit -> assert, then use cmocka's mock_assert
(compile with `--wrap=exit`) */
extern void exit(int status);
extern void __real_exit(int status);
void __wrap_exit(int status);
void __wrap_exit(int status) {
assert(0);
}
/* ignore all printfs */
#undef printf
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}
/* Rand with 0 seed would broke in the past */
static void test_hash(void **state) {
char bitmap[64] = {0};
u64 hash0 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
bitmap[10] = 1;
u64 hash1 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
assert_int_not_equal(hash0, hash1);
bitmap[10] = 0;
assert_int_equal(hash0, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
bitmap[10] = 1;
assert_int_equal(hash1, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_hash)
};
//return cmocka_run_group_tests (tests, setup, teardown);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -126,6 +126,8 @@ int main(int argc, char **argv) {
};
//return cmocka_run_group_tests (tests, setup, teardown);
return cmocka_run_group_tests (tests, NULL, NULL);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -156,6 +156,8 @@ int main(int argc, char **argv) {
};
//return cmocka_run_group_tests (tests, setup, teardown);
return cmocka_run_group_tests (tests, NULL, NULL);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -109,6 +109,8 @@ int main(int argc, char **argv) {
};
//return cmocka_run_group_tests (tests, setup, teardown);
return cmocka_run_group_tests (tests, NULL, NULL);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -0,0 +1,84 @@
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <assert.h>
#include <cmocka.h>
#include <sys/stat.h>
#include <fcntl.h>
/* cmocka < 1.0 didn't support these features we need */
#ifndef assert_ptr_equal
#define assert_ptr_equal(a, b) \
_assert_int_equal(cast_ptr_to_largest_integral_type(a), \
cast_ptr_to_largest_integral_type(b), \
__FILE__, __LINE__)
#define CMUnitTest UnitTest
#define cmocka_unit_test unit_test
#define cmocka_run_group_tests(t, setup, teardown) run_tests(t)
#endif
extern void mock_assert(const int result, const char* const expression,
const char * const file, const int line);
#undef assert
#define assert(expression) \
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
#include "afl-fuzz.h"
/* remap exit -> assert, then use cmocka's mock_assert
(compile with `--wrap=exit`) */
extern void exit(int status);
extern void __real_exit(int status);
void __wrap_exit(int status);
void __wrap_exit(int status) {
assert(0);
}
/* ignore all printfs */
#undef printf
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}
/* Rand with 0 seed would broke in the past */
static void test_rand_0(void **state) {
afl_state_t afl = {0};
rand_set_seed(&afl, 0);
/* give this one chance to retry */
assert_int_not_equal(
(rand_next(&afl) != rand_next(&afl)
|| rand_next(&afl) != rand_next(&afl))
, 0);
}
static void test_rand_below(void **state) {
afl_state_t afl = {0};
rand_set_seed(&afl, 1337);
afl.fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
assert(!(rand_below(&afl, 9000) > 9000));
assert_int_equal(rand_below(&afl, 1), 0);
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_rand_0),
cmocka_unit_test(test_rand_below)
};
//return cmocka_run_group_tests (tests, setup, teardown);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -1 +1 @@
a6e943c
0ca7a8f2

@ -1 +1 @@
Subproject commit a6e943c683ecb3aba1baaddc7a02eefd2c5a5ad9
Subproject commit 0ca7a8f22b8bb028eb9fe053c0974a60ee640f18