mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-11 01:31:37 +00:00
commit
8f1b78f49e
4
.gitignore
vendored
4
.gitignore
vendored
@ -18,6 +18,7 @@ afl-gcc-fast
|
||||
afl-g++-fast
|
||||
afl-gotcpu
|
||||
afl-ld
|
||||
afl-ld-lto
|
||||
afl-qemu-trace
|
||||
afl-showmap
|
||||
afl-tmin
|
||||
@ -45,9 +46,12 @@ ld
|
||||
qemu_mode/qemu-*
|
||||
unicorn_mode/samples/*/\.test-*
|
||||
unicorn_mode/samples/*/output/
|
||||
unicorn_mode/unicornafl
|
||||
core\.*
|
||||
test/unittests/unit_maybe_alloc
|
||||
test/unittests/unit_preallocable
|
||||
test/unittests/unit_list
|
||||
test/unittests/unit_rand
|
||||
test/unittests/unit_hash
|
||||
examples/afl_network_proxy/afl-network-server
|
||||
examples/afl_network_proxy/afl-network-client
|
||||
|
@ -9,9 +9,9 @@ branches:
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: focal
|
||||
env: NAME="focal-amd64" MODERN="yes" GCC="9"
|
||||
# - os: linux # focal errors every run with a timeout while installing packages
|
||||
# dist: focal
|
||||
# env: NAME="focal-amd64" MODERN="yes" GCC="9"
|
||||
- os: linux
|
||||
dist: bionic
|
||||
env: NAME="bionic-amd64" MODERN="yes" GCC="7"
|
||||
|
112
GNUmakefile
112
GNUmakefile
@ -50,19 +50,30 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
|
||||
endif
|
||||
|
||||
ifneq "$(shell uname)" "Darwin"
|
||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
# CFLAGS_OPT += -march=native
|
||||
#endif
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
#CFLAGS_OPT += -march=native
|
||||
SPECIAL_PERFORMANCE += -march=native
|
||||
endif
|
||||
# OS X does not like _FORTIFY_SOURCE=2
|
||||
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
|
||||
ifeq "$(shell uname)" "SunOS"
|
||||
CFLAGS_OPT += -Wno-format-truncation
|
||||
LDFLAGS=-lkstat
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
$(info Compiling static version of binaries)
|
||||
$(info Compiling static version of binaries, disabling python though)
|
||||
# Disable python for static compilation to simplify things
|
||||
PYTHON_OK=0
|
||||
PYFLAGS=
|
||||
PYTHON_INCLUDE=/
|
||||
|
||||
CFLAGS_OPT += -static
|
||||
LDFLAGS += -lm -lpthread -lz -lutil
|
||||
@ -86,7 +97,7 @@ endif
|
||||
|
||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
||||
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
|
||||
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||
|
||||
ifeq "$(shell uname -s)" "FreeBSD"
|
||||
@ -109,6 +120,13 @@ ifeq "$(shell uname -s)" "NetBSD"
|
||||
LDFLAGS += -L /usr/pkg/lib/
|
||||
endif
|
||||
|
||||
ifeq "$(shell uname -s)" "Haiku"
|
||||
SHMAT_OK=0
|
||||
override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fPIC
|
||||
LDFLAGS += -Wno-deprecated-declarations -lgnu
|
||||
SPECIAL_PERFORMANCE += -DUSEMMAP=1
|
||||
endif
|
||||
|
||||
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
|
||||
|
||||
ifneq "$(shell command -v python3m 2>/dev/null)" ""
|
||||
@ -182,12 +200,12 @@ ifneq "$(filter Linux GNU%,$(shell uname))" ""
|
||||
endif
|
||||
|
||||
ifneq "$(findstring FreeBSD, $(shell uname))" ""
|
||||
CFLAGS += -pthread
|
||||
override CFLAGS += -pthread
|
||||
LDFLAGS += -lpthread
|
||||
endif
|
||||
|
||||
ifneq "$(findstring NetBSD, $(shell uname))" ""
|
||||
CFLAGS += -pthread
|
||||
override CFLAGS += -pthread
|
||||
LDFLAGS += -lpthread
|
||||
endif
|
||||
|
||||
@ -227,7 +245,7 @@ endif
|
||||
|
||||
ifdef ASAN_BUILD
|
||||
$(info Compiling ASAN version of binaries)
|
||||
CFLAGS+=$(ASAN_CFLAGS)
|
||||
override CFLAGS+=$(ASAN_CFLAGS)
|
||||
LDFLAGS+=$(ASAN_LDFLAGS)
|
||||
endif
|
||||
|
||||
@ -235,14 +253,14 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
|
||||
SHMAT_OK=1
|
||||
else
|
||||
SHMAT_OK=0
|
||||
CFLAGS+=-DUSEMMAP=1
|
||||
LDFLAGS+=-Wno-deprecated-declarations
|
||||
override CFLAGS+=-DUSEMMAP=1
|
||||
LDFLAGS += -Wno-deprecated-declarations -lrt
|
||||
endif
|
||||
|
||||
ifeq "$(TEST_MMAP)" "1"
|
||||
ifdef TEST_MMAP
|
||||
SHMAT_OK=0
|
||||
CFLAGS+=-DUSEMMAP=1
|
||||
LDFLAGS+=-Wno-deprecated-declarations
|
||||
override CFLAGS += -DUSEMMAP=1
|
||||
LDFLAGS += -Wno-deprecated-declarations -lrt
|
||||
endif
|
||||
|
||||
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done
|
||||
@ -265,8 +283,8 @@ help:
|
||||
@echo "HELP --- the following make targets exist:"
|
||||
@echo "=========================================="
|
||||
@echo "all: just the main afl++ binaries"
|
||||
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa"
|
||||
@echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa"
|
||||
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap"
|
||||
@echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap"
|
||||
@echo "distrib: everything (for both binary-only and source code fuzzing)"
|
||||
@echo "man: creates simple man pages from the help option of the programs"
|
||||
@echo "install: installs everything you have compiled with the build option above"
|
||||
@ -294,6 +312,8 @@ ifndef AFL_NO_X86
|
||||
test_x86:
|
||||
@echo "[*] Checking for the default compiler cc..."
|
||||
@type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC=<yourCcompiler>'."; echo; exit 1 )
|
||||
@echo "[*] Testing the PATH environment variable..."
|
||||
@test "$${PATH}" != "$${PATH#.:}" && { echo "Please remove current directory '.' from PATH to avoid recursion of 'as', thanks!"; echo; exit 1; } || :
|
||||
@echo "[*] Checking for the ability to compile x86 code..."
|
||||
@echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 )
|
||||
@rm -f .test1
|
||||
@ -345,6 +365,9 @@ afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
ln -sf afl-as as
|
||||
|
||||
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||
$(CC) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o
|
||||
|
||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
||||
|
||||
@ -354,42 +377,47 @@ src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
|
||||
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
|
||||
radamsa: src/third_party/libradamsa/libradamsa.so
|
||||
cp src/third_party/libradamsa/libradamsa.so .
|
||||
|
||||
src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h
|
||||
$(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)"
|
||||
|
||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
|
||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS)
|
||||
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# document all mutations and only do one run (use with only one input file!)
|
||||
document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
|
||||
$(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
|
||||
document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-performance.o | test_x86
|
||||
$(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
|
||||
|
||||
test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
|
||||
|
||||
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
|
||||
|
||||
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
|
||||
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_maybe_alloc
|
||||
|
||||
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
|
||||
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_hash
|
||||
|
||||
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
|
||||
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_rand
|
||||
|
||||
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
|
||||
|
||||
@ -397,8 +425,8 @@ unit_list: test/unittests/unit_list.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_list
|
||||
|
||||
test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o
|
||||
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
|
||||
|
||||
unit_preallocable: test/unittests/unit_preallocable.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@ -409,7 +437,7 @@ unit_clean:
|
||||
|
||||
ifneq "$(shell uname)" "Darwin"
|
||||
|
||||
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean
|
||||
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
|
||||
|
||||
else
|
||||
|
||||
@ -429,6 +457,8 @@ code-format:
|
||||
./.custom-format.py -i gcc_plugin/*.c
|
||||
#./.custom-format.py -i gcc_plugin/*.h
|
||||
./.custom-format.py -i gcc_plugin/*.cc
|
||||
./.custom-format.py -i custom_mutators/*/*.c
|
||||
./.custom-format.py -i custom_mutators/*/*.h
|
||||
./.custom-format.py -i examples/*/*.c
|
||||
./.custom-format.py -i examples/*/*.h
|
||||
./.custom-format.py -i test/*.c
|
||||
@ -481,7 +511,6 @@ clean:
|
||||
$(MAKE) -C examples/argv_fuzzing clean
|
||||
$(MAKE) -C qemu_mode/unsigaction clean
|
||||
$(MAKE) -C qemu_mode/libcompcov clean
|
||||
$(MAKE) -C src/third_party/libradamsa/ clean
|
||||
rm -rf qemu_mode/qemu-3.1.1
|
||||
ifeq "$(IN_REPO)" "1"
|
||||
test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
|
||||
@ -495,7 +524,7 @@ deepclean: clean
|
||||
rm -rf unicorn_mode/unicornafl
|
||||
git reset --hard >/dev/null 2>&1 || true
|
||||
|
||||
distrib: all radamsa
|
||||
distrib: all
|
||||
-$(MAKE) -C llvm_mode
|
||||
-$(MAKE) -C gcc_plugin
|
||||
$(MAKE) -C libdislocator
|
||||
@ -504,18 +533,18 @@ distrib: all radamsa
|
||||
$(MAKE) -C examples/socket_fuzzing
|
||||
$(MAKE) -C examples/argv_fuzzing
|
||||
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||
cd unicorn_mode && sh ./build_unicorn_support.sh
|
||||
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||
|
||||
binary-only: all radamsa
|
||||
binary-only: all
|
||||
$(MAKE) -C libdislocator
|
||||
$(MAKE) -C libtokencap
|
||||
$(MAKE) -C examples/afl_network_proxy
|
||||
$(MAKE) -C examples/socket_fuzzing
|
||||
$(MAKE) -C examples/argv_fuzzing
|
||||
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||
cd unicorn_mode && sh ./build_unicorn_support.sh
|
||||
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||
|
||||
source-only: all radamsa
|
||||
source-only: all
|
||||
-$(MAKE) -C llvm_mode
|
||||
-$(MAKE) -C gcc_plugin
|
||||
$(MAKE) -C libdislocator
|
||||
@ -554,7 +583,6 @@ install: all $(MANPAGES)
|
||||
if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
|
||||
if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi
|
||||
if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi
|
||||
|
23
README.md
23
README.md
@ -54,7 +54,7 @@
|
||||
|
||||
* Win32 PE binary-only fuzzing with QEMU and Wine
|
||||
|
||||
* Radamsa mutator (enable with `-R` to add or `-RR` to run it exclusively).
|
||||
* Radamsa mutator (as a custom mutator).
|
||||
|
||||
* QBDI mode to fuzz android native libraries via QBDI framework
|
||||
|
||||
@ -167,8 +167,8 @@ is what you should choose.
|
||||
These build targets exist:
|
||||
|
||||
* all: just the main afl++ binaries
|
||||
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa
|
||||
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap, radamsa
|
||||
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap
|
||||
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap
|
||||
* distrib: everything (for both binary-only and source code fuzzing)
|
||||
* man: creates simple man pages from the help option of the programs
|
||||
* install: installs everything you have compiled with the build options above
|
||||
@ -371,14 +371,15 @@ therefore may increase the code coverage.
|
||||
|
||||
The available schedules are:
|
||||
|
||||
- explore (default)
|
||||
- fast
|
||||
- coe
|
||||
- quad
|
||||
- lin
|
||||
- exploit
|
||||
- mmopt (experimental)
|
||||
- rare (experimental)
|
||||
- explore (default, original AFL)
|
||||
- exploit (original AFL)
|
||||
- fast (AFLfast)
|
||||
- coe (AFLfast)
|
||||
- quad (AFLfast)
|
||||
- lin (AFLfast)
|
||||
- rare (afl++ experimental)
|
||||
- mmopt (afl++ experimental)
|
||||
- seek (afl++ experimental)
|
||||
|
||||
In parallel mode (-M/-S, several instances with the shared queue), we suggest to
|
||||
run the main node using the explore or fast schedule (-p explore) and the secondary
|
||||
|
11
TODO.md
11
TODO.md
@ -3,13 +3,9 @@
|
||||
## Roadmap 2.65+
|
||||
|
||||
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
|
||||
- random crc32 HASH_CONST per run? because with 65536 paths we have collisions
|
||||
- namespace for targets? e.g. network
|
||||
- libradamsa as a custom module?
|
||||
- learn from honggfuzz
|
||||
- for persistent mode, have a functionality that transports the test case
|
||||
via shared memory (and the int write to the FD from afl-fuzz is the size)
|
||||
- CPU affinity for many cores?
|
||||
- learn from honggfuzz (mutations, maybe ptrace?)
|
||||
- CPU affinity for many cores? There seems to be an issue > 96 cores
|
||||
|
||||
## Further down the road
|
||||
|
||||
@ -18,9 +14,10 @@ afl-fuzz:
|
||||
- setting min_len/max_len/start_offset/end_offset limits for mutation output
|
||||
|
||||
llvm_mode:
|
||||
- better whitelist solution for LTO
|
||||
- LTO - imitate sancov
|
||||
|
||||
gcc_plugin:
|
||||
- (wait for submission then decide)
|
||||
- laf-intel
|
||||
- better instrumentation (seems to be better with gcc-9+)
|
||||
|
||||
|
@ -134,7 +134,6 @@ Environment variables used:
|
||||
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
|
||||
AFL_PATH: path for the afl-showmap binary
|
||||
AFL_SKIP_BIN_CHECK: skip check for target binary
|
||||
AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp
|
||||
_EOF_
|
||||
exit 1
|
||||
fi
|
||||
@ -142,29 +141,29 @@ fi
|
||||
# Do a sanity check to discourage the use of /tmp, since we can't really
|
||||
# handle this safely from a shell script.
|
||||
|
||||
if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||
|
||||
echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
|
||||
T1="$?"
|
||||
|
||||
echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
|
||||
T2="$?"
|
||||
|
||||
echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
|
||||
T3="$?"
|
||||
|
||||
echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
|
||||
T4="$?"
|
||||
|
||||
echo "$PWD" | grep -qE '^(/var)?/tmp/'
|
||||
T5="$?"
|
||||
|
||||
if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
|
||||
echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
#if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||
#
|
||||
# echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
|
||||
# T1="$?"
|
||||
#
|
||||
# echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
|
||||
# T2="$?"
|
||||
#
|
||||
# echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
|
||||
# T3="$?"
|
||||
#
|
||||
# echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
|
||||
# T4="$?"
|
||||
#
|
||||
# echo "$PWD" | grep -qE '^(/var)?/tmp/'
|
||||
# T5="$?"
|
||||
#
|
||||
# if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
|
||||
# echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
|
||||
# exit 1
|
||||
# fi
|
||||
#
|
||||
#fi
|
||||
|
||||
# If @@ is specified, but there's no -f, let's come up with a temporary input
|
||||
# file name.
|
||||
@ -246,7 +245,7 @@ if [ ! "$STDIN_FILE" = "" ]; then
|
||||
fi
|
||||
|
||||
if [ "$AFL_PATH" = "" ]; then
|
||||
SHOWMAP="${0%/afl-cmin}/afl-showmap"
|
||||
SHOWMAP="${0%/afl-cmin.bash}/afl-showmap"
|
||||
else
|
||||
SHOWMAP="$AFL_PATH/afl-showmap"
|
||||
fi
|
||||
|
76
afl-plot
76
afl-plot
@ -15,6 +15,10 @@
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
|
||||
get_abs_path() {
|
||||
echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`"
|
||||
}
|
||||
|
||||
echo "progress plotting utility for afl-fuzz by Michal Zalewski"
|
||||
echo
|
||||
|
||||
@ -31,40 +35,40 @@ an empty directory where this tool can write the resulting plots to.
|
||||
|
||||
The program will put index.html and three PNG images in the output directory;
|
||||
you should be able to view it with any web browser of your choice.
|
||||
|
||||
Environment variables used:
|
||||
AFL_ALLOW_TMP: allow /var/tmp or /tmp for input and output directories
|
||||
_EOF_
|
||||
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||
inputdir=`get_abs_path "$1"`
|
||||
outputdir=`get_abs_path "$2"`
|
||||
|
||||
echo "$1" | grep -qE '^(/var)?/tmp/'
|
||||
T1="$?"
|
||||
#if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||
#
|
||||
# echo "$inputdir" | grep -qE '^(/var)?/tmp/'
|
||||
# T1="$?"
|
||||
#
|
||||
# echo "$outputdir" | grep -qE '^(/var)?/tmp/'
|
||||
# T2="$?"
|
||||
#
|
||||
# if [ "$T1" = "0" -o "$T2" = "0" ]; then
|
||||
#
|
||||
# echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
|
||||
# exit 1
|
||||
#
|
||||
# fi
|
||||
#
|
||||
#fi
|
||||
|
||||
echo "$2" | grep -qE '^(/var)?/tmp/'
|
||||
T2="$?"
|
||||
|
||||
if [ "$T1" = "0" -o "$T2" = "0" ]; then
|
||||
|
||||
echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -f "$1/plot_data" ]; then
|
||||
if [ ! -f "$inputdir/plot_data" ]; then
|
||||
|
||||
echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
BANNER="`cat "$1/fuzzer_stats" | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
|
||||
BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
|
||||
|
||||
test "$BANNER" = "" && BANNER="(none)"
|
||||
|
||||
@ -77,17 +81,17 @@ if [ "$GNUPLOT" = "" ]; then
|
||||
|
||||
fi
|
||||
|
||||
mkdir "$2" 2>/dev/null
|
||||
mkdir "$outputdir" 2>/dev/null
|
||||
|
||||
if [ ! -d "$2" ]; then
|
||||
if [ ! -d "$outputdir" ]; then
|
||||
|
||||
echo "[-] Error: unable to create the output directory - pick another location." 1>&2
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
rm -f "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png"
|
||||
mv -f "$2/index.html" "$2/index.html.orig" 2>/dev/null
|
||||
rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png"
|
||||
mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null
|
||||
|
||||
echo "[*] Generating plots..."
|
||||
|
||||
@ -96,7 +100,7 @@ echo "[*] Generating plots..."
|
||||
cat <<_EOF_
|
||||
set terminal png truecolor enhanced size 1000,300 butt
|
||||
|
||||
set output '$2/high_freq.png'
|
||||
set output '$outputdir/high_freq.png'
|
||||
|
||||
set xdata time
|
||||
set timefmt '%s'
|
||||
@ -114,31 +118,31 @@ set key outside
|
||||
set autoscale xfixmin
|
||||
set autoscale xfixmax
|
||||
|
||||
plot '$1/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
|
||||
plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
|
||||
'' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
|
||||
'' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\
|
||||
'' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
|
||||
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3
|
||||
|
||||
set terminal png truecolor enhanced size 1000,200 butt
|
||||
set output '$2/low_freq.png'
|
||||
set output '$outputdir/low_freq.png'
|
||||
|
||||
plot '$1/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
|
||||
plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
|
||||
'' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\
|
||||
'' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\
|
||||
'' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3
|
||||
|
||||
set terminal png truecolor enhanced size 1000,200 butt
|
||||
set output '$2/exec_speed.png'
|
||||
set output '$outputdir/exec_speed.png'
|
||||
|
||||
plot '$1/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
|
||||
'$1/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
|
||||
plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
|
||||
'$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
|
||||
|
||||
_EOF_
|
||||
|
||||
) | gnuplot
|
||||
|
||||
if [ ! -s "$2/exec_speed.png" ]; then
|
||||
if [ ! -s "$outputdir/exec_speed.png" ]; then
|
||||
|
||||
echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2
|
||||
exit 1
|
||||
@ -147,10 +151,10 @@ fi
|
||||
|
||||
echo "[*] Generating index.html..."
|
||||
|
||||
cat >"$2/index.html" <<_EOF_
|
||||
cat >"$outputdir/index.html" <<_EOF_
|
||||
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
|
||||
<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr>
|
||||
<tr><td><b>Directory:</b></td><td>$1</td></tr>
|
||||
<tr><td><b>Directory:</b></td><td>$inputdir</td></tr>
|
||||
<tr><td><b>Generated on:</b></td><td>`date`</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
@ -164,8 +168,8 @@ _EOF_
|
||||
# served by Apache or other HTTP daemon. Since the plots aren't horribly
|
||||
# sensitive, this seems like a reasonable trade-off.
|
||||
|
||||
chmod 755 "$2"
|
||||
chmod 644 "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" "$2/index.html"
|
||||
chmod 755 "$outputdir"
|
||||
chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/index.html"
|
||||
|
||||
echo "[+] All done - enjoy your charts!"
|
||||
|
||||
|
12
custom_mutators/README.md
Normal file
12
custom_mutators/README.md
Normal 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.
|
@ -1,15 +1,15 @@
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
all: libradamsa.so
|
||||
all: radamsa-mutator.so
|
||||
|
||||
# These can be overriden:
|
||||
CFLAGS ?= -march=native $(CFLAGS_FLTO)
|
||||
CFLAGS ?= $(CFLAGS_FLTO)
|
||||
|
||||
# These are required: (otherwise radamsa gets very very slooooow)
|
||||
CFLAGS += -O3 -funroll-loops
|
||||
|
||||
libradamsa.so: libradamsa.a
|
||||
$(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
|
||||
#libradamsa.so: libradamsa.a
|
||||
# $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
|
||||
|
||||
libradamsa.a: libradamsa.c radamsa.h
|
||||
@echo " ***************************************************************"
|
||||
@ -17,10 +17,14 @@ libradamsa.a: libradamsa.c radamsa.h
|
||||
@echo " ***************************************************************"
|
||||
$(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c
|
||||
|
||||
radamsa-mutator.so: radamsa-mutator.c libradamsa.a
|
||||
$(CC) $(CFLAGS) -g -I. -I../../include -shared -fPIC -c radamsa-mutator.c
|
||||
$(CC) $(CFLAGS) -shared -fPIC -o radamsa-mutator.so radamsa-mutator.o libradamsa.a
|
||||
|
||||
test: libradamsa.a libradamsa-test.c
|
||||
$(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
|
||||
./libradamsa-test libradamsa-test.c | grep "library test passed"
|
||||
rm /tmp/libradamsa-*.fuzz
|
||||
|
||||
clean:
|
||||
rm -f libradamsa.a libradamsa.so libradamsa-test
|
||||
rm -f radamsa-mutator.so libradamsa.a libradamsa-test *.o *~ core
|
@ -1,4 +1,4 @@
|
||||
# libradamsa
|
||||
# custum mutator: libradamsa
|
||||
|
||||
Pretranslated radamsa library. This code belongs to the radamsa author.
|
||||
|
342
custom_mutators/radamsa/custom_mutator_helpers.h
Normal file
342
custom_mutators/radamsa/custom_mutator_helpers.h
Normal 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
|
||||
|
81
custom_mutators/radamsa/libradamsa-test.c
Normal file
81
custom_mutators/radamsa/libradamsa-test.c
Normal 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;
|
||||
|
||||
}
|
||||
|
61880
custom_mutators/radamsa/libradamsa.c
Normal file
61880
custom_mutators/radamsa/libradamsa.c
Normal file
File diff suppressed because it is too large
Load Diff
70
custom_mutators/radamsa/radamsa-mutator.c
Normal file
70
custom_mutators/radamsa/radamsa-mutator.c
Normal 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);
|
||||
|
||||
}
|
||||
|
10
custom_mutators/radamsa/radamsa.h
Normal file
10
custom_mutators/radamsa/radamsa.h
Normal 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
124
dictionaries/ftp.dict
Normal 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"
|
@ -71,7 +71,7 @@
|
||||
"Location"
|
||||
"Max-Forwards"
|
||||
"Origin"
|
||||
"P3P "
|
||||
"P3P"
|
||||
"Pragma"
|
||||
"Proxy-Authenticate"
|
||||
"Proxy-Authorization"
|
||||
|
@ -373,7 +373,7 @@
|
||||
"ALT "
|
||||
"AMH "
|
||||
"ANG "
|
||||
"APPH"
|
||||
"APPH"
|
||||
"ARA "
|
||||
"ARG "
|
||||
"ARI "
|
||||
@ -394,9 +394,9 @@
|
||||
"BAR "
|
||||
"BAU "
|
||||
"BBC "
|
||||
"BBR "
|
||||
"BBR "
|
||||
"BCH "
|
||||
"BCR "
|
||||
"BCR "
|
||||
"BDY "
|
||||
"BEL "
|
||||
"BEM "
|
||||
@ -416,7 +416,7 @@
|
||||
"BLN "
|
||||
"BLT "
|
||||
"BMB "
|
||||
"BML "
|
||||
"BML "
|
||||
"BOS "
|
||||
"BPY "
|
||||
"BRE "
|
||||
@ -521,7 +521,7 @@
|
||||
"GAE "
|
||||
"GAG "
|
||||
"GAL "
|
||||
"GAR "
|
||||
"GAR "
|
||||
"GAW "
|
||||
"GEZ "
|
||||
"GIH "
|
||||
@ -725,7 +725,7 @@
|
||||
"MOK "
|
||||
"MOL "
|
||||
"MON "
|
||||
"MOR "
|
||||
"MOR "
|
||||
"MOS "
|
||||
"MRI "
|
||||
"MTH "
|
||||
@ -751,7 +751,7 @@
|
||||
"NEP "
|
||||
"NEW "
|
||||
"NGA "
|
||||
"NGR "
|
||||
"NGR "
|
||||
"NHC "
|
||||
"NIS "
|
||||
"NIU "
|
||||
@ -930,7 +930,7 @@
|
||||
"VIT "
|
||||
"VOL "
|
||||
"VRO "
|
||||
"WA "
|
||||
"WA "
|
||||
"WAG "
|
||||
"WAR "
|
||||
"WCR "
|
||||
@ -949,7 +949,7 @@
|
||||
"YAP "
|
||||
"YBA "
|
||||
"YCR "
|
||||
"YIC "
|
||||
"YIC "
|
||||
"YIM "
|
||||
"ZEA "
|
||||
"ZGH "
|
||||
|
@ -11,21 +11,32 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
|
||||
### Version ++2.65d (dev)
|
||||
- afl-fuzz:
|
||||
- -S secondary nodes now only sync from the main node to increase performance,
|
||||
the -M main node still syncs from everyone. Added checks that ensure
|
||||
exactly one main node is present and warn otherwise
|
||||
- If no main node is present at a sync one secondary node automatically becomes
|
||||
a temporary main node until a real main nodes shows up
|
||||
- -S secondary nodes now only sync from the main node to increase
|
||||
performance, the -M main node still syncs from everyone. Added checks
|
||||
that ensure exactly one main node is present and warn otherwise
|
||||
- Add -D after -S to force a secondary to perform deterministic fuzzing
|
||||
- If no main node is present at a sync one secondary node automatically
|
||||
becomes a temporary main node until a real main nodes shows up
|
||||
- Fixed a mayor performance issue we inherited from AFLfast
|
||||
- switched murmur2 hashing and random() for xxh3 and xoshiro256**,
|
||||
resulting in an up to 5.5% speed increase
|
||||
- Resizing the window does not crash afl-fuzz anymore
|
||||
- Ensure that the targets are killed on exit
|
||||
- fix/update to MOpt (thanks to arnow117)
|
||||
- added MOpt dictionary support from repo
|
||||
- added experimental SEEK power schedule. It is EXPLORE with ignoring
|
||||
the runtime and less focus on the length of the test case
|
||||
- llvm_mode:
|
||||
- the default instrumentation is now PCGUARD, as it is faster and provides
|
||||
better coverage. The original afl instrumentation can be set via
|
||||
AFL_LLVM_INSTRUMENT=AFL. This is automatically done when the WHITELIST
|
||||
feature is used.
|
||||
- some targets want a ld variant for LD that is not gcc/clang but ld, added
|
||||
afl-ld-lto to solve this
|
||||
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim,
|
||||
which needs 3.8.0)
|
||||
- the default instrumentation is now PCGUARD if the llvm version is >= 7,
|
||||
as it is faster and provides better coverage. The original afl
|
||||
instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is
|
||||
automatically done when the WHITELIST feature is used.
|
||||
- PCGUARD mode is now even better because we made it collision free - plus
|
||||
it has a fixed map size, so it is also faster! :)
|
||||
- some targets want a ld variant for LD that is not gcc/clang but ld,
|
||||
added afl-ld-lto to solve this
|
||||
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which
|
||||
needs 3.8.0)
|
||||
- WHITELIST feature now supports wildcards (thanks to sirmc)
|
||||
- small change to cmplog to make it work with current llvm 11-dev
|
||||
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
|
||||
@ -37,16 +48,23 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- enable snapshot lkm also for persistent mode
|
||||
- Unicornafl
|
||||
- Added powerPC support from unicorn/next
|
||||
- rust bindings!
|
||||
- CMPLOG/Redqueen now also works for MMAP sharedmem
|
||||
- ensure shmem is released on errors
|
||||
- we moved radamsa to be a custom mutator in ./custom_mutators/. It is not
|
||||
compiled by default anymore.
|
||||
- allow running in /tmp (only unsafe with umask 0)
|
||||
- persistent mode shared memory testcase handover (instead of via
|
||||
files/stdin) - 10-100% performance increase
|
||||
- General support for 64 bit PowerPC, RiscV, Sparc etc.
|
||||
- fix afl-cmin.bash
|
||||
- slightly better performance compilation options for afl++ and targets
|
||||
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in
|
||||
the same second
|
||||
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
|
||||
- added former post_library examples to examples/custom_mutators/
|
||||
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and gcc 10
|
||||
so afl-clang-lto can be build
|
||||
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and
|
||||
gcc 10 so afl-clang-lto can be build
|
||||
|
||||
|
||||
### Version ++2.65c (release):
|
||||
|
@ -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
|
@ -6,7 +6,7 @@ for future AFL++ versions.
|
||||
For GSOC2020 interested students please see
|
||||
[https://github.com/AFLplusplus/AFLplusplus/issues/208](https://github.com/AFLplusplus/AFLplusplus/issues/208)
|
||||
|
||||
## Flexible Grammar Mutator
|
||||
## Flexible Grammar Mutator (currently in development)
|
||||
|
||||
Currently, AFL++'s mutation does not have deeper knowledge about the fuzzed
|
||||
binary, apart from feedback, even though the developer may have insights
|
||||
@ -25,41 +25,21 @@ various results.
|
||||
|
||||
Mentor: andreafioraldi
|
||||
|
||||
## Expand on the MOpt mutator
|
||||
|
||||
Work on the MOpt mutator that is already in AFL++.
|
||||
|
||||
This is an excellent mutations scheduler based on Particle Swarm
|
||||
Optimization but the current implementation schedule only the mutations
|
||||
that were present on AFL.
|
||||
|
||||
AFL++ added a lot of optional mutators like the Input-2-State one based
|
||||
on Redqueen, the Radamsa mutator, the Custom mutator (the user can define
|
||||
its own mutator) and the work is to generalize MOpt for all the current
|
||||
and future mutators.
|
||||
|
||||
Mentor: vanhauser-thc or andreafioraldi
|
||||
|
||||
## perf-fuzz Linux Kernel Module
|
||||
|
||||
Either Port the patch to the upcoming Ubuntu LTS 20.04 default kernel
|
||||
and provide a qemu-kvm image or find a different userspace snapshot
|
||||
solution that has a good performance and is reliable, e.g. with docker.
|
||||
[perf-fuzz](https://gts3.org/assets/papers/2017/xu:os-fuzz.pdf)
|
||||
The perf-fuzz kernel can be found at [https://github.com/sslab-gatech/perf-fuzz](https://github.com/sslab-gatech/perf-fuzz)
|
||||
There also is/was a FreeBSD project at [https://github.com/veracode-research/freebsd-perf-fuzz](https://github.com/veracode-research/freebsd-perf-fuzz)
|
||||
|
||||
This enables snapshot fuzzing on Linux with an incredible performance!
|
||||
Expand on [snapshot LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
|
||||
To make it thread safe, can snapshot several processes at once and increase
|
||||
overall performance.
|
||||
|
||||
Mentor: any
|
||||
Idea/Issue tracker: [https://github.com/AFLplusplus/AFLplusplus/issues/248](https://github.com/AFLplusplus/AFLplusplus/issues/248)
|
||||
|
||||
## QEMU 4-based Instrumentation
|
||||
## QEMU 5-based Instrumentation
|
||||
|
||||
First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior
|
||||
changed, which vastly decreases fuzzing speeds.
|
||||
|
||||
This is the cause why, right now, we cannot switch to QEMU 4.2.
|
||||
In this task test if QEMU 5 performs better and port the afl++ QEMU 3.1
|
||||
patches to QEMU 5.
|
||||
|
||||
Understanding the current instrumentation and fixing the current caching
|
||||
issues will be needed.
|
||||
@ -86,7 +66,7 @@ Either improve a single mutator thorugh learning of many different bugs
|
||||
|
||||
Mentor: domenukk
|
||||
|
||||
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library
|
||||
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library (currently in development)
|
||||
|
||||
Right now, afl-fuzz is single threaded, cannot safely be embedded in tools,
|
||||
and not multi-threaded. It makes use of a large number of globals, must always
|
||||
|
@ -21,6 +21,7 @@ We find that AFL's exploitation-based constant schedule assigns **too much energ
|
||||
| `-p exploit` (AFL) |  |
|
||||
| `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries |
|
||||
| `-p rare` | Experimental: `rare` puts focus on queue entries that hit rare edges |
|
||||
| `-p seek` | Experimental: `seek` is EXPLORE but ignoring the runtime of the queue input and less focus on the size |
|
||||
where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path.
|
||||
|
||||
More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).
|
||||
|
@ -7,20 +7,22 @@ ifneq "" "$(LLVM_BINDIR)"
|
||||
LLVM_BINDIR := $(LLVM_BINDIR)/
|
||||
endif
|
||||
|
||||
FLAGS=-O3 -funroll-loops
|
||||
FLAGS=-O3 -funroll-loops -g
|
||||
|
||||
all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
|
||||
|
||||
aflpp_driver.o: aflpp_driver.cpp
|
||||
$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
|
||||
$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -std=c++11 -c aflpp_driver.cpp
|
||||
|
||||
libAFLDriver.a: aflpp_driver.o
|
||||
ar ru libAFLDriver.a aflpp_driver.o
|
||||
|
||||
debug:
|
||||
$(LLVM_BINDIR)clang++ -D_DEBUG=\"1\" $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
|
||||
ar ru libAFLDriver.a aflpp_driver.o
|
||||
|
||||
$(LLVM_BINDIR)clang++ -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c
|
||||
$(LLVM_BINDIR)clang++ -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
|
||||
#$(LLVM_BINDIR)clang++ -S -emit-llvm -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c
|
||||
#$(LLVM_BINDIR)clang++ -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
|
||||
ar ru libAFLDriver.a afl-performance.o aflpp_driver.o
|
||||
|
||||
aflpp_qemu_driver.o: aflpp_qemu_driver.c
|
||||
$(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c
|
||||
@ -34,8 +36,9 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o
|
||||
aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c
|
||||
$(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c
|
||||
|
||||
test: libAFLDriver.a aflpp_driver_test.cpp
|
||||
afl-clang-fast++ -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a
|
||||
test: debug
|
||||
#clang++ -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test.ll aflpp_driver_test.cpp
|
||||
afl-clang-fast++ -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a
|
||||
|
||||
clean:
|
||||
rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test
|
||||
|
@ -54,6 +54,10 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "hash.h"
|
||||
#endif
|
||||
|
||||
// Platform detection. Copied from FuzzerInternal.h
|
||||
#ifdef __linux__
|
||||
#define LIBFUZZER_LINUX 1
|
||||
@ -273,7 +277,11 @@ int main(int argc, char **argv) {
|
||||
int num_runs = 0;
|
||||
while (__afl_persistent_loop(N)) {
|
||||
#ifdef _DEBUG
|
||||
fprintf(stderr, "len: %u\n", *__afl_fuzz_len);
|
||||
fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len);
|
||||
fprintf(stderr, "RECV:");
|
||||
for (int i = 0; i < *__afl_fuzz_len; i++)
|
||||
fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
|
||||
fprintf(stderr,"\n");
|
||||
#endif
|
||||
if (*__afl_fuzz_len) {
|
||||
num_runs++;
|
||||
|
@ -1,19 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "hash.h"
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
|
||||
fprintf(stderr, "Received size %lu\n", Size);
|
||||
fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size);
|
||||
|
||||
if (Size < 4)
|
||||
if (Size < 5)
|
||||
return 0;
|
||||
|
||||
if (Data[0] == 'F')
|
||||
if (Data[1] == 'A')
|
||||
if (Data[2] == '$')
|
||||
if (Data[3] == '$')
|
||||
abort();
|
||||
if (Data[4] == '$')
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -49,9 +49,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
len = __AFL_FUZZ_TESTCASE_LEN;
|
||||
|
||||
fprintf(stderr, "input: %zd \"%s\"\n", len, buf);
|
||||
|
||||
/* do we have enough data? */
|
||||
if (len < 8) continue;
|
||||
|
||||
if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n");
|
||||
|
||||
if (buf[0] == 'f') {
|
||||
|
||||
printf("one\n");
|
||||
|
@ -28,11 +28,12 @@ MAN_PATH ?= $(PREFIX)/man/man8
|
||||
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
|
||||
CFLAGS = -Wall -I../include -Wno-pointer-sign \
|
||||
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
|
||||
-Wno-unused-function
|
||||
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
|
||||
CFLAGS_SAFE := -Wall -I../include -Wno-pointer-sign \
|
||||
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
|
||||
-Wno-unused-function
|
||||
override CFLAGS += $(CFLAGS_SAFE)
|
||||
|
||||
CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
|
||||
CXXEFLAGS := $(CXXFLAGS) -Wall
|
||||
@ -60,13 +61,15 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
|
||||
SHMAT_OK=1
|
||||
else
|
||||
SHMAT_OK=0
|
||||
CFLAGS+=-DUSEMMAP=1
|
||||
LDFLAGS += -lrt
|
||||
override CFLAGS += -DUSEMMAP=1
|
||||
endif
|
||||
|
||||
ifeq "$(TEST_MMAP)" "1"
|
||||
SHMAT_OK=0
|
||||
CFLAGS+=-DUSEMMAP=1
|
||||
override CFLAGS += -DUSEMMAP=1
|
||||
endif
|
||||
|
||||
ifneq "$(shell uname -s)" "Haiku"
|
||||
LDFLAGS += -lrt
|
||||
endif
|
||||
|
||||
@ -111,7 +114,7 @@ afl-common.o: ../src/afl-common.c
|
||||
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
|
||||
|
||||
../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps
|
||||
$(CC) $(CFLAGS) -fPIC -c $< -o $@
|
||||
$(CC) $(CFLAGS_SAFE) -fPIC -c $< -o $@
|
||||
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
|
@ -231,7 +231,7 @@ static void edit_params(u32 argc, char **argv) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef USEMMAP
|
||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||
cc_params[cc_par_cnt++] = "-lrt";
|
||||
#endif
|
||||
|
||||
|
@ -35,7 +35,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "sharedmem.h"
|
||||
#include "forkserver.h"
|
||||
#include "common.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -66,7 +67,9 @@
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
@ -83,7 +86,7 @@
|
||||
can hope... */
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||
defined(__DragonFly__)
|
||||
defined(__DragonFly__) || defined(__sun)
|
||||
#define HAVE_AFFINITY 1
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#include <sys/param.h>
|
||||
@ -96,6 +99,11 @@
|
||||
#define cpu_set_t cpuset_t
|
||||
#elif defined(__NetBSD__)
|
||||
#include <pthread.h>
|
||||
#elif defined(__sun)
|
||||
#include <sys/types.h>
|
||||
#include <kstat.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/pset.h>
|
||||
#endif
|
||||
#endif /* __linux__ */
|
||||
|
||||
@ -134,13 +142,13 @@ struct queue_entry {
|
||||
fully_colorized; /* Do not run redqueen stage again */
|
||||
|
||||
u32 bitmap_size, /* Number of bits set in bitmap */
|
||||
fuzz_level, /* Number of fuzzing iterations */
|
||||
exec_cksum; /* Checksum of the execution trace */
|
||||
fuzz_level; /* Number of fuzzing iterations */
|
||||
|
||||
u64 exec_us, /* Execution time (us) */
|
||||
handicap, /* Number of queue cycles behind */
|
||||
n_fuzz, /* Number of fuzz, does not overflow */
|
||||
depth; /* Path depth */
|
||||
n_fuzz, /* Number of fuzz, does not overflow*/
|
||||
depth, /* Path depth */
|
||||
exec_cksum; /* Checksum of the execution trace */
|
||||
|
||||
u8 *trace_mini; /* Trace bytes, if kept */
|
||||
u32 tc_ref; /* Trace bytes ref count */
|
||||
@ -180,10 +188,11 @@ enum {
|
||||
/* 15 */ STAGE_HAVOC,
|
||||
/* 16 */ STAGE_SPLICE,
|
||||
/* 17 */ STAGE_PYTHON,
|
||||
/* 18 */ STAGE_RADAMSA,
|
||||
/* 19 */ STAGE_CUSTOM_MUTATOR,
|
||||
/* 20 */ STAGE_COLORIZATION,
|
||||
/* 21 */ STAGE_ITS,
|
||||
/* 18 */ STAGE_CUSTOM_MUTATOR,
|
||||
/* 19 */ STAGE_COLORIZATION,
|
||||
/* 20 */ STAGE_ITS,
|
||||
|
||||
STAGE_NUM_MAX
|
||||
|
||||
};
|
||||
|
||||
@ -197,7 +206,7 @@ enum {
|
||||
|
||||
};
|
||||
|
||||
#define operator_num 16
|
||||
#define operator_num 18
|
||||
#define swarm_num 5
|
||||
#define period_core 500000
|
||||
|
||||
@ -211,18 +220,21 @@ enum {
|
||||
#define STAGE_DELETEBYTE 13
|
||||
#define STAGE_Clone75 14
|
||||
#define STAGE_OverWrite75 15
|
||||
#define STAGE_OverWriteExtra 16
|
||||
#define STAGE_InsertExtra 17
|
||||
#define period_pilot 50000
|
||||
|
||||
enum {
|
||||
|
||||
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
|
||||
/* 01 */ FAST, /* Exponential schedule */
|
||||
/* 02 */ COE, /* Cut-Off Exponential schedule */
|
||||
/* 03 */ LIN, /* Linear schedule */
|
||||
/* 04 */ QUAD, /* Quadratic schedule */
|
||||
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
|
||||
/* 06 */ MMOPT, /* Modified MOPT schedule */
|
||||
/* 07 */ RARE, /* Rare edges */
|
||||
/* 01 */ EXPLOIT, /* AFL's exploitation-based const. */
|
||||
/* 02 */ FAST, /* Exponential schedule */
|
||||
/* 03 */ COE, /* Cut-Off Exponential schedule */
|
||||
/* 04 */ LIN, /* Linear schedule */
|
||||
/* 05 */ QUAD, /* Quadratic schedule */
|
||||
/* 06 */ RARE, /* Rare edges */
|
||||
/* 07 */ MMOPT, /* Modified MOPT schedule */
|
||||
/* 08 */ SEEK, /* EXPLORE that ignores timings */
|
||||
|
||||
POWER_SCHEDULES_NUM
|
||||
|
||||
@ -416,9 +428,6 @@ typedef struct afl_state {
|
||||
u8 schedule; /* Power schedule (default: EXPLORE)*/
|
||||
u8 havoc_max_mult;
|
||||
|
||||
u8 use_radamsa;
|
||||
size_t (*radamsa_mutate_ptr)(u8 *, size_t, u8 *, size_t, u32);
|
||||
|
||||
u8 skip_deterministic, /* Skip deterministic stages? */
|
||||
use_splicing, /* Recombine input files? */
|
||||
non_instrumented_mode, /* Run in non-instrumented mode? */
|
||||
@ -515,11 +524,9 @@ typedef struct afl_state {
|
||||
u64 stage_finds[32], /* Patterns found per fuzz stage */
|
||||
stage_cycles[32]; /* Execs per fuzz stage */
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
u32 rand_cnt; /* Random number counter */
|
||||
#endif
|
||||
|
||||
u32 rand_seed[2];
|
||||
u64 rand_seed[4];
|
||||
s64 init_seed;
|
||||
|
||||
u64 total_cal_us, /* Total calibration time (us) */
|
||||
@ -937,7 +944,10 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
|
||||
|
||||
/* RedQueen */
|
||||
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
||||
u32 exec_cksum);
|
||||
u64 exec_cksum);
|
||||
|
||||
/* xoshiro256** */
|
||||
uint64_t rand_next(afl_state_t *afl);
|
||||
|
||||
/**** Inline routines ****/
|
||||
|
||||
@ -946,34 +956,31 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
||||
|
||||
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||
|
||||
#ifdef HAVE_ARC4RANDOM
|
||||
if (unlikely(afl->fixed_seed)) { return random() % limit; }
|
||||
|
||||
/* The boundary not being necessarily a power of 2,
|
||||
we need to ensure the result uniformity. */
|
||||
return arc4random_uniform(limit);
|
||||
#else
|
||||
if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {
|
||||
|
||||
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
|
||||
"/dev/urandom");
|
||||
srandom(afl->rand_seed[0]);
|
||||
// srandom(afl->rand_seed[0]);
|
||||
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
|
||||
|
||||
}
|
||||
|
||||
return random() % limit;
|
||||
#endif
|
||||
return rand_next(afl) % limit;
|
||||
|
||||
}
|
||||
|
||||
static inline u32 get_rand_seed(afl_state_t *afl) {
|
||||
static inline s64 rand_get_seed(afl_state_t *afl) {
|
||||
|
||||
if (unlikely(afl->fixed_seed)) { return (u32)afl->init_seed; }
|
||||
if (unlikely(afl->fixed_seed)) { return afl->init_seed; }
|
||||
return afl->rand_seed[0];
|
||||
|
||||
}
|
||||
|
||||
/* initialize randomness with a given seed. Can be called again at any time. */
|
||||
void rand_set_seed(afl_state_t *afl, s64 init_seed);
|
||||
|
||||
/* Find first power of two greater or equal to val (assuming val under
|
||||
2^63). */
|
||||
|
||||
|
@ -60,7 +60,7 @@ typedef enum prealloc_status {
|
||||
\
|
||||
if ((prealloc_counter) >= (prealloc_size)) { \
|
||||
\
|
||||
el_ptr = malloc(sizeof(*el_ptr)); \
|
||||
el_ptr = (void *)malloc(sizeof(*el_ptr)); \
|
||||
if (!el_ptr) { FATAL("error in list.h -> out of memory for element!"); } \
|
||||
el_ptr->pre_status = PRE_STATUS_MALLOC; \
|
||||
\
|
||||
|
@ -170,10 +170,10 @@ static inline u8 *DFL_ck_strdup(u8 *str) {
|
||||
size = strlen((char *)str) + 1;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size);
|
||||
ret = (u8 *)malloc(size);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
return memcpy(ret, str, size);
|
||||
return (u8 *)memcpy(ret, str, size);
|
||||
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ static inline u8 *DFL_ck_memdup_str(u8 *mem, u32 size) {
|
||||
if (!mem || !size) { return NULL; }
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + 1);
|
||||
ret = (u8 *)malloc(size + 1);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
memcpy(ret, mem, size);
|
||||
|
@ -293,7 +293,7 @@
|
||||
|
||||
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
|
||||
|
||||
#define RESEED_RNG 10000
|
||||
#define RESEED_RNG 100000
|
||||
|
||||
/* Maximum line length passed from GCC to 'as' and used for parsing
|
||||
configuration files: */
|
||||
@ -397,12 +397,5 @@
|
||||
|
||||
// #define IGNORE_FINDS
|
||||
|
||||
/* for *BSD: use ARC4RANDOM and save a file descriptor */
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
#define HAVE_ARC4RANDOM 1
|
||||
#endif
|
||||
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
|
||||
|
||||
#endif /* ! _HAVE_CONFIG_H */
|
||||
|
||||
|
@ -262,7 +262,7 @@
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/* Die with FAULT() or PFAULT() depending on the value of res (used to
|
||||
/* Die with FATAL() or PFATAL() depending on the value of res (used to
|
||||
interpret different failure modes for read(), write(), etc). */
|
||||
|
||||
#define RPFATAL(res, x...) \
|
||||
|
@ -47,9 +47,8 @@ typedef struct afl_forkserver {
|
||||
out_dir_fd; /* FD of the lock file */
|
||||
|
||||
s32 out_fd, /* Persistent fd for fsrv->out_file */
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
dev_urandom_fd, /* Persistent fd for /dev/urandom */
|
||||
#endif
|
||||
|
||||
dev_null_fd, /* Persistent fd for /dev/null */
|
||||
fsrv_ctl_fd, /* Fork server control pipe (write) */
|
||||
fsrv_st_fd; /* Fork server status pipe (read) */
|
||||
|
@ -30,11 +30,18 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
u32 hash32(u8 *key, u32 len, u32 seed);
|
||||
u64 hash64(u8 *key, u32 len, u64 seed);
|
||||
|
||||
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
|
||||
#if 0
|
||||
|
||||
static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
||||
The following code is disabled because xxh3 is 30% faster
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
|
||||
|
||||
static inline u32 hash32(u8 *key, u32 len, u32 seed) {
|
||||
|
||||
const u64 *data = (u64 *)key;
|
||||
u64 h1 = seed ^ len;
|
||||
@ -65,9 +72,9 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
|
||||
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
|
||||
|
||||
static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
||||
|
||||
@ -100,7 +107,8 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* ^__x86_64__ */
|
||||
#endif /* ^__x86_64__ */
|
||||
#endif
|
||||
|
||||
#endif /* !_HAVE_HASH_H */
|
||||
|
||||
|
@ -38,6 +38,8 @@ typedef struct sharedmem {
|
||||
/* ================ Proteas ================ */
|
||||
int g_shm_fd;
|
||||
char g_shm_file_path[L_tmpnam];
|
||||
int cmplog_g_shm_fd;
|
||||
char cmplog_g_shm_file_path[L_tmpnam];
|
||||
/* ========================================= */
|
||||
#else
|
||||
s32 shm_id; /* ID of the SHM region */
|
||||
|
3187
include/xxh3.h
Normal file
3187
include/xxh3.h
Normal file
File diff suppressed because it is too large
Load Diff
2442
include/xxhash.h
Normal file
2442
include/xxhash.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -37,9 +37,12 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__HAIKU__)
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef __NR_getrandom
|
||||
#define arc4random_buf(p, l) \
|
||||
do { \
|
||||
|
@ -35,10 +35,11 @@ _UNIQ=_QINU_
|
||||
_____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=)
|
||||
______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl")
|
||||
|
||||
_OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ))
|
||||
__OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ))
|
||||
___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ))
|
||||
____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=)
|
||||
_OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ))
|
||||
__OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ))
|
||||
___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ))
|
||||
____OS_TARGET = $(___OS_TARGET:$(_UNIQ)Haiku=$(_UNIQ))
|
||||
_____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=)
|
||||
|
||||
TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so)
|
||||
|
||||
|
@ -33,8 +33,9 @@
|
||||
#include "../types.h"
|
||||
#include "../config.h"
|
||||
|
||||
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
|
||||
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__
|
||||
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
|
||||
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ && \
|
||||
!defined(__HAIKU__)
|
||||
#error "Sorry, this library is unsupported in this platform for now!"
|
||||
#endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \
|
||||
!__NetBSD__*/
|
||||
@ -49,6 +50,8 @@
|
||||
#include <sys/user.h>
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#elif defined __HAIKU__
|
||||
#include <kernel/image.h>
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
@ -230,6 +233,19 @@ static void __tokencap_load_mappings(void) {
|
||||
}
|
||||
|
||||
munmap(buf, len);
|
||||
#elif defined __HAIKU__
|
||||
image_info ii;
|
||||
int32_t group = 0;
|
||||
|
||||
while (get_next_image_info(0, &group, &ii) == B_OK) {
|
||||
|
||||
__tokencap_ro[__tokencap_ro_cnt].st = ii.text;
|
||||
__tokencap_ro[__tokencap_ro_cnt].en = ((char *)ii.text) + ii.text_size;
|
||||
|
||||
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -357,7 +373,7 @@ int strcasecmp(const char *str1, const char *str2) {
|
||||
|
||||
while (1) {
|
||||
|
||||
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
|
||||
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
|
||||
|
||||
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
||||
if (!c1) return 0;
|
||||
@ -381,7 +397,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
|
||||
|
||||
while (len--) {
|
||||
|
||||
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
|
||||
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
|
||||
|
||||
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
||||
if (!c1) return 0;
|
||||
@ -495,7 +511,7 @@ char *strcasestr(const char *haystack, const char *needle) {
|
||||
const char *n = needle;
|
||||
const char *h = haystack;
|
||||
|
||||
while (*n && *h && tolower(*n) == tolower(*h))
|
||||
while (*n && *h && tolower((int)*n) == tolower((int)*h))
|
||||
n++, h++;
|
||||
|
||||
if (!*n) return (char *)haystack;
|
||||
|
@ -196,24 +196,31 @@ ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`com
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
|
||||
override CFLAGS += -Wall \
|
||||
-g -Wno-pointer-sign -I ../include/ \
|
||||
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
|
||||
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
|
||||
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
|
||||
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
|
||||
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
|
||||
CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
|
||||
CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ../include/ \
|
||||
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
|
||||
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
|
||||
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
|
||||
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
|
||||
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
|
||||
override CFLAGS += $(CFLAGS_SAFE)
|
||||
|
||||
ifdef AFL_TRACE_PC
|
||||
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
|
||||
endif
|
||||
|
||||
CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
|
||||
CXXFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
|
||||
override CXXFLAGS += -Wall -g -I ../include/ \
|
||||
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros
|
||||
|
||||
CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fpic $(CXXFLAGS)
|
||||
ifneq "$(shell $(LLVM_CONFIG) --includedir) 2> /dev/null" ""
|
||||
CLANG_CFL = -I$(shell $(LLVM_CONFIG) --includedir)
|
||||
endif
|
||||
ifneq "$(LLVM_CONFIG)" ""
|
||||
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
|
||||
endif
|
||||
CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS)
|
||||
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
|
||||
|
||||
|
||||
@ -221,12 +228,12 @@ CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
|
||||
ifeq "$(shell uname)" "Darwin"
|
||||
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
|
||||
else
|
||||
CLANG_CFL += -Wl,-znodelete
|
||||
CLANG_CPPFL += -Wl,-znodelete
|
||||
endif
|
||||
|
||||
ifeq "$(shell uname)" "OpenBSD"
|
||||
CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
|
||||
CLANG_CFL += -mno-retpoline
|
||||
CLANG_CPPFL += -mno-retpoline
|
||||
CFLAGS += -mno-retpoline
|
||||
# Needed for unwind symbols
|
||||
LDFLAGS += -lc++abi
|
||||
@ -304,7 +311,7 @@ afl-common.o: ../src/afl-common.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
|
||||
../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
|
||||
$(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
|
||||
$(CC) $(CLANG_CFL) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
|
||||
ln -sf afl-clang-fast ../afl-clang-fast++
|
||||
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
@ -317,17 +324,17 @@ afl-llvm-common.o: afl-llvm-common.cc afl-llvm-common.h
|
||||
$(CXX) $(CFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
||||
|
||||
../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps
|
||||
-$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
-$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
|
||||
../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps
|
||||
ifeq "$(LLVM_MIN_4_0_1)" "0"
|
||||
$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
|
||||
endif
|
||||
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
|
||||
../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
$(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
endif
|
||||
|
||||
../afl-ld-lto: afl-ld-lto.c
|
||||
@ -337,47 +344,47 @@ endif
|
||||
|
||||
../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
|
||||
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||
$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
|
||||
@$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||
@$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||
endif
|
||||
|
||||
../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
endif
|
||||
|
||||
# laf
|
||||
../split-switches-pass.so: split-switches-pass.so.cc afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
../compare-transform-pass.so: compare-transform-pass.so.cc afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
../split-compares-pass.so: split-compares-pass.so.cc afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
# /laf
|
||||
|
||||
../cmplog-routines-pass.so: cmplog-routines-pass.cc afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
|
||||
../cmplog-instructions-pass.so: cmplog-instructions-pass.cc afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
|
||||
document:
|
||||
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
|
||||
../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
|
||||
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -fPIC -c $< -o $@
|
||||
$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c $< -o $@
|
||||
|
||||
../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
|
||||
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
|
||||
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
@$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
|
||||
../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
|
||||
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
|
||||
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
@$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
|
@ -103,6 +103,7 @@ struct InsTrim : public ModulePass {
|
||||
bool runOnModule(Module &M) override {
|
||||
|
||||
char be_quiet = 0;
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
static u8 * obj_path; /* Path to runtime libraries */
|
||||
static u8 **cc_params; /* Parameters passed to the real CC */
|
||||
static u32 cc_par_cnt = 1; /* Param count, including argv0 */
|
||||
@ -464,7 +466,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef USEMMAP
|
||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||
cc_params[cc_par_cnt++] = "-lrt";
|
||||
#endif
|
||||
|
||||
@ -500,7 +502,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
"unsigned char *__afl_fuzz_alt_ptr;";
|
||||
cc_params[cc_par_cnt++] =
|
||||
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
|
||||
"(__afl_fuzz_alt_ptr = malloc(1 * 1024 * 1024)))";
|
||||
"(__afl_fuzz_alt_ptr = (unsigned char *) malloc(1 * 1024 * 1024)))";
|
||||
cc_params[cc_par_cnt++] =
|
||||
"-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
|
||||
"__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
|
||||
@ -757,12 +759,14 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
if (instrument_mode == 0) {
|
||||
|
||||
#ifndef USE_TRACE_PC
|
||||
#if LLVM_VERSION_MAJOR <= 6
|
||||
instrument_mode = INSTRUMENT_AFL;
|
||||
#else
|
||||
if (getenv("AFL_LLVM_WHITELIST"))
|
||||
instrument_mode = INSTRUMENT_AFL;
|
||||
else
|
||||
#endif
|
||||
instrument_mode = INSTRUMENT_PCGUARD;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,11 @@ struct InsTrimLTO : public ModulePass {
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
|
||||
char be_quiet = 0;
|
||||
char *ptr;
|
||||
char be_quiet = 0;
|
||||
char * ptr;
|
||||
uint32_t locations = 0, functions = 0;
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
|
||||
|
||||
@ -561,6 +564,8 @@ struct InsTrimLTO : public ModulePass {
|
||||
if (F.size() < function_minimum_size) continue;
|
||||
if (isBlacklisted(&F)) continue;
|
||||
|
||||
functions++;
|
||||
|
||||
// whitelist check
|
||||
AttributeList Attrs = F.getAttributes();
|
||||
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
|
||||
@ -657,6 +662,7 @@ struct InsTrimLTO : public ModulePass {
|
||||
if (PI == PE) {
|
||||
|
||||
L = ConstantInt::get(Int32Ty, afl_global_id++);
|
||||
locations++;
|
||||
|
||||
} else {
|
||||
|
||||
@ -668,6 +674,7 @@ struct InsTrimLTO : public ModulePass {
|
||||
auto It = PredMap.insert({PBB, afl_global_id++});
|
||||
unsigned Label = It.first->second;
|
||||
PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB);
|
||||
locations++;
|
||||
|
||||
}
|
||||
|
||||
@ -885,7 +892,7 @@ struct InsTrimLTO : public ModulePass {
|
||||
for (BasicBlock *Succ : successors(Pred))
|
||||
if (Succ != NULL) count++;
|
||||
|
||||
if (count > 1) return true;
|
||||
if (count > 1) would_instrument = true;
|
||||
|
||||
}
|
||||
|
||||
@ -910,11 +917,12 @@ struct InsTrimLTO : public ModulePass {
|
||||
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
|
||||
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
||||
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
||||
OKF("Instrumented %u locations (%llu, %llu) with no collisions (on "
|
||||
OKF("Instrumented %u locations for %u edges in %u functions (%llu, "
|
||||
"%llu) with no collisions (on "
|
||||
"average %llu collisions would be in afl-gcc/afl-clang-fast for %u "
|
||||
"edges) (%s mode).",
|
||||
inst_blocks, total_rs, total_hs, calculateCollisions(edges), edges,
|
||||
modeline);
|
||||
inst_blocks, locations, functions, total_rs, total_hs,
|
||||
calculateCollisions(edges), edges, modeline);
|
||||
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
||||
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
|
||||
|
||||
/* Show a banner */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
|
||||
|
||||
@ -162,7 +163,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); }
|
||||
if (debug) { fprintf(stderr, "map address is 0x%lx\n", map_addr); }
|
||||
|
||||
/* Get/set the globals for the SHM region. */
|
||||
|
||||
|
@ -111,6 +111,7 @@ bool AFLwhitelist::runOnModule(Module &M) {
|
||||
/* Show a banner */
|
||||
|
||||
char be_quiet = 0;
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
|
||||
|
||||
|
@ -140,6 +140,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
/* Show a banner */
|
||||
|
||||
char be_quiet = 0;
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
if (getenv("AFL_DEBUG")) debug = 1;
|
||||
|
||||
|
@ -139,7 +139,8 @@ static void __afl_map_shm_fuzz() {
|
||||
|
||||
}
|
||||
|
||||
map = (u8 *)mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
|
||||
map =
|
||||
(u8 *)mmap(0, MAX_FILE + sizeof(u32), PROT_READ, MAP_SHARED, shm_fd, 0);
|
||||
|
||||
#else
|
||||
u32 shm_id = atoi(id_str);
|
||||
@ -157,7 +158,7 @@ static void __afl_map_shm_fuzz() {
|
||||
}
|
||||
|
||||
__afl_fuzz_len = (u32 *)map;
|
||||
__afl_fuzz_ptr = (u8 *)(map + sizeof(u32));
|
||||
__afl_fuzz_ptr = map + sizeof(u32);
|
||||
|
||||
if (getenv("AFL_DEBUG")) {
|
||||
|
||||
@ -182,6 +183,9 @@ static void __afl_map_shm(void) {
|
||||
|
||||
if (__afl_final_loc) {
|
||||
|
||||
if (__afl_final_loc % 8)
|
||||
__afl_final_loc = (((__afl_final_loc + 7) >> 3) << 3);
|
||||
|
||||
__afl_map_size = __afl_final_loc;
|
||||
if (__afl_final_loc > MAP_SIZE) {
|
||||
|
||||
@ -391,7 +395,10 @@ static void __afl_start_snapshots(void) {
|
||||
|
||||
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
|
||||
|
||||
if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) ==
|
||||
if (getenv("AFL_DEBUG"))
|
||||
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
|
||||
|
||||
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
|
||||
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
|
||||
|
||||
__afl_map_shm_fuzz();
|
||||
@ -590,6 +597,9 @@ static void __afl_start_forkserver(void) {
|
||||
|
||||
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
|
||||
|
||||
if (getenv("AFL_DEBUG"))
|
||||
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
|
||||
|
||||
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
|
||||
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
|
||||
|
||||
@ -870,7 +880,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
||||
while (start < stop) {
|
||||
|
||||
if (R(100) < inst_ratio)
|
||||
*start = R(MAP_SIZE - 1) + 1;
|
||||
*start = ++__afl_final_loc;
|
||||
else
|
||||
*start = 0;
|
||||
|
||||
|
@ -237,16 +237,16 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
switch (max_size) {
|
||||
|
||||
case 8:
|
||||
IRB.CreateCall(cmplogHookIns1, args, "tmp");
|
||||
IRB.CreateCall(cmplogHookIns1, args);
|
||||
break;
|
||||
case 16:
|
||||
IRB.CreateCall(cmplogHookIns2, args, "tmp");
|
||||
IRB.CreateCall(cmplogHookIns2, args);
|
||||
break;
|
||||
case 32:
|
||||
IRB.CreateCall(cmplogHookIns4, args, "tmp");
|
||||
IRB.CreateCall(cmplogHookIns4, args);
|
||||
break;
|
||||
case 64:
|
||||
IRB.CreateCall(cmplogHookIns8, args, "tmp");
|
||||
IRB.CreateCall(cmplogHookIns8, args);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -169,7 +169,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
IRB.CreateCall(cmplogHookFn, args, "tmp");
|
||||
IRB.CreateCall(cmplogHookFn, args);
|
||||
|
||||
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||
|
||||
|
@ -500,7 +500,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
load = cur_cmp_IRB.CreateZExt(load, Int32Ty);
|
||||
std::vector<Value *> args;
|
||||
args.push_back(load);
|
||||
load = cur_cmp_IRB.CreateCall(tolowerFn, args, "tmp");
|
||||
load = cur_cmp_IRB.CreateCall(tolowerFn, args);
|
||||
load = cur_cmp_IRB.CreateTrunc(load, Int8Ty);
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ MAN_PATH ?= $(PREFIX)/man/man8
|
||||
|
||||
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
CFLAGS ?= -O3 -funroll-loops -I ../../include/
|
||||
CFLAGS ?= -O3 -funroll-loops
|
||||
CFLAGS += -I ../../include/
|
||||
CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
|
||||
LDFLAGS += -ldl
|
||||
|
||||
|
@ -51,7 +51,9 @@
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
@ -66,11 +68,12 @@ static u8 *in_file, /* Analyzer input test case */
|
||||
static u8 *in_data; /* Input data for analysis */
|
||||
|
||||
static u32 in_len, /* Input data length */
|
||||
orig_cksum, /* Original checksum */
|
||||
total_execs, /* Total number of execs */
|
||||
exec_hangs, /* Total number of hangs */
|
||||
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
|
||||
|
||||
static u64 orig_cksum; /* Original checksum */
|
||||
|
||||
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
||||
|
||||
static s32 dev_null_fd = -1; /* FD to /dev/null */
|
||||
@ -222,7 +225,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
||||
int status = 0;
|
||||
|
||||
s32 prog_in_fd;
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
|
||||
memset(trace_bits, 0, map_size);
|
||||
MEM_BARRIER();
|
||||
@ -321,7 +324,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
||||
|
||||
}
|
||||
|
||||
cksum = hash32(trace_bits, map_size, HASH_CONST);
|
||||
cksum = hash64(trace_bits, map_size, HASH_CONST);
|
||||
|
||||
/* We don't actually care if the target is crashing or not,
|
||||
except that when it does, the checksum should be different. */
|
||||
@ -1046,6 +1049,9 @@ int main(int argc, char **argv, char **envp) {
|
||||
check_environment_vars(envp);
|
||||
|
||||
sharedmem_t shm = {0};
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
shm.cmplog_mode = 0;
|
||||
trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||
atexit(at_exit_handler);
|
||||
setup_signal_handlers();
|
||||
|
@ -54,6 +54,7 @@ char *afl_environment_variables[] = {
|
||||
"AFL_CMIN_CRASHES_ONLY", "AFL_CODE_END", "AFL_CODE_START",
|
||||
"AFL_COMPCOV_BINNAME", "AFL_COMPCOV_LEVEL", "AFL_CUSTOM_MUTATOR_LIBRARY",
|
||||
"AFL_CUSTOM_MUTATOR_ONLY", "AFL_CXX", "AFL_DEBUG", "AFL_DEBUG_CHILD_OUTPUT",
|
||||
"AFL_DEBUG_GDB",
|
||||
//"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally
|
||||
"AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV",
|
||||
"AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI",
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "common.h"
|
||||
#include "list.h"
|
||||
#include "forkserver.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -70,9 +71,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
||||
fsrv->out_fd = -1;
|
||||
fsrv->out_dir_fd = -1;
|
||||
fsrv->dev_null_fd = -1;
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
fsrv->dev_urandom_fd = -1;
|
||||
#endif
|
||||
|
||||
/* Settings */
|
||||
fsrv->use_stdin = 1;
|
||||
fsrv->no_unlink = 0;
|
||||
@ -103,9 +103,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
||||
fsrv_to->map_size = from->map_size;
|
||||
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
|
||||
#endif
|
||||
|
||||
// These are forkserver specific.
|
||||
fsrv_to->out_dir_fd = -1;
|
||||
@ -131,7 +129,8 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
struct timeval timeout;
|
||||
size_t len = 4;
|
||||
int sret;
|
||||
ssize_t len_read;
|
||||
|
||||
timeout.tv_sec = (timeout_ms / 1000);
|
||||
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
@ -140,33 +139,52 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
|
||||
#endif
|
||||
|
||||
/* set exceptfds as well to return when a child exited/closed the pipe. */
|
||||
int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
|
||||
restart_select:
|
||||
sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
|
||||
|
||||
if (!sret) {
|
||||
if (likely(sret > 0)) {
|
||||
|
||||
restart_read:
|
||||
len_read = read(fd, (u8 *)buf, 4);
|
||||
|
||||
if (likely(len_read == 4)) { // for speed we put this first
|
||||
|
||||
#if defined(__linux__)
|
||||
u32 exec_ms = MIN(
|
||||
timeout_ms,
|
||||
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
|
||||
#else
|
||||
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
|
||||
#endif
|
||||
|
||||
// ensure to report 1 ms has passed (0 is an error)
|
||||
return exec_ms > 0 ? exec_ms : 1;
|
||||
|
||||
} else if (unlikely(len_read == -1 && errno == EINTR)) {
|
||||
|
||||
goto restart_read;
|
||||
|
||||
} else if (unlikely(len_read < 4)) {
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
} else if (unlikely(!sret)) {
|
||||
|
||||
*buf = -1;
|
||||
return timeout_ms + 1;
|
||||
|
||||
} else if (sret < 0) {
|
||||
} else if (unlikely(sret < 0)) {
|
||||
|
||||
if (likely(errno == EINTR)) goto restart_select;
|
||||
|
||||
*buf = -1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
ssize_t len_read = read(fd, ((u8 *)buf), len);
|
||||
if (len_read < len) { return 0; }
|
||||
|
||||
#if defined(__linux__)
|
||||
u32 exec_ms =
|
||||
MIN(timeout_ms,
|
||||
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
|
||||
#else
|
||||
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
|
||||
#endif
|
||||
|
||||
// ensure to report 1 ms has passed (0 is an error)
|
||||
return exec_ms > 0 ? exec_ms : 1;
|
||||
return 0; // not reached
|
||||
|
||||
}
|
||||
|
||||
@ -400,9 +418,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
close(fsrv->out_dir_fd);
|
||||
close(fsrv->dev_null_fd);
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
close(fsrv->dev_urandom_fd);
|
||||
#endif
|
||||
|
||||
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
|
||||
|
||||
/* This should improve performance a bit, since it stops the linker from
|
||||
@ -445,6 +462,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
/* PARENT PROCESS */
|
||||
|
||||
char pid_buf[16];
|
||||
sprintf(pid_buf, "%d", fsrv->fsrv_pid);
|
||||
if (fsrv->cmplog_binary)
|
||||
setenv("__AFL_TARGET_PID2", pid_buf, 1);
|
||||
else
|
||||
setenv("__AFL_TARGET_PID1", pid_buf, 1);
|
||||
|
||||
/* Close the unneeded endpoints. */
|
||||
|
||||
close(ctl_pipe[0]);
|
||||
@ -545,7 +569,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
if (unlikely(tmp_map_size % 8)) {
|
||||
|
||||
// should not happen
|
||||
WARNF("Target reported non-aligned map size of %ud", tmp_map_size);
|
||||
WARNF("Target reported non-aligned map size of %u", tmp_map_size);
|
||||
tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
|
||||
|
||||
}
|
||||
@ -572,9 +596,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
// this is not afl-fuzz - we deny and return
|
||||
if (fsrv->use_shmem_fuzz)
|
||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
|
||||
status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
|
||||
else
|
||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
||||
status = (FS_OPT_ENABLED);
|
||||
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
|
||||
|
||||
FATAL("Writing to forkserver failed.");
|
||||
@ -586,7 +610,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
}
|
||||
|
||||
if (!be_quiet) { ACTF("Using AUTODICT feature."); }
|
||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
||||
|
||||
if (fsrv->use_shmem_fuzz)
|
||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
|
||||
else
|
||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
||||
|
||||
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
|
||||
|
||||
FATAL("Writing to forkserver failed.");
|
||||
@ -837,8 +866,23 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
||||
|
||||
*fsrv->shmem_fuzz_len = len;
|
||||
memcpy(fsrv->shmem_fuzz, buf, len);
|
||||
// printf("test case len: %u [0]:0x%02x\n", *fsrv->shmem_fuzz_len, buf[0]);
|
||||
// fflush(stdout);
|
||||
#ifdef _DEBUG
|
||||
if (getenv("AFL_DEBUG")) {
|
||||
|
||||
fprintf(stderr, "FS crc: %016llx len: %u\n",
|
||||
hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705),
|
||||
*fsrv->shmem_fuzz_len);
|
||||
fprintf(stderr, "SHM :");
|
||||
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
|
||||
fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]);
|
||||
fprintf(stderr, "\nORIG:");
|
||||
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
|
||||
fprintf(stderr, "%02x", buf[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -542,27 +542,35 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||
u8 hnb = '\0';
|
||||
s32 fd;
|
||||
u8 keeping = 0, res;
|
||||
u64 cksum = 0;
|
||||
|
||||
u8 fn[PATH_MAX];
|
||||
|
||||
/* Update path frequency. */
|
||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
struct queue_entry *q = afl->queue;
|
||||
while (q) {
|
||||
/* Generating a hash on every input is super expensive. Bad idea and should
|
||||
only be used for special schedules */
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||
|
||||
if (q->exec_cksum == cksum) {
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
q->n_fuzz = q->n_fuzz + 1;
|
||||
break;
|
||||
struct queue_entry *q = afl->queue;
|
||||
while (q) {
|
||||
|
||||
if (q->exec_cksum == cksum) {
|
||||
|
||||
++q->n_fuzz;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
q = q->next;
|
||||
|
||||
}
|
||||
|
||||
q = q->next;
|
||||
|
||||
}
|
||||
|
||||
if (unlikely(fault == afl->crash_mode)) {
|
||||
if (likely(fault == afl->crash_mode)) {
|
||||
|
||||
/* Keep only if there are new bits in the map, add to queue for
|
||||
future fuzzing, etc. */
|
||||
@ -595,7 +603,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||
|
||||
}
|
||||
|
||||
afl->queue_top->exec_cksum = cksum;
|
||||
if (cksum)
|
||||
afl->queue_top->exec_cksum = cksum;
|
||||
else
|
||||
afl->queue_top->exec_cksum =
|
||||
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
/* Try to calibrate inline; this also calls update_bitmap_score() when
|
||||
successful. */
|
||||
|
@ -37,6 +37,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
cpu_set_t c;
|
||||
#elif defined(__NetBSD__)
|
||||
cpuset_t * c;
|
||||
#elif defined(__sun)
|
||||
psetid_t c;
|
||||
#endif
|
||||
|
||||
u8 cpu_used[4096] = {0};
|
||||
@ -181,6 +183,56 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
}
|
||||
|
||||
ck_free(procs);
|
||||
#elif defined(__sun)
|
||||
kstat_named_t *n;
|
||||
kstat_ctl_t * m;
|
||||
kstat_t * k;
|
||||
cpu_stat_t cs;
|
||||
u32 ncpus;
|
||||
|
||||
m = kstat_open();
|
||||
|
||||
if (!m) FATAL("kstat_open failed");
|
||||
|
||||
k = kstat_lookup(m, "unix", 0, "system_misc");
|
||||
|
||||
if (!k) {
|
||||
|
||||
kstat_close(m);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (kstat_read(m, k, NULL)) {
|
||||
|
||||
kstat_close(m);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
n = kstat_data_lookup(k, "ncpus");
|
||||
ncpus = n->value.i32;
|
||||
|
||||
if (ncpus > sizeof(cpu_used)) ncpus = sizeof(cpu_used);
|
||||
|
||||
for (i = 0; i < ncpus; i++) {
|
||||
|
||||
k = kstat_lookup(m, "cpu_stat", i, NULL);
|
||||
if (kstat_read(m, k, &cs)) {
|
||||
|
||||
kstat_close(m);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (cs.cpu_sysinfo.cpu[CPU_IDLE] > 0) continue;
|
||||
|
||||
if (cs.cpu_sysinfo.cpu[CPU_USER] > 0 || cs.cpu_sysinfo.cpu[CPU_KERNEL] > 0)
|
||||
cpu_used[i] = 1;
|
||||
|
||||
}
|
||||
|
||||
kstat_close(m);
|
||||
#else
|
||||
#warning \
|
||||
"For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus"
|
||||
@ -189,7 +241,7 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
size_t cpu_start = 0;
|
||||
|
||||
try:
|
||||
#ifndef __ANDROID__
|
||||
#if !defined(__ANDROID__)
|
||||
for (i = cpu_start; i < afl->cpu_core_count; i++) {
|
||||
|
||||
if (!cpu_used[i]) { break; }
|
||||
@ -228,6 +280,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
c = cpuset_create();
|
||||
if (c == NULL) PFATAL("cpuset_create failed");
|
||||
cpuset_set(i, c);
|
||||
#elif defined(__sun)
|
||||
pset_create(&c);
|
||||
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
@ -271,6 +326,19 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) {
|
||||
}
|
||||
|
||||
cpuset_destroy(c);
|
||||
#elif defined(__sun)
|
||||
if (pset_bind(c, P_PID, getpid(), NULL)) {
|
||||
|
||||
if (cpu_start == afl->cpu_core_count)
|
||||
PFATAL("pset_bind failed for cpu %d, exit", i);
|
||||
WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i);
|
||||
cpu_start++;
|
||||
goto try
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
pset_destroy(c);
|
||||
#else
|
||||
// this will need something for other platforms
|
||||
// TODO: Solaris/Illumos has processor_bind ... might worth a try
|
||||
@ -1473,10 +1541,8 @@ void setup_dirs_fds(afl_state_t *afl) {
|
||||
afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR);
|
||||
if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||
#endif
|
||||
|
||||
/* Gnuplot output file. */
|
||||
|
||||
@ -2062,14 +2128,17 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
|
||||
/* Check for blatant user errors. */
|
||||
|
||||
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
|
||||
!strchr(afl->fsrv.target_path + 5, '/')) ||
|
||||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
|
||||
!strchr(afl->fsrv.target_path + 9, '/'))) {
|
||||
/* disabled. not a real-worl scenario where this is a problem.
|
||||
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
|
||||
!strchr(afl->fsrv.target_path + 5, '/')) ||
|
||||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
|
||||
!strchr(afl->fsrv.target_path + 9, '/'))) {
|
||||
|
||||
FATAL("Please don't keep binaries in /tmp or /var/tmp");
|
||||
FATAL("Please don't keep binaries in /tmp or /var/tmp");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
fd = open(afl->fsrv.target_path, O_RDONLY);
|
||||
|
||||
|
@ -44,7 +44,7 @@ void setup_custom_mutators(afl_state_t *afl) {
|
||||
FATAL(
|
||||
"MOpt and custom mutator are mutually exclusive. We accept pull "
|
||||
"requests that integrates MOpt with the optional mutators "
|
||||
"(custom/radamsa/redqueen/...).");
|
||||
"(custom/redqueen/...).");
|
||||
|
||||
u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
|
||||
|
||||
@ -89,7 +89,7 @@ void setup_custom_mutators(afl_state_t *afl) {
|
||||
FATAL(
|
||||
"MOpt and Python mutator are mutually exclusive. We accept pull "
|
||||
"requests that integrates MOpt with the optional mutators "
|
||||
"(custom/radamsa/redqueen/...).");
|
||||
"(custom/redqueen/...).");
|
||||
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
||||
sprintf(afl->stage_name_buf, "ptrim %s",
|
||||
u_stringify_int(val_buf, trim_exec));
|
||||
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
|
||||
size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
|
||||
|
||||
@ -295,7 +295,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
||||
|
||||
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
||||
|
||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
if (cksum == q->exec_cksum) {
|
||||
|
||||
|
@ -29,10 +29,14 @@
|
||||
|
||||
static int select_algorithm(afl_state_t *afl) {
|
||||
|
||||
int i_puppet, j_puppet;
|
||||
int i_puppet, j_puppet = 0, operator_number = operator_num;
|
||||
|
||||
if (!afl->extras_cnt && !afl->a_extras_cnt) operator_number -= 2;
|
||||
|
||||
double range_sele =
|
||||
(double)afl->probability_now[afl->swarm_now][operator_number - 1];
|
||||
double sele = ((double)(rand_below(afl, 10000) * 0.0001 * range_sele));
|
||||
|
||||
double sele = ((double)(rand_below(afl, 10000)) * 0.0001);
|
||||
j_puppet = 0;
|
||||
for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
|
||||
|
||||
if (unlikely(i_puppet == 0)) {
|
||||
@ -52,8 +56,10 @@ static int select_algorithm(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
if (j_puppet == 1 &&
|
||||
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) {
|
||||
if ((j_puppet == 1 &&
|
||||
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) ||
|
||||
(i_puppet + 1 < operator_num &&
|
||||
sele > afl->probability_now[afl->swarm_now][i_puppet + 1])) {
|
||||
|
||||
FATAL("error select_algorithm");
|
||||
|
||||
@ -364,8 +370,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
s32 len, fd, temp_len, i, j;
|
||||
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
||||
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt;
|
||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
|
||||
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum;
|
||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
|
||||
|
||||
u8 ret_val = 1, doing_det = 0;
|
||||
|
||||
@ -488,6 +494,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
if (afl->queue_cur->cal_failed < CAL_CHANCES) {
|
||||
|
||||
afl->queue_cur->exec_cksum = 0;
|
||||
|
||||
res =
|
||||
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
|
||||
|
||||
@ -548,8 +556,6 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
if (unlikely(perf_score == 0)) { goto abandon_entry; }
|
||||
|
||||
if (unlikely(afl->use_radamsa > 1)) { goto radamsa_stage; }
|
||||
|
||||
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
|
||||
|
||||
if (input_to_state_stage(afl, in_buf, out_buf, len,
|
||||
@ -566,12 +572,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
if it has gone through deterministic testing in earlier, resumed runs
|
||||
(passed_det). */
|
||||
|
||||
if (afl->skip_deterministic ||
|
||||
((!afl->queue_cur->passed_det) &&
|
||||
perf_score < (afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
||||
? afl->queue_cur->depth * 30
|
||||
: afl->havoc_max_mult * 100)) ||
|
||||
afl->queue_cur->passed_det) {
|
||||
if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
|
||||
likely(perf_score <
|
||||
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
||||
? afl->queue_cur->depth * 30
|
||||
: afl->havoc_max_mult * 100))) {
|
||||
|
||||
goto custom_mutator_stage;
|
||||
|
||||
@ -653,7 +658,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
||||
|
||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
||||
|
||||
@ -821,14 +826,14 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
||||
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
|
||||
/* If in non-instrumented mode or if the file is very short, just flag
|
||||
everything without wasting time on checksums. */
|
||||
|
||||
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
||||
|
||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
} else {
|
||||
|
||||
@ -1680,6 +1685,7 @@ custom_mutator_stage:
|
||||
|
||||
retry_external_pick:
|
||||
/* Pick a random other queue entry for passing to external API */
|
||||
|
||||
do {
|
||||
|
||||
tid = rand_below(afl, afl->queued_paths);
|
||||
@ -1704,7 +1710,7 @@ custom_mutator_stage:
|
||||
/* Make sure that the target has a reasonable length. */
|
||||
|
||||
while (target && (target->len < 2 || target == afl->queue_cur) &&
|
||||
afl->queued_paths > 1) {
|
||||
afl->queued_paths > 3) {
|
||||
|
||||
target = target->next;
|
||||
++afl->splicing_with;
|
||||
@ -2230,7 +2236,7 @@ havoc_stage:
|
||||
case 16: {
|
||||
|
||||
u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1);
|
||||
u8 *new_buf;
|
||||
u8 *ptr;
|
||||
|
||||
/* Insert an extra. Do the same dice-rolling stuff as for the
|
||||
previous case. */
|
||||
@ -2239,44 +2245,27 @@ havoc_stage:
|
||||
|
||||
use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||
extra_len = afl->a_extras[use_extra].len;
|
||||
|
||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||
|
||||
new_buf =
|
||||
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
|
||||
|
||||
/* Head */
|
||||
memcpy(new_buf, out_buf, insert_at);
|
||||
|
||||
/* Inserted part */
|
||||
memcpy(new_buf + insert_at, afl->a_extras[use_extra].data,
|
||||
extra_len);
|
||||
ptr = afl->a_extras[use_extra].data;
|
||||
|
||||
} else {
|
||||
|
||||
use_extra = rand_below(afl, afl->extras_cnt);
|
||||
extra_len = afl->extras[use_extra].len;
|
||||
|
||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||
|
||||
new_buf =
|
||||
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
|
||||
|
||||
/* Head */
|
||||
memcpy(new_buf, out_buf, insert_at);
|
||||
|
||||
/* Inserted part */
|
||||
memcpy(new_buf + insert_at, afl->extras[use_extra].data, extra_len);
|
||||
ptr = afl->extras[use_extra].data;
|
||||
|
||||
}
|
||||
|
||||
/* Tail */
|
||||
memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,
|
||||
temp_len - insert_at);
|
||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||
|
||||
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||
|
||||
/* Tail */
|
||||
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
||||
temp_len - insert_at);
|
||||
|
||||
/* Inserted part */
|
||||
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||
|
||||
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
|
||||
out_buf = new_buf;
|
||||
new_buf = NULL;
|
||||
temp_len += extra_len;
|
||||
|
||||
break;
|
||||
@ -2438,63 +2427,6 @@ retry_splicing:
|
||||
#endif /* !IGNORE_FINDS */
|
||||
|
||||
ret_val = 0;
|
||||
goto radamsa_stage;
|
||||
|
||||
radamsa_stage:
|
||||
|
||||
if (likely(!afl->use_radamsa || !afl->radamsa_mutate_ptr)) {
|
||||
|
||||
goto abandon_entry;
|
||||
|
||||
}
|
||||
|
||||
afl->stage_name = "radamsa";
|
||||
afl->stage_short = "radamsa";
|
||||
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100)
|
||||
<< afl->use_radamsa;
|
||||
|
||||
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
||||
|
||||
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||
|
||||
/* Read the additional testcase.
|
||||
We'll reuse in_scratch, as it is free at this point.
|
||||
*/
|
||||
u8 *save_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), len);
|
||||
memcpy(save_buf, out_buf, len);
|
||||
|
||||
u32 max_len = len + choose_block_len(afl, HAVOC_BLK_XL);
|
||||
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), max_len);
|
||||
u8 *tmp_buf;
|
||||
|
||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||
|
||||
u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
|
||||
get_rand_seed(afl));
|
||||
|
||||
if (new_len) {
|
||||
|
||||
temp_len = new_len;
|
||||
tmp_buf = new_buf;
|
||||
|
||||
} else {
|
||||
|
||||
tmp_buf = save_buf; // nope but I dont care
|
||||
temp_len = len;
|
||||
|
||||
}
|
||||
|
||||
if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; }
|
||||
|
||||
}
|
||||
|
||||
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||
|
||||
afl->stage_finds[STAGE_RADAMSA] += new_hit_cnt - orig_hit_cnt;
|
||||
afl->stage_cycles[STAGE_RADAMSA] += afl->stage_max;
|
||||
|
||||
ret_val = 0;
|
||||
goto abandon_entry;
|
||||
|
||||
/* we are through with this queue entry - for this iteration */
|
||||
abandon_entry:
|
||||
@ -2539,8 +2471,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
||||
|
||||
s32 len, fd, temp_len, i, j;
|
||||
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
||||
u64 havoc_queued, orig_hit_cnt, new_hit_cnt, cur_ms_lv;
|
||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
|
||||
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum;
|
||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
|
||||
|
||||
u8 ret_val = 1, doing_det = 0;
|
||||
|
||||
@ -2637,6 +2569,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
||||
|
||||
if (afl->queue_cur->cal_failed < CAL_CHANCES) {
|
||||
|
||||
afl->queue_cur->exec_cksum = 0;
|
||||
|
||||
res =
|
||||
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
|
||||
|
||||
@ -2806,7 +2740,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
||||
|
||||
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
||||
|
||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
||||
|
||||
@ -2974,14 +2908,14 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
||||
|
||||
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
||||
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
|
||||
/* If in non-instrumented mode or if the file is very short, just flag
|
||||
everything without wasting time on checksums. */
|
||||
|
||||
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
||||
|
||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
} else {
|
||||
|
||||
@ -4208,6 +4142,94 @@ pacemaker_fuzzing:
|
||||
|
||||
} /* case 15 */
|
||||
|
||||
/* Values 16 and 17 can be selected only if there are any extras
|
||||
present in the dictionaries. */
|
||||
|
||||
case 16: {
|
||||
|
||||
/* Overwrite bytes with an extra. */
|
||||
|
||||
if (!afl->extras_cnt ||
|
||||
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||
|
||||
/* No user-specified extras or odds in our favor. Let's use an
|
||||
auto-detected one. */
|
||||
|
||||
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||
u32 extra_len = afl->a_extras[use_extra].len;
|
||||
|
||||
if (extra_len > temp_len) break;
|
||||
|
||||
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
|
||||
extra_len);
|
||||
|
||||
} else {
|
||||
|
||||
/* No auto extras or odds in our favor. Use the dictionary. */
|
||||
|
||||
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||
u32 extra_len = afl->extras[use_extra].len;
|
||||
|
||||
if (extra_len > temp_len) break;
|
||||
|
||||
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
||||
extra_len);
|
||||
|
||||
}
|
||||
|
||||
afl->stage_cycles_puppet_v2[afl->swarm_now]
|
||||
[STAGE_OverWriteExtra] += 1;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Insert an extra. */
|
||||
|
||||
case 17: {
|
||||
|
||||
u32 use_extra, extra_len,
|
||||
insert_at = rand_below(afl, temp_len + 1);
|
||||
u8 *ptr;
|
||||
|
||||
/* Insert an extra. Do the same dice-rolling stuff as for the
|
||||
previous case. */
|
||||
|
||||
if (!afl->extras_cnt ||
|
||||
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||
|
||||
use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||
extra_len = afl->a_extras[use_extra].len;
|
||||
ptr = afl->a_extras[use_extra].data;
|
||||
|
||||
} else {
|
||||
|
||||
use_extra = rand_below(afl, afl->extras_cnt);
|
||||
extra_len = afl->extras[use_extra].len;
|
||||
ptr = afl->extras[use_extra].data;
|
||||
|
||||
}
|
||||
|
||||
if (temp_len + extra_len >= MAX_FILE) break;
|
||||
|
||||
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||
|
||||
/* Tail */
|
||||
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
||||
temp_len - insert_at);
|
||||
|
||||
/* Inserted part */
|
||||
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||
|
||||
temp_len += extra_len;
|
||||
afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_InsertExtra] +=
|
||||
1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} /* switch select_algorithm() */
|
||||
|
||||
} /* for i=0; i < use_stacking */
|
||||
|
@ -194,10 +194,14 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
u32 i;
|
||||
u64 fav_factor;
|
||||
u64 fuzz_p2 = next_pow2(q->n_fuzz);
|
||||
u64 fuzz_p2;
|
||||
|
||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||
unlikely(afl->fixed_seed)) {
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
|
||||
fuzz_p2 = next_pow2(q->n_fuzz);
|
||||
else
|
||||
fuzz_p2 = q->fuzz_level;
|
||||
|
||||
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||
|
||||
fav_factor = q->len << 2;
|
||||
|
||||
@ -217,10 +221,13 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
/* Faster-executing or smaller test cases are favored. */
|
||||
u64 top_rated_fav_factor;
|
||||
u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
|
||||
u64 top_rated_fuzz_p2;
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
|
||||
top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
|
||||
else
|
||||
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
|
||||
|
||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||
unlikely(afl->fixed_seed)) {
|
||||
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||
|
||||
top_rated_fav_factor = afl->top_rated[i]->len << 2;
|
||||
|
||||
@ -241,8 +248,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||
unlikely(afl->fixed_seed)) {
|
||||
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||
|
||||
if (fav_factor > afl->top_rated[i]->len << 2) { continue; }
|
||||
|
||||
@ -387,8 +393,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
// Longer execution time means longer work on the input, the deeper in
|
||||
// coverage, the better the fuzzing, right? -mh
|
||||
|
||||
if (afl->schedule != MMOPT && afl->schedule != RARE &&
|
||||
likely(!afl->fixed_seed)) {
|
||||
if (afl->schedule >= RARE && likely(!afl->fixed_seed)) {
|
||||
|
||||
if (q->exec_us * 0.1 > avg_exec_us) {
|
||||
|
||||
@ -500,6 +505,9 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
case EXPLORE:
|
||||
break;
|
||||
|
||||
case SEEK:
|
||||
break;
|
||||
|
||||
case EXPLOIT:
|
||||
factor = MAX_FACTOR;
|
||||
break;
|
||||
@ -593,9 +601,12 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
}
|
||||
|
||||
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||
|
||||
perf_score *= factor / POWER_BETA;
|
||||
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
|
||||
perf_score *= factor / POWER_BETA;
|
||||
|
||||
}
|
||||
|
||||
// MOpt mode
|
||||
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) {
|
||||
|
@ -89,11 +89,11 @@ static struct range *pop_biggest_range(struct range **ranges) {
|
||||
|
||||
}
|
||||
|
||||
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
|
||||
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
|
||||
|
||||
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
|
||||
|
||||
*cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
*cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
return 0;
|
||||
|
||||
}
|
||||
@ -109,7 +109,7 @@ static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
|
||||
|
||||
}
|
||||
|
||||
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
||||
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
||||
|
||||
struct range *ranges = add_range(NULL, 0, len);
|
||||
u8 * backup = ck_alloc_nozero(len);
|
||||
@ -137,7 +137,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
||||
memcpy(backup, buf + rng->start, s);
|
||||
rand_replace(afl, buf + rng->start, s);
|
||||
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
u64 start_us = get_cur_time_us();
|
||||
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
|
||||
|
||||
@ -180,7 +180,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
||||
while (ranges) {
|
||||
|
||||
rng = ranges;
|
||||
ranges = ranges->next;
|
||||
ranges = rng->next;
|
||||
ck_free(rng);
|
||||
rng = NULL;
|
||||
|
||||
@ -224,7 +224,7 @@ checksum_fail:
|
||||
while (ranges) {
|
||||
|
||||
rng = ranges;
|
||||
ranges = ranges->next;
|
||||
ranges = rng->next;
|
||||
ck_free(rng);
|
||||
rng = NULL;
|
||||
|
||||
@ -695,7 +695,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
||||
|
||||
// afl->queue_cur->exec_cksum
|
||||
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
||||
u32 exec_cksum) {
|
||||
u64 exec_cksum) {
|
||||
|
||||
u8 r = 1;
|
||||
if (afl->orig_cmp_map == NULL) {
|
||||
|
@ -142,7 +142,41 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
|
||||
s32 fd = afl->fsrv.out_fd;
|
||||
u32 tail_len = len - skip_at - skip_len;
|
||||
|
||||
if (afl->fsrv.out_file) {
|
||||
if (afl->fsrv.shmem_fuzz) {
|
||||
|
||||
if (skip_at) { memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); }
|
||||
|
||||
if (tail_len) {
|
||||
|
||||
memcpy(afl->fsrv.shmem_fuzz + skip_at, (u8 *)mem + skip_at + skip_len,
|
||||
tail_len);
|
||||
|
||||
}
|
||||
|
||||
*afl->fsrv.shmem_fuzz_len = len - skip_len;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (afl->debug) {
|
||||
|
||||
fprintf(
|
||||
stderr, "FS crc: %16llx len: %u\n",
|
||||
hash64(afl->fsrv.shmem_fuzz, *afl->fsrv.shmem_fuzz_len, 0xa5b35705),
|
||||
*afl->fsrv.shmem_fuzz_len);
|
||||
fprintf(stderr, "SHM :");
|
||||
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
|
||||
fprintf(stderr, "%02x", afl->fsrv.shmem_fuzz[i]);
|
||||
fprintf(stderr, "\nORIG:");
|
||||
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
|
||||
fprintf(stderr, "%02x", (u8)((u8 *)mem)[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
} else if (afl->fsrv.out_file) {
|
||||
|
||||
if (afl->no_unlink) {
|
||||
|
||||
@ -234,6 +268,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
|
||||
if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
|
||||
|
||||
unsetenv(SHM_FUZZ_ENV_VAR);
|
||||
afl_shm_deinit(afl->shm_fuzz);
|
||||
ck_free(afl->shm_fuzz);
|
||||
afl->shm_fuzz = NULL;
|
||||
@ -256,13 +291,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
|
||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||
|
||||
u32 cksum;
|
||||
|
||||
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) {
|
||||
|
||||
show_stats(afl);
|
||||
|
||||
}
|
||||
u64 cksum;
|
||||
|
||||
write_to_testcase(afl, use_mem, q->len);
|
||||
|
||||
@ -281,7 +310,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
|
||||
}
|
||||
|
||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
if (q->exec_cksum != cksum) {
|
||||
|
||||
hnb = has_new_bits(afl, afl->virgin_bits);
|
||||
@ -385,7 +414,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
DIR * sd;
|
||||
struct dirent *sd_ent;
|
||||
u32 sync_cnt = 0, synced = 0, entries = 0;
|
||||
u8 path[PATH_MAX];
|
||||
u8 path[PATH_MAX + 256];
|
||||
|
||||
sd = opendir(afl->sync_dir);
|
||||
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
|
||||
@ -399,7 +428,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
while ((sd_ent = readdir(sd))) {
|
||||
|
||||
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
|
||||
u32 min_accept = 0, next_min_accept;
|
||||
u32 min_accept = 0, next_min_accept = 0;
|
||||
|
||||
s32 id_fd;
|
||||
|
||||
@ -438,6 +467,12 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
synced++;
|
||||
|
||||
/* document the attempt to sync to this instance */
|
||||
|
||||
sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name);
|
||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
if (id_fd >= 0) close(id_fd);
|
||||
|
||||
/* Skip anything that doesn't have a queue/ subdirectory. */
|
||||
|
||||
sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name);
|
||||
@ -462,14 +497,13 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
|
||||
|
||||
if (read(id_fd, &min_accept, sizeof(u32)) > 0) {
|
||||
if (read(id_fd, &min_accept, sizeof(u32)) == sizeof(u32)) {
|
||||
|
||||
next_min_accept = min_accept;
|
||||
lseek(id_fd, 0, SEEK_SET);
|
||||
|
||||
}
|
||||
|
||||
next_min_accept = min_accept;
|
||||
|
||||
/* Show stats */
|
||||
|
||||
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt);
|
||||
@ -505,7 +539,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
s32 fd;
|
||||
struct stat st;
|
||||
|
||||
sprintf(path, "%s/%s", qd_path, namelist[o]->d_name);
|
||||
snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name);
|
||||
afl->syncing_case = next_min_accept;
|
||||
next_min_accept++;
|
||||
o--;
|
||||
@ -646,7 +680,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||
while (remove_pos < q->len) {
|
||||
|
||||
u32 trim_avail = MIN(remove_len, q->len - remove_pos);
|
||||
u32 cksum;
|
||||
u64 cksum;
|
||||
|
||||
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
|
||||
|
||||
@ -658,7 +692,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
|
||||
*/
|
||||
|
||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
/* If the deletion had no impact on the trace, make it permanent. This
|
||||
isn't perfect for variable-path inputs, but we're just making a
|
||||
|
@ -30,9 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
|
||||
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
|
||||
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
|
||||
|
||||
char *power_names[POWER_SCHEDULES_NUM] = {
|
||||
|
||||
"explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
|
||||
char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast",
|
||||
"coe", "lin", "quad",
|
||||
"rare", "mmopt", "seek"};
|
||||
|
||||
/* Initialize MOpt "globals" for this afl state */
|
||||
|
||||
@ -124,9 +124,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
||||
|
||||
afl->stats_update_freq = 1;
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
afl->fsrv.dev_urandom_fd = -1;
|
||||
#endif
|
||||
afl->fsrv.dev_null_fd = -1;
|
||||
|
||||
afl->fsrv.child_pid = -1;
|
||||
|
@ -31,7 +31,9 @@
|
||||
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
||||
double eps) {
|
||||
|
||||
#ifndef __HAIKU__
|
||||
struct rusage rus;
|
||||
#endif
|
||||
|
||||
unsigned long long int cur_time = get_cur_time();
|
||||
u8 fn[PATH_MAX];
|
||||
@ -65,7 +67,9 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
||||
|
||||
}
|
||||
|
||||
#ifndef __HAIKU__
|
||||
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
||||
#endif
|
||||
|
||||
fprintf(
|
||||
f,
|
||||
@ -119,12 +123,21 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
||||
afl->last_path_time / 1000, afl->last_crash_time / 1000,
|
||||
afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
|
||||
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
|
||||
#ifdef __APPLE__
|
||||
#ifndef __HAIKU__
|
||||
#ifdef __APPLE__
|
||||
(unsigned long int)(rus.ru_maxrss >> 20),
|
||||
#else
|
||||
#else
|
||||
(unsigned long int)(rus.ru_maxrss >> 10),
|
||||
#endif
|
||||
#else
|
||||
-1UL,
|
||||
#endif
|
||||
afl->cpu_aff, t_bytes, afl->var_byte_count, afl->use_banner,
|
||||
#ifdef HAVE_AFFINITY
|
||||
afl->cpu_aff,
|
||||
#else
|
||||
-1,
|
||||
#endif
|
||||
t_bytes, afl->var_byte_count, afl->use_banner,
|
||||
afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
|
||||
afl->non_instrumented_mode ? " non_instrumented " : "",
|
||||
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
|
||||
@ -181,7 +194,8 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
|
||||
afl->plot_prev_uc == afl->unique_crashes &&
|
||||
afl->plot_prev_uh == afl->unique_hangs &&
|
||||
afl->plot_prev_md == afl->max_depth) ||
|
||||
unlikely(!afl->queue_cycle)) {
|
||||
unlikely(!afl->queue_cycle) ||
|
||||
unlikely(get_cur_time() - afl->start_time <= 60)) {
|
||||
|
||||
return;
|
||||
|
||||
@ -732,15 +746,13 @@ void show_stats(afl_state_t *afl) {
|
||||
afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
|
||||
: (u8 *)"n/a");
|
||||
|
||||
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
||||
sprintf(tmp, "%s/%s, %s/%s",
|
||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
|
||||
u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
|
||||
u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
|
||||
u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]),
|
||||
u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
|
||||
u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
|
||||
u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]));
|
||||
|
||||
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
|
||||
SAYF(bV bSTOP "havoc/splice : " cRST "%-36s " bSTG bV bSTOP, tmp);
|
||||
|
||||
if (t_bytes) {
|
||||
|
||||
@ -821,18 +833,19 @@ void show_stats(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->custom_mutators_count) {
|
||||
// if (afl->custom_mutators_count) {
|
||||
|
||||
sprintf(tmp, "%s/%s",
|
||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
|
||||
u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
|
||||
SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
|
||||
//
|
||||
// sprintf(tmp, "%s/%s",
|
||||
// u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
|
||||
// u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
|
||||
// SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
|
||||
//
|
||||
//} else {
|
||||
|
||||
} else {
|
||||
SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
|
||||
|
||||
SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
/* Provide some CPU utilization stats. */
|
||||
|
||||
|
206
src/afl-fuzz.c
206
src/afl-fuzz.c
@ -26,66 +26,53 @@
|
||||
#include "afl-fuzz.h"
|
||||
#include "cmplog.h"
|
||||
#include <limits.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
|
||||
#ifdef PROFILING
|
||||
extern u64 time_spent_working;
|
||||
#endif
|
||||
|
||||
static u8 *get_libradamsa_path(u8 *own_loc) {
|
||||
static void at_exit() {
|
||||
|
||||
u8 *tmp, *cp, *rsl, *own_copy;
|
||||
int i;
|
||||
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
|
||||
char *ptr = getenv("__AFL_TARGET_PID1");
|
||||
|
||||
tmp = getenv("AFL_PATH");
|
||||
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||
|
||||
if (tmp) {
|
||||
ptr = getenv("__AFL_TARGET_PID2");
|
||||
|
||||
cp = alloc_printf("%s/libradamsa.so", tmp);
|
||||
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||
|
||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", cp); }
|
||||
i = 0;
|
||||
while (list[i] != NULL) {
|
||||
|
||||
return cp;
|
||||
ptr = getenv(list[i]);
|
||||
|
||||
if (ptr && *ptr) {
|
||||
|
||||
#ifdef USEMMAP
|
||||
|
||||
shm_unlink(ptr);
|
||||
|
||||
#else
|
||||
|
||||
shmctl(atoi(ptr), IPC_RMID, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
cp = alloc_printf("%s/libradamsa.so", own_copy);
|
||||
ck_free(own_copy);
|
||||
|
||||
if (!access(cp, X_OK)) { return cp; }
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
}
|
||||
|
||||
if (!access(AFL_PATH "/libradamsa.so", X_OK)) {
|
||||
|
||||
return ck_strdup(AFL_PATH "/libradamsa.so");
|
||||
|
||||
}
|
||||
|
||||
if (!access(BIN_PATH "/libradamsa.so", X_OK)) {
|
||||
|
||||
return ck_strdup(BIN_PATH "/libradamsa.so");
|
||||
|
||||
}
|
||||
|
||||
SAYF(
|
||||
"\n" cLRD "[-] " cRST
|
||||
"Oops, unable to find the 'libradamsa.so' binary. The binary must be "
|
||||
"built\n"
|
||||
" separately using 'make radamsa'. If you already have the binary "
|
||||
"installed,\n you may need to specify AFL_PATH in the environment.\n");
|
||||
|
||||
FATAL("Failed to locate 'libradamsa.so'.");
|
||||
|
||||
}
|
||||
|
||||
/* Display usage hints. */
|
||||
@ -100,12 +87,13 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
||||
" -o dir - output directory for fuzzer findings\n\n"
|
||||
|
||||
"Execution control settings:\n"
|
||||
" -p schedule - power schedules recompute a seed's performance "
|
||||
"score.\n"
|
||||
" <explore(default), fast, coe, lin, quad, exploit, "
|
||||
"mmopt, rare>\n"
|
||||
" -p schedule - power schedules compute a seed's performance score. "
|
||||
"<explore\n"
|
||||
" (default), fast, coe, lin, quad, exploit, mmopt, "
|
||||
"rare, seek>\n"
|
||||
" see docs/power_schedules.md\n"
|
||||
" -f file - location read by the fuzzed program (stdin)\n"
|
||||
" -f file - location read by the fuzzed program (default: stdin "
|
||||
"or @@)\n"
|
||||
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
|
||||
" -m megs - memory limit for child process (%d MB)\n"
|
||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||
@ -114,8 +102,6 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
||||
"mode)\n\n"
|
||||
|
||||
"Mutator settings:\n"
|
||||
" -R[R] - add Radamsa as mutator, add another -R to exclusivly "
|
||||
"run it\n"
|
||||
" -L minutes - use MOpt(imize) mode and set the time limit for "
|
||||
"entering the\n"
|
||||
" pacemaker mode (minutes of no new paths). 0 = "
|
||||
@ -131,7 +117,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
||||
"devices etc.!)\n"
|
||||
" -d - quick & dirty mode (skips deterministic steps)\n"
|
||||
" -n - fuzz without instrumentation (non-instrumented mode)\n"
|
||||
" -x dir - optional fuzzer dictionary (see README.md, its really "
|
||||
" -x dict_file - optional fuzzer dictionary (see README.md, its really "
|
||||
"good!)\n\n"
|
||||
|
||||
"Testing settings:\n"
|
||||
@ -144,14 +130,16 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
||||
|
||||
"Other stuff:\n"
|
||||
" -T text - text banner to show on the screen\n"
|
||||
" -M / -S id - distributed mode (see docs/parallel_fuzzing.md)\n"
|
||||
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
|
||||
" use -D to force -S secondary to perform deterministic "
|
||||
"fuzzing\n"
|
||||
" -I command - execute this command/script when a new crash is "
|
||||
"found\n"
|
||||
" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap "
|
||||
"file\n"
|
||||
//" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
|
||||
//" "file\n"
|
||||
" -C - crash exploration mode (the peruvian rabbit thing)\n"
|
||||
" -e ext - file extension for the temporarily generated test "
|
||||
"case\n\n",
|
||||
" -e ext - file extension for the fuzz test input file (if "
|
||||
"needed)\n\n",
|
||||
argv0, EXEC_TIMEOUT, MEM_LIMIT);
|
||||
|
||||
if (more_help > 1) {
|
||||
@ -231,7 +219,7 @@ static int stricmp(char const *a, char const *b) {
|
||||
for (;; ++a, ++b) {
|
||||
|
||||
int d;
|
||||
d = tolower(*a) - tolower(*b);
|
||||
d = tolower((int)*a) - tolower((int)*b);
|
||||
if (d != 0 || !*a) { return d; }
|
||||
|
||||
}
|
||||
@ -274,10 +262,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
||||
rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
|
||||
|
||||
while ((opt = getopt(argc, argv,
|
||||
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
|
||||
"+c:i:I:o:f:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
|
||||
0) {
|
||||
|
||||
switch (opt) {
|
||||
@ -296,7 +284,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
case 's': {
|
||||
|
||||
afl->init_seed = strtoul(optarg, 0L, 10);
|
||||
rand_set_seed(afl, strtoul(optarg, 0L, 10));
|
||||
afl->fixed_seed = 1;
|
||||
break;
|
||||
|
||||
@ -332,6 +320,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
afl->schedule = RARE;
|
||||
|
||||
} else if (!stricmp(optarg, "seek")) {
|
||||
|
||||
afl->schedule = SEEK;
|
||||
|
||||
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
|
||||
|
||||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
|
||||
@ -369,7 +361,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
afl->out_dir = optarg;
|
||||
break;
|
||||
|
||||
case 'M': { /* master sync ID */
|
||||
case 'M': { /* main sync ID */
|
||||
|
||||
u8 *c;
|
||||
|
||||
@ -398,7 +390,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'S': /* secondary sync id */
|
||||
|
||||
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
|
||||
afl->sync_id = ck_strdup(optarg);
|
||||
@ -503,6 +495,11 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
break;
|
||||
|
||||
case 'D': /* enforce deterministic */
|
||||
|
||||
afl->skip_deterministic = 0;
|
||||
break;
|
||||
|
||||
case 'd': /* skip deterministic */
|
||||
|
||||
afl->skip_deterministic = 1;
|
||||
@ -767,15 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
case 'R':
|
||||
|
||||
if (afl->use_radamsa) {
|
||||
|
||||
afl->use_radamsa = 2;
|
||||
|
||||
} else {
|
||||
|
||||
afl->use_radamsa = 1;
|
||||
|
||||
}
|
||||
FATAL(
|
||||
"Radamsa is now a custom mutator, please use that "
|
||||
"(custom_mutators/radamsa/).");
|
||||
|
||||
break;
|
||||
|
||||
@ -808,8 +799,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
WARNF(
|
||||
"Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
|
||||
"will "
|
||||
"result in no deterministic mutations being done!");
|
||||
"will result in no deterministic mutations being done!");
|
||||
|
||||
}
|
||||
|
||||
@ -819,50 +809,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
srandom((u32)afl->init_seed);
|
||||
srand((u32)afl->init_seed); // in case it is a different implementation
|
||||
|
||||
if (afl->use_radamsa) {
|
||||
|
||||
if (afl->limit_time_sig > 0) {
|
||||
|
||||
FATAL(
|
||||
"MOpt and Radamsa are mutually exclusive unless you specify -L -1. "
|
||||
"We accept pull requests that integrates MOpt with the optional "
|
||||
"mutators (custom/radamsa/redqueen/...).");
|
||||
|
||||
}
|
||||
|
||||
if (afl->limit_time_sig && afl->use_radamsa > 1) {
|
||||
|
||||
FATAL("Radamsa in radamsa-only mode can not run together with -L");
|
||||
|
||||
}
|
||||
|
||||
OKF("Using Radamsa add-on");
|
||||
|
||||
u8 * libradamsa_path = get_libradamsa_path(argv[0]);
|
||||
void *handle = dlopen(libradamsa_path, RTLD_NOW);
|
||||
ck_free(libradamsa_path);
|
||||
|
||||
if (!handle) { FATAL("Failed to dlopen() libradamsa"); }
|
||||
|
||||
void (*radamsa_init_ptr)(void) = dlsym(handle, "radamsa_init");
|
||||
afl->radamsa_mutate_ptr = dlsym(handle, "radamsa");
|
||||
|
||||
if (!radamsa_init_ptr || !afl->radamsa_mutate_ptr) {
|
||||
|
||||
FATAL("Failed to dlsym() libradamsa");
|
||||
|
||||
}
|
||||
|
||||
/* radamsa_init installs some signal handlers, call it before
|
||||
setup_signal_handlers so that AFL++ can then replace those signal
|
||||
handlers */
|
||||
radamsa_init_ptr();
|
||||
|
||||
}
|
||||
|
||||
#if defined(__SANITIZE_ADDRESS__)
|
||||
if (afl->fsrv.mem_limit) {
|
||||
|
||||
@ -936,6 +882,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
case RARE:
|
||||
OKF("Using rare edge focus power schedule (RARE)");
|
||||
break;
|
||||
case SEEK:
|
||||
OKF("Using seek power schedule (SEEK)");
|
||||
break;
|
||||
case EXPLORE:
|
||||
OKF("Using exploration-based constant power schedule (EXPLORE, default)");
|
||||
break;
|
||||
@ -1071,6 +1020,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
check_crash_handling();
|
||||
check_cpu_governor(afl);
|
||||
|
||||
atexit(at_exit);
|
||||
|
||||
afl->fsrv.trace_bits =
|
||||
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
|
||||
|
||||
@ -1082,7 +1033,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (afl->is_main_node && check_main_node_exists(afl) == 1) {
|
||||
|
||||
WARNF("it is wasteful to run more than one master!");
|
||||
WARNF("it is wasteful to run more than one main node!");
|
||||
sleep(1);
|
||||
|
||||
}
|
||||
@ -1327,7 +1278,15 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) {
|
||||
|
||||
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
|
||||
if (unlikely(afl->is_main_node)) {
|
||||
|
||||
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); }
|
||||
|
||||
} else {
|
||||
|
||||
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1396,10 +1355,13 @@ stop_fuzzing:
|
||||
destroy_queue(afl);
|
||||
destroy_extras(afl);
|
||||
destroy_custom_mutators(afl);
|
||||
unsetenv(SHM_ENV_VAR);
|
||||
unsetenv(CMPLOG_SHM_ENV_VAR);
|
||||
afl_shm_deinit(&afl->shm);
|
||||
|
||||
if (afl->shm_fuzz) {
|
||||
|
||||
unsetenv(SHM_FUZZ_ENV_VAR);
|
||||
afl_shm_deinit(afl->shm_fuzz);
|
||||
ck_free(afl->shm_fuzz);
|
||||
|
||||
|
@ -335,7 +335,7 @@ static void edit_params(u32 argc, char **argv) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef USEMMAP
|
||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||
cc_params[cc_par_cnt++] = "-lrt";
|
||||
#endif
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||
defined(__APPLE__) || defined(__DragonFly__)
|
||||
defined(__APPLE__) || defined(__DragonFly__) || defined(__sun)
|
||||
#define HAVE_AFFINITY 1
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#include <pthread.h>
|
||||
@ -70,6 +70,8 @@
|
||||
#include <pthread.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#elif defined(__sun)
|
||||
#include <sys/pset.h>
|
||||
#endif
|
||||
#endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */
|
||||
|
||||
@ -181,6 +183,12 @@ int main(int argc, char **argv) {
|
||||
if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY,
|
||||
(thread_policy_t)&c, 1) != KERN_SUCCESS)
|
||||
PFATAL("thread_policy_set failed");
|
||||
#elif defined(__sun)
|
||||
psetid_t c;
|
||||
|
||||
if (pset_create(&c)) PFATAL("pset_create failed");
|
||||
|
||||
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
@ -195,6 +203,12 @@ int main(int argc, char **argv) {
|
||||
cpuset_destroy(c);
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
if (pset_bind(c, P_PID, getpid(), NULL)) PFATAL("pset_bind failed");
|
||||
|
||||
pset_destroy(c);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
if (sched_setaffinity(0, sizeof(c), &c)) {
|
||||
|
||||
|
167
src/afl-performance.c
Normal file
167
src/afl-performance.c
Normal 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);
|
||||
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ static list_t shm_list = {.element_prealloc_count = 0};
|
||||
|
||||
void afl_shm_deinit(sharedmem_t *shm) {
|
||||
|
||||
if (shm == NULL) return;
|
||||
|
||||
list_remove(&shm_list, shm);
|
||||
|
||||
#ifdef USEMMAP
|
||||
@ -83,6 +85,38 @@ void afl_shm_deinit(sharedmem_t *shm) {
|
||||
|
||||
}
|
||||
|
||||
if (shm->g_shm_file_path[0]) {
|
||||
|
||||
shm_unlink(shm->g_shm_file_path);
|
||||
shm->g_shm_file_path[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
if (shm->cmp_map != NULL) {
|
||||
|
||||
munmap(shm->cmp_map, shm->map_size);
|
||||
shm->map = NULL;
|
||||
|
||||
}
|
||||
|
||||
if (shm->cmplog_g_shm_fd != -1) {
|
||||
|
||||
close(shm->cmplog_g_shm_fd);
|
||||
shm->cmplog_g_shm_fd = -1;
|
||||
|
||||
}
|
||||
|
||||
if (shm->cmplog_g_shm_file_path[0]) {
|
||||
|
||||
shm_unlink(shm->cmplog_g_shm_file_path);
|
||||
shm->cmplog_g_shm_file_path[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
shmctl(shm->shm_id, IPC_RMID, NULL);
|
||||
if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); }
|
||||
@ -99,13 +133,15 @@ void afl_shm_deinit(sharedmem_t *shm) {
|
||||
u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
unsigned char non_instrumented_mode) {
|
||||
|
||||
shm->map_size = map_size;
|
||||
shm->map_size = 0;
|
||||
|
||||
shm->map = NULL;
|
||||
shm->cmp_map = NULL;
|
||||
|
||||
#ifdef USEMMAP
|
||||
|
||||
shm->g_shm_fd = -1;
|
||||
shm->cmplog_g_shm_fd = -1;
|
||||
|
||||
/* ======
|
||||
generate random file name for multi instance
|
||||
@ -134,6 +170,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
close(shm->g_shm_fd);
|
||||
shm->g_shm_fd = -1;
|
||||
shm_unlink(shm->g_shm_file_path);
|
||||
shm->g_shm_file_path[0] = 0;
|
||||
PFATAL("mmap() failed");
|
||||
|
||||
}
|
||||
@ -145,13 +183,55 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
|
||||
|
||||
if (shm->map == -1 || !shm->map) PFATAL("mmap() failed");
|
||||
if (shm->map == (void *)-1 || !shm->map) PFATAL("mmap() failed");
|
||||
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
snprintf(shm->cmplog_g_shm_file_path, L_tmpnam, "/afl_cmplog_%d_%ld",
|
||||
getpid(), random());
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm->cmplog_g_shm_fd =
|
||||
shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
|
||||
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
|
||||
|
||||
/* configure the size of the shared memory segment */
|
||||
if (ftruncate(shm->cmplog_g_shm_fd, map_size)) {
|
||||
|
||||
PFATAL("setup_shm(): cmplog ftruncate() failed");
|
||||
|
||||
}
|
||||
|
||||
/* map the shared memory segment to the address space of the process */
|
||||
shm->cmp_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
shm->cmplog_g_shm_fd, 0);
|
||||
if (shm->map == MAP_FAILED) {
|
||||
|
||||
close(shm->cmplog_g_shm_fd);
|
||||
shm->cmplog_g_shm_fd = -1;
|
||||
shm_unlink(shm->cmplog_g_shm_file_path);
|
||||
shm->cmplog_g_shm_file_path[0] = 0;
|
||||
PFATAL("mmap() failed");
|
||||
|
||||
}
|
||||
|
||||
/* If somebody is asking us to fuzz instrumented binaries in
|
||||
non-instrumented mode, we don't want them to detect instrumentation,
|
||||
since we won't be sending fork server commands. This should be replaced
|
||||
with better auto-detection later on, perhaps? */
|
||||
|
||||
if (!non_instrumented_mode)
|
||||
setenv(CMPLOG_SHM_ENV_VAR, shm->cmplog_g_shm_file_path, 1);
|
||||
|
||||
if (shm->cmp_map == (void *)-1 || !shm->cmp_map)
|
||||
PFATAL("cmplog mmap() failed");
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
u8 *shm_str;
|
||||
|
||||
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
|
||||
|
||||
if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
|
||||
|
||||
if (shm->cmplog_mode) {
|
||||
@ -159,7 +239,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
|
||||
IPC_CREAT | IPC_EXCL | 0600);
|
||||
|
||||
if (shm->cmplog_shm_id < 0) { PFATAL("shmget() failed"); }
|
||||
if (shm->cmplog_shm_id < 0) {
|
||||
|
||||
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
|
||||
PFATAL("shmget() failed");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -186,7 +271,18 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
shm->map = shmat(shm->shm_id, NULL, 0);
|
||||
|
||||
if (shm->map == (void *)-1 || !shm->map) { PFATAL("shmat() failed"); }
|
||||
if (shm->map == (void *)-1 || !shm->map) {
|
||||
|
||||
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
|
||||
|
||||
}
|
||||
|
||||
PFATAL("shmat() failed");
|
||||
|
||||
}
|
||||
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
@ -194,6 +290,13 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
if (shm->cmp_map == (void *)-1 || !shm->cmp_map) {
|
||||
|
||||
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
|
||||
|
||||
}
|
||||
|
||||
PFATAL("shmat() failed");
|
||||
|
||||
}
|
||||
@ -202,6 +305,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
#endif
|
||||
|
||||
shm->map_size = map_size;
|
||||
list_append(&shm_list, shm);
|
||||
|
||||
return shm->map;
|
||||
|
@ -56,7 +56,9 @@
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
@ -80,11 +82,16 @@ static u8 quiet_mode, /* Hide non-essential messages? */
|
||||
raw_instr_output, /* Do not apply AFL filters */
|
||||
cmin_mode, /* Generate output in afl-cmin mode? */
|
||||
binary_mode, /* Write output as a binary map */
|
||||
keep_cores; /* Allow coredumps? */
|
||||
keep_cores, /* Allow coredumps? */
|
||||
remove_shm = 1; /* remove shmem? */
|
||||
|
||||
static volatile u8 stop_soon, /* Ctrl-C pressed? */
|
||||
child_crashed; /* Child crashed? */
|
||||
|
||||
static sharedmem_t shm;
|
||||
static afl_forkserver_t *fsrv;
|
||||
static sharedmem_t * shm_fuzz;
|
||||
|
||||
/* Classify tuple counts. Instead of mapping to individual bits, as in
|
||||
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
|
||||
|
||||
@ -139,12 +146,33 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
||||
|
||||
}
|
||||
|
||||
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
|
||||
sharedmem_t * shm_fuzz) {
|
||||
|
||||
afl_shm_deinit(shm_fuzz);
|
||||
fsrv->support_shmem_fuzz = 0;
|
||||
fsrv->shmem_fuzz_len = NULL;
|
||||
fsrv->shmem_fuzz = NULL;
|
||||
ck_free(shm_fuzz);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Get rid of temp files (atexit handler). */
|
||||
|
||||
static void at_exit_handler(void) {
|
||||
|
||||
if (stdin_file) { unlink(stdin_file); }
|
||||
|
||||
if (remove_shm) {
|
||||
|
||||
if (shm.map) afl_shm_deinit(&shm);
|
||||
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
}
|
||||
|
||||
afl_fsrv_killall();
|
||||
|
||||
}
|
||||
|
||||
/* Write results. */
|
||||
@ -557,7 +585,7 @@ static void usage(u8 *argv0) {
|
||||
"size\n"
|
||||
" the target was compiled for\n"
|
||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||
"AFL_QUIET: do not print extra informational output",
|
||||
"AFL_QUIET: do not print extra informational output\n",
|
||||
argv0, MEM_LIMIT, doc_path);
|
||||
|
||||
exit(1);
|
||||
@ -577,8 +605,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
char **argv = argv_cpy_dup(argc, argv_orig);
|
||||
|
||||
afl_forkserver_t fsrv_var = {0};
|
||||
afl_forkserver_t *fsrv = &fsrv_var;
|
||||
afl_forkserver_t fsrv_var = {0};
|
||||
fsrv = &fsrv_var;
|
||||
afl_fsrv_init(fsrv);
|
||||
map_size = get_map_size();
|
||||
fsrv->map_size = map_size;
|
||||
@ -773,7 +801,19 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
check_environment_vars(envp);
|
||||
|
||||
sharedmem_t shm = {0};
|
||||
if (getenv("AFL_DEBUG")) {
|
||||
|
||||
SAYF(cMGN "[D]" cRST);
|
||||
for (i = 0; i < argc; i++)
|
||||
SAYF(" %s", argv[i]);
|
||||
SAYF("\n");
|
||||
|
||||
}
|
||||
|
||||
// if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
shm.cmplog_mode = 0;
|
||||
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||
setup_signal_handlers();
|
||||
|
||||
@ -827,16 +867,36 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
shm_fuzz->cmplog_mode = 0;
|
||||
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
|
||||
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
|
||||
#ifdef USEMMAP
|
||||
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
|
||||
#else
|
||||
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
|
||||
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
|
||||
ck_free(shm_str);
|
||||
#endif
|
||||
fsrv->support_shmem_fuzz = 1;
|
||||
fsrv->shmem_fuzz_len = (u32 *)map;
|
||||
fsrv->shmem_fuzz = map + sizeof(u32);
|
||||
|
||||
if (in_dir) {
|
||||
|
||||
DIR * dir_in, *dir_out;
|
||||
struct dirent *dir_ent;
|
||||
int done = 0;
|
||||
u8 infile[PATH_MAX], outfile[PATH_MAX];
|
||||
u8 wait_for_gdb = 0;
|
||||
#if !defined(DT_REG)
|
||||
struct stat statbuf;
|
||||
#endif
|
||||
|
||||
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = 1;
|
||||
|
||||
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
||||
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||
|
||||
@ -895,6 +955,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
afl_fsrv_start(fsrv, use_argv, &stop_soon,
|
||||
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
|
||||
|
||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
while (done == 0 && (dir_ent = readdir(dir_in))) {
|
||||
|
||||
if (dir_ent->d_name[0] == '.') {
|
||||
@ -922,6 +985,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (read_file(infile)) {
|
||||
|
||||
if (wait_for_gdb) {
|
||||
|
||||
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
|
||||
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
|
||||
kill(0, SIGSTOP);
|
||||
|
||||
}
|
||||
|
||||
showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
|
||||
ck_free(in_data);
|
||||
tcnt = write_results_to_file(fsrv, outfile);
|
||||
@ -937,6 +1008,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
} else {
|
||||
|
||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
showmap_run_target(fsrv, use_argv);
|
||||
tcnt = write_results_to_file(fsrv, out_file);
|
||||
|
||||
@ -958,13 +1032,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
remove_shm = 0;
|
||||
afl_shm_deinit(&shm);
|
||||
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
|
||||
|
||||
if (fsrv->target_path) { ck_free(fsrv->target_path); }
|
||||
|
||||
afl_fsrv_deinit(fsrv);
|
||||
|
||||
if (stdin_file) { ck_free(stdin_file); }
|
||||
|
||||
argv_cpy_free(argv);
|
||||
|
@ -54,7 +54,9 @@
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/shm.h>
|
||||
#ifndef USEMMAP
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
@ -67,20 +69,27 @@ static u8 *in_file, /* Minimizer input test case */
|
||||
static u8 *in_data; /* Input data for trimming */
|
||||
|
||||
static u32 in_len, /* Input data length */
|
||||
orig_cksum, /* Original checksum */
|
||||
missed_hangs, /* Misses due to hangs */
|
||||
missed_crashes, /* Misses due to crashes */
|
||||
missed_paths, /* Misses due to exec path diffs */
|
||||
map_size = MAP_SIZE;
|
||||
|
||||
static u64 orig_cksum; /* Original checksum */
|
||||
|
||||
static u8 crash_mode, /* Crash-centric mode? */
|
||||
hang_mode, /* Minimize as long as it hangs */
|
||||
exit_crash, /* Treat non-zero exit as crash? */
|
||||
edges_only, /* Ignore hit counts? */
|
||||
exact_mode; /* Require path match for crashes? */
|
||||
exact_mode, /* Require path match for crashes? */
|
||||
remove_out_file, /* remove out_file on exit? */
|
||||
remove_shm = 1; /* remove shmem on exit? */
|
||||
|
||||
static volatile u8 stop_soon; /* Ctrl-C pressed? */
|
||||
|
||||
static afl_forkserver_t *fsrv;
|
||||
static sharedmem_t shm;
|
||||
static sharedmem_t * shm_fuzz;
|
||||
|
||||
/*
|
||||
* forkserver section
|
||||
*/
|
||||
@ -102,6 +111,18 @@ static const u8 count_class_lookup[256] = {
|
||||
|
||||
};
|
||||
|
||||
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
|
||||
sharedmem_t * shm_fuzz) {
|
||||
|
||||
afl_shm_deinit(shm_fuzz);
|
||||
fsrv->support_shmem_fuzz = 0;
|
||||
fsrv->shmem_fuzz_len = NULL;
|
||||
fsrv->shmem_fuzz = NULL;
|
||||
ck_free(shm_fuzz);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Apply mask to classified bitmap (if set). */
|
||||
|
||||
static void apply_mask(u32 *mem, u32 *mask) {
|
||||
@ -166,7 +187,15 @@ static inline u8 anything_set(afl_forkserver_t *fsrv) {
|
||||
|
||||
static void at_exit_handler(void) {
|
||||
|
||||
if (remove_shm) {
|
||||
|
||||
if (shm.map) afl_shm_deinit(&shm);
|
||||
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
}
|
||||
|
||||
afl_fsrv_killall();
|
||||
if (remove_out_file) unlink(out_file);
|
||||
|
||||
}
|
||||
|
||||
@ -300,7 +329,7 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
||||
|
||||
if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
|
||||
|
||||
u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
||||
u64 cksum = hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
||||
|
||||
if (first_run) { orig_cksum = cksum; }
|
||||
|
||||
@ -620,6 +649,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
||||
}
|
||||
|
||||
out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid());
|
||||
remove_out_file = 1;
|
||||
|
||||
}
|
||||
|
||||
@ -809,8 +839,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
char **argv = argv_cpy_dup(argc, argv_orig);
|
||||
|
||||
afl_forkserver_t fsrv_var = {0};
|
||||
afl_forkserver_t *fsrv = &fsrv_var;
|
||||
afl_forkserver_t fsrv_var = {0};
|
||||
fsrv = &fsrv_var;
|
||||
afl_fsrv_init(fsrv);
|
||||
map_size = get_map_size();
|
||||
fsrv->map_size = map_size;
|
||||
@ -1007,7 +1037,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
check_environment_vars(envp);
|
||||
|
||||
sharedmem_t shm = {0};
|
||||
/* initialize cmplog_mode */
|
||||
shm.cmplog_mode = 0;
|
||||
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||
|
||||
atexit(at_exit_handler);
|
||||
@ -1049,11 +1080,31 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
SAYF("\n");
|
||||
|
||||
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
shm_fuzz->cmplog_mode = 0;
|
||||
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
|
||||
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
|
||||
#ifdef USEMMAP
|
||||
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
|
||||
#else
|
||||
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
|
||||
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
|
||||
ck_free(shm_str);
|
||||
#endif
|
||||
fsrv->support_shmem_fuzz = 1;
|
||||
fsrv->shmem_fuzz_len = (u32 *)map;
|
||||
fsrv->shmem_fuzz = map + sizeof(u32);
|
||||
|
||||
read_initial_file();
|
||||
|
||||
afl_fsrv_start(fsrv, use_argv, &stop_soon,
|
||||
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
|
||||
|
||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
|
||||
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
|
||||
|
||||
@ -1107,7 +1158,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
OKF("We're done here. Have a nice day!\n");
|
||||
|
||||
remove_shm = 0;
|
||||
afl_shm_deinit(&shm);
|
||||
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
afl_fsrv_deinit(fsrv);
|
||||
if (fsrv->target_path) { ck_free(fsrv->target_path); }
|
||||
if (mask_bitmap) { ck_free(mask_bitmap); }
|
||||
|
3
src/third_party/libradamsa/.gitignore
vendored
3
src/third_party/libradamsa/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
*.a
|
||||
*.o
|
||||
libradamsa-test
|
75
src/third_party/libradamsa/libradamsa-test.c
vendored
75
src/third_party/libradamsa/libradamsa-test.c
vendored
@ -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;
|
||||
}
|
||||
|
30850
src/third_party/libradamsa/libradamsa.c
vendored
30850
src/third_party/libradamsa/libradamsa.c
vendored
File diff suppressed because it is too large
Load Diff
13
src/third_party/libradamsa/radamsa.h
vendored
13
src/third_party/libradamsa/radamsa.h
vendored
@ -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);
|
119
test/test.sh
119
test/test.sh
@ -23,7 +23,7 @@ else
|
||||
fi
|
||||
|
||||
test_compcov_binary_functionality() {
|
||||
RUN="../afl-showmap -o /dev/null -- $1"
|
||||
RUN="../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- $1"
|
||||
$RUN 'LIBTOKENCAP' | grep 'your string was LIBTOKENCAP' \
|
||||
&& $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \
|
||||
&& $RUN 'BANANA' | grep 'your string started with BAN' \
|
||||
@ -86,7 +86,7 @@ export AFL_LLVM_INSTRUMENT=AFL
|
||||
|
||||
# on OpenBSD we need to work with llvm from /usr/local/bin
|
||||
test -e /usr/local/bin/opt && {
|
||||
export PATH=/usr/local/bin:${PATH}
|
||||
export PATH="/usr/local/bin:${PATH}"
|
||||
}
|
||||
# on MacOS X we prefer afl-clang over afl-gcc, because
|
||||
# afl-gcc does not work there
|
||||
@ -108,7 +108,7 @@ RESET="\\033[0m"
|
||||
|
||||
MEM_LIMIT=none
|
||||
|
||||
export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
|
||||
|
||||
$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..."
|
||||
|
||||
@ -459,24 +459,23 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && {
|
||||
}
|
||||
rm -f test-instr.plain
|
||||
|
||||
# Disabled whitelist until I have a different solution -mh
|
||||
# echo foobar.c > whitelist.txt
|
||||
# AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1
|
||||
# test -e test-compcov && {
|
||||
# grep -q "No instrumentation targets found" test.out && {
|
||||
# $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
|
||||
# } || {
|
||||
# $ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
|
||||
# CODE=1
|
||||
# }
|
||||
# } || {
|
||||
# $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
|
||||
# CODE=1
|
||||
# }
|
||||
# rm -f test-compcov test.out whitelist.txt
|
||||
echo foobar.c > whitelist.txt
|
||||
AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1
|
||||
test -e test-compcov && {
|
||||
grep -q "No instrumentation targets found" test.out && {
|
||||
$ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
|
||||
CODE=1
|
||||
}
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
|
||||
CODE=1
|
||||
}
|
||||
rm -f test-compcov test.out whitelist.txt
|
||||
../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
|
||||
test -e test-persistent && {
|
||||
echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && {
|
||||
echo foo | ../afl-showmap -m none -o /dev/null -q -r ./test-persistent && {
|
||||
$ECHO "$GREEN[+] llvm_mode LTO persistent mode feature works correctly"
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work"
|
||||
@ -638,43 +637,43 @@ test -e ../libdislocator.so && {
|
||||
INCOMPLETE=1
|
||||
}
|
||||
rm -f test-compcov
|
||||
test -e ../libradamsa.so && {
|
||||
# on FreeBSD need to set AFL_CC
|
||||
test `uname -s` = 'FreeBSD' && {
|
||||
if type clang >/dev/null; then
|
||||
export AFL_CC=`command -v clang`
|
||||
else
|
||||
export AFL_CC=`$LLVM_CONFIG --bindir`/clang
|
||||
fi
|
||||
}
|
||||
test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
test -e test-instr.plain && {
|
||||
mkdir -p in
|
||||
printf 1 > in/in
|
||||
$ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds"
|
||||
{
|
||||
../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
|
||||
} >>errors 2>&1
|
||||
test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
|
||||
$ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
|
||||
} || {
|
||||
echo CUT------------------------------------------------------------------CUT
|
||||
cat errors
|
||||
echo CUT------------------------------------------------------------------CUT
|
||||
$ECHO "$RED[!] libradamsa failed"
|
||||
CODE=1
|
||||
}
|
||||
rm -rf in out errors test-instr.plain
|
||||
} || {
|
||||
$ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
|
||||
INCOMPLETE=1
|
||||
}
|
||||
} || {
|
||||
$ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
|
||||
INCOMPLETE=1
|
||||
}
|
||||
#test -e ../libradamsa.so && {
|
||||
# # on FreeBSD need to set AFL_CC
|
||||
# test `uname -s` = 'FreeBSD' && {
|
||||
# if type clang >/dev/null; then
|
||||
# export AFL_CC=`command -v clang`
|
||||
# else
|
||||
# export AFL_CC=`$LLVM_CONFIG --bindir`/clang
|
||||
# fi
|
||||
# }
|
||||
# test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
# test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
# test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
|
||||
# test -e test-instr.plain && {
|
||||
# mkdir -p in
|
||||
# printf 1 > in/in
|
||||
# $ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds"
|
||||
# {
|
||||
# ../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
|
||||
# } >>errors 2>&1
|
||||
# test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
|
||||
# $ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
|
||||
# } || {
|
||||
# echo CUT------------------------------------------------------------------CUT
|
||||
# cat errors
|
||||
# echo CUT------------------------------------------------------------------CUT
|
||||
# $ECHO "$RED[!] libradamsa failed"
|
||||
# CODE=1
|
||||
# }
|
||||
# rm -rf in out errors test-instr.plain
|
||||
# } || {
|
||||
# $ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
|
||||
# INCOMPLETE=1
|
||||
# }
|
||||
#} || {
|
||||
# $ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
|
||||
# INCOMPLETE=1
|
||||
#}
|
||||
|
||||
test -z "$AFL_CC" && {
|
||||
if type gcc >/dev/null; then
|
||||
@ -902,6 +901,9 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
|
||||
test -d ../unicorn_mode/unicornafl && {
|
||||
test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
|
||||
{
|
||||
# We want to see python errors etc. in logs, in case something doesn't work
|
||||
export AFL_DEBUG_CHILD_OUTPUT=1
|
||||
|
||||
# some python version should be available now
|
||||
PYTHONS="`command -v python3` `command -v python` `command -v python2`"
|
||||
EASY_INSTALL_FOUND=0
|
||||
@ -988,6 +990,9 @@ test -d ../unicorn_mode/unicornafl && {
|
||||
rm -rf in out errors
|
||||
}
|
||||
fi
|
||||
|
||||
unset AFL_DEBUG_CHILD_OUTPUT
|
||||
|
||||
}
|
||||
} || {
|
||||
$ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??"
|
||||
@ -1121,7 +1126,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
||||
|
||||
$ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY"
|
||||
unset AFL_CC
|
||||
make -C .. unit || "$CODE" = "1"
|
||||
make -C .. unit || CODE=1 INCOMPLETE=1 :
|
||||
|
||||
$ECHO "$GREY[*] all test cases completed.$RESET"
|
||||
test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed"
|
||||
|
75
test/unittests/unit_hash.c
Normal file
75
test/unittests/unit_hash.c
Normal 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;
|
||||
}
|
@ -126,6 +126,8 @@ int main(int argc, char **argv) {
|
||||
};
|
||||
|
||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
||||
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||
|
||||
// fake return for dumb compilers
|
||||
return 0;
|
||||
}
|
||||
|
@ -156,6 +156,8 @@ int main(int argc, char **argv) {
|
||||
};
|
||||
|
||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
||||
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||
|
||||
// fake return for dumb compilers
|
||||
return 0;
|
||||
}
|
||||
|
@ -109,6 +109,8 @@ int main(int argc, char **argv) {
|
||||
};
|
||||
|
||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
||||
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||
|
||||
// fake return for dumb compilers
|
||||
return 0;
|
||||
}
|
||||
|
84
test/unittests/unit_rand.c
Normal file
84
test/unittests/unit_rand.c
Normal 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;
|
||||
}
|
@ -1 +1 @@
|
||||
a6e943c
|
||||
0ca7a8f2
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit a6e943c683ecb3aba1baaddc7a02eefd2c5a5ad9
|
||||
Subproject commit 0ca7a8f22b8bb028eb9fe053c0974a60ee640f18
|
Loading…
x
Reference in New Issue
Block a user