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
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-g++-fast
afl-gotcpu afl-gotcpu
afl-ld afl-ld
afl-ld-lto
afl-qemu-trace afl-qemu-trace
afl-showmap afl-showmap
afl-tmin afl-tmin
@ -45,9 +46,12 @@ ld
qemu_mode/qemu-* qemu_mode/qemu-*
unicorn_mode/samples/*/\.test-* unicorn_mode/samples/*/\.test-*
unicorn_mode/samples/*/output/ unicorn_mode/samples/*/output/
unicorn_mode/unicornafl
core\.* core\.*
test/unittests/unit_maybe_alloc test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable test/unittests/unit_preallocable
test/unittests/unit_list 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-server
examples/afl_network_proxy/afl-network-client examples/afl_network_proxy/afl-network-client

View File

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

View File

@ -50,19 +50,30 @@ else
endif endif
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" 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" 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 #CFLAGS_OPT += -march=native
#endif SPECIAL_PERFORMANCE += -march=native
endif
# OS X does not like _FORTIFY_SOURCE=2 # OS X does not like _FORTIFY_SOURCE=2
CFLAGS_OPT += -D_FORTIFY_SOURCE=2 CFLAGS_OPT += -D_FORTIFY_SOURCE=2
endif endif
ifeq "$(shell uname)" "SunOS"
CFLAGS_OPT += -Wno-format-truncation
LDFLAGS=-lkstat
endif
ifdef STATIC 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 # Disable python for static compilation to simplify things
PYTHON_OK=0 PYTHON_OK=0
PYFLAGS= PYFLAGS=
PYTHON_INCLUDE=/
CFLAGS_OPT += -static CFLAGS_OPT += -static
LDFLAGS += -lm -lpthread -lz -lutil LDFLAGS += -lm -lpthread -lz -lutil
@ -86,7 +97,7 @@ endif
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\ 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)\" -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
ifeq "$(shell uname -s)" "FreeBSD" ifeq "$(shell uname -s)" "FreeBSD"
@ -109,6 +120,13 @@ ifeq "$(shell uname -s)" "NetBSD"
LDFLAGS += -L /usr/pkg/lib/ LDFLAGS += -L /usr/pkg/lib/
endif 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) AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
ifneq "$(shell command -v python3m 2>/dev/null)" "" ifneq "$(shell command -v python3m 2>/dev/null)" ""
@ -182,12 +200,12 @@ ifneq "$(filter Linux GNU%,$(shell uname))" ""
endif endif
ifneq "$(findstring FreeBSD, $(shell uname))" "" ifneq "$(findstring FreeBSD, $(shell uname))" ""
CFLAGS += -pthread override CFLAGS += -pthread
LDFLAGS += -lpthread LDFLAGS += -lpthread
endif endif
ifneq "$(findstring NetBSD, $(shell uname))" "" ifneq "$(findstring NetBSD, $(shell uname))" ""
CFLAGS += -pthread override CFLAGS += -pthread
LDFLAGS += -lpthread LDFLAGS += -lpthread
endif endif
@ -227,7 +245,7 @@ endif
ifdef ASAN_BUILD ifdef ASAN_BUILD
$(info Compiling ASAN version of binaries) $(info Compiling ASAN version of binaries)
CFLAGS+=$(ASAN_CFLAGS) override CFLAGS+=$(ASAN_CFLAGS)
LDFLAGS+=$(ASAN_LDFLAGS) LDFLAGS+=$(ASAN_LDFLAGS)
endif endif
@ -235,14 +253,14 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
SHMAT_OK=1 SHMAT_OK=1
else else
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations LDFLAGS += -Wno-deprecated-declarations -lrt
endif endif
ifeq "$(TEST_MMAP)" "1" ifdef TEST_MMAP
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations LDFLAGS += -Wno-deprecated-declarations -lrt
endif endif
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done 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 "HELP --- the following make targets exist:"
@echo "==========================================" @echo "=========================================="
@echo "all: just the main afl++ binaries" @echo "all: just the main afl++ binaries"
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, 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, radamsa" @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 "distrib: everything (for both binary-only and source code fuzzing)"
@echo "man: creates simple man pages from the help option of the programs" @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" @echo "install: installs everything you have compiled with the build option above"
@ -294,6 +312,8 @@ ifndef AFL_NO_X86
test_x86: test_x86:
@echo "[*] Checking for the default compiler cc..." @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 ) @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 "[*] 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 ) @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 @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) $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
ln -sf afl-as as 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 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 $(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 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 $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
radamsa: src/third_party/libradamsa/libradamsa.so 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
cp src/third_party/libradamsa/libradamsa.so . $(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)
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-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 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) $(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 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 -o $@ $(LDFLAGS) $(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 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 -o $@ $(LDFLAGS) $(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 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) $(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 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 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_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) $(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) 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 @$(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 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 @$(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_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) 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 @$(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 @$(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/unit_list
test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
unit_preallocable: 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 @$(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" 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 else
@ -429,6 +457,8 @@ code-format:
./.custom-format.py -i gcc_plugin/*.c ./.custom-format.py -i gcc_plugin/*.c
#./.custom-format.py -i gcc_plugin/*.h #./.custom-format.py -i gcc_plugin/*.h
./.custom-format.py -i gcc_plugin/*.cc ./.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/*/*.c
./.custom-format.py -i examples/*/*.h ./.custom-format.py -i examples/*/*.h
./.custom-format.py -i test/*.c ./.custom-format.py -i test/*.c
@ -481,7 +511,6 @@ clean:
$(MAKE) -C examples/argv_fuzzing clean $(MAKE) -C examples/argv_fuzzing clean
$(MAKE) -C qemu_mode/unsigaction clean $(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C src/third_party/libradamsa/ clean
rm -rf qemu_mode/qemu-3.1.1 rm -rf qemu_mode/qemu-3.1.1
ifeq "$(IN_REPO)" "1" ifeq "$(IN_REPO)" "1"
test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
@ -495,7 +524,7 @@ deepclean: clean
rm -rf unicorn_mode/unicornafl rm -rf unicorn_mode/unicornafl
git reset --hard >/dev/null 2>&1 || true git reset --hard >/dev/null 2>&1 || true
distrib: all radamsa distrib: all
-$(MAKE) -C llvm_mode -$(MAKE) -C llvm_mode
-$(MAKE) -C gcc_plugin -$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
@ -504,18 +533,18 @@ distrib: all radamsa
$(MAKE) -C examples/socket_fuzzing $(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing $(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh -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 libdislocator
$(MAKE) -C libtokencap $(MAKE) -C libtokencap
$(MAKE) -C examples/afl_network_proxy $(MAKE) -C examples/afl_network_proxy
$(MAKE) -C examples/socket_fuzzing $(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing $(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh -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 llvm_mode
-$(MAKE) -C gcc_plugin -$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator $(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 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 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 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 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 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 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 * 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 * QBDI mode to fuzz android native libraries via QBDI framework
@ -167,8 +167,8 @@ is what you should choose.
These build targets exist: These build targets exist:
* all: just the main afl++ binaries * all: just the main afl++ binaries
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_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, radamsa * source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap
* distrib: everything (for both binary-only and source code fuzzing) * distrib: everything (for both binary-only and source code fuzzing)
* man: creates simple man pages from the help option of the programs * man: creates simple man pages from the help option of the programs
* install: installs everything you have compiled with the build options above * 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: The available schedules are:
- explore (default) - explore (default, original AFL)
- fast - exploit (original AFL)
- coe - fast (AFLfast)
- quad - coe (AFLfast)
- lin - quad (AFLfast)
- exploit - lin (AFLfast)
- mmopt (experimental) - rare (afl++ experimental)
- rare (experimental) - mmopt (afl++ experimental)
- seek (afl++ experimental)
In parallel mode (-M/-S, several instances with the shared queue), we suggest to 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 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+ ## Roadmap 2.65+
- AFL_MAP_SIZE for qemu_mode and unicorn_mode - 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 - namespace for targets? e.g. network
- libradamsa as a custom module? - learn from honggfuzz (mutations, maybe ptrace?)
- learn from honggfuzz - CPU affinity for many cores? There seems to be an issue > 96 cores
- 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?
## Further down the road ## Further down the road
@ -18,9 +14,10 @@ afl-fuzz:
- setting min_len/max_len/start_offset/end_offset limits for mutation output - setting min_len/max_len/start_offset/end_offset limits for mutation output
llvm_mode: llvm_mode:
- better whitelist solution for LTO - LTO - imitate sancov
gcc_plugin: gcc_plugin:
- (wait for submission then decide)
- laf-intel - laf-intel
- better instrumentation (seems to be better with gcc-9+) - 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_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
AFL_PATH: path for the afl-showmap binary AFL_PATH: path for the afl-showmap binary
AFL_SKIP_BIN_CHECK: skip check for target binary AFL_SKIP_BIN_CHECK: skip check for target binary
AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp
_EOF_ _EOF_
exit 1 exit 1
fi fi
@ -142,29 +141,29 @@ fi
# Do a sanity check to discourage the use of /tmp, since we can't really # Do a sanity check to discourage the use of /tmp, since we can't really
# handle this safely from a shell script. # handle this safely from a shell script.
if [ "$AFL_ALLOW_TMP" = "" ]; then #if [ "$AFL_ALLOW_TMP" = "" ]; then
#
echo "$IN_DIR" | grep -qE '^(/var)?/tmp/' # echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
T1="$?" # T1="$?"
#
echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/' # echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
T2="$?" # T2="$?"
#
echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/' # echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
T3="$?" # T3="$?"
#
echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/' # echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
T4="$?" # T4="$?"
#
echo "$PWD" | grep -qE '^(/var)?/tmp/' # echo "$PWD" | grep -qE '^(/var)?/tmp/'
T5="$?" # T5="$?"
#
if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then # 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 # echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
exit 1 # exit 1
fi # fi
#
fi #fi
# If @@ is specified, but there's no -f, let's come up with a temporary input # If @@ is specified, but there's no -f, let's come up with a temporary input
# file name. # file name.
@ -246,7 +245,7 @@ if [ ! "$STDIN_FILE" = "" ]; then
fi fi
if [ "$AFL_PATH" = "" ]; then if [ "$AFL_PATH" = "" ]; then
SHOWMAP="${0%/afl-cmin}/afl-showmap" SHOWMAP="${0%/afl-cmin.bash}/afl-showmap"
else else
SHOWMAP="$AFL_PATH/afl-showmap" SHOWMAP="$AFL_PATH/afl-showmap"
fi fi

View File

@ -15,6 +15,10 @@
# http://www.apache.org/licenses/LICENSE-2.0 # 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 "progress plotting utility for afl-fuzz by Michal Zalewski"
echo 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; 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. 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_ _EOF_
exit 1 exit 1
fi fi
if [ "$AFL_ALLOW_TMP" = "" ]; then inputdir=`get_abs_path "$1"`
outputdir=`get_abs_path "$2"`
echo "$1" | grep -qE '^(/var)?/tmp/' #if [ "$AFL_ALLOW_TMP" = "" ]; then
T1="$?" #
# 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/' if [ ! -f "$inputdir/plot_data" ]; then
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
echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
exit 1 exit 1
fi 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)" test "$BANNER" = "" && BANNER="(none)"
@ -77,17 +81,17 @@ if [ "$GNUPLOT" = "" ]; then
fi 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 echo "[-] Error: unable to create the output directory - pick another location." 1>&2
exit 1 exit 1
fi fi
rm -f "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png"
mv -f "$2/index.html" "$2/index.html.orig" 2>/dev/null mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null
echo "[*] Generating plots..." echo "[*] Generating plots..."
@ -96,7 +100,7 @@ echo "[*] Generating plots..."
cat <<_EOF_ cat <<_EOF_
set terminal png truecolor enhanced size 1000,300 butt 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 xdata time
set timefmt '%s' set timefmt '%s'
@ -114,31 +118,31 @@ set key outside
set autoscale xfixmin set autoscale xfixmin
set autoscale xfixmax 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: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: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:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' 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 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: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:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\
'' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3 '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3
set terminal png truecolor enhanced size 1000,200 butt 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, \\ plot '$inputdir/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; '$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
_EOF_ _EOF_
) | gnuplot ) | 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 echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2
exit 1 exit 1
@ -147,10 +151,10 @@ fi
echo "[*] Generating index.html..." echo "[*] Generating index.html..."
cat >"$2/index.html" <<_EOF_ cat >"$outputdir/index.html" <<_EOF_
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'"> <table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr> <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> <tr><td><b>Generated on:</b></td><td>`date`</td></tr>
</table> </table>
<p> <p>
@ -164,8 +168,8 @@ _EOF_
# served by Apache or other HTTP daemon. Since the plots aren't horribly # served by Apache or other HTTP daemon. Since the plots aren't horribly
# sensitive, this seems like a reasonable trade-off. # sensitive, this seems like a reasonable trade-off.
chmod 755 "$2" chmod 755 "$outputdir"
chmod 644 "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" "$2/index.html" chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/index.html"
echo "[+] All done - enjoy your charts!" 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)))) CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
all: libradamsa.so all: radamsa-mutator.so
# These can be overriden: # These can be overriden:
CFLAGS ?= -march=native $(CFLAGS_FLTO) CFLAGS ?= $(CFLAGS_FLTO)
# These are required: (otherwise radamsa gets very very slooooow) # These are required: (otherwise radamsa gets very very slooooow)
CFLAGS += -O3 -funroll-loops CFLAGS += -O3 -funroll-loops
libradamsa.so: libradamsa.a #libradamsa.so: libradamsa.a
$(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so # $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
libradamsa.a: libradamsa.c radamsa.h libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************" @echo " ***************************************************************"
@ -17,10 +17,14 @@ libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************" @echo " ***************************************************************"
$(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c $(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 test: libradamsa.a libradamsa-test.c
$(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
./libradamsa-test libradamsa-test.c | grep "library test passed" ./libradamsa-test libradamsa-test.c | grep "library test passed"
rm /tmp/libradamsa-*.fuzz rm /tmp/libradamsa-*.fuzz
clean: 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. 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" "Location"
"Max-Forwards" "Max-Forwards"
"Origin" "Origin"
"P3P " "P3P"
"Pragma" "Pragma"
"Proxy-Authenticate" "Proxy-Authenticate"
"Proxy-Authorization" "Proxy-Authorization"

View File

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

View File

@ -11,21 +11,32 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++2.65d (dev) ### Version ++2.65d (dev)
- afl-fuzz: - afl-fuzz:
- -S secondary nodes now only sync from the main node to increase performance, - -S secondary nodes now only sync from the main node to increase
the -M main node still syncs from everyone. Added checks that ensure performance, the -M main node still syncs from everyone. Added checks
exactly one main node is present and warn otherwise 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 - Add -D after -S to force a secondary to perform deterministic fuzzing
a temporary main node until a real main nodes shows up - 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) - 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: - llvm_mode:
- the default instrumentation is now PCGUARD, as it is faster and provides - the default instrumentation is now PCGUARD if the llvm version is >= 7,
better coverage. The original afl instrumentation can be set via as it is faster and provides better coverage. The original afl
AFL_LLVM_INSTRUMENT=AFL. This is automatically done when the WHITELIST instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is
feature is used. automatically done when the WHITELIST feature is used.
- some targets want a ld variant for LD that is not gcc/clang but ld, added - PCGUARD mode is now even better because we made it collision free - plus
afl-ld-lto to solve this it has a fixed map size, so it is also faster! :)
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim, - some targets want a ld variant for LD that is not gcc/clang but ld,
which needs 3.8.0) 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) - WHITELIST feature now supports wildcards (thanks to sirmc)
- small change to cmplog to make it work with current llvm 11-dev - small change to cmplog to make it work with current llvm 11-dev
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings - 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 - enable snapshot lkm also for persistent mode
- Unicornafl - Unicornafl
- Added powerPC support from unicorn/next - 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 - persistent mode shared memory testcase handover (instead of via
files/stdin) - 10-100% performance increase files/stdin) - 10-100% performance increase
- General support for 64 bit PowerPC, RiscV, Sparc etc. - General support for 64 bit PowerPC, RiscV, Sparc etc.
- fix afl-cmin.bash
- slightly better performance compilation options for afl++ and targets - slightly better performance compilation options for afl++ and targets
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in - fixed afl-gcc/afl-as that could break on fast systems reusing pids in
the same second the same second
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk - added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
- added former post_library examples to examples/custom_mutators/ - added former post_library examples to examples/custom_mutators/
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and gcc 10 - Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and
so afl-clang-lto can be build gcc 10 so afl-clang-lto can be build
### Version ++2.65c (release): ### 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 For GSOC2020 interested students please see
[https://github.com/AFLplusplus/AFLplusplus/issues/208](https://github.com/AFLplusplus/AFLplusplus/issues/208) [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 Currently, AFL++'s mutation does not have deeper knowledge about the fuzzed
binary, apart from feedback, even though the developer may have insights binary, apart from feedback, even though the developer may have insights
@ -25,41 +25,21 @@ various results.
Mentor: andreafioraldi 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 ## perf-fuzz Linux Kernel Module
Either Port the patch to the upcoming Ubuntu LTS 20.04 default kernel Expand on [snapshot LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
and provide a qemu-kvm image or find a different userspace snapshot To make it thread safe, can snapshot several processes at once and increase
solution that has a good performance and is reliable, e.g. with docker. overall performance.
[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!
Mentor: any 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 First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior
changed, which vastly decreases fuzzing speeds. 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 Understanding the current instrumentation and fixing the current caching
issues will be needed. issues will be needed.
@ -86,7 +66,7 @@ Either improve a single mutator thorugh learning of many different bugs
Mentor: domenukk 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, 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 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 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 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 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. 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/). 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)/ LLVM_BINDIR := $(LLVM_BINDIR)/
endif endif
FLAGS=-O3 -funroll-loops FLAGS=-O3 -funroll-loops -g
all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
aflpp_driver.o: aflpp_driver.cpp 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 libAFLDriver.a: aflpp_driver.o
ar ru libAFLDriver.a aflpp_driver.o ar ru libAFLDriver.a aflpp_driver.o
debug: debug:
$(LLVM_BINDIR)clang++ -D_DEBUG=\"1\" $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp $(LLVM_BINDIR)clang++ -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c
ar ru libAFLDriver.a aflpp_driver.o $(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 aflpp_qemu_driver.o: aflpp_qemu_driver.c
$(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c 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 aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c
$(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c 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 test: debug
afl-clang-fast++ -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a #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: clean:
rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test 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 <iostream>
#include <vector> #include <vector>
#ifdef _DEBUG
#include "hash.h"
#endif
// Platform detection. Copied from FuzzerInternal.h // Platform detection. Copied from FuzzerInternal.h
#ifdef __linux__ #ifdef __linux__
#define LIBFUZZER_LINUX 1 #define LIBFUZZER_LINUX 1
@ -273,7 +277,11 @@ int main(int argc, char **argv) {
int num_runs = 0; int num_runs = 0;
while (__afl_persistent_loop(N)) { while (__afl_persistent_loop(N)) {
#ifdef _DEBUG #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 #endif
if (*__afl_fuzz_len) { if (*__afl_fuzz_len) {
num_runs++; num_runs++;

View File

@ -1,19 +1,21 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include "hash.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 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; return 0;
if (Data[0] == 'F') if (Data[0] == 'F')
if (Data[1] == 'A') if (Data[1] == 'A')
if (Data[2] == '$') if (Data[2] == '$')
if (Data[3] == '$') if (Data[3] == '$')
abort(); if (Data[4] == '$')
abort();
return 0; return 0;

View File

@ -49,9 +49,13 @@ int main(int argc, char **argv) {
len = __AFL_FUZZ_TESTCASE_LEN; len = __AFL_FUZZ_TESTCASE_LEN;
fprintf(stderr, "input: %zd \"%s\"\n", len, buf);
/* do we have enough data? */ /* do we have enough data? */
if (len < 8) continue; if (len < 8) continue;
if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n");
if (buf[0] == 'f') { if (buf[0] == 'f') {
printf("one\n"); 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) VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CFLAGS = -Wall -I../include -Wno-pointer-sign \ CFLAGS_SAFE := -Wall -I../include -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
-Wno-unused-function -Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CXXEFLAGS := $(CXXFLAGS) -Wall 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 SHMAT_OK=1
else else
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
LDFLAGS += -lrt
endif endif
ifeq "$(TEST_MMAP)" "1" ifeq "$(TEST_MMAP)" "1"
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
endif
ifneq "$(shell uname -s)" "Haiku"
LDFLAGS += -lrt LDFLAGS += -lrt
endif endif
@ -111,7 +114,7 @@ afl-common.o: ../src/afl-common.c
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps ../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) test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..." @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"; cc_params[cc_par_cnt++] = "-lrt";
#endif #endif

View File

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

View File

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

View File

@ -60,7 +60,7 @@ typedef enum prealloc_status {
\ \
if ((prealloc_counter) >= (prealloc_size)) { \ 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!"); } \ if (!el_ptr) { FATAL("error in list.h -> out of memory for element!"); } \
el_ptr->pre_status = PRE_STATUS_MALLOC; \ 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; size = strlen((char *)str) + 1;
ALLOC_CHECK_SIZE(size); ALLOC_CHECK_SIZE(size);
ret = malloc(size); ret = (u8 *)malloc(size);
ALLOC_CHECK_RESULT(ret, 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; } if (!mem || !size) { return NULL; }
ALLOC_CHECK_SIZE(size); ALLOC_CHECK_SIZE(size);
ret = malloc(size + 1); ret = (u8 *)malloc(size + 1);
ALLOC_CHECK_RESULT(ret, size); ALLOC_CHECK_RESULT(ret, size);
memcpy(ret, mem, size); memcpy(ret, mem, size);

View File

@ -293,7 +293,7 @@
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */ /* 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 /* Maximum line length passed from GCC to 'as' and used for parsing
configuration files: */ configuration files: */
@ -397,12 +397,5 @@
// #define IGNORE_FINDS // #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 */ #endif /* ! _HAVE_CONFIG_H */

View File

@ -262,7 +262,7 @@
\ \
} while (0) } 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). */ interpret different failure modes for read(), write(), etc). */
#define RPFATAL(res, x...) \ #define RPFATAL(res, x...) \

View File

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

View File

@ -30,11 +30,18 @@
#include "types.h" #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; const u64 *data = (u64 *)key;
u64 h1 = seed ^ len; 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) { 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 */ #endif /* !_HAVE_HASH_H */

View File

@ -38,6 +38,8 @@ typedef struct sharedmem {
/* ================ Proteas ================ */ /* ================ Proteas ================ */
int g_shm_fd; int g_shm_fd;
char g_shm_file_path[L_tmpnam]; char g_shm_file_path[L_tmpnam];
int cmplog_g_shm_fd;
char cmplog_g_shm_file_path[L_tmpnam];
/* ========================================= */ /* ========================================= */
#else #else
s32 shm_id; /* ID of the SHM region */ 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> #include <sys/param.h>
#endif #endif
#if defined(__linux__) && !defined(__ANDROID__) #if (defined(__linux__) && !defined(__ANDROID__)) || defined(__HAIKU__)
#include <unistd.h> #include <unistd.h>
#include <sys/syscall.h> #ifdef __linux__
#include <sys/syscall.h>
#include <malloc.h>
#endif
#ifdef __NR_getrandom #ifdef __NR_getrandom
#define arc4random_buf(p, l) \ #define arc4random_buf(p, l) \
do { \ do { \

View File

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

View File

@ -33,8 +33,9 @@
#include "../types.h" #include "../types.h"
#include "../config.h" #include "../config.h"
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \ #if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ !defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ && \
!defined(__HAIKU__)
#error "Sorry, this library is unsupported in this platform for now!" #error "Sorry, this library is unsupported in this platform for now!"
#endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \ #endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \
!__NetBSD__*/ !__NetBSD__*/
@ -49,6 +50,8 @@
#include <sys/user.h> #include <sys/user.h>
#endif #endif
#include <sys/mman.h> #include <sys/mman.h>
#elif defined __HAIKU__
#include <kernel/image.h>
#endif #endif
#include <dlfcn.h> #include <dlfcn.h>
@ -230,6 +233,19 @@ static void __tokencap_load_mappings(void) {
} }
munmap(buf, len); 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 #endif
} }
@ -357,7 +373,7 @@ int strcasecmp(const char *str1, const char *str2) {
while (1) { 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 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0; if (!c1) return 0;
@ -381,7 +397,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
while (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 != c2) return (c1 > c2) ? 1 : -1;
if (!c1) return 0; if (!c1) return 0;
@ -495,7 +511,7 @@ char *strcasestr(const char *haystack, const char *needle) {
const char *n = needle; const char *n = needle;
const char *h = haystack; const char *h = haystack;
while (*n && *h && tolower(*n) == tolower(*h)) while (*n && *h && tolower((int)*n) == tolower((int)*h))
n++, h++; n++, h++;
if (!*n) return (char *)haystack; 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
endif endif
CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
override CFLAGS += -Wall \ CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ../include/ \
-g -Wno-pointer-sign -I ../include/ \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ -DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \ -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
-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
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function override CFLAGS += $(CFLAGS_SAFE)
ifdef AFL_TRACE_PC ifdef AFL_TRACE_PC
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets ) $(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
endif endif
CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 CXXFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
override CXXFLAGS += -Wall -g -I ../include/ \ override CXXFLAGS += -Wall -g -I ../include/ \
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros -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) CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
@ -221,12 +228,12 @@ CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
ifeq "$(shell uname)" "Darwin" ifeq "$(shell uname)" "Darwin"
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
else else
CLANG_CFL += -Wl,-znodelete CLANG_CPPFL += -Wl,-znodelete
endif endif
ifeq "$(shell uname)" "OpenBSD" ifeq "$(shell uname)" "OpenBSD"
CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
CLANG_CFL += -mno-retpoline CLANG_CPPFL += -mno-retpoline
CFLAGS += -mno-retpoline CFLAGS += -mno-retpoline
# Needed for unwind symbols # Needed for unwind symbols
LDFLAGS += -lc++abi LDFLAGS += -lc++abi
@ -304,7 +311,7 @@ afl-common.o: ../src/afl-common.c
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps ../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++ ln -sf afl-clang-fast ../afl-clang-fast++
ifneq "$(AFL_CLANG_FLTO)" "" ifneq "$(AFL_CLANG_FLTO)" ""
ifeq "$(LLVM_LTO)" "1" 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 $@ $(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 ../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 ../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps
ifeq "$(LLVM_MIN_4_0_1)" "0" ifeq "$(LLVM_MIN_4_0_1)" "0"
$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
endif 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 ../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" 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 endif
../afl-ld-lto: afl-ld-lto.c ../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 ../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -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_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) -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) -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 @$(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 endif
../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o ../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" 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 endif
# laf # laf
../split-switches-pass.so: split-switches-pass.so.cc afl-llvm-common.o | test_deps ../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 ../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 ../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 # /laf
../cmplog-routines-pass.so: cmplog-routines-pass.cc afl-llvm-common.o | test_deps ../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 ../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: 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_SAFE) -O3 -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_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) -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 -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 ../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 ../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 32-bit variant of the runtime (-m32)... " @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 ../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 64-bit variant of the runtime (-m64)... " @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) test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..." @echo "[*] Testing the CC wrapper and instrumentation output..."

View File

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

View File

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

View File

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

View File

@ -109,6 +109,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C); IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
/* Show a banner */ /* Show a banner */
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { 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. */ /* Get/set the globals for the SHM region. */

View File

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

View File

@ -140,6 +140,7 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Show a banner */ /* Show a banner */
char be_quiet = 0; char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) debug = 1; 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 #else
u32 shm_id = atoi(id_str); u32 shm_id = atoi(id_str);
@ -157,7 +158,7 @@ static void __afl_map_shm_fuzz() {
} }
__afl_fuzz_len = (u32 *)map; __afl_fuzz_len = (u32 *)map;
__afl_fuzz_ptr = (u8 *)(map + sizeof(u32)); __afl_fuzz_ptr = map + sizeof(u32);
if (getenv("AFL_DEBUG")) { if (getenv("AFL_DEBUG")) {
@ -182,6 +183,9 @@ static void __afl_map_shm(void) {
if (__afl_final_loc) { if (__afl_final_loc) {
if (__afl_final_loc % 8)
__afl_final_loc = (((__afl_final_loc + 7) >> 3) << 3);
__afl_map_size = __afl_final_loc; __afl_map_size = __afl_final_loc;
if (__afl_final_loc > MAP_SIZE) { 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 (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)) { (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
__afl_map_shm_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 (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)) == if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(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) { while (start < stop) {
if (R(100) < inst_ratio) if (R(100) < inst_ratio)
*start = R(MAP_SIZE - 1) + 1; *start = ++__afl_final_loc;
else else
*start = 0; *start = 0;

View File

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

View File

@ -169,7 +169,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
args.push_back(v1Pcasted); args.push_back(v1Pcasted);
args.push_back(v2Pcasted); args.push_back(v2Pcasted);
IRB.CreateCall(cmplogHookFn, args, "tmp"); IRB.CreateCall(cmplogHookFn, args);
// errs() << callInst->getCalledFunction()->getName() << "\n"; // 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); load = cur_cmp_IRB.CreateZExt(load, Int32Ty);
std::vector<Value *> args; std::vector<Value *> args;
args.push_back(load); 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); 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) 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 CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
LDFLAGS += -ldl LDFLAGS += -ldl

View File

@ -51,7 +51,9 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/shm.h> #ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/resource.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 u8 *in_data; /* Input data for analysis */
static u32 in_len, /* Input data length */ static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
total_execs, /* Total number of execs */ total_execs, /* Total number of execs */
exec_hangs, /* Total number of hangs */ exec_hangs, /* Total number of hangs */
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */ exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
static u64 orig_cksum; /* Original checksum */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */ static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
static s32 dev_null_fd = -1; /* FD to /dev/null */ 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; int status = 0;
s32 prog_in_fd; s32 prog_in_fd;
u32 cksum; u64 cksum;
memset(trace_bits, 0, map_size); memset(trace_bits, 0, map_size);
MEM_BARRIER(); 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, /* We don't actually care if the target is crashing or not,
except that when it does, the checksum should be different. */ 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); check_environment_vars(envp);
sharedmem_t shm = {0}; sharedmem_t shm = {0};
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
trace_bits = afl_shm_init(&shm, map_size, 0); trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler); atexit(at_exit_handler);
setup_signal_handlers(); setup_signal_handlers();

View File

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

View File

@ -32,6 +32,7 @@
#include "common.h" #include "common.h"
#include "list.h" #include "list.h"
#include "forkserver.h" #include "forkserver.h"
#include "hash.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -70,9 +71,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->out_fd = -1; fsrv->out_fd = -1;
fsrv->out_dir_fd = -1; fsrv->out_dir_fd = -1;
fsrv->dev_null_fd = -1; fsrv->dev_null_fd = -1;
#ifndef HAVE_ARC4RANDOM
fsrv->dev_urandom_fd = -1; fsrv->dev_urandom_fd = -1;
#endif
/* Settings */ /* Settings */
fsrv->use_stdin = 1; fsrv->use_stdin = 1;
fsrv->no_unlink = 0; 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->map_size = from->map_size;
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz; fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
#ifndef HAVE_ARC4RANDOM
fsrv_to->dev_urandom_fd = from->dev_urandom_fd; fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
#endif
// These are forkserver specific. // These are forkserver specific.
fsrv_to->out_dir_fd = -1; 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_ZERO(&readfds);
FD_SET(fd, &readfds); FD_SET(fd, &readfds);
struct timeval timeout; struct timeval timeout;
size_t len = 4; int sret;
ssize_t len_read;
timeout.tv_sec = (timeout_ms / 1000); timeout.tv_sec = (timeout_ms / 1000);
timeout.tv_usec = (timeout_ms % 1000) * 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 #endif
/* set exceptfds as well to return when a child exited/closed the pipe. */ /* 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; *buf = -1;
return timeout_ms + 1; return timeout_ms + 1;
} else if (sret < 0) { } else if (unlikely(sret < 0)) {
if (likely(errno == EINTR)) goto restart_select;
*buf = -1; *buf = -1;
return 0; return 0;
} }
ssize_t len_read = read(fd, ((u8 *)buf), len); return 0; // not reached
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;
} }
@ -400,9 +418,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
close(fsrv->out_dir_fd); close(fsrv->out_dir_fd);
close(fsrv->dev_null_fd); close(fsrv->dev_null_fd);
#ifndef HAVE_ARC4RANDOM
close(fsrv->dev_urandom_fd); close(fsrv->dev_urandom_fd);
#endif
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); } if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
/* This should improve performance a bit, since it stops the linker from /* 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 */ /* 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 the unneeded endpoints. */
close(ctl_pipe[0]); close(ctl_pipe[0]);
@ -545,7 +569,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (unlikely(tmp_map_size % 8)) { if (unlikely(tmp_map_size % 8)) {
// should not happen // 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); 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 // this is not afl-fuzz - we deny and return
if (fsrv->use_shmem_fuzz) 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 else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); status = (FS_OPT_ENABLED);
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed."); 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."); } 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) { if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed."); 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; *fsrv->shmem_fuzz_len = len;
memcpy(fsrv->shmem_fuzz, buf, len); memcpy(fsrv->shmem_fuzz, buf, len);
// printf("test case len: %u [0]:0x%02x\n", *fsrv->shmem_fuzz_len, buf[0]); #ifdef _DEBUG
// fflush(stdout); 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 { } else {

View File

@ -542,27 +542,35 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
u8 hnb = '\0'; u8 hnb = '\0';
s32 fd; s32 fd;
u8 keeping = 0, res; u8 keeping = 0, res;
u64 cksum = 0;
u8 fn[PATH_MAX]; u8 fn[PATH_MAX];
/* Update path frequency. */ /* Update path frequency. */
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
struct queue_entry *q = afl->queue; /* Generating a hash on every input is super expensive. Bad idea and should
while (q) { 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; struct queue_entry *q = afl->queue;
break; 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 /* Keep only if there are new bits in the map, add to queue for
future fuzzing, etc. */ 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 /* Try to calibrate inline; this also calls update_bitmap_score() when
successful. */ successful. */

View File

@ -37,6 +37,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
cpu_set_t c; cpu_set_t c;
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
cpuset_t * c; cpuset_t * c;
#elif defined(__sun)
psetid_t c;
#endif #endif
u8 cpu_used[4096] = {0}; u8 cpu_used[4096] = {0};
@ -181,6 +183,56 @@ void bind_to_free_cpu(afl_state_t *afl) {
} }
ck_free(procs); 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 #else
#warning \ #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" "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; size_t cpu_start = 0;
try: try:
#ifndef __ANDROID__ #if !defined(__ANDROID__)
for (i = cpu_start; i < afl->cpu_core_count; i++) { for (i = cpu_start; i < afl->cpu_core_count; i++) {
if (!cpu_used[i]) { break; } if (!cpu_used[i]) { break; }
@ -228,6 +280,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
c = cpuset_create(); c = cpuset_create();
if (c == NULL) PFATAL("cpuset_create failed"); if (c == NULL) PFATAL("cpuset_create failed");
cpuset_set(i, c); cpuset_set(i, c);
#elif defined(__sun)
pset_create(&c);
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
#endif #endif
#if defined(__linux__) #if defined(__linux__)
@ -271,6 +326,19 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) {
} }
cpuset_destroy(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 #else
// this will need something for other platforms // this will need something for other platforms
// TODO: Solaris/Illumos has processor_bind ... might worth a try // 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); afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR);
if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } 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); afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
#endif
/* Gnuplot output file. */ /* Gnuplot output file. */
@ -2062,14 +2128,17 @@ void check_binary(afl_state_t *afl, u8 *fname) {
/* Check for blatant user errors. */ /* Check for blatant user errors. */
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) && /* disabled. not a real-worl scenario where this is a problem.
!strchr(afl->fsrv.target_path + 5, '/')) || if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) && !strchr(afl->fsrv.target_path + 5, '/')) ||
!strchr(afl->fsrv.target_path + 9, '/'))) { (!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); fd = open(afl->fsrv.target_path, O_RDONLY);

View File

@ -44,7 +44,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL( FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull " "MOpt and custom mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators " "requests that integrates MOpt with the optional mutators "
"(custom/radamsa/redqueen/...)."); "(custom/redqueen/...).");
u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,"); u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
@ -89,7 +89,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL( FATAL(
"MOpt and Python mutator are mutually exclusive. We accept pull " "MOpt and Python mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators " "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", sprintf(afl->stage_name_buf, "ptrim %s",
u_stringify_int(val_buf, trim_exec)); u_stringify_int(val_buf, trim_exec));
u32 cksum; u64 cksum;
size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf); 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; } 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) { if (cksum == q->exec_cksum) {

View File

@ -29,10 +29,14 @@
static int select_algorithm(afl_state_t *afl) { 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) { for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
if (unlikely(i_puppet == 0)) { if (unlikely(i_puppet == 0)) {
@ -52,8 +56,10 @@ static int select_algorithm(afl_state_t *afl) {
} }
if (j_puppet == 1 && if ((j_puppet == 1 &&
sele < afl->probability_now[afl->swarm_now][i_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"); FATAL("error select_algorithm");
@ -364,8 +370,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
s32 len, fd, temp_len, i, j; s32 len, fd, temp_len, i, j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt; u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum;
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1; u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0; 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) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res = res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); 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(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 (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len, 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 if it has gone through deterministic testing in earlier, resumed runs
(passed_det). */ (passed_det). */
if (afl->skip_deterministic || if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
((!afl->queue_cur->passed_det) && likely(perf_score <
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->depth * 30 ? afl->queue_cur->depth * 30
: afl->havoc_max_mult * 100)) || : afl->havoc_max_mult * 100))) {
afl->queue_cur->passed_det) {
goto custom_mutator_stage; 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) { 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) { 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)]) { 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 /* If in non-instrumented mode or if the file is very short, just flag
everything without wasting time on checksums. */ everything without wasting time on checksums. */
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) { 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 { } else {
@ -1680,6 +1685,7 @@ custom_mutator_stage:
retry_external_pick: retry_external_pick:
/* Pick a random other queue entry for passing to external API */ /* Pick a random other queue entry for passing to external API */
do { do {
tid = rand_below(afl, afl->queued_paths); tid = rand_below(afl, afl->queued_paths);
@ -1704,7 +1710,7 @@ custom_mutator_stage:
/* Make sure that the target has a reasonable length. */ /* Make sure that the target has a reasonable length. */
while (target && (target->len < 2 || target == afl->queue_cur) && while (target && (target->len < 2 || target == afl->queue_cur) &&
afl->queued_paths > 1) { afl->queued_paths > 3) {
target = target->next; target = target->next;
++afl->splicing_with; ++afl->splicing_with;
@ -2230,7 +2236,7 @@ havoc_stage:
case 16: { case 16: {
u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1); 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 /* Insert an extra. Do the same dice-rolling stuff as for the
previous case. */ previous case. */
@ -2239,44 +2245,27 @@ havoc_stage:
use_extra = rand_below(afl, afl->a_extras_cnt); use_extra = rand_below(afl, afl->a_extras_cnt);
extra_len = afl->a_extras[use_extra].len; extra_len = afl->a_extras[use_extra].len;
ptr = afl->a_extras[use_extra].data;
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);
} else { } else {
use_extra = rand_below(afl, afl->extras_cnt); use_extra = rand_below(afl, afl->extras_cnt);
extra_len = afl->extras[use_extra].len; extra_len = afl->extras[use_extra].len;
ptr = afl->extras[use_extra].data;
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);
} }
/* Tail */ if (temp_len + extra_len >= MAX_FILE) { break; }
memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,
temp_len - insert_at); 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; temp_len += extra_len;
break; break;
@ -2438,63 +2427,6 @@ retry_splicing:
#endif /* !IGNORE_FINDS */ #endif /* !IGNORE_FINDS */
ret_val = 0; 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 */ /* we are through with this queue entry - for this iteration */
abandon_entry: 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; s32 len, fd, temp_len, i, j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
u64 havoc_queued, orig_hit_cnt, new_hit_cnt, cur_ms_lv; 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, prev_cksum, eff_cnt = 1; u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0; 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) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res = res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); 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) { 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) { 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)]) { 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 /* If in non-instrumented mode or if the file is very short, just flag
everything without wasting time on checksums. */ everything without wasting time on checksums. */
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) { 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 { } else {
@ -4208,6 +4142,94 @@ pacemaker_fuzzing:
} /* case 15 */ } /* 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() */ } /* switch select_algorithm() */
} /* for i=0; i < use_stacking */ } /* 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; u32 i;
u64 fav_factor; u64 fav_factor;
u64 fuzz_p2 = next_pow2(q->n_fuzz); u64 fuzz_p2;
if (afl->schedule == MMOPT || afl->schedule == RARE || if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
unlikely(afl->fixed_seed)) { 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; 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. */ /* Faster-executing or smaller test cases are favored. */
u64 top_rated_fav_factor; 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 || if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
unlikely(afl->fixed_seed)) {
top_rated_fav_factor = afl->top_rated[i]->len << 2; 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 || if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
unlikely(afl->fixed_seed)) {
if (fav_factor > afl->top_rated[i]->len << 2) { continue; } 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 // Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh // coverage, the better the fuzzing, right? -mh
if (afl->schedule != MMOPT && afl->schedule != RARE && if (afl->schedule >= RARE && likely(!afl->fixed_seed)) {
likely(!afl->fixed_seed)) {
if (q->exec_us * 0.1 > avg_exec_us) { 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: case EXPLORE:
break; break;
case SEEK:
break;
case EXPLOIT: case EXPLOIT:
factor = MAX_FACTOR; factor = MAX_FACTOR;
break; 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 // MOpt mode
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) { 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; } 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; 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); struct range *ranges = add_range(NULL, 0, len);
u8 * backup = ck_alloc_nozero(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); memcpy(backup, buf + rng->start, s);
rand_replace(afl, buf + rng->start, s); rand_replace(afl, buf + rng->start, s);
u32 cksum; u64 cksum;
u64 start_us = get_cur_time_us(); u64 start_us = get_cur_time_us();
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) { 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) { while (ranges) {
rng = ranges; rng = ranges;
ranges = ranges->next; ranges = rng->next;
ck_free(rng); ck_free(rng);
rng = NULL; rng = NULL;
@ -224,7 +224,7 @@ checksum_fail:
while (ranges) { while (ranges) {
rng = ranges; rng = ranges;
ranges = ranges->next; ranges = rng->next;
ck_free(rng); ck_free(rng);
rng = NULL; 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 // afl->queue_cur->exec_cksum
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, 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; u8 r = 1;
if (afl->orig_cmp_map == NULL) { 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; s32 fd = afl->fsrv.out_fd;
u32 tail_len = len - skip_at - skip_len; 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) { 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) { if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz); afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz); ck_free(afl->shm_fuzz);
afl->shm_fuzz = NULL; 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) { for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 cksum; u64 cksum;
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) {
show_stats(afl);
}
write_to_testcase(afl, use_mem, q->len); 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) { if (q->exec_cksum != cksum) {
hnb = has_new_bits(afl, afl->virgin_bits); hnb = has_new_bits(afl, afl->virgin_bits);
@ -385,7 +414,7 @@ void sync_fuzzers(afl_state_t *afl) {
DIR * sd; DIR * sd;
struct dirent *sd_ent; struct dirent *sd_ent;
u32 sync_cnt = 0, synced = 0, entries = 0; u32 sync_cnt = 0, synced = 0, entries = 0;
u8 path[PATH_MAX]; u8 path[PATH_MAX + 256];
sd = opendir(afl->sync_dir); sd = opendir(afl->sync_dir);
if (!sd) { PFATAL("Unable to open '%s'", 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))) { while ((sd_ent = readdir(sd))) {
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX]; 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; s32 id_fd;
@ -438,6 +467,12 @@ void sync_fuzzers(afl_state_t *afl) {
synced++; 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. */ /* Skip anything that doesn't have a queue/ subdirectory. */
sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name); 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 (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); lseek(id_fd, 0, SEEK_SET);
} }
next_min_accept = min_accept;
/* Show stats */ /* Show stats */
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt); 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; s32 fd;
struct stat st; 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; afl->syncing_case = next_min_accept;
next_min_accept++; next_min_accept++;
o--; o--;
@ -646,7 +680,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
while (remove_pos < q->len) { while (remove_pos < q->len) {
u32 trim_avail = MIN(remove_len, q->len - remove_pos); 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); 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? /* 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 /* 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 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}; s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
char *power_names[POWER_SCHEDULES_NUM] = { char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast",
"coe", "lin", "quad",
"explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"}; "rare", "mmopt", "seek"};
/* Initialize MOpt "globals" for this afl state */ /* 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; afl->stats_update_freq = 1;
#ifndef HAVE_ARC4RANDOM
afl->fsrv.dev_urandom_fd = -1; afl->fsrv.dev_urandom_fd = -1;
#endif
afl->fsrv.dev_null_fd = -1; afl->fsrv.dev_null_fd = -1;
afl->fsrv.child_pid = -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, void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
double eps) { double eps) {
#ifndef __HAIKU__
struct rusage rus; struct rusage rus;
#endif
unsigned long long int cur_time = get_cur_time(); unsigned long long int cur_time = get_cur_time();
u8 fn[PATH_MAX]; 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; } if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
#endif
fprintf( fprintf(
f, 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_path_time / 1000, afl->last_crash_time / 1000,
afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs, afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
afl->fsrv.exec_tmout, afl->slowest_exec_ms, afl->fsrv.exec_tmout, afl->slowest_exec_ms,
#ifdef __APPLE__ #ifndef __HAIKU__
#ifdef __APPLE__
(unsigned long int)(rus.ru_maxrss >> 20), (unsigned long int)(rus.ru_maxrss >> 20),
#else #else
(unsigned long int)(rus.ru_maxrss >> 10), (unsigned long int)(rus.ru_maxrss >> 10),
#endif
#else
-1UL,
#endif #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->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
afl->non_instrumented_mode ? " non_instrumented " : "", afl->non_instrumented_mode ? " non_instrumented " : "",
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", 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_uc == afl->unique_crashes &&
afl->plot_prev_uh == afl->unique_hangs && afl->plot_prev_uh == afl->unique_hangs &&
afl->plot_prev_md == afl->max_depth) || afl->plot_prev_md == afl->max_depth) ||
unlikely(!afl->queue_cycle)) { unlikely(!afl->queue_cycle) ||
unlikely(get_cur_time() - afl->start_time <= 60)) {
return; return;
@ -732,15 +746,13 @@ void show_stats(afl_state_t *afl) {
afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
: (u8 *)"n/a"); : (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(0), afl->stage_finds[STAGE_HAVOC]),
u_stringify_int(IB(2), afl->stage_cycles[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(3), afl->stage_finds[STAGE_SPLICE]),
u_stringify_int(IB(4), afl->stage_cycles[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]));
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) { 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]), // sprintf(tmp, "%s/%s",
u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); // u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp); // 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. */ /* Provide some CPU utilization stats. */

View File

@ -26,66 +26,53 @@
#include "afl-fuzz.h" #include "afl-fuzz.h"
#include "cmplog.h" #include "cmplog.h"
#include <limits.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 #ifdef PROFILING
extern u64 time_spent_working; extern u64 time_spent_working;
#endif #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. */ /* 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" " -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n" "Execution control settings:\n"
" -p schedule - power schedules recompute a seed's performance " " -p schedule - power schedules compute a seed's performance score. "
"score.\n" "<explore\n"
" <explore(default), fast, coe, lin, quad, exploit, " " (default), fast, coe, lin, quad, exploit, mmopt, "
"mmopt, rare>\n" "rare, seek>\n"
" see docs/power_schedules.md\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" " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
" -m megs - memory limit for child process (%d MB)\n" " -m megs - memory limit for child process (%d MB)\n"
" -Q - use binary-only instrumentation (QEMU mode)\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" "mode)\n\n"
"Mutator settings:\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 " " -L minutes - use MOpt(imize) mode and set the time limit for "
"entering the\n" "entering the\n"
" pacemaker mode (minutes of no new paths). 0 = " " 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" "devices etc.!)\n"
" -d - quick & dirty mode (skips deterministic steps)\n" " -d - quick & dirty mode (skips deterministic steps)\n"
" -n - fuzz without instrumentation (non-instrumented mode)\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" "good!)\n\n"
"Testing settings:\n" "Testing settings:\n"
@ -144,14 +130,16 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"Other stuff:\n" "Other stuff:\n"
" -T text - text banner to show on the screen\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 " " -I command - execute this command/script when a new crash is "
"found\n" "found\n"
" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap " //" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
"file\n" //" "file\n"
" -C - crash exploration mode (the peruvian rabbit thing)\n" " -C - crash exploration mode (the peruvian rabbit thing)\n"
" -e ext - file extension for the temporarily generated test " " -e ext - file extension for the fuzz test input file (if "
"case\n\n", "needed)\n\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT); argv0, EXEC_TIMEOUT, MEM_LIMIT);
if (more_help > 1) { if (more_help > 1) {
@ -231,7 +219,7 @@ static int stricmp(char const *a, char const *b) {
for (;; ++a, ++b) { for (;; ++a, ++b) {
int d; int d;
d = tolower(*a) - tolower(*b); d = tolower((int)*a) - tolower((int)*b);
if (d != 0 || !*a) { return d; } 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; doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz); 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, 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) { 0) {
switch (opt) { switch (opt) {
@ -296,7 +284,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 's': { case 's': {
afl->init_seed = strtoul(optarg, 0L, 10); rand_set_seed(afl, strtoul(optarg, 0L, 10));
afl->fixed_seed = 1; afl->fixed_seed = 1;
break; break;
@ -332,6 +320,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->schedule = RARE; afl->schedule = RARE;
} else if (!stricmp(optarg, "seek")) {
afl->schedule = SEEK;
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) { !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
@ -369,7 +361,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->out_dir = optarg; afl->out_dir = optarg;
break; break;
case 'M': { /* master sync ID */ case 'M': { /* main sync ID */
u8 *c; u8 *c;
@ -398,7 +390,7 @@ int main(int argc, char **argv_orig, char **envp) {
break; break;
case 'S': case 'S': /* secondary sync id */
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
afl->sync_id = ck_strdup(optarg); afl->sync_id = ck_strdup(optarg);
@ -503,6 +495,11 @@ int main(int argc, char **argv_orig, char **envp) {
break; break;
case 'D': /* enforce deterministic */
afl->skip_deterministic = 0;
break;
case 'd': /* skip deterministic */ case 'd': /* skip deterministic */
afl->skip_deterministic = 1; afl->skip_deterministic = 1;
@ -767,15 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
case 'R': case 'R':
if (afl->use_radamsa) { FATAL(
"Radamsa is now a custom mutator, please use that "
afl->use_radamsa = 2; "(custom_mutators/radamsa/).");
} else {
afl->use_radamsa = 1;
}
break; break;
@ -808,8 +799,7 @@ int main(int argc, char **argv_orig, char **envp) {
WARNF( WARNF(
"Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options " "Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
"will " "will result in no deterministic mutations being done!");
"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 defined(__SANITIZE_ADDRESS__)
if (afl->fsrv.mem_limit) { if (afl->fsrv.mem_limit) {
@ -936,6 +882,9 @@ int main(int argc, char **argv_orig, char **envp) {
case RARE: case RARE:
OKF("Using rare edge focus power schedule (RARE)"); OKF("Using rare edge focus power schedule (RARE)");
break; break;
case SEEK:
OKF("Using seek power schedule (SEEK)");
break;
case EXPLORE: case EXPLORE:
OKF("Using exploration-based constant power schedule (EXPLORE, default)"); OKF("Using exploration-based constant power schedule (EXPLORE, default)");
break; break;
@ -1071,6 +1020,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_crash_handling(); check_crash_handling();
check_cpu_governor(afl); check_cpu_governor(afl);
atexit(at_exit);
afl->fsrv.trace_bits = afl->fsrv.trace_bits =
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); 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) { 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); 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 (!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_queue(afl);
destroy_extras(afl); destroy_extras(afl);
destroy_custom_mutators(afl); destroy_custom_mutators(afl);
unsetenv(SHM_ENV_VAR);
unsetenv(CMPLOG_SHM_ENV_VAR);
afl_shm_deinit(&afl->shm); afl_shm_deinit(&afl->shm);
if (afl->shm_fuzz) { if (afl->shm_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz); afl_shm_deinit(afl->shm_fuzz);
ck_free(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"; cc_params[cc_par_cnt++] = "-lrt";
#endif #endif

View File

@ -54,7 +54,7 @@
#include "common.h" #include "common.h"
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__APPLE__) || defined(__DragonFly__) defined(__APPLE__) || defined(__DragonFly__) || defined(__sun)
#define HAVE_AFFINITY 1 #define HAVE_AFFINITY 1
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)
#include <pthread.h> #include <pthread.h>
@ -70,6 +70,8 @@
#include <pthread.h> #include <pthread.h>
#include <mach/thread_act.h> #include <mach/thread_act.h>
#include <mach/thread_policy.h> #include <mach/thread_policy.h>
#elif defined(__sun)
#include <sys/pset.h>
#endif #endif
#endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */ #endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */
@ -181,6 +183,12 @@ int main(int argc, char **argv) {
if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY, if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY,
(thread_policy_t)&c, 1) != KERN_SUCCESS) (thread_policy_t)&c, 1) != KERN_SUCCESS)
PFATAL("thread_policy_set failed"); 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 #endif
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)
@ -195,6 +203,12 @@ int main(int argc, char **argv) {
cpuset_destroy(c); cpuset_destroy(c);
#endif #endif
#if defined(__sun)
if (pset_bind(c, P_PID, getpid(), NULL)) PFATAL("pset_bind failed");
pset_destroy(c);
#endif
#if defined(__linux__) #if defined(__linux__)
if (sched_setaffinity(0, sizeof(c), &c)) { 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) { void afl_shm_deinit(sharedmem_t *shm) {
if (shm == NULL) return;
list_remove(&shm_list, shm); list_remove(&shm_list, shm);
#ifdef USEMMAP #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 #else
shmctl(shm->shm_id, IPC_RMID, NULL); shmctl(shm->shm_id, IPC_RMID, NULL);
if (shm->cmplog_mode) { shmctl(shm->cmplog_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, u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
unsigned char non_instrumented_mode) { unsigned char non_instrumented_mode) {
shm->map_size = map_size; shm->map_size = 0;
shm->map = NULL; shm->map = NULL;
shm->cmp_map = NULL;
#ifdef USEMMAP #ifdef USEMMAP
shm->g_shm_fd = -1; shm->g_shm_fd = -1;
shm->cmplog_g_shm_fd = -1;
/* ====== /* ======
generate random file name for multi instance 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); close(shm->g_shm_fd);
shm->g_shm_fd = -1; shm->g_shm_fd = -1;
shm_unlink(shm->g_shm_file_path);
shm->g_shm_file_path[0] = 0;
PFATAL("mmap() failed"); 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 (!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 #else
u8 *shm_str; u8 *shm_str;
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600); shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
if (shm->shm_id < 0) { PFATAL("shmget() failed"); } if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
if (shm->cmplog_mode) { 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), shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
IPC_CREAT | IPC_EXCL | 0600); 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); 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) { 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) { 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"); PFATAL("shmat() failed");
} }
@ -202,6 +305,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
#endif #endif
shm->map_size = map_size;
list_append(&shm_list, shm); list_append(&shm_list, shm);
return shm->map; return shm->map;

View File

@ -56,7 +56,9 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/shm.h> #ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/resource.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 */ raw_instr_output, /* Do not apply AFL filters */
cmin_mode, /* Generate output in afl-cmin mode? */ cmin_mode, /* Generate output in afl-cmin mode? */
binary_mode, /* Write output as a binary map */ 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? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_crashed; /* Child crashed? */ 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 /* 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. */ 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). */ /* Get rid of temp files (atexit handler). */
static void at_exit_handler(void) { static void at_exit_handler(void) {
if (stdin_file) { unlink(stdin_file); } 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. */ /* Write results. */
@ -557,7 +585,7 @@ static void usage(u8 *argv0) {
"size\n" "size\n"
" the target was compiled for\n" " the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\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); argv0, MEM_LIMIT, doc_path);
exit(1); exit(1);
@ -577,8 +605,8 @@ int main(int argc, char **argv_orig, char **envp) {
char **argv = argv_cpy_dup(argc, argv_orig); char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0}; afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var; fsrv = &fsrv_var;
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
map_size = get_map_size(); map_size = get_map_size();
fsrv->map_size = map_size; fsrv->map_size = map_size;
@ -773,7 +801,19 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(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); fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
setup_signal_handlers(); 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) { if (in_dir) {
DIR * dir_in, *dir_out; DIR * dir_in, *dir_out;
struct dirent *dir_ent; struct dirent *dir_ent;
int done = 0; int done = 0;
u8 infile[PATH_MAX], outfile[PATH_MAX]; u8 infile[PATH_MAX], outfile[PATH_MAX];
u8 wait_for_gdb = 0;
#if !defined(DT_REG) #if !defined(DT_REG)
struct stat statbuf; struct stat statbuf;
#endif #endif
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = 1;
fsrv->dev_null_fd = open("/dev/null", O_RDWR); fsrv->dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } 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, afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); 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))) { while (done == 0 && (dir_ent = readdir(dir_in))) {
if (dir_ent->d_name[0] == '.') { if (dir_ent->d_name[0] == '.') {
@ -922,6 +985,14 @@ int main(int argc, char **argv_orig, char **envp) {
if (read_file(infile)) { 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); showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
ck_free(in_data); ck_free(in_data);
tcnt = write_results_to_file(fsrv, outfile); tcnt = write_results_to_file(fsrv, outfile);
@ -937,6 +1008,9 @@ int main(int argc, char **argv_orig, char **envp) {
} else { } else {
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
showmap_run_target(fsrv, use_argv); showmap_run_target(fsrv, use_argv);
tcnt = write_results_to_file(fsrv, out_file); 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); 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; u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
if (fsrv->target_path) { ck_free(fsrv->target_path); } if (fsrv->target_path) { ck_free(fsrv->target_path); }
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
if (stdin_file) { ck_free(stdin_file); } if (stdin_file) { ck_free(stdin_file); }
argv_cpy_free(argv); argv_cpy_free(argv);

View File

@ -54,7 +54,9 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/shm.h> #ifndef USEMMAP
#include <sys/shm.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/resource.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 u8 *in_data; /* Input data for trimming */
static u32 in_len, /* Input data length */ static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
missed_hangs, /* Misses due to hangs */ missed_hangs, /* Misses due to hangs */
missed_crashes, /* Misses due to crashes */ missed_crashes, /* Misses due to crashes */
missed_paths, /* Misses due to exec path diffs */ missed_paths, /* Misses due to exec path diffs */
map_size = MAP_SIZE; map_size = MAP_SIZE;
static u64 orig_cksum; /* Original checksum */
static u8 crash_mode, /* Crash-centric mode? */ static u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */ hang_mode, /* Minimize as long as it hangs */
exit_crash, /* Treat non-zero exit as crash? */ exit_crash, /* Treat non-zero exit as crash? */
edges_only, /* Ignore hit counts? */ 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 volatile u8 stop_soon; /* Ctrl-C pressed? */
static afl_forkserver_t *fsrv;
static sharedmem_t shm;
static sharedmem_t * shm_fuzz;
/* /*
* forkserver section * 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). */ /* Apply mask to classified bitmap (if set). */
static void apply_mask(u32 *mem, u32 *mask) { 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) { 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(); 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?"); } 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; } 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()); 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); char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0}; afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var; fsrv = &fsrv_var;
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
map_size = get_map_size(); map_size = get_map_size();
fsrv->map_size = map_size; fsrv->map_size = map_size;
@ -1007,7 +1037,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(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); fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler); atexit(at_exit_handler);
@ -1049,11 +1080,31 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF("\n"); 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(); read_initial_file();
afl_fsrv_start(fsrv, use_argv, &stop_soon, afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); 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)...", ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : ""); 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"); OKF("We're done here. Have a nice day!\n");
remove_shm = 0;
afl_shm_deinit(&shm); afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
if (fsrv->target_path) { ck_free(fsrv->target_path); } if (fsrv->target_path) { ck_free(fsrv->target_path); }
if (mask_bitmap) { ck_free(mask_bitmap); } 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 fi
test_compcov_binary_functionality() { 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 'LIBTOKENCAP' | grep 'your string was LIBTOKENCAP' \
&& $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \ && $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \
&& $RUN 'BANANA' | grep 'your string started with BAN' \ && $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 # on OpenBSD we need to work with llvm from /usr/local/bin
test -e /usr/local/bin/opt && { 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 # on MacOS X we prefer afl-clang over afl-gcc, because
# afl-gcc does not work there # afl-gcc does not work there
@ -108,7 +108,7 @@ RESET="\\033[0m"
MEM_LIMIT=none 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 ..." $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 rm -f test-instr.plain
# Disabled whitelist until I have a different solution -mh echo foobar.c > 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
# AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && {
# test -e test-compcov && { grep -q "No instrumentation targets found" test.out && {
# grep -q "No instrumentation targets found" test.out && { $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
# $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly" } || {
# } || { $ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
# $ECHO "$RED[!] llvm_mode LTO whitelist feature failed" CODE=1
# CODE=1 }
# } } || {
# } || { $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
# $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed" CODE=1
# CODE=1 }
# } rm -f test-compcov test.out whitelist.txt
# rm -f test-compcov test.out whitelist.txt
../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 ../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
test -e test-persistent && { 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 "$GREEN[+] llvm_mode LTO persistent mode feature works correctly"
} || { } || {
$ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work" $ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work"
@ -638,43 +637,43 @@ test -e ../libdislocator.so && {
INCOMPLETE=1 INCOMPLETE=1
} }
rm -f test-compcov rm -f test-compcov
test -e ../libradamsa.so && { #test -e ../libradamsa.so && {
# on FreeBSD need to set AFL_CC # # on FreeBSD need to set AFL_CC
test `uname -s` = 'FreeBSD' && { # test `uname -s` = 'FreeBSD' && {
if type clang >/dev/null; then # if type clang >/dev/null; then
export AFL_CC=`command -v clang` # export AFL_CC=`command -v clang`
else # else
export AFL_CC=`$LLVM_CONFIG --bindir`/clang # export AFL_CC=`$LLVM_CONFIG --bindir`/clang
fi # 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-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-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 || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain && { # test -e test-instr.plain && {
mkdir -p in # mkdir -p in
printf 1 > in/in # printf 1 > in/in
$ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds" # $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 # ../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
} >>errors 2>&1 # } >>errors 2>&1
test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
$ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations" # $ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
} || { # } || {
echo CUT------------------------------------------------------------------CUT # echo CUT------------------------------------------------------------------CUT
cat errors # cat errors
echo CUT------------------------------------------------------------------CUT # echo CUT------------------------------------------------------------------CUT
$ECHO "$RED[!] libradamsa failed" # $ECHO "$RED[!] libradamsa failed"
CODE=1 # CODE=1
} # }
rm -rf in out errors test-instr.plain # rm -rf in out errors test-instr.plain
} || { # } || {
$ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa" # $ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
INCOMPLETE=1 # INCOMPLETE=1
} # }
} || { #} || {
$ECHO "$YELLOW[-] libradamsa is not compiled, cannot test" # $ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
INCOMPLETE=1 # INCOMPLETE=1
} #}
test -z "$AFL_CC" && { test -z "$AFL_CC" && {
if type gcc >/dev/null; then if type gcc >/dev/null; then
@ -902,6 +901,9 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
test -d ../unicorn_mode/unicornafl && { test -d ../unicorn_mode/unicornafl && {
test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && { 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 # some python version should be available now
PYTHONS="`command -v python3` `command -v python` `command -v python2`" PYTHONS="`command -v python3` `command -v python` `command -v python2`"
EASY_INSTALL_FOUND=0 EASY_INSTALL_FOUND=0
@ -988,6 +990,9 @@ test -d ../unicorn_mode/unicornafl && {
rm -rf in out errors rm -rf in out errors
} }
fi fi
unset AFL_DEBUG_CHILD_OUTPUT
} }
} || { } || {
$ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??" $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" $ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY"
unset AFL_CC unset AFL_CC
make -C .. unit || "$CODE" = "1" make -C .. unit || CODE=1 INCOMPLETE=1 :
$ECHO "$GREY[*] all test cases completed.$RESET" $ECHO "$GREY[*] all test cases completed.$RESET"
test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed" 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, 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, 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, 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