From 0a251f93e0842c92755e9bcba61e520669a6c2e6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 15 Aug 2020 13:34:51 +0200 Subject: increase initial memory sized --- include/config.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 344a368f..a978a27c 100644 --- a/include/config.h +++ b/include/config.h @@ -70,21 +70,21 @@ #ifndef __NetBSD__ #ifndef WORD_SIZE_64 - #define MEM_LIMIT 25 - #else #define MEM_LIMIT 50 + #else + #define MEM_LIMIT 75 #endif /* ^!WORD_SIZE_64 */ #else /* NetBSD's kernel needs more space for stack, see discussion for issue \ #165 */ - #define MEM_LIMIT 200 + #define MEM_LIMIT 250 #endif /* Default memory limit when running in QEMU mode (MB): */ -#define MEM_LIMIT_QEMU 200 +#define MEM_LIMIT_QEMU 250 /* Default memory limit when running in Unicorn mode (MB): */ -#define MEM_LIMIT_UNICORN 200 +#define MEM_LIMIT_UNICORN 250 /* Number of calibration cycles per every new test case (and for test cases that show variable behavior): */ -- cgit 1.4.1 From 1c64048d0f3a7bb7ec460d86a6abba7c4123d18f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 18 Aug 2020 19:56:47 +0200 Subject: 2.67c --- README.md | 4 ++-- docs/Changelog.md | 8 ++++---- include/config.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 97c0a0d7..b7b699cf 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) - Release Version: [2.66c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [2.67c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.66d + Github Version: 2.67d Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 55b0c7dd..f562b727 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++2.66d (devel) +### Version ++2.67c (release) - Support for improved afl++ snapshot module: https://github.com/AFLplusplus/AFL-Snapshot-LKM - Due to the instrumentation needing more memory, the initial memory sizes @@ -23,11 +23,11 @@ sending a mail to . MOpt into the mix - fixed a bug in redqueen for strings and made deterministic with -s - llvm_mode: - - now supports llvm 12! + - now supports llvm 12 - support for AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST (previous AFL_LLVM_WHITELIST and AFL_LLVM_INSTRUMENT_FILE are deprecated and are matched to AFL_LLVM_ALLOWLIST). The format is compatible to llvm - sancov, and also supports function matching! + sancov, and also supports function matching :) - added neverzero counting to trace-pc/pcgard - fixes for laf-intel float splitting (thanks to mark-griffin for reporting) @@ -40,7 +40,7 @@ sending a mail to . - LTO: fixed autodict for long strings - LTO: laf-intel and redqueen/cmplog are now applied at link time to prevent llvm optimizing away the splits - - LTO: autodictionary mode is a default + - LTO: autodictionary mode is a fixed default now - LTO: instrim instrumentation disabled, only classic support used as it is always better - LTO: env var AFL_LLVM_DOCUMENT_IDS=file will document which edge ID diff --git a/include/config.h b/include/config.h index a978a27c..9cc2dae5 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.66d" +#define VERSION "++2.67c" /****************************************************** * * -- cgit 1.4.1 From 9faf7b6fc81cf88aed43c7d4955bc05ee74a8a54 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 18 Aug 2020 20:08:29 +0200 Subject: v2.67d --- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index b80d4047..15dccd2c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++2.67d (develop) + - Fix for auto dictionary not to throw out a -x dictionary + + ### Version ++2.67c (release) - Support for improved afl++ snapshot module: https://github.com/AFLplusplus/AFL-Snapshot-LKM diff --git a/include/config.h b/include/config.h index 9cc2dae5..6c73bced 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.67c" +#define VERSION "++2.67d" /****************************************************** * * -- cgit 1.4.1 From fac108476c1cb5326cf4339b2a4c846828698816 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 4 Sep 2020 22:50:45 +0200 Subject: v2.68c --- README.md | 4 ++-- docs/Changelog.md | 2 +- include/config.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 7b73a5f3..4cad6b47 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) - Release Version: [2.67c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [2.68c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.67d + Github Version: 3.00a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 0d93ee1f..6321aee4 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++2.67d (develop) +### Version ++2.68c (release) - added the GSoC excellent afl++ grammar mutator by Shengtuo to our custom_mutators/ (see custom_mutators/README.md) - or get it here: https://github.com/AFLplusplus/Grammar-Mutator diff --git a/include/config.h b/include/config.h index 6c73bced..77407d50 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.67d" +#define VERSION "++2.68c" /****************************************************** * * -- cgit 1.4.1 From e30b2c6af6e369844c92c00a20ebdd53473a747c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 13:18:28 +0200 Subject: final changes for pre-3.0 --- .gitignore | 6 ++ Android.bp | 6 +- GNUmakefile | 3 +- GNUmakefile.gcc_plugin | 1 + GNUmakefile.llvm | 8 ++- README.md | 2 +- docs/Changelog.md | 14 ++++ docs/FAQ.md | 104 +++++++++++++++--------------- docs/INSTALL.md | 19 +++--- docs/env_variables.md | 121 ++++++++++++++++++----------------- docs/ideas.md | 57 ----------------- docs/life_pro_tips.md | 4 +- docs/perf_tips.md | 8 +-- docs/sister_projects.md | 4 +- docs/status_screen.md | 2 +- examples/README.md | 2 +- examples/aflpp_driver/aflpp_driver.c | 2 +- include/afl-fuzz.h | 3 +- include/config.h | 4 +- include/envs.h | 1 + qemu_mode/patches/afl-qemu-cpu-inl.h | 2 +- src/afl-fuzz-init.c | 3 +- src/afl-fuzz-queue.c | 13 ++-- src/afl-fuzz-stats.c | 8 +-- src/afl-fuzz.c | 3 +- test/test-gcc-plugin.sh | 2 +- test/test-unittests.sh | 2 + 27 files changed, 188 insertions(+), 216 deletions(-) (limited to 'include/config.h') diff --git a/.gitignore b/.gitignore index 0527a0b2..e3adb6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,12 @@ afl-showmap.8 afl-system-config.8 afl-tmin.8 afl-whatsup.8 +afl-c++ +afl-cc +afl-lto +afl-lto++ +afl-lto++.8 +afl-lto.8 qemu_mode/libcompcov/compcovtest qemu_mode/qemu-* unicorn_mode/samples/*/\.test-* diff --git a/Android.bp b/Android.bp index e59129db..2c2114b2 100644 --- a/Android.bp +++ b/Android.bp @@ -101,7 +101,7 @@ cc_binary_host { ], srcs: [ - "llvm_mode/afl-clang-fast.c", + "src/afl-cc.c", ], } @@ -119,7 +119,7 @@ cc_binary_host { ], srcs: [ - "llvm_mode/afl-clang-fast.c", + "src/afl-cc.c", ], } @@ -136,6 +136,6 @@ cc_library_static { ], srcs: [ - "llvm_mode/afl-llvm-rt.o.c", + "instrumentation/afl-llvm-rt.o.c", ], } diff --git a/GNUmakefile b/GNUmakefile index 0046a481..7455483c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -533,7 +533,7 @@ endif deepclean: clean rm -rf qemu_mode/qemu-3.1.1.tar.xz rm -rf unicorn_mode/unicornafl - git reset --hard >/dev/null 2>&1 || true + # NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true .PHONY: distrib distrib: all @@ -591,6 +591,7 @@ install: all $(MANPAGES) @install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) @rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh @rm -f $${DESTDIR}$(BIN_PATH)/afl-as + @rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) @if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi @if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index aeb1ef16..b73fcfda 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -158,6 +158,7 @@ vpath % .. install: all ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-gcc-fast ln -sf afl-c++ $${DESTDIR}$(BIN_PATH)/afl-g++-fast + ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o install -m 755 ./afl-gcc-pass.so $${DESTDIR}$(HELPER_PATH) install -m 644 -T instrumentation/README.gcc_plugin.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index d76e0b28..1bb3d265 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -423,10 +423,12 @@ document: ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c | test_deps @printf "[*] Building 32-bit variant of the runtime (-m32)... " @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + @test -e afl-compiler-rt-32.o && ln -sf afl-compiler-rt-32.o afl-llvm-rt-64.o ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c | test_deps @printf "[*] Building 64-bit variant of the runtime (-m64)... " @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + @test -e afl-compiler-rt-64.o && ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o .PHONY: test_build test_build: $(PROGS) @@ -448,11 +450,11 @@ all_done: test_build install: all @install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) @if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi - @if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); fi + @if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)afl-llvm-rt.o ;fi @if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-lto-instrumentation.so ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi - @if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); fi - @if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); fi + @if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)afl-llvm-rt-32.o ;fi + @if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)afl-llvm-rt-64.o ; fi @if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi @if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi diff --git a/README.md b/README.md index 96b34260..c886489d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Release Version: [2.67c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.67d + Github Version: 3.00a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 6321aee4..9de03e78 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,20 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++3.00a (develop) + - llvm_mode/ and gcc_plugin/ moved to instrumentation/ + - all compilers combined to afl-cc which emulates the previous ones + - afl-llvm/gcc-rt.o merged into afl-compiler-rt.o + - afl-fuzz + - reading testcases from -i now descends into subdirectories + - allow up to 4 -x command line options + - loaded extras now have a duplicate protection + - instrumentation + - new llvm pass: dict2file via AFL_LLVM_DICT2FILE, create afl-fuzz + -x dictionary of string comparisons found during compilation + - not overriding -Ox or -fno-unroll-loops anymore + + ### Version ++2.68c (release) - added the GSoC excellent afl++ grammar mutator by Shengtuo to our custom_mutators/ (see custom_mutators/README.md) - or get it here: diff --git a/docs/FAQ.md b/docs/FAQ.md index 064638f4..24942492 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -4,11 +4,11 @@ * [What is the difference between afl and afl++?](#what-is-the-difference-between-afl-and-afl) * [How to improve the fuzzing speed?](#how-to-improve-the-fuzzing-speed) - * [How do I fuzz a network service?](#how-do-i-fuzz-a-network-service) - * [How do I fuzz a GUI program?](#how-do-i-fuzz-a-gui-program) + * [How do I fuzz a network service?](#how-to-fuzz-a-network-service) + * [How do I fuzz a GUI program?](#how-to-fuzz-a-gui-program) * [What is an edge?](#what-is-an-edge) * [Why is my stability below 100%?](#why-is-my-stability-below-100) - * [How can I improve the stability value?](#how-can-i-improve-the-stability-value) + * [How can I improve the stability value](#how-can-i-improve-the-stability-value) If you find an interesting or important question missing, submit it via [https://github.com/AFLplusplus/AFLplusplus/issues](https://github.com/AFLplusplus/AFLplusplus/issues) @@ -18,52 +18,51 @@ If you find an interesting or important question missing, submit it via American Fuzzy Lop (AFL) was developed by Michał "lcamtuf" Zalewski starting in 2013/2014, and when he left Google end of 2017 he stopped developing it. -At the end of 2019 the Google fuzzing team took over maintenance of AFL, however -it is only accepting PRs from the community and is not developing enhancements +At the end of 2019 the Google fuzzing team took over maintance of AFL, however +it is only accepting PR from the community and is not developing enhancements anymore. -In the second quarter of 2019, 1 1/2 year later when no further development of -AFL had happened and it became clear there would none be coming, afl++ -was born, where initially community patches were collected and applied -for bug fixes and enhancements. Then from various AFL spin-offs - mostly academic +In the second quarter of 2019, 1 1/2 years after no further development of +AFL had happened and it became clear there would be none coming, afl++ +was born, where initially first community patches were collected and applied +for bugs and enhancements. Then from various AFL spin-offs - mostly academic research - features were integrated. This already resulted in a much advanced AFL. Until the end of 2019 the afl++ team had grown to four active developers which -then implemented their own research and features, making it now by far the most +then implemented their own research and feature, making it now by far the most flexible and feature rich guided fuzzer available as open source. And in independent fuzzing benchmarks it is one of the best fuzzers available, e.g. [Fuzzbench Report](https://www.fuzzbench.com/reports/2020-08-03/index.html) -## How to improve the fuzzing speed? +## How to improve the fuzzing speed - 1. Use [llvm_mode](docs/llvm_mode/README.md): afl-clang-lto (llvm >= 11) or afl-clang-fast (llvm >= 9 recommended) - 2. Use [persistent mode](llvm_mode/README.persistent_mode.md) (x2-x20 speed increase) + 1. use [instrumentation](docs/README.llvm.md): afl-clang-lto (llvm >= 11) or afl-clang-fast (llvm >= 9 recommended) + 2. Use [persistent mode](instrumentation/README.persistent_mode.md) (x2-x20 speed increase) 3. Use the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase) - 4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to put the input file directory on a tempfs location, see [docs/env_variables.md](docs/env_variables.md) - 5. Improve Linux kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system less secure) + 4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input file on a tempfs location, see [docs/env_variables.md](docs/env_variables.md) + 5. Improve kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system more insecure) 6. Running on an `ext2` filesystem with `noatime` mount option will be a bit faster than on any other journaling filesystem 7. Use your cores! [README.md:3.b) Using multiple cores/threads](../README.md#b-using-multiple-coresthreads) ## How do I fuzz a network service? -The short answer is - you cannot, at least not "out of the box". +The short answer is - you cannot, at least "out of the box". -Using a network channel is inadequate for several reasons: -- it has a slow-down of x10-20 on the fuzzing speed -- it does not scale to fuzzing multiple instances easily, -- instead of one initial data packet often a back-and-forth interplay of packets is needed for stateful protocols (which is totally unsupported by most coverage aware fuzzers). +Using network has a slow-down of x10-20 on the fuzzing speed, does not scale, +and finally usually it is more than one initial data packet but a back-and-forth +which is totally unsupported by most coverage aware fuzzers. The established method to fuzz network services is to modify the source code to read from a file or stdin (fd 0) (or even faster via shared memory, combine -this with persistent mode [llvm_mode/README.persistent_mode.md](llvm_mode/README.persistent_mode.md) +this with persistent mode [instrumentation/README.persistent_mode.md](instrumentation/README.persistent_mode.md) and you have a performance gain of x10 instead of a performance loss of over -x10 - that is a x100 difference!). +x10 - that is a x100 difference! If modifying the source is not an option (e.g. because you only have a binary and perform binary fuzzing) you can also use a shared library with AFL_PRELOAD -to emulate the network. This is also much faster than the real network would be. -See [examples/socket_fuzzing/](../examples/socket_fuzzing/). +to emulate the network. This is also much faster than network would be. +See [examples/socket_fuzzing/](../examples/socket_fuzzing/) There is an outdated afl++ branch that implements networking if you are desperate though: [https://github.com/AFLplusplus/AFLplusplus/tree/networking](https://github.com/AFLplusplus/AFLplusplus/tree/networking) - @@ -74,7 +73,7 @@ which allows you to define network state with different type of data packets. If the GUI program can read the fuzz data from a file (via the command line, a fixed location or via an environment variable) without needing any user -interaction then it would be suitable for fuzzing. +interaction then then yes. Otherwise it is not possible without modifying the source code - which is a very good idea anyway as the GUI functionality is a huge CPU/time overhead @@ -83,13 +82,13 @@ for the fuzzing. So create a new `main()` that just reads the test case and calls the functionality for processing the input that the GUI program is using. -## What is an "edge"? +## What is an "edge" A program contains `functions`, `functions` contain the compiled machine code. The compiled machine code in a `function` can be in a single or many `basic blocks`. A `basic block` is the largest possible number of subsequent machine code -instructions that has exactly one entrypoint (which can be be entered by multiple other basic blocks) -and runs linearly without branching or jumping to other addresses (except at the end). +instructions that runs independent, meaning it does not split up to different +locations nor is it jumped into it from a different location: ``` function() { A: @@ -99,7 +98,7 @@ function() { if (x) goto C; else goto D; C: some code - goto E + goto D D: some code goto B @@ -109,7 +108,7 @@ function() { ``` Every code block between two jump locations is a `basic block`. -An `edge` is then the unique relationship between two directly connected `basic blocks` (from the +An `edge` is then the unique relationship between two `basic blocks` (from the code example above): ``` Block A @@ -124,9 +123,8 @@ code example above): Block E ``` Every line between two blocks is an `edge`. -Note that a few basic block loop to itself, this too would be an edge. -## Why is my stability below 100%? +## Why is my stability below 100% Stability is measured by how many percent of the edges in the target are "stable". Sending the same input again and again should take the exact same @@ -134,37 +132,37 @@ path through the target every time. If that is the case, the stability is 100%. If however randomness happens, e.g. a thread reading other external data, reaction to timing, etc. then in some of the re-executions with the same data -the edge coverage result will be different accross runs. +the result in the edge information will be different accross runs. Those edges that change are then flagged "unstable". The more "unstable" edges, the more difficult for afl++ to identify valid new paths. A value above 90% is usually fine and a value above 80% is also still ok, and -even a value above 20% can still result in successful finds of bugs. -However, it is recommended that for values below 90% or 80% you should take -countermeasures to improve stability. +even above 20% can still result in successful finds of bugs. +However, it is recommended that below 90% or 80% you should take measures to +improve the stability. -## How can I improve the stability value? +## How can I improve the stability value -For fuzzing a 100% stable target that covers all edges is the best case. +For fuzzing a 100% stable target that covers all edges is the best. A 90% stable target that covers all edges is however better than a 100% stable target that ignores 10% of the edges. With instability you basically have a partial coverage loss on an edge, with -ignored functions you have a full loss on that edges. +ignore you have a full loss on that edge. There are functions that are unstable, but also provide value to coverage, eg init functions that use fuzz data as input for example. -If however a function that has nothing to do with the input data is the -source of instability, e.g. checking jitter, or is a hash map function etc. -then it should not be instrumented. +If however it is a function that has nothing to do with the input data is the +source, e.g. checking jitter, or is a hash map function etc. then it should +not be instrumented. -To be able to exclude these functions (based on AFL++'s measured stability) -the following process will allow to identify functions with variable edges. +To be able to make this decision the following process will allow you to +identify the functions with variable edges so you can make this decision. -Four steps are required to do this and it also requires quite some knowledge -of coding and/or disassembly and is effectively possible only with +Four steps are required to do this and requires quite some knowledge of +coding and/or disassembly and it is only effectively possible with afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation. 1. First step: Identify which edge ID numbers are unstable @@ -173,7 +171,7 @@ afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation. The out/fuzzer_stats file will then show the edge IDs that were identified as unstable. - 2. Second step: Find the responsible function(s). + 2. Second step: Find the responsible function. a) For LTO instrumented binaries this can be documented during compile time, just set `export AFL_LLVM_DOCUMENT_IDS=/path/to/a/file`. @@ -182,10 +180,10 @@ afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation. b) For PCGUARD instrumented binaries it is much more difficult. Here you can either modify the __sanitizer_cov_trace_pc_guard function in - llvm_mode/afl-llvm-rt.o.c to write a backtrace to a file if the ID in + instrumentation/afl-llvm-rt.o.c to write a backtrace to a file if the ID in __afl_area_ptr[*guard] is one of the unstable edge IDs. (Example code is already there). - Then recompile and reinstall llvm_mode and rebuild your target. + Then recompile and reinstall instrumentation and rebuild your target. Run the recompiled target with afl-fuzz for a while and then check the file that you wrote with the backtrace information. Alternatively you can use `gdb` to hook __sanitizer_cov_trace_pc_guard_init @@ -193,20 +191,20 @@ afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation. and set a write breakpoint to that address (`watch 0x.....`). c) in all other instrumentation types this is not possible. So just - recompile with the two mentioned above. This is just for + recompile with the the two mentioned above. This is just for identifying the functions that have unstable edges. 3. Third step: create a text file with the filenames/functions Identify which source code files contain the functions that you need to remove from instrumentation, or just specify the functions you want to - skip for instrumentation. Note that optimization might inline functions! + skip instrumenting. Note that optimization might inline functions! - Simply follow this document on how to do this: [llvm_mode/README.instrument_list.md](llvm_mode/README.instrument_list.md) + Simply follow this document on how to do this: [instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md) If PCGUARD is used, then you need to follow this guide (needs llvm 12+!): [http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation](http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation) - Only exclude those functions from instrumentation that provide no value + Only deny those functions from instrumentation that provide no value for coverage - that is if it does not process any fuzz data directly or indirectly (e.g. hash maps, thread management etc.). If however a function directly or indirectly handles fuzz data then you diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 766f24d7..fb7b5642 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -24,7 +24,7 @@ There are no special dependencies to speak of; you will need GNU make and a working compiler (gcc or clang). Some of the optional scripts bundled with the program may depend on bash, gdb, and similar basic tools. -If you are using clang, please review llvm_mode/README.md; the LLVM +If you are using clang, please review README.llvm.md; the LLVM integration mode can offer substantial performance gains compared to the traditional approach. @@ -52,10 +52,10 @@ sudo gmake install Keep in mind that if you are using csh as your shell, the syntax of some of the shell commands given in the README.md and other docs will be different. -The `llvm_mode` requires a dynamically linked, fully-operational installation of +The `llvm` requires a dynamically linked, fully-operational installation of clang. At least on FreeBSD, the clang binaries are static and do not include some of the essential tools, so if you want to make it work, you may need to -follow the instructions in llvm_mode/README.md. +follow the instructions in README.llvm.md. Beyond that, everything should work as advertised. @@ -97,27 +97,24 @@ and definitely don't look POSIX-compliant. This means two things: User emulation mode of QEMU does not appear to be supported on MacOS X, so black-box instrumentation mode (`-Q`) will not work. -The llvm_mode requires a fully-operational installation of clang. The one that +The llvm instrumentation requires a fully-operational installation of clang. The one that comes with Xcode is missing some of the essential headers and helper tools. -See llvm_mode/README.md for advice on how to build the compiler from scratch. +See README.llvm.md for advice on how to build the compiler from scratch. ## 4. Linux or *BSD on non-x86 systems Standard build will fail on non-x86 systems, but you should be able to leverage two other options: - - The LLVM mode (see llvm_mode/README.md), which does not rely on + - The LLVM mode (see README.llvm.md), which does not rely on x86-specific assembly shims. It's fast and robust, but requires a complete installation of clang. - The QEMU mode (see qemu_mode/README.md), which can be also used for fuzzing cross-platform binaries. It's slower and more fragile, but can be used even when you don't have the source for the tested app. -If you're not sure what you need, you need the LLVM mode. To get it, try: - -```bash -AFL_NO_X86=1 gmake && gmake -C llvm_mode -``` +If you're not sure what you need, you need the LLVM mode, which is built by +default. ...and compile your target program with afl-clang-fast or afl-clang-fast++ instead of the traditional afl-gcc or afl-clang wrappers. diff --git a/docs/env_variables.md b/docs/env_variables.md index c47d10e8..9d289f6d 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -5,13 +5,25 @@ users or for some types of custom fuzzing setups. See README.md for the general instruction manual. -## 1) Settings for afl-gcc, afl-clang, and afl-as - and gcc_plugin afl-gcc-fast +## 1) Settings for all compilers -Because they can't directly accept command-line options, the compile-time -tools make fairly broad use of environmental variables: +Starting with afl++ 3.0 there is only one compiler: afl-cc +To select the different instrumentation modes this can be done by + 1. passing --afl-MODE command line options to the compiler + 2. use a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++, + afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++, + afl-gcc-fast, afl-g++-fast + 3. using the environment variable AFL_CC_COMPILER with MODE - - Most afl tools do not print any output if stdout/stderr are redirected. - If you want to save the output in a file then set the AFL_DEBUG +MODE can one of LTO (afl-clang-lto*), LLVM (afl-clang-fast*), GCC_PLUGIN +(afl-g*-fast) or GCC (afl-gcc/afl-g++). + +Because beside the --afl-MODE command no afl specific command-line options +are accepted, the compile-time tools make fairly broad use of environmental +variables: + + - Most afl tools do not print any ouput if stout/stderr are redirected. + If you want to have the output into a file then set the AFL_DEBUG environment variable. This is sadly necessary for various build processes which fail otherwise. @@ -24,6 +36,8 @@ tools make fairly broad use of environmental variables: will cause problems in programs built with -Werror, simply because -O3 enables more thorough code analysis and can spew out additional warnings. To disable optimizations, set AFL_DONT_OPTIMIZE. + However if -O... and/or -fno-unroll-loops are set, these are not + overriden. - Setting AFL_USE_ASAN automatically enables ASAN, provided that your compiler supports that. Note that fuzzing with ASAN is mildly challenging @@ -44,7 +58,7 @@ tools make fairly broad use of environmental variables: you instrument hand-written assembly when compiling clang code by plugging a normalizer into the chain. (There is no equivalent feature for GCC.) - - Setting AFL_INST_RATIO to a percentage between 0% and 100% controls the + - Setting AFL_INST_RATIO to a percentage between 0 and 100% controls the probability of instrumenting every branch. This is (very rarely) useful when dealing with exceptionally complex programs that saturate the output bitmap. Examples include v8, ffmpeg, and perl. @@ -55,19 +69,16 @@ tools make fairly broad use of environmental variables: Setting AFL_INST_RATIO to 0 is a valid choice. This will instrument only the transitions between function entry points, but not individual branches. + Note that this is an outdated variable. A few instances (e.g. afl-gcc) + still support these, but state-of-the-art (e.g. LLVM LTO and LLVM PCGUARD) + do not need this. + - AFL_NO_BUILTIN causes the compiler to generate code suitable for use with libtokencap.so (but perhaps running a bit slower than without the flag). - TMPDIR is used by afl-as for temporary files; if this variable is not set, the tool defaults to /tmp. - - Setting AFL_KEEP_ASSEMBLY prevents afl-as from deleting instrumented - assembly files. Useful for troubleshooting problems or understanding how - the tool works. To get them in a predictable place, try something like: - - mkdir assembly_here - TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all - - If you are a weird person that wants to compile and instrument asm text files then use the AFL_AS_FORCE_INSTRUMENT variable: AFL_AS_FORCE_INSTRUMENT=1 afl-gcc foo.s -o foo @@ -78,19 +89,24 @@ tools make fairly broad use of environmental variables: - Setting AFL_CAL_FAST will speed up the initial calibration, if the application is very slow -## 2) Settings for afl-clang-fast / afl-clang-fast++ / afl-gcc-fast / afl-g++-fast +## 2) Settings for LLVM and LTO: afl-clang-fast / afl-clang-fast++ / afl-clang-lto / afl-clang-lto++ -The native instrumentation helpers (llvm_mode and gcc_plugin) accept a subset +The native instrumentation helpers (instrumentation and gcc_plugin) accept a subset of the settings discussed in section #1, with the exception of: + - LLVM modes support `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` which will + write all constant string comparisons to this file to be used with + afl-fuzz' `-x` option. + - AFL_AS, since this toolchain does not directly invoke GNU as. - TMPDIR and AFL_KEEP_ASSEMBLY, since no temporary assembly files are created. - - AFL_INST_RATIO, as we by default use collision free instrumentation. + - AFL_INST_RATIO, as we by default collision free instrumentation is used. + Not all passes support this option though as it is an outdated feature. -Then there are a few specific features that are only available in llvm_mode: +Then there are a few specific features that are only available in instrumentation: ### Select the instrumentation mode @@ -121,7 +137,7 @@ Then there are a few specific features that are only available in llvm_mode: None of the following options are necessary to be used and are rather for manual use (which only ever the author of this LTO implementation will use). - These are used if several seperated instrumentations are performed which + These are used if several seperated instrumentation are performed which are then later combined. - AFL_LLVM_DOCUMENT_IDS=file will document to a file which edge ID was given @@ -136,7 +152,7 @@ Then there are a few specific features that are only available in llvm_mode: - AFL_LLVM_LTO_DONTWRITEID prevents that the highest location ID written into the instrumentation is set in a global variable - See llvm_mode/README.LTO.md for more information. + See instrumentation/README.LTO.md for more information. ### INSTRIM @@ -154,7 +170,7 @@ Then there are a few specific features that are only available in llvm_mode: afl-fuzz will only be able to see the path the loop took, but not how many times it was called (unless it is a complex loop). - See llvm_mode/README.instrim.md + See instrumentation/README.instrim.md ### NGRAM @@ -165,7 +181,7 @@ Then there are a few specific features that are only available in llvm_mode: config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur. - See llvm_mode/README.ctx.md + See instrumentation/README.ctx.md ### CTX @@ -176,7 +192,7 @@ Then there are a few specific features that are only available in llvm_mode: config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur. - See llvm_mode/README.ngram.md + See instrumentation/README.ngram.md ### LAF-INTEL @@ -196,17 +212,17 @@ Then there are a few specific features that are only available in llvm_mode: - Setting AFL_LLVM_LAF_ALL sets all of the above - See llvm_mode/README.laf-intel.md for more information. + See instrumentation/README.laf-intel.md for more information. ### INSTRUMENT LIST (selectively instrument files and functions) - This feature allows selective instrumentation of the source + This feature allows selectively instrumentation of the source - Setting AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST with a filenames and/or function will only instrument (or skip) those files that match the names listed in the specified file. - See llvm_mode/README.instrument_list.md for more information. + See instrumentation/README.instrument_list.md for more information. ### NOT_ZERO @@ -220,27 +236,34 @@ Then there are a few specific features that are only available in llvm_mode: test. If the target performs only few loops then this will give a small performance boost. - See llvm_mode/README.neverzero.md + See instrumentation/README.neverzero.md ### CMPLOG - Setting AFL_LLVM_CMPLOG=1 during compilation will tell afl-clang-fast to - produce a CmpLog binary. See llvm_mode/README.cmplog.md + produce a CmpLog binary. See instrumentation/README.cmplog.md - See llvm_mode/README.neverzero.md + See instrumentation/README.neverzero.md -Then there are a few specific features that are only available in the gcc_plugin: +## 3) Settings for GCC / GCC_PLUGIN modes -### INSTRUMENT_FILE +Then there are a few specific features that are only available in GCC and +GCC_PLUGIN mode. - This feature allows selective instrumentation of the source + - Setting AFL_KEEP_ASSEMBLY prevents afl-as from deleting instrumented + assembly files. Useful for troubleshooting problems or understanding how + the tool works. (GCC mode only) + To get them in a predictable place, try something like: - - Setting AFL_GCC_INSTRUMENT_FILE with a filename will only instrument those - files that match the names listed in this file (one filename per line). + mkdir assembly_here + TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all + - Setting AFL_GCC_INSTRUMENT_FILE with a filename will only instrument those + files that match the names listed in this file (one filename per line). See gcc_plugin/README.instrument_list.md for more information. + (GCC_PLUGIN mode only) -## 3) Settings for afl-fuzz +## 4) Settings for afl-fuzz The main fuzzer binary accepts several options that disable a couple of sanity checks or alter some of the more exotic semantics of the tool: @@ -278,14 +301,6 @@ checks or alter some of the more exotic semantics of the tool: don't want AFL to spend too much time classifying that stuff and just rapidly put all timeouts in that bin. - - Setting AFL_FORKSRV_INIT_TMOUT allows yout to specify a different timeout - to wait for the forkserver to spin up. The default is the `-t` value times - `FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the - default would wait `1000` milis. Setting a different time here is useful - if the target has a very slow startup time, for example when doing - full-system fuzzing or emulation, but you don't want the actual runs - to wait too long for timeouts. - - AFL_NO_ARITH causes AFL to skip most of the deterministic arithmetics. This can be useful to speed up the fuzzing of text-based file formats. @@ -377,22 +392,12 @@ checks or alter some of the more exotic semantics of the tool: Note that this setting inhibits some of the user-friendly diagnostics normally done when starting up the forkserver and causes a pretty significant performance drop. - - - Setting AFL_MAX_DET_EXTRAS changes the count of dictionary entries/extras - (default 200), after which the entries will be used probabilistically. - So, if the dict/extras file (`-x`) contains more tokens than this threshold, - not all of the tokens will be used in each fuzzing step, every time. - Instead, there is a chance that the entry will be skipped during fuzzing. - This makes sure that the fuzzer doesn't spend all its time only inserting - the extras, but will still do other mutations. However, it decreases the - likelihood for each token to be inserted, before the next queue entry is fuzzed. - Either way, all tokens will be used eventually, in a longer fuzzing campaign. - Outdated environment variables that are that not supported anymore: AFL_DEFER_FORKSRV AFL_PERSISTENT -## 4) Settings for afl-qemu-trace +## 5) Settings for afl-qemu-trace The QEMU wrapper used to instrument binary-only code supports several settings: @@ -446,7 +451,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings: stack pointer in which QEMU can find the return address when `start addr` is hitted. -## 5) Settings for afl-cmin +## 6) Settings for afl-cmin The corpus minimization script offers very little customization: @@ -472,12 +477,12 @@ to match when minimizing crashes. This will make minimization less useful, but may prevent the tool from "jumping" from one crashing condition to another in very buggy software. You probably want to combine it with the -e flag. -## 7) Settings for afl-analyze +## 8) Settings for afl-analyze You can set AFL_ANALYZE_HEX to get file offsets printed as hexadecimal instead of decimal. -## 8) Settings for libdislocator +## 9) Settings for libdislocator The library honors these environmental variables: @@ -499,12 +504,12 @@ The library honors these environmental variables: - AFL_ALIGNED_ALLOC=1 will force the alignment of the allocation size to max_align_t to be compliant with the C standard. -## 9) Settings for libtokencap +## 10) Settings for libtokencap This library accepts AFL_TOKEN_FILE to indicate the location to which the discovered tokens should be written. -## 10) Third-party variables set by afl-fuzz & other tools +## 11) Third-party variables set by afl-fuzz & other tools Several variables are not directly interpreted by afl-fuzz, but are set to optimal values if not already present in the environment: diff --git a/docs/ideas.md b/docs/ideas.md index 65e2e8e6..a5d40963 100644 --- a/docs/ideas.md +++ b/docs/ideas.md @@ -3,49 +3,6 @@ In the following, we describe a variety of ideas that could be implemented 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 (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 -about the target. - -A developer may choose to provide dictionaries and implement own mutations -in python or C, but an easy mutator that behaves according to a given grammar, -does not exist. - -State-of-the-art research on grammar fuzzing has some problems in their -implementations like code quality, scalability, or ease of use and other -common issues of the academic code. - -We aim to develop a pluggable grammar mutator for afl++ that combines -various results. - -Mentor: andreafioraldi - -## perf-fuzz Linux Kernel Module - -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 - -## QEMU 5-based Instrumentation - -First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior -changed, which vastly decreases fuzzing speeds. - -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. - -Mentor: andreafioraldi - ## WASM Instrumentation Currently, AFL++ can be used for source code fuzzing and traditional binaries. @@ -66,20 +23,6 @@ Either improve a single mutator thorugh learning of many different bugs Mentor: domenukk -## 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 -be the parent process and exec child processes. -Instead, afl-fuzz could be refactored to contain no global state and globals. -This allows for different use cases that could be implemented during this -project. -Note that in the mean time a lot has happened here already, but e.g. making -it all work and implement multithreading in afl-fuzz ... there is still quite -some work to do. - -Mentor: hexcoder- or vanhauser-thc - ## Collision-free Binary-Only Maps AFL++ supports collison-free maps using an LTO (link-time-optimization) pass. diff --git a/docs/life_pro_tips.md b/docs/life_pro_tips.md index a5bd7286..0004c297 100644 --- a/docs/life_pro_tips.md +++ b/docs/life_pro_tips.md @@ -30,10 +30,10 @@ Check out the `fuzzer_stats` file in the AFL output dir or try `afl-whatsup`. It could be important - consult docs/status_screen.md right away! ## Know your target? Convert it to persistent mode for a huge performance gain! -Consult section #5 in llvm_mode/README.md for tips. +Consult section #5 in README.llvm.md for tips. ## Using clang? -Check out llvm_mode/ for a faster alternative to afl-gcc! +Check out instrumentation/ for a faster alternative to afl-gcc! ## Did you know that AFL can fuzz closed-source or cross-platform binaries? Check out qemu_mode/README.md and unicorn_mode/README.md for more. diff --git a/docs/perf_tips.md b/docs/perf_tips.md index 731dc238..fbcb4d8d 100644 --- a/docs/perf_tips.md +++ b/docs/perf_tips.md @@ -51,7 +51,7 @@ a file. ## 3. Use LLVM instrumentation When fuzzing slow targets, you can gain 20-100% performance improvement by -using the LLVM-based instrumentation mode described in [the llvm_mode README](../llvm_mode/README.md). +using the LLVM-based instrumentation mode described in [the instrumentation README](../instrumentation/README.llvm.md). Note that this mode requires the use of clang and will not work with GCC. The LLVM mode also offers a "persistent", in-process fuzzing mode that can @@ -62,12 +62,12 @@ modes require you to edit the source code of the fuzzed program, but the changes often amount to just strategically placing a single line or two. If there are important data comparisons performed (e.g. `strcmp(ptr, MAGIC_HDR)`) -then using laf-intel (see llvm_mode/README.laf-intel.md) will help `afl-fuzz` a lot +then using laf-intel (see instrumentation/README.laf-intel.md) will help `afl-fuzz` a lot to get to the important parts in the code. If you are only interested in specific parts of the code being fuzzed, you can instrument_files the files that are actually relevant. This improves the speed and -accuracy of afl. See llvm_mode/README.instrument_list.md +accuracy of afl. See instrumentation/README.instrument_list.md Also use the InsTrim mode on larger binaries, this improves performance and coverage a lot. @@ -110,7 +110,7 @@ e.g.: https://launchpad.net/libeatmydata In programs that are slow due to unavoidable initialization overhead, you may -want to try the LLVM deferred forkserver mode (see llvm_mode/README.md), +want to try the LLVM deferred forkserver mode (see README.llvm.md), which can give you speed gains up to 10x, as mentioned above. Last but not least, if you are using ASAN and the performance is unacceptable, diff --git a/docs/sister_projects.md b/docs/sister_projects.md index a501ecbd..640e59f7 100644 --- a/docs/sister_projects.md +++ b/docs/sister_projects.md @@ -52,7 +52,7 @@ options. Provides an evolutionary instrumentation-guided fuzzing harness that allows some programs to be fuzzed without the fork / execve overhead. (Similar functionality is now available as the "persistent" feature described in -[the llvm_mode readme](../llvm_mode/README.md)) +[the llvm_mode readme](../instrumentation/README.llvm.md)) http://llvm.org/docs/LibFuzzer.html @@ -245,7 +245,7 @@ https://code.google.com/p/address-sanitizer/wiki/AsanCoverage#Coverage_counters ### AFL JS (Han Choongwoo) One-off optimizations to speed up the fuzzing of JavaScriptCore (now likely -superseded by LLVM deferred forkserver init - see llvm_mode/README.md). +superseded by LLVM deferred forkserver init - see README.llvm.md). https://github.com/tunz/afl-fuzz-js diff --git a/docs/status_screen.md b/docs/status_screen.md index b89468ce..2eeb8f3f 100644 --- a/docs/status_screen.md +++ b/docs/status_screen.md @@ -324,7 +324,7 @@ there are several things to look at: - Multiple threads executing at once in semi-random order. This is harmless when the 'stability' metric stays over 90% or so, but can become an issue if not. Here's what to try: - * Use afl-clang-fast from [llvm_mode](../llvm_mode/) - it uses a thread-local tracking + * Use afl-clang-fast from [instrumentation](../instrumentation/) - it uses a thread-local tracking model that is less prone to concurrency issues, * See if the target can be compiled or run without threads. Common `./configure` options include `--without-threads`, `--disable-pthreads`, or diff --git a/examples/README.md b/examples/README.md index d28aadbe..46a92c6e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -47,7 +47,7 @@ Here's a quick overview of the stuff you can find in this directory: Note that the minimize_corpus.sh tool has graduated from the examples/ directory and is now available as ../afl-cmin. The LLVM mode has likewise -graduated to ../llvm_mode/*. +graduated to ../instrumentation/*. Most of the tools in this directory are meant chiefly as examples that need to be tweaked for your specific needs. They come with some basic documentation, diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c index ff5446e9..82e55fc4 100644 --- a/examples/aflpp_driver/aflpp_driver.c +++ b/examples/aflpp_driver/aflpp_driver.c @@ -27,7 +27,7 @@ EOF # Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang. clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c # Build afl-llvm-rt.o.c from the AFL distribution. -clang -c -w $AFL_HOME/llvm_mode/afl-llvm-rt.o.c +clang -c -w $AFL_HOME/instrumentation/afl-llvm-rt.o.c # Build this file, link it with afl-llvm-rt.o.o and the target code. clang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o # Run AFL: diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 4281c554..9e469864 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -935,6 +935,7 @@ u8 has_new_bits(afl_state_t *, u8 *); void load_extras_file(afl_state_t *, u8 *, u32 *, u32 *, u32); void load_extras(afl_state_t *, u8 *); +void dedup_extras(afl_state_t *); void add_extra(afl_state_t *afl, u8 *mem, u32 len); void maybe_add_auto(afl_state_t *, u8 *, u32); void save_auto(afl_state_t *); @@ -972,7 +973,7 @@ u8 fuzz_one(afl_state_t *); void bind_to_free_cpu(afl_state_t *); #endif void setup_post(afl_state_t *); -void read_testcases(afl_state_t *); +void read_testcases(afl_state_t *, u8 *); void perform_dry_run(afl_state_t *); void pivot_inputs(afl_state_t *); u32 find_start_position(afl_state_t *); diff --git a/include/config.h b/include/config.h index 77407d50..8cc70075 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.68c" +#define VERSION "++3.00a" /****************************************************** * * @@ -195,7 +195,7 @@ steps; past this point, the "extras/user" step will be still carried out, but with proportionally lower odds: */ -#define MAX_DET_EXTRAS 200 +#define MAX_DET_EXTRAS 256 /* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing (first value), and to keep in memory as candidates. The latter should be much diff --git a/include/envs.h b/include/envs.h index 2dc1dbbf..d9968fcd 100644 --- a/include/envs.h +++ b/include/envs.h @@ -69,6 +69,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX", + "AFL_LLVM_DICT2FILE", "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h index 63b7581d..0e38f38b 100644 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-inl.h @@ -466,7 +466,7 @@ void afl_forkserver(CPUState *cpu) { } /* A simplified persistent mode handler, used as explained in - * llvm_mode/README.md. */ + * instrumentation/README.llvm.md */ void afl_persistent_loop(void) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 713849a1..1351d274 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -626,6 +626,7 @@ if (dir == NULL) { if (!access(fn1, F_OK)) { afl->in_dir = fn1; + subdirs = 0; } else { @@ -1063,7 +1064,7 @@ restart_outer_cull_loop: } - afl->q_prev100 = afl->queue = afl->queue_top = afl->queue; + afl->queue = afl->queue_top = afl->queue; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index db91813b..af52aa45 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -138,8 +138,7 @@ static u8 check_if_text(struct queue_entry *q) { } // non-overlong 2-byte - if (len - offset > 1 && - ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && + if (len - offset > 1 && ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { offset += 2; @@ -230,7 +229,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } else { - afl->q_prev100 = afl->queue = afl->queue_top = q; + afl->queue = afl->queue_top = q; } @@ -274,15 +273,15 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - struct queue_entry *q = afl->queue, *n; + struct queue_entry *q; + u32 i; - while (q) { + for (i = 0; i < afl->queued_paths; i++) { - n = q->next; + q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); ck_free(q); - q = n; } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 51eed14b..c60c65aa 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -982,10 +982,9 @@ void show_stats(afl_state_t *afl) { void show_init_stats(afl_state_t *afl) { struct queue_entry *q = afl->queue; - u32 min_bits = 0, max_bits = 0; + u32 min_bits = 0, max_bits = 0, max_len = 0, count = 0; u64 min_us = 0, max_us = 0; u64 avg_us = 0; - u32 max_len = 0; u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX]; #define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)]) @@ -1006,6 +1005,7 @@ void show_init_stats(afl_state_t *afl) { if (q->len > max_len) { max_len = q->len; } + ++count; q = q->next; } @@ -1072,10 +1072,10 @@ void show_init_stats(afl_state_t *afl) { OKF("Here are some useful stats:\n\n" cGRA " Test case count : " cRST - "%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST + "%u favored, %u variable, %u ignored, %u total\n" cGRA " Bitmap range : " cRST "%u to %u bits (average: %0.02f bits)\n" cGRA " Exec timing : " cRST "%s to %s us (average: %s us)\n", - afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits, + afl->queued_favored, afl->queued_variable, afl->queued_paths - count, afl->queued_paths, min_bits, max_bits, ((double)afl->total_bitmap_size) / (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1), diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bfaa22e8..73ca6aaa 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1133,8 +1133,9 @@ int main(int argc, char **argv_orig, char **envp) { setup_cmdline_file(afl, argv + optind); - read_testcases(afl); + read_testcases(afl, NULL); // read_foreign_testcases(afl, 1); for the moment dont do this + OKF("Loaded a total of %u seeds.", afl->queued_paths); load_auto(afl); diff --git a/test/test-gcc-plugin.sh b/test/test-gcc-plugin.sh index 2ed10a72..8b8cbd8e 100755 --- a/test/test-gcc-plugin.sh +++ b/test/test-gcc-plugin.sh @@ -3,7 +3,7 @@ . ./test-pre.sh $ECHO "$BLUE[*] Testing: gcc_plugin" -test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { +test -e ../afl-gcc-fast -a -e ../afl-compiler-rt.o && { SAVE_AFL_CC=${AFL_CC} export AFL_CC=`command -v gcc` ../afl-gcc-fast -o test-instr.plain.gccpi ../test-instr.c > /dev/null 2>&1 diff --git a/test/test-unittests.sh b/test/test-unittests.sh index f540b5f8..58c2eea9 100755 --- a/test/test-unittests.sh +++ b/test/test-unittests.sh @@ -7,3 +7,5 @@ unset AFL_CC make -C .. unit || CODE=1 INCOMPLETE=1 : . ./test-post.sh + +rm -rf unittests/unit_hash unittests/unit_rand -- cgit 1.4.1 From 1225f3aa70c797752c9a9a9c1e8b8aadf3a855dc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 18 Sep 2020 10:29:49 +0200 Subject: improved defaults from fuzzbench results --- include/config.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 8cc70075..86285944 100644 --- a/include/config.h +++ b/include/config.h @@ -109,12 +109,12 @@ /* Maximum multiplier for the above (should be a power of two, beware of 32-bit int overflows): */ -#define HAVOC_MAX_MULT 16 +#define HAVOC_MAX_MULT 32 #define HAVOC_MAX_MULT_MOPT 32 /* Absolute minimum number of havoc cycles (after all adjustments): */ -#define HAVOC_MIN 16 +#define HAVOC_MIN 12 /* Power Schedule Divisor */ #define POWER_BETA 1 @@ -126,10 +126,10 @@ n = random between 1 and HAVOC_STACK_POW2 stacking = 2^n - In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or - 128 stacked tweaks: */ + In other words, the default (n = 6) produces 2, 4, 8, 16, 32, or 64 + stacked tweaks: */ -#define HAVOC_STACK_POW2 7 +#define HAVOC_STACK_POW2 6 /* Caps on block sizes for cloning and deletion operations. Each of these ranges has a 33% probability of getting picked, except for the first -- cgit 1.4.1 From e38ca0e7508752c8a8d1e87d4bb215d90126babf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 25 Sep 2020 10:48:08 +0200 Subject: setting HAVOC_STACK_POW2 to 4, as fuzzbench shows that too mach mutation is less effective --- include/config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 86285944..a01491e7 100644 --- a/include/config.h +++ b/include/config.h @@ -126,17 +126,17 @@ n = random between 1 and HAVOC_STACK_POW2 stacking = 2^n - In other words, the default (n = 6) produces 2, 4, 8, 16, 32, or 64 + In other words, the default (n = 4) produces 2, 4, 8, 16 stacked tweaks: */ -#define HAVOC_STACK_POW2 6 +#define HAVOC_STACK_POW2 4 /* Caps on block sizes for cloning and deletion operations. Each of these ranges has a 33% probability of getting picked, except for the first two cycles where smaller blocks are favored: */ #define HAVOC_BLK_SMALL 32 -#define HAVOC_BLK_MEDIUM 128 +#define HAVOC_BLK_MEDIUM 128 #define HAVOC_BLK_LARGE 1500 /* Extra-large blocks, selected very rarely (<5% of the time): */ -- cgit 1.4.1 From 6b3b1775b6b274bc62f9c79f686fc79fa110d0a8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 25 Sep 2020 12:03:24 +0200 Subject: improving on splice candidate check patch --- include/afl-fuzz.h | 4 ++-- include/config.h | 2 +- src/afl-fuzz-one.c | 33 +++++++++------------------------ src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-state.c | 48 +++++++++++++----------------------------------- 5 files changed, 26 insertions(+), 63 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 0efd48ec..441ecc61 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -483,7 +483,7 @@ typedef struct afl_state { disable_trim, /* Never trim in fuzz_one */ shmem_testcase_mode, /* If sharedmem testcases are used */ expand_havoc, /* perform expensive havoc after no find */ - cycle_schedules; /* cycle power schedules ? */ + cycle_schedules; /* cycle power schedules? */ u8 *virgin_bits, /* Regions yet untouched by fuzzing */ *virgin_tmout, /* Bits we haven't seen in tmouts */ @@ -657,7 +657,7 @@ typedef struct afl_state { * they do not call another function */ u8 *map_tmp_buf; - /* queue entries ready for splicing count (len > 1) */ + /* queue entries ready for splicing count (len > 4) */ u32 ready_for_splicing_count; } afl_state_t; diff --git a/include/config.h b/include/config.h index a01491e7..7c8e0c7d 100644 --- a/include/config.h +++ b/include/config.h @@ -136,7 +136,7 @@ two cycles where smaller blocks are favored: */ #define HAVOC_BLK_SMALL 32 -#define HAVOC_BLK_MEDIUM 128 +#define HAVOC_BLK_MEDIUM 128 #define HAVOC_BLK_LARGE 1500 /* Extra-large blocks, selected very rarely (<5% of the time): */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 8c1aa179..e96c4311 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1699,36 +1699,22 @@ custom_mutator_stage: u8 * new_buf = NULL; u32 target_len = 0; - /* check if splicing is possible (if the only entry has len > 1 - * check it is not current entry) - */ - if (afl->ready_for_splicing_count > 1 || - (afl->ready_for_splicing_count == 1 && - afl->queue_cur->len == 1)) { + /* check if splicing makes sense yet (enough entries) */ + if (likely(afl->ready_for_splicing_count > 1)) { - retry_external_pick: - /* Pick a random other queue entry for passing to external API */ + /* Pick a random other queue entry for passing to external API + that has the necessary length */ do { tid = rand_below(afl, afl->queued_paths); - } while (tid == afl->current_entry && afl->queued_paths > 1); - - afl->splicing_with = tid; - target = afl->queue_buf[tid]; - - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 2) { - - target = target->next; - ++afl->splicing_with; + } while (unlikely(tid == afl->current_entry && - } + afl->queue_buf[tid]->len >= 4)); - if (!target) { goto retry_external_pick; } + target = afl->queue_buf[tid]; + afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); @@ -2773,8 +2759,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { len = afl->queue_cur->len; /* maybe current entry is not ready for splicing anymore */ - if (old_len > 1 && afl->queue_cur->len == 1) - afl->ready_for_splicing_count--; + if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 14aa34fc..53c3e984 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -234,7 +234,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - if (q->len > 1) afl->ready_for_splicing_count++; + if (likely(q->len > 4)) afl->ready_for_splicing_count++; ++afl->queued_paths; ++afl->pending_not_fuzzed; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 9f68bb51..5e0995fe 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -95,6 +95,11 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stage_name = "init"; /* Name of the current fuzz stage */ afl->splicing_with = -1; /* Splicing with which test case? */ afl->cpu_to_bind = -1; + afl->cal_cycles = CAL_CYCLES; + afl->cal_cycles_long = CAL_CYCLES_LONG; + afl->hang_tmout = EXEC_TIMEOUT; + afl->stats_update_freq = 1; + afl->stats_avg_exec = -1; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -115,48 +120,13 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { // afl_state_t is not available in forkserver.c afl->fsrv.afl_ptr = (void *)afl; afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) & add_extra; - - afl->cal_cycles = CAL_CYCLES; - afl->cal_cycles_long = CAL_CYCLES_LONG; - afl->fsrv.exec_tmout = EXEC_TIMEOUT; - afl->hang_tmout = EXEC_TIMEOUT; - afl->fsrv.mem_limit = MEM_LIMIT; - - afl->stats_update_freq = 1; - afl->fsrv.dev_urandom_fd = -1; afl->fsrv.dev_null_fd = -1; - afl->fsrv.child_pid = -1; afl->fsrv.out_dir_fd = -1; - afl->cmplog_prev_timed_out = 0; - - /* statis file */ - afl->last_bitmap_cvg = 0; - afl->last_stability = 0; - afl->last_eps = 0; - - /* plot file saves from last run */ - afl->plot_prev_qp = 0; - afl->plot_prev_pf = 0; - afl->plot_prev_pnf = 0; - afl->plot_prev_ce = 0; - afl->plot_prev_md = 0; - afl->plot_prev_qc = 0; - afl->plot_prev_uc = 0; - afl->plot_prev_uh = 0; - - afl->stats_last_stats_ms = 0; - afl->stats_last_plot_ms = 0; - afl->stats_last_ms = 0; - afl->stats_last_execs = 0; - afl->stats_avg_exec = -1; - - afl->ready_for_splicing_count = 0; - init_mopt_globals(afl); list_append(&afl_states, afl); @@ -177,6 +147,14 @@ void read_afl_environment(afl_state_t *afl, char **envp) { WARNF("Potentially mistyped AFL environment variable: %s", env); issue_detected = 1; + } else if (strncmp(env, "USE_", 4) == 0) { + + WARNF( + "Potentially mistyped AFL environment variable: %s, did you mean " + "AFL_%s?", + env, env); + issue_detected = 1; + } else if (strncmp(env, "AFL_", 4) == 0) { int i = 0, match = 0; -- cgit 1.4.1 From 26dcddab0cdb3ca662746b1fd02cd58de3266269 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sat, 3 Oct 2020 23:56:55 +0200 Subject: Add config ifdef --- include/config.h | 6 ++++++ src/afl-fuzz-run.c | 2 ++ 2 files changed, 8 insertions(+) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 77407d50..104276e3 100644 --- a/include/config.h +++ b/include/config.h @@ -41,6 +41,12 @@ #define USE_COLOR +/* Enable sending statistics over a StatsD daemon. +Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. +*/ + +#define USE_STATSD + /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8dc0b334..b7c4ae05 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -901,10 +901,12 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); + #ifdef USE_STATSD if(send_statsd_metric(afl)){ //Change me to something realistic; don't fail on connection / lookup fail for metrics... exit(1); } + #endif } return 0; -- cgit 1.4.1 From 6006cce0cf012884d1509c00ef0f088aeac66bb7 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 03:24:09 +0200 Subject: Define config, change parent func to show_stats --- include/config.h | 1 + src/afl-fuzz-run.c | 6 ------ src/afl-fuzz-stats.c | 8 ++++++++ 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 104276e3..c55dda2b 100644 --- a/include/config.h +++ b/include/config.h @@ -46,6 +46,7 @@ Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. */ #define USE_STATSD +#define STATSD_UPDATE_SEC 1 /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b7c4ae05..6fa142d2 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -901,12 +901,6 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); - #ifdef USE_STATSD - if(send_statsd_metric(afl)){ - //Change me to something realistic; don't fail on connection / lookup fail for metrics... - exit(1); - } - #endif } return 0; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 51eed14b..bbbe6ba6 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -422,6 +422,14 @@ void show_stats(afl_state_t *afl) { } + #ifdef USE_STATSD + if (cur_ms - afl->stats_last_stats_ms > STATSD_UPDATE_SEC * 1000) { + if(send_statsd_metric(afl)){ + WARNF("coundln't send statsd metric."); + } + } + #endif + /* Every now and then, write plot data. */ if (cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000) { -- cgit 1.4.1 From ca6106a1dc5b39df9f167b3d30ea4472636564c9 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 14:24:25 +0200 Subject: Refactor --- include/afl-fuzz.h | 4 ++- include/config.h | 2 ++ src/afl-fuzz-stats.c | 6 +++-- src/afl-fuzz-statsd.c | 73 ++++++++++++++++++++++++++------------------------- 4 files changed, 46 insertions(+), 39 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index eecfcf75..f341e300 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -635,6 +635,8 @@ typedef struct afl_state { u64 plot_prev_qc, plot_prev_uc, plot_prev_uh, plot_prev_ed; u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_ms, stats_last_execs; + // StatsD + u64 statsd_last_send_ms; double stats_avg_exec; u8 *clean_trace; @@ -957,7 +959,7 @@ void show_init_stats(afl_state_t *); /* StatsD */ int statsd_socket_init(char *host, int port); -int send_statsd_metric(afl_state_t *afl); +int statsd_send_metric(afl_state_t *afl); int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen); /* Run */ diff --git a/include/config.h b/include/config.h index c55dda2b..8cdf0633 100644 --- a/include/config.h +++ b/include/config.h @@ -47,6 +47,8 @@ Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. #define USE_STATSD #define STATSD_UPDATE_SEC 1 +#define STATSD_DEFAULT_PORT 8125 +#define STATSD_DEFAULT_HOST "127.0.0.1" /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bbbe6ba6..ffef7647 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,8 +423,10 @@ void show_stats(afl_state_t *afl) { } #ifdef USE_STATSD - if (cur_ms - afl->stats_last_stats_ms > STATSD_UPDATE_SEC * 1000) { - if(send_statsd_metric(afl)){ + if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { + /* reset counter, even if send failed. */ + afl->statsd_last_send_ms = cur_ms; + if(statsd_send_metric(afl)){ WARNF("coundln't send statsd metric."); } } diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index d9cd12d2..5bd1b537 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -13,11 +13,12 @@ #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" -int sock = 0; struct sockaddr_in server; int error = 0; +int statds_sock = 0; int statsd_socket_init(char *host, int port){ + int sock; if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ perror("socket"); exit(1); @@ -42,72 +43,72 @@ int statsd_socket_init(char *host, int port){ memcpy(&(server.sin_addr), &((struct sockaddr_in*)result->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(result); - return 0; + return sock; } -int send_statsd_metric(afl_state_t *afl){ - /* default port and host. +int statsd_send_metric(afl_state_t *afl){ + + char buff[MAX_STATSD_PACKET_SIZE] = {0}; + /* Default port and host. Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment variable, if they exists. - */ - u16 port = 8125; - char* host = "127.0.0.1"; + */ + u16 port = STATSD_DEFAULT_PORT; + char* host = STATSD_DEFAULT_HOST; char* port_env; char* host_env; if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { - // sanitization check ? port = atoi(port_env); } if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { - // sanitization check ? host = host_env; } - - error = statsd_socket_init(host, port); - if (error){ - perror("Failed to init statsd client. Aborting"); - return -1; - } - - if(!sock){ - perror("sock"); - return -1; - } - char buff[MAX_STATSD_PACKET_SIZE] = {0}; + /* statds_sock is a global variable. We set it once in the beginning and reuse the socket. + If the sendto later fail, we reset it to 0 to be able to recreate it. + */ + if(!statds_sock){ + statds_sock = statsd_socket_init(host, port); + if(!statds_sock){ + perror("Cannot create socket"); + return -1; + } + } statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(sock, buff, strlen(buff), 0, - (struct sockaddr *)&server, sizeof(server)) == -1) { - perror("sendto"); - return -1; + if (sendto(statds_sock, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server)) == -1) { + if(!close(statds_sock)){ + perror("Cannot close socket"); + } + statds_sock = 0; + perror("Cannot sendto"); + return -1; } - close(sock); - sock=0; - return 0; } int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ - /* - metric format: - :|| - tags format: + /* Metric format: + :| */ #ifdef USE_STATSD_TAGS - /* #key:value,key:value,key + /* Tags format: DogStatsD + :||#key:value,key:value,key */ char tags[MAX_TAG_LEN * 2] = {0}; snprintf(tags, MAX_TAG_LEN * 2, "|#banner:%s,afl_version:%s", afl->use_banner, VERSION); - #else + #else + /* No tags. + */ char *tags = ""; #endif - // Sends multiple metrics with one UDP Packet. - // bufflen will limit to the max safe size. + /* Sends multiple metrics with one UDP Packet. + bufflen will limit to the max safe size. + */ snprintf(buff, bufflen, METRIC_PREFIX".cycle_done:%llu|g%s\n" METRIC_PREFIX".cycles_wo_finds:%llu|g%s\n" -- cgit 1.4.1 From b0de6fed11d4a8de8f016f1d8db0cb19a6b96eb2 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 14:29:50 +0200 Subject: Mention tags format in macro's name --- include/config.h | 3 +++ src/afl-fuzz-statsd.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 8cdf0633..33113318 100644 --- a/include/config.h +++ b/include/config.h @@ -50,6 +50,9 @@ Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. #define STATSD_DEFAULT_PORT 8125 #define STATSD_DEFAULT_HOST "127.0.0.1" +/* comment out to disable tags. */ +#define USE_DOGSTATSD_TAGS + /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 5bd1b537..298138be 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -92,7 +92,7 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ /* Metric format: :| */ - #ifdef USE_STATSD_TAGS + #ifdef USE_DOGSTATSD_TAGS /* Tags format: DogStatsD :||#key:value,key:value,key */ -- cgit 1.4.1 From a4b60ca5b61c9bca5fa7b67528baeb3a8ea9320e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 15:37:59 +0200 Subject: testcase cache added --- include/afl-fuzz.h | 15 ++++++ include/config.h | 8 +++ src/afl-fuzz-one.c | 148 ++++++++++++++++++--------------------------------- src/afl-fuzz-queue.c | 65 ++++++++++++++++++++++ src/afl-fuzz.c | 3 +- 5 files changed, 142 insertions(+), 97 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index fb661ce5..46da8c7d 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -162,6 +162,9 @@ struct queue_entry { u8 *trace_mini; /* Trace bytes, if kept */ u32 tc_ref; /* Trace bytes ref count */ + u8 *testcase_buf; /* The testcase buffer, if loaded. */ + u32 testcase_refs; /* count of users of testcase buf */ + struct queue_entry *next; /* Next element, if any */ }; @@ -664,6 +667,11 @@ typedef struct afl_state { /* queue entries ready for splicing count (len > 4) */ u32 ready_for_splicing_count; + /* How many queue entries currently have cached testcases */ + u32 q_testcase_cache_count; + /* Refs to each queue entry with cached testcase (for eviction, if cache_count is too large) */ + struct queue_entry *q_testcase_cache[TESTCASE_CACHE_SIZE]; + } afl_state_t; struct custom_mutator { @@ -1101,5 +1109,12 @@ static inline u64 next_p2(u64 val) { } +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q); + +/* Tell afl that this testcase may be evicted from the cache */ +void queue_testcase_release(afl_state_t *afl, struct queue_entry *q); + #endif diff --git a/include/config.h b/include/config.h index 7c8e0c7d..38a734ce 100644 --- a/include/config.h +++ b/include/config.h @@ -295,6 +295,14 @@ #define RESEED_RNG 100000 +/* The amount of entries in the testcase cache, held in memory. +Decrease if RAM usage is high. */ +#define TESTCASE_CACHE_SIZE 2048 + +#if TESTCASE_CACHE_SIZE < 4 + #error "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h! +#endif + /* Maximum line length passed from GCC to 'as' and used for parsing configuration files: */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c04b492b..20558618 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, fd, temp_len; + s32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,28 +453,9 @@ u8 fuzz_one_original(afl_state_t *afl) { } - /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", afl->queue_cur->fname); - - } - + orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(orig_in == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); - - } - - close(fd); - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -1694,7 +1675,7 @@ custom_mutator_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - struct queue_entry *target; + struct queue_entry *target = NULL; u32 tid; u8 * new_buf = NULL; u32 target_len = 0; @@ -1717,17 +1698,7 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + new_buf = queue_testcase_take(afl, target); target_len = target->len; } @@ -1738,6 +1709,11 @@ custom_mutator_stage: el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, target_len, max_seed_size); + if (new_buf) { + queue_testcase_release(afl, target); + new_buf = NULL; + } + if (unlikely(!mutated_buf)) { FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); @@ -2320,51 +2296,44 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk from another testcase or insert that chunk. */ - if (afl->queued_paths < 4) break; + if (afl->queued_paths < 4) { break; } /* Pick a random queue entry and seek to it. */ u32 tid; - do + do { tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry); + } while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ - while (target && (target->len < 2 || target == afl->queue_cur)) + while (target && (target->len < 2 || target == afl->queue_cur)) { target = target->next; + } - if (!target) break; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { + if (!target) { break; } - PFATAL("Unable to open '%s'", target->fname); - - } u32 new_len = target->len; - u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, new_len, target->fname); - close(fd); + /* Get the testcase contents for splicing. */ + u8 *new_buf = queue_testcase_take(afl, target); u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) + if (temp_len >= 2 && rand_below(afl, 2)) { overwrite = 1; + } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { - if (temp_len >= 2) + if (temp_len >= 2) { overwrite = 1; - else + } else { + queue_testcase_release(afl, target); + new_buf = NULL; break; + } } @@ -2411,6 +2380,9 @@ havoc_stage: } + /* We don't need this splice testcase anymore */ + queue_testcase_release(afl, target); + new_buf = NULL; break; } @@ -2516,24 +2488,16 @@ retry_splicing: if (!target) { goto retry_splicing; } - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - + /* Get the testcase buffer */ + u8 *splice_buf = queue_testcase_take(afl, target); new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); - /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); + locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -2545,6 +2509,7 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); + memcpy(new_buf + split_at, splice_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; @@ -2552,6 +2517,9 @@ retry_splicing: if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); + queue_testcase_release(afl, target); + splice_buf = NULL; + goto custom_mutator_stage; /* ???: While integrating Python module, the author decided to jump to python stage, but the reason behind this is not clear.*/ @@ -2582,7 +2550,8 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - munmap(orig_in, afl->queue_cur->len); + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; return ret_val; @@ -2604,7 +2573,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, fd, temp_len; + s32 len, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2669,23 +2638,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } - + orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (orig_in == MAP_FAILED) { - - PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); - - } - - close(fd); - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -4522,31 +4477,24 @@ pacemaker_fuzzing: if (!target) { goto retry_splicing_puppet; } /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + u8 *splicing_buf = queue_testcase_take(afl, target); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, + locate_diffs(in_buf, splicing_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { + queue_testcase_release(afl, target); goto retry_splicing_puppet; } + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + /* Split somewhere between the first and last differing byte. */ split_at = f_diff + rand_below(afl, l_diff - f_diff); @@ -4555,12 +4503,16 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); + memcpy(new_buf + split_at, splicing_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); + queue_testcase_release(afl, target); + splicing_buf = NULL; + goto havoc_stage_puppet; } /* if splice_cycle */ @@ -4594,7 +4546,8 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - munmap(orig_in, afl->queue_cur->len); + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; if (afl->key_puppet == 1) { @@ -4730,6 +4683,9 @@ pacemaker_fuzzing: } /* block */ + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; + return ret_val; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 0d7d0314..e2387aaa 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -220,6 +220,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->trace_mini = NULL; + q->testcase_buf = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } @@ -767,3 +768,67 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } +/* Tell afl that this testcase may be evicted from the cache */ +inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { + (void) afl; + q->testcase_refs--; + if (unlikely(q->testcase_refs < 0)) { FATAL("Testcase refcount smaller than 0"); } +} + +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { + if (!q->testcase_buf) { + u32 tid = 0; + /* Buf not cached, let's do that now */ + + if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { + /* Cache full. We neet to evict one to map one. + Get a random one which is not in use */ + do { + + tid = rand_below(afl, afl->q_testcase_cache_count); + + } while (afl->q_testcase_cache[tid]->testcase_refs > 0); + + struct queue_entry *old_cached = afl->q_testcase_cache[tid]; + /* free the current buf from cache */ + munmap(old_cached->testcase_buf, old_cached->len); + old_cached->testcase_buf = NULL; + + } else { + tid = afl->q_testcase_cache_count; + afl->q_testcase_cache_count++; + } + + /* Map the test case into memory. */ + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", q->fname); + + } + + u32 len = q->len; + + q->testcase_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (unlikely(q->testcase_buf == MAP_FAILED)) { + + PFATAL("Unable to mmap '%s' with len %d", q->fname, len); + + } + + close(fd); + + /* Register us as cached */ + afl->q_testcase_cache[tid] = q; + + } + q->testcase_refs++; + if (!q->testcase_buf) { FATAL("Testcase buf is NULL, this should never happen"); } + return q->testcase_buf; + +} diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2f8aa3fd..dd9aaa8f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1152,8 +1152,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { - for (i = 0; i < extras_dir_cnt; i++) + for (i = 0; i < extras_dir_cnt; i++) { load_extras(afl, extras_dir[i]); + } dedup_extras(afl); OKF("Loaded a total of %u extras.", afl->extras_cnt); -- cgit 1.4.1 From 74dc227c4412d0121c9b972e5d89db89f54c6b3a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 15:38:36 +0200 Subject: code format --- include/afl-fuzz.h | 5 +++-- include/config.h | 3 ++- src/afl-fuzz-one.c | 22 +++++++++++++++++----- src/afl-fuzz-queue.c | 34 ++++++++++++++++++++++++---------- src/afl-fuzz.c | 2 ++ 5 files changed, 48 insertions(+), 18 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 46da8c7d..5ab787e0 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -163,7 +163,7 @@ struct queue_entry { u32 tc_ref; /* Trace bytes ref count */ u8 *testcase_buf; /* The testcase buffer, if loaded. */ - u32 testcase_refs; /* count of users of testcase buf */ + u32 testcase_refs; /* count of users of testcase buf */ struct queue_entry *next; /* Next element, if any */ @@ -669,7 +669,8 @@ typedef struct afl_state { /* How many queue entries currently have cached testcases */ u32 q_testcase_cache_count; - /* Refs to each queue entry with cached testcase (for eviction, if cache_count is too large) */ + /* Refs to each queue entry with cached testcase (for eviction, if cache_count + * is too large) */ struct queue_entry *q_testcase_cache[TESTCASE_CACHE_SIZE]; } afl_state_t; diff --git a/include/config.h b/include/config.h index 38a734ce..ec378036 100644 --- a/include/config.h +++ b/include/config.h @@ -300,7 +300,8 @@ Decrease if RAM usage is high. */ #define TESTCASE_CACHE_SIZE 2048 #if TESTCASE_CACHE_SIZE < 4 - #error "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h! + #error \ + "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h! #endif /* Maximum line length passed from GCC to 'as' and used for parsing diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 20558618..a5f77f11 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1710,8 +1710,10 @@ custom_mutator_stage: target_len, max_seed_size); if (new_buf) { + queue_testcase_release(afl, target); new_buf = NULL; + } if (unlikely(!mutated_buf)) { @@ -2302,7 +2304,9 @@ havoc_stage: u32 tid; do { + tid = rand_below(afl, afl->queued_paths); + } while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; @@ -2310,12 +2314,13 @@ havoc_stage: /* Make sure that the target has a reasonable length. */ while (target && (target->len < 2 || target == afl->queue_cur)) { + target = target->next; + } if (!target) { break; } - u32 new_len = target->len; /* Get the testcase contents for splicing. */ @@ -2323,16 +2328,21 @@ havoc_stage: u8 overwrite = 0; if (temp_len >= 2 && rand_below(afl, 2)) { + overwrite = 1; - } - else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + + } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { if (temp_len >= 2) { + overwrite = 1; + } else { + queue_testcase_release(afl, target); new_buf = NULL; break; + } } @@ -2497,7 +2507,8 @@ retry_splicing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); + locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, + &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -4503,7 +4514,8 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splicing_buf + split_at, target->len - split_at); + memcpy(new_buf + split_at, splicing_buf + split_at, + target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index e2387aaa..721f9ac7 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -770,24 +770,33 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { /* Tell afl that this testcase may be evicted from the cache */ inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { - (void) afl; + + (void)afl; q->testcase_refs--; - if (unlikely(q->testcase_refs < 0)) { FATAL("Testcase refcount smaller than 0"); } + if (unlikely(q->testcase_refs < 0)) { + + FATAL("Testcase refcount smaller than 0"); + + } + } /* Returns the testcase buf from the file behind this queue entry. Increases the refcount. */ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { + if (!q->testcase_buf) { + u32 tid = 0; /* Buf not cached, let's do that now */ if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { + /* Cache full. We neet to evict one to map one. Get a random one which is not in use */ do { - tid = rand_below(afl, afl->q_testcase_cache_count); + tid = rand_below(afl, afl->q_testcase_cache_count); } while (afl->q_testcase_cache[tid]->testcase_refs > 0); @@ -795,21 +804,19 @@ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { /* free the current buf from cache */ munmap(old_cached->testcase_buf, old_cached->len); old_cached->testcase_buf = NULL; - + } else { + tid = afl->q_testcase_cache_count; afl->q_testcase_cache_count++; + } /* Map the test case into memory. */ int fd = open(q->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", q->fname); - - } + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } u32 len = q->len; @@ -827,8 +834,15 @@ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { afl->q_testcase_cache[tid] = q; } + q->testcase_refs++; - if (!q->testcase_buf) { FATAL("Testcase buf is NULL, this should never happen"); } + if (!q->testcase_buf) { + + FATAL("Testcase buf is NULL, this should never happen"); + + } + return q->testcase_buf; } + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index dd9aaa8f..9b7c1445 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1153,7 +1153,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { for (i = 0; i < extras_dir_cnt; i++) { + load_extras(afl, extras_dir[i]); + } dedup_extras(afl); -- cgit 1.4.1 From 693252c737f053c6efa260320bdf23d8c68f32a4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 16:17:53 +0200 Subject: fixed missing quote warning --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index ec378036..f01ddc04 100644 --- a/include/config.h +++ b/include/config.h @@ -301,7 +301,7 @@ Decrease if RAM usage is high. */ #if TESTCASE_CACHE_SIZE < 4 #error \ - "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h! + "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h!" #endif /* Maximum line length passed from GCC to 'as' and used for parsing -- cgit 1.4.1 From 3d7bdc9f0b6892cb359fc07a0cef387851cbd8b1 Mon Sep 17 00:00:00 2001 From: Edznux Date: Tue, 6 Oct 2020 23:00:11 +0200 Subject: [WIP: segfault on non dogstatsd] Adding MACROS for format --- include/afl-fuzz.h | 13 +++-- include/config.h | 3 -- include/envs.h | 1 + src/afl-fuzz-state.c | 7 +++ src/afl-fuzz-statsd.c | 140 +++++++++++++++++++++++++++++++++++++------------- src/afl-fuzz.c | 5 ++ 6 files changed, 127 insertions(+), 42 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 92375b2c..ffb518ad 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -359,7 +359,8 @@ typedef struct afl_env_vars { u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, - *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port; + *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port, + *afl_statsd_tags_flavor; } afl_env_vars_t; @@ -638,6 +639,9 @@ typedef struct afl_state { u64 statsd_last_send_ms; struct sockaddr_in statsd_server; int statsd_sock; + char * statsd_tags_flavor; + char * statsd_tags_format; + char * statsd_metric_format; double stats_avg_exec; @@ -961,9 +965,10 @@ void show_init_stats(afl_state_t *); /* StatsD */ -int statsd_socket_init(afl_state_t *afl); -int statsd_send_metric(afl_state_t *afl); -int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen); +void statsd_setup_format(afl_state_t *afl); +int statsd_socket_init(afl_state_t *afl); +int statsd_send_metric(afl_state_t *afl); +int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen); /* Run */ diff --git a/include/config.h b/include/config.h index c0a04565..3d6b0395 100644 --- a/include/config.h +++ b/include/config.h @@ -50,9 +50,6 @@ Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. #define STATSD_DEFAULT_PORT 8125 #define STATSD_DEFAULT_HOST "127.0.0.1" -/* comment out to disable tags. */ -#define USE_DOGSTATSD_TAGS - /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ diff --git a/include/envs.h b/include/envs.h index 1fc9e83d..16da14cb 100644 --- a/include/envs.h +++ b/include/envs.h @@ -137,6 +137,7 @@ static char *afl_environment_variables[] = { "AFL_SKIP_CRASHES", "AFL_STATSD_HOST", "AFL_STATSD_PORT", + "AFL_STATSD_TAGS_FLAVOR", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 5e719a85..77b30b5b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -377,6 +377,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd_port = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_TAGS_FLAVOR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 9cb8fde4..f77df17e 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -12,6 +12,107 @@ #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" +/* Tags format for metrics + DogStatsD: + metric.name:||#key:value,key2:value2 + + InfluxDB + metric.name,key=value,key2=value2:| + + Librato + metric.name#key=value,key2=value2:| + + SignalFX + metric.name[key=value,key2=value2]:| + +*/ + +// after the whole metric. +#define DOGSTATSD_TAGS_FORMAT "|#banner:%s,afl_version:%s" + +// just after the metric name. +#define LIBRATO_TAGS_FORMAT "#banner=%s,afl_version=%s" +#define INFLUXDB_TAGS_FORMAT ",banner=%s,afl_version=%s" +#define SIGNALFX_TAGS_FORMAT "[banner=%s,afl_version=%s]" + +// For DogstatsD +#define STATSD_TAGS_AFTER_METRICS \ + METRIC_PREFIX \ + ".cycle_done:%llu|g%s\n" METRIC_PREFIX \ + ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX \ + ".execs_done:%llu|g%s\n" METRIC_PREFIX \ + ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX \ + ".paths_total:%u|g%s\n" METRIC_PREFIX \ + ".paths_favored:%u|g%s\n" METRIC_PREFIX \ + ".paths_found:%u|g%s\n" METRIC_PREFIX \ + ".paths_imported:%u|g%s\n" METRIC_PREFIX \ + ".max_depth:%u|g%s\n" METRIC_PREFIX ".cur_path:%u|g%s\n" METRIC_PREFIX \ + ".pending_favs:%u|g%s\n" METRIC_PREFIX \ + ".pending_total:%u|g%s\n" METRIC_PREFIX \ + ".variable_paths:%u|g%s\n" METRIC_PREFIX \ + ".unique_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".unique_hangs:%llu|g%s\n" METRIC_PREFIX \ + ".total_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX \ + ".edges_found:%u|g%s\n" METRIC_PREFIX \ + ".var_byte_count:%u|g%s\n" METRIC_PREFIX ".havoc_expansion:%u|g%s\n" + +// For Librato, InfluxDB, SignalFX +#define STATSD_TAGS_MID_METRICS \ + METRIC_PREFIX \ + ".cycle_done%s:%llu|g\n" METRIC_PREFIX \ + ".cycles_wo_finds%s:%llu|g\n" METRIC_PREFIX \ + ".execs_done%s:%llu|g\n" METRIC_PREFIX \ + ".execs_per_sec%s:%0.02f|g\n" METRIC_PREFIX \ + ".paths_total%s:%u|g\n" METRIC_PREFIX \ + ".paths_favored%s:%u|g\n" METRIC_PREFIX \ + ".paths_found%s:%u|g\n" METRIC_PREFIX \ + ".paths_imported%s:%u|g\n" METRIC_PREFIX \ + ".max_depth%s:%u|g\n" METRIC_PREFIX ".cur_path%s:%u|g\n" METRIC_PREFIX \ + ".pending_favs%s:%u|g\n" METRIC_PREFIX \ + ".pending_total%s:%u|g\n" METRIC_PREFIX \ + ".variable_paths%s:%u|g\n" METRIC_PREFIX \ + ".unique_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".unique_hangs%s:%llu|g\n" METRIC_PREFIX \ + ".total_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".slowest_exec_ms%s:%u|g\n" METRIC_PREFIX \ + ".edges_found%s:%u|g\n" METRIC_PREFIX \ + ".var_byte_count%s:%u|g\n" METRIC_PREFIX ".havoc_expansion%s:%u|g\n" + +void statsd_setup_format(afl_state_t *afl) { + + if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "dogstatsd") == 0) { + + afl->statsd_tags_format = DOGSTATSD_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_AFTER_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "librato") == 0) { + + afl->statsd_tags_format = LIBRATO_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "influxdb") == 0) { + + afl->statsd_tags_format = INFLUXDB_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "signalfx") == 0) { + + afl->statsd_tags_format = SIGNALFX_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else { + + // No tags at all. + afl->statsd_tags_format = ""; + // Still need to pick a format. Doesn't change anything since if will be + // replaced by the empty string anyway. + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } + +} + int statsd_socket_init(afl_state_t *afl) { /* Default port and host. @@ -87,7 +188,7 @@ int statsd_send_metric(afl_state_t *afl) { (struct sockaddr *)&afl->statsd_server, sizeof(afl->statsd_server)) == -1) { - if (!close(afl->statsd_sock)) { perror("Cannot close socket"); } + if (!close(afl->statsd_sock)) { FATAL("Cannot close socket"); } afl->statsd_sock = 0; WARNF("Cannot sendto"); return -1; @@ -100,45 +201,14 @@ int statsd_send_metric(afl_state_t *afl) { int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { -/* Metric format: -:| -*/ -#ifdef USE_DOGSTATSD_TAGS - /* Tags format: DogStatsD - :||#key:value,key:value,key - */ char tags[MAX_TAG_LEN * 2] = {0}; - snprintf(tags, MAX_TAG_LEN * 2, "|#banner:%s,afl_version:%s", afl->use_banner, + snprintf(tags, MAX_TAG_LEN * 2, afl->statsd_tags_format, afl->use_banner, VERSION); -#else - /* No tags. - */ - char *tags = ""; -#endif + /* Sends multiple metrics with one UDP Packet. bufflen will limit to the max safe size. */ - snprintf(buff, bufflen, - METRIC_PREFIX ".cycle_done:%llu|g%s\n" METRIC_PREFIX - ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX - ".execs_done:%llu|g%s\n" METRIC_PREFIX - ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX - ".paths_total:%u|g%s\n" METRIC_PREFIX - ".paths_favored:%u|g%s\n" METRIC_PREFIX - ".paths_found:%u|g%s\n" METRIC_PREFIX - ".paths_imported:%u|g%s\n" METRIC_PREFIX - ".max_depth:%u|g%s\n" METRIC_PREFIX - ".cur_path:%u|g%s\n" METRIC_PREFIX - ".pending_favs:%u|g%s\n" METRIC_PREFIX - ".pending_total:%u|g%s\n" METRIC_PREFIX - ".variable_paths:%u|g%s\n" METRIC_PREFIX - ".unique_crashes:%llu|g%s\n" METRIC_PREFIX - ".unique_hangs:%llu|g%s\n" METRIC_PREFIX - ".total_crashes:%llu|g%s\n" METRIC_PREFIX - ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX - ".edges_found:%u|g%s\n" METRIC_PREFIX - ".var_byte_count:%u|g%s\n" METRIC_PREFIX - ".havoc_expansion:%u|g%s\n", + snprintf(buff, bufflen, afl->statsd_metric_format, afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, afl->fsrv.total_execs / diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0b08f426..e0e9487f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -891,6 +891,11 @@ int main(int argc, char **argv_orig, char **envp) { } + #ifdef USE_STATSD + statsd_setup_format(afl); + statsd_socket_init(afl); + #endif + if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { WARNF(cLRD -- cgit 1.4.1 From 794e8d2d67dcd8337550e480ea21139289944a4b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 7 Oct 2020 08:32:58 +0200 Subject: change HAVOC_MAX_MULT* to 64 --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 7c8e0c7d..3f5c5448 100644 --- a/include/config.h +++ b/include/config.h @@ -109,8 +109,8 @@ /* Maximum multiplier for the above (should be a power of two, beware of 32-bit int overflows): */ -#define HAVOC_MAX_MULT 32 -#define HAVOC_MAX_MULT_MOPT 32 +#define HAVOC_MAX_MULT 64 +#define HAVOC_MAX_MULT_MOPT 64 /* Absolute minimum number of havoc cycles (after all adjustments): */ -- cgit 1.4.1 From 0220a8ff6670da2b9fd8cb883528d2a86f683c74 Mon Sep 17 00:00:00 2001 From: Edznux Date: Thu, 8 Oct 2020 20:48:46 +0200 Subject: Add env var toggle for StatsD --- include/afl-fuzz.h | 2 +- include/config.h | 7 +++---- include/envs.h | 1 + src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz-stats.c | 15 ++++++++------- src/afl-fuzz.c | 8 +++----- 6 files changed, 23 insertions(+), 17 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index df7dd644..8ad0ced1 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -355,7 +355,7 @@ typedef struct afl_env_vars { afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui, afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, afl_bench_until_crash, afl_debug_child_output, afl_autoresume, - afl_cal_fast, afl_cycle_schedules, afl_expand_havoc; + afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, diff --git a/include/config.h b/include/config.h index 3d6b0395..405c2712 100644 --- a/include/config.h +++ b/include/config.h @@ -41,11 +41,10 @@ #define USE_COLOR -/* Enable sending statistics over a StatsD daemon. -Server config can be adjusted with AFL_STATSD_HOST and AFL_STATSD_PORT env var. +/* StatsD config + Config can be adjusted via AFL_STATSD_HOST and AFL_STATSD_PORT environment + variable. */ - -#define USE_STATSD #define STATSD_UPDATE_SEC 1 #define STATSD_DEFAULT_PORT 8125 #define STATSD_DEFAULT_HOST "127.0.0.1" diff --git a/include/envs.h b/include/envs.h index 16da14cb..51520312 100644 --- a/include/envs.h +++ b/include/envs.h @@ -135,6 +135,7 @@ static char *afl_environment_variables[] = { "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ", "AFL_SKIP_CRASHES", + "AFL_STATSD", "AFL_STATSD_HOST", "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 77b30b5b..a7c7aff9 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -316,6 +316,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_cal_fast = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_STATSD", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TMPDIR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 942670b4..0d6c6a66 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,16 +423,17 @@ void show_stats(afl_state_t *afl) { } -#ifdef USE_STATSD - if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { + if (unlikely(afl->afl_env.afl_statsd == 1)) { - /* reset counter, even if send failed. */ - afl->statsd_last_send_ms = cur_ms; - if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } + if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { - } + /* reset counter, even if send failed. */ + afl->statsd_last_send_ms = cur_ms; + if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } -#endif + } + + } /* Every now and then, write plot data. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c26e53b9..2c2f0ba5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -194,7 +194,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" - "AFL_STATSD_HOST: change default statsd host. (default 127.0.0.1)" + "AFL_STATSD: enables StatsD metrics collection" + "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)" "AFL_STATSD_PORT: change default statsd port (default: 8125)" "AFL_STATSD_TAGS_FLAVOR: change default statsd tags format (default will disable tags)." " Supported formats are: 'dogstatsd', 'librato', 'signalfx' and 'influxdb'" @@ -893,10 +894,7 @@ int main(int argc, char **argv_orig, char **envp) { } - #ifdef USE_STATSD - statsd_setup_format(afl); - - #endif + if (unlikely(afl->afl_env.afl_statsd == 1)) { statsd_setup_format(afl); } if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { -- cgit 1.4.1 From 43d8296504fc2dbb80ebbdf04072286805ae9bff Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 9 Oct 2020 16:45:27 +0200 Subject: increase default cache size --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index f01ddc04..9c316a86 100644 --- a/include/config.h +++ b/include/config.h @@ -297,7 +297,7 @@ /* The amount of entries in the testcase cache, held in memory. Decrease if RAM usage is high. */ -#define TESTCASE_CACHE_SIZE 2048 +#define TESTCASE_CACHE_SIZE 3072 #if TESTCASE_CACHE_SIZE < 4 #error \ -- cgit 1.4.1 From 125f8b6ba71fba91735374b1bd07333b19aae635 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 9 Oct 2020 23:23:44 +0200 Subject: -m none is the default now --- docs/Changelog.md | 1 + examples/persistent_demo/persistent_demo_new.c | 3 ++- include/config.h | 24 ++++++++---------------- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 4 ++-- 5 files changed, 14 insertions(+), 20 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index 0f923423..ba7028df 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,7 @@ sending a mail to . - all compilers combined to afl-cc which emulates the previous ones - afl-llvm/gcc-rt.o merged into afl-compiler-rt.o - afl-fuzz + - memory limits are now disabled by default, set them with -m if required - Marcel Boehme submitted a patch that improves all AFFast schedules :) - reading testcases from -i now descends into subdirectories - allow up to 4 -x command line options diff --git a/examples/persistent_demo/persistent_demo_new.c b/examples/persistent_demo/persistent_demo_new.c index 13123d33..b8b4cda0 100644 --- a/examples/persistent_demo/persistent_demo_new.c +++ b/examples/persistent_demo/persistent_demo_new.c @@ -37,7 +37,8 @@ unsigned char fuzz_buf[1024000]; #define __AFL_FUZZ_TESTCASE_LEN fuzz_len #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf #define __AFL_FUZZ_INIT() void sync(void); - #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) + #define __AFL_LOOP(x) \ + ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) #define __AFL_INIT() sync() #endif diff --git a/include/config.h b/include/config.h index 3f5c5448..5df604e7 100644 --- a/include/config.h +++ b/include/config.h @@ -66,25 +66,17 @@ #define WORD_SIZE_64 1 #endif -/* Default memory limit for child process (MB): */ - -#ifndef __NetBSD__ - #ifndef WORD_SIZE_64 - #define MEM_LIMIT 50 - #else - #define MEM_LIMIT 75 - #endif /* ^!WORD_SIZE_64 */ -#else /* NetBSD's kernel needs more space for stack, see discussion for issue \ - #165 */ - #define MEM_LIMIT 250 -#endif -/* Default memory limit when running in QEMU mode (MB): */ +/* Default memory limit for child process (MB) 0 = disabled : */ + +#define MEM_LIMIT 0 + +/* Default memory limit when running in QEMU mode (MB) 0 = disabled : */ -#define MEM_LIMIT_QEMU 250 +#define MEM_LIMIT_QEMU 0 -/* Default memory limit when running in Unicorn mode (MB): */ +/* Default memory limit when running in Unicorn mode (MB) 0 = disabled : */ -#define MEM_LIMIT_UNICORN 250 +#define MEM_LIMIT_UNICORN 0 /* Number of calibration cycles per every new test case (and for test cases that show variable behavior): */ diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 4a1e739f..a8e56e60 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = COE; /* Power schedule (default: COE) */ + afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8458b50f..cf0a30c9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -90,13 +90,13 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\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" + " -m megs - memory limit for child process (%d MB, 0 = no limit)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " -- cgit 1.4.1 From b7e0490bcdaa7fa792a9dccfa5983e03af92730e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Oct 2020 03:44:34 +0200 Subject: Revert "Merge branch 'memcache_marc' into dev" This reverts commit c03fbcedaa68db5324423975a34331287426f7c2, reversing changes made to dab017dddaaab6d836a590f7bba3eea3549758d2. --- include/afl-fuzz.h | 16 ------ include/config.h | 9 --- src/afl-fuzz-one.c | 157 +++++++++++++++++++++++++++++++-------------------- src/afl-fuzz-queue.c | 87 ---------------------------- src/afl-fuzz.c | 5 +- 5 files changed, 97 insertions(+), 177 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index a3e87129..45de197d 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -168,9 +168,6 @@ struct queue_entry { double perf_score; /* performance score */ - u8 *testcase_buf; /* The testcase buffer, if loaded. */ - u32 testcase_refs; /* count of users of testcase buf */ - struct queue_entry *next; /* Next element, if any */ }; @@ -689,12 +686,6 @@ typedef struct afl_state { /* queue entries ready for splicing count (len > 4) */ u32 ready_for_splicing_count; - /* How many queue entries currently have cached testcases */ - u32 q_testcase_cache_count; - /* Refs to each queue entry with cached testcase (for eviction, if cache_count - * is too large) */ - struct queue_entry *q_testcase_cache[TESTCASE_CACHE_SIZE]; - } afl_state_t; struct custom_mutator { @@ -1141,12 +1132,5 @@ static inline u64 next_p2(u64 val) { } -/* Returns the testcase buf from the file behind this queue entry. - Increases the refcount. */ -u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q); - -/* Tell afl that this testcase may be evicted from the cache */ -void queue_testcase_release(afl_state_t *afl, struct queue_entry *q); - #endif diff --git a/include/config.h b/include/config.h index 3f498275..7dd045e3 100644 --- a/include/config.h +++ b/include/config.h @@ -295,15 +295,6 @@ #define RESEED_RNG 100000 -/* The amount of entries in the testcase cache, held in memory. -Decrease if RAM usage is high. */ -#define TESTCASE_CACHE_SIZE 3072 - -#if TESTCASE_CACHE_SIZE < 4 - #error \ - "Dangerously low cache size: Set TESTCASE_CACHE_SIZE to 4 or more in config.h!" -#endif - /* Maximum line length passed from GCC to 'as' and used for parsing configuration files: */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ebe541a2..6ef728e0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, temp_len; + s32 len, fd, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,9 +453,28 @@ u8 fuzz_one_original(afl_state_t *afl) { } - orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); + /* Map the test case into memory. */ + + fd = open(afl->queue_cur->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", afl->queue_cur->fname); + + } + len = afl->queue_cur->len; + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (unlikely(orig_in == MAP_FAILED)) { + + PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); + + } + + close(fd); + /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -1678,7 +1697,7 @@ custom_mutator_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - struct queue_entry *target = NULL; + struct queue_entry *target; u32 tid; u8 * new_buf = NULL; u32 target_len = 0; @@ -1701,7 +1720,17 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - new_buf = queue_testcase_take(afl, target); + fd = open(target->fname, O_RDONLY); + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", target->fname); + + } + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + close(fd); target_len = target->len; } @@ -1712,13 +1741,6 @@ custom_mutator_stage: el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, target_len, max_seed_size); - if (new_buf) { - - queue_testcase_release(afl, target); - new_buf = NULL; - - } - if (unlikely(!mutated_buf)) { FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); @@ -2301,53 +2323,52 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk from another testcase or insert that chunk. */ - if (afl->queued_paths < 4) { break; } + if (afl->queued_paths < 4) break; /* Pick a random queue entry and seek to it. */ u32 tid; - do { - + do tid = rand_below(afl, afl->queued_paths); - - } while (tid == afl->current_entry); + while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ - while (target && (target->len < 2 || target == afl->queue_cur)) { - + while (target && (target->len < 2 || target == afl->queue_cur)) target = target->next; - } + if (!target) break; - if (!target) { break; } + /* Read the testcase into a new buffer. */ - u32 new_len = target->len; + fd = open(target->fname, O_RDONLY); - /* Get the testcase contents for splicing. */ - u8 *new_buf = queue_testcase_take(afl, target); + if (unlikely(fd < 0)) { - u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) { + PFATAL("Unable to open '%s'", target->fname); - overwrite = 1; + } - } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + u32 new_len = target->len; + u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } - if (temp_len >= 2) { + ck_read(fd, new_buf, new_len, target->fname); - overwrite = 1; + close(fd); - } else { + u8 overwrite = 0; + if (temp_len >= 2 && rand_below(afl, 2)) + overwrite = 1; + else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { - queue_testcase_release(afl, target); - new_buf = NULL; + if (temp_len >= 2) + overwrite = 1; + else break; - } - } if (overwrite) { @@ -2393,9 +2414,6 @@ havoc_stage: } - /* We don't need this splice testcase anymore */ - queue_testcase_release(afl, target); - new_buf = NULL; break; } @@ -2501,17 +2519,24 @@ retry_splicing: if (!target) { goto retry_splicing; } - /* Get the testcase buffer */ - u8 *splice_buf = queue_testcase_take(afl, target); + /* Read the testcase into a new buffer. */ + + fd = open(target->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + + close(fd); + /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, - &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -2523,7 +2548,6 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splice_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; @@ -2531,9 +2555,6 @@ retry_splicing: if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); - queue_testcase_release(afl, target); - splice_buf = NULL; - goto custom_mutator_stage; /* ???: While integrating Python module, the author decided to jump to python stage, but the reason behind this is not clear.*/ @@ -2564,8 +2585,7 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - queue_testcase_release(afl, afl->queue_cur); - orig_in = NULL; + munmap(orig_in, afl->queue_cur->len); return ret_val; @@ -2587,7 +2607,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, temp_len; + s32 len, fd, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2652,9 +2672,23 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); + + fd = open(afl->queue_cur->fname, O_RDONLY); + + if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } + len = afl->queue_cur->len; + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (orig_in == MAP_FAILED) { + + PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); + + } + + close(fd); + /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -4494,24 +4528,31 @@ pacemaker_fuzzing: if (!target) { goto retry_splicing_puppet; } /* Read the testcase into a new buffer. */ - u8 *splicing_buf = queue_testcase_take(afl, target); + + fd = open(target->fname, O_RDONLY); + + if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } + + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + + ck_read(fd, new_buf, target->len, target->fname); + + close(fd); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splicing_buf, MIN(len, (s32)target->len), &f_diff, + locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - queue_testcase_release(afl, target); goto retry_splicing_puppet; } - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - /* Split somewhere between the first and last differing byte. */ split_at = f_diff + rand_below(afl, l_diff - f_diff); @@ -4520,17 +4561,12 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splicing_buf + split_at, - target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); - queue_testcase_release(afl, target); - splicing_buf = NULL; - goto havoc_stage_puppet; } /* if splice_cycle */ @@ -4564,8 +4600,7 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - queue_testcase_release(afl, afl->queue_cur); - orig_in = NULL; + munmap(orig_in, afl->queue_cur->len); if (afl->key_puppet == 1) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index a034b168..d608e890 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -343,7 +343,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->trace_mini = NULL; - q->testcase_buf = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } @@ -892,89 +891,3 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } -/* Tell afl that this testcase may be evicted from the cache */ -inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { - - (void)afl; - if (unlikely(q->testcase_refs == 0)) { - - FATAL("Testcase refcount reduced past 0"); - - } - - q->testcase_refs--; - -} - -/* Returns the testcase buf from the file behind this queue entry. - Increases the refcount. */ -u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { - - if (!q->testcase_buf) { - - u32 tid = 0; - /* Buf not cached, let's do that now */ - - if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { - - /* Cache full. We neet to evict one to map one. - Get a random one which is not in use */ - do { - - tid = rand_below(afl, afl->q_testcase_cache_count); - - } while (afl->q_testcase_cache[tid]->testcase_refs > 0); - - struct queue_entry *old_cached = afl->q_testcase_cache[tid]; - /* free the current buf from cache */ - munmap(old_cached->testcase_buf, old_cached->len); - old_cached->testcase_buf = NULL; - - } else { - - tid = afl->q_testcase_cache_count; - afl->q_testcase_cache_count++; - - } - - /* Map the test case into memory. */ - - int fd = open(q->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } - - u32 len = q->len; - - q->testcase_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(q->testcase_buf == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", q->fname, len); - - } - - close(fd); - - /* Register us as cached */ - afl->q_testcase_cache[tid] = q; - - } - - q->testcase_refs++; - if (unlikely(!q->testcase_buf || !q->testcase_refs)) { - if (!q->testcase_buf) { - - FATAL("Testcase buf is NULL, this should never happen"); - - } - if (!q->testcase_refs) { - - FATAL("Testcase ref overflow. Missing a testcase release somwhere?"); - - } - } - - return q->testcase_buf; - -} - diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cb5eb37a..d42a0d36 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1174,12 +1174,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { - for (i = 0; i < extras_dir_cnt; i++) { - + for (i = 0; i < extras_dir_cnt; i++) load_extras(afl, extras_dir[i]); - } - dedup_extras(afl); OKF("Loaded a total of %u extras.", afl->extras_cnt); -- cgit 1.4.1 From 56ac3fcdc511d124ad058412021ead21bbbcf4bf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 14 Oct 2020 15:30:30 +0200 Subject: configurable testcache with malloc (#581) * cache item number to cache memory size * reload testcase if trimming changed the size * fix splicing selection * slim splicing * import sync fix * write testcache stats to fuzzer_stats * fix new seed selection algo * malloc+read instead of mmap * fix * testcache is configurable now and no reference counts * fixes compilation, test script * fixes * switch TEST_CC to afl-cc in makefile * code format * fix * fix crash * fix crash * fix env help output * remove unnecessary pointer resets * fix endless loop bug * actually use the cache if set * one more fix * increase default cache entries, add default cache size value to config.h Co-authored-by: hexcoder- --- GNUmakefile | 4 +- include/afl-fuzz.h | 31 +++++++- include/config.h | 9 +++ include/envs.h | 1 + src/afl-fuzz-init.c | 4 +- src/afl-fuzz-one.c | 169 +++++++++---------------------------------- src/afl-fuzz-queue.c | 167 ++++++++++++++++++++++++++++++++++++++---- src/afl-fuzz-run.c | 6 ++ src/afl-fuzz-state.c | 8 ++ src/afl-fuzz-stats.c | 7 +- src/afl-fuzz.c | 29 ++++++-- src/afl-performance.c | 2 +- test/test-custom-mutators.sh | 2 +- 13 files changed, 276 insertions(+), 163 deletions(-) (limited to 'include/config.h') diff --git a/GNUmakefile b/GNUmakefile index c885a935..80b7b68b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -223,8 +223,6 @@ ifneq "$(findstring OpenBSD, $(shell uname))" "" LDFLAGS += -lpthread endif -TEST_CC = afl-gcc - COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" @@ -488,7 +486,7 @@ code-format: ifndef AFL_NO_X86 test_build: afl-cc afl-as afl-showmap @echo "[*] Testing the CC wrapper and instrumentation output..." - @unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 ) + @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr @rm -f test-instr diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 85597150..940c5602 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -168,6 +168,8 @@ struct queue_entry { double perf_score; /* performance score */ + u8 *testcase_buf; /* The testcase buffer, if loaded. */ + struct queue_entry *next; /* Next element, if any */ }; @@ -363,7 +365,7 @@ typedef struct afl_env_vars { u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port, - *afl_statsd_tags_flavor; + *afl_statsd_tags_flavor, *afl_testcache_size; } afl_env_vars_t; @@ -675,6 +677,9 @@ typedef struct afl_state { u8 *in_scratch_buf; u8 *ex_buf; + + u8 *testcase_buf, *splicecase_buf; + u32 custom_mutators_count; list_t custom_mutator_list; @@ -686,6 +691,22 @@ typedef struct afl_state { /* queue entries ready for splicing count (len > 4) */ u32 ready_for_splicing_count; + /* This is the user specified maximum size to use for the testcase cache */ + u64 q_testcase_max_cache_size; + + /* How much of the testcase cache is used so far */ + u64 q_testcase_cache_size; + + /* highest cache count so far */ + u32 q_testcase_max_cache_count; + + /* How many queue entries currently have cached testcases */ + u32 q_testcase_cache_count; + + /* Refs to each queue entry with cached testcase (for eviction, if cache_count + * is too large) */ + struct queue_entry *q_testcase_cache[TESTCASE_ENTRIES]; + } afl_state_t; struct custom_mutator { @@ -1135,5 +1156,13 @@ static inline u64 next_p2(u64 val) { } +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q); + +/* If trimming changes the testcase size we have to reload it */ +void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, + u32 old_len); + #endif diff --git a/include/config.h b/include/config.h index 7dd045e3..b4f3a775 100644 --- a/include/config.h +++ b/include/config.h @@ -295,6 +295,15 @@ #define RESEED_RNG 100000 +/* The maximum number of testcases to cache */ + +#define TESTCASE_ENTRIES 16384 + +/* The default maximum testcase cache size in MB, 0 = disable. + A value between 50 and 250 is a good default value. */ + +#define TESTCASE_CACHE 0 + /* Maximum line length passed from GCC to 'as' and used for parsing configuration files: */ diff --git a/include/envs.h b/include/envs.h index 51520312..a1b3ad12 100644 --- a/include/envs.h +++ b/include/envs.h @@ -139,6 +139,7 @@ static char *afl_environment_variables[] = { "AFL_STATSD_HOST", "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", + "AFL_TESTCACHE_SIZE", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 881bf10f..607b652f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1045,7 +1045,7 @@ restart_outer_cull_loop: while (q) { - if (q->cal_failed || !q->exec_cksum) continue; + if (q->cal_failed || !q->exec_cksum) { goto next_entry; } restart_inner_cull_loop: @@ -1090,6 +1090,8 @@ restart_outer_cull_loop: } + next_entry: + prev = q; q = q->next; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index fc092f8d..154e4b45 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, fd, temp_len; + s32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,32 +453,9 @@ u8 fuzz_one_original(afl_state_t *afl) { } - /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", afl->queue_cur->fname); - - } - + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(orig_in == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); - - } - - close(fd); - - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every - single byte anyway, so it wouldn't give us any performance or memory usage - benefits. */ - out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } @@ -526,6 +503,7 @@ u8 fuzz_one_original(afl_state_t *afl) { !afl->disable_trim)) { u8 res = trim_case(afl, afl->queue_cur, in_buf); + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); if (unlikely(res == FSRV_RUN_ERROR)) { @@ -1720,17 +1698,7 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + new_buf = queue_testcase_get(afl, target); target_len = target->len; } @@ -2182,7 +2150,6 @@ havoc_stage: afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); out_buf = new_buf; - new_buf = NULL; temp_len += clone_len; } @@ -2326,43 +2293,21 @@ havoc_stage: /* Pick a random queue entry and seek to it. */ u32 tid; - do - tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); - - struct queue_entry *target = afl->queue_buf[tid]; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - u32 new_len = target->len; - u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, new_len, target->fname); + do { - close(fd); + tid = rand_below(afl, afl->queued_paths); - u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) - overwrite = 1; - else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); - if (temp_len >= 2) - overwrite = 1; - else - break; + /* Get the testcase for splicing. */ + struct queue_entry *target = afl->queue_buf[tid]; + u32 new_len = target->len; + u8 * new_buf = queue_testcase_get(afl, target); - } + if ((temp_len >= 2 && rand_below(afl, 2)) || + temp_len + HAVOC_BLK_XL >= MAX_FILE) { - if (overwrite) { + /* overwrite mode */ u32 copy_from, copy_to, copy_len; @@ -2376,15 +2321,16 @@ havoc_stage: } else { + /* insert mode */ + u32 clone_from, clone_to, clone_len; clone_len = choose_block_len(afl, new_len); clone_from = rand_below(afl, new_len - clone_len + 1); + clone_to = rand_below(afl, temp_len + 1); - clone_to = rand_below(afl, temp_len); - - u8 *temp_buf = - afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); + u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), + temp_len + clone_len + 1); if (unlikely(!temp_buf)) { PFATAL("alloc"); } /* Head */ @@ -2496,21 +2442,10 @@ retry_splicing: } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + /* Get the testcase */ afl->splicing_with = tid; target = afl->queue_buf[tid]; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + new_buf = queue_testcase_get(afl, target); /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single @@ -2527,18 +2462,16 @@ retry_splicing: /* Do the thing. */ len = target->len; - memcpy(new_buf, in_buf, split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); - in_buf = new_buf; + afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); + memcpy(afl->in_scratch_buf, in_buf, split_at); + memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + in_buf = afl->in_scratch_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); goto custom_mutator_stage; - /* ???: While integrating Python module, the author decided to jump to - python stage, but the reason behind this is not clear.*/ - // goto havoc_stage; } @@ -2564,9 +2497,7 @@ abandon_entry: } ++afl->queue_cur->fuzz_level; - - munmap(orig_in, afl->queue_cur->len); - + orig_in = NULL; return ret_val; #undef FLIP_BIT @@ -2587,7 +2518,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, fd, temp_len; + s32 len, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2652,32 +2583,11 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } - + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); len = afl->queue_cur->len; - - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (orig_in == MAP_FAILED) { - - PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); - - } - - close(fd); - - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every - single byte anyway, so it wouldn't give us any performance or memory usage - benefits. */ - out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } - afl->subseq_tmouts = 0; - afl->cur_depth = afl->queue_cur->depth; /******************************************* @@ -2721,6 +2631,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { u32 old_len = afl->queue_cur->len; u8 res = trim_case(afl, afl->queue_cur, in_buf); + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); if (res == FSRV_RUN_ERROR) { @@ -4497,17 +4408,7 @@ pacemaker_fuzzing: target = afl->queue_buf[tid]; /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + new_buf = queue_testcase_get(afl, target); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single @@ -4529,9 +4430,11 @@ pacemaker_fuzzing: /* Do the thing. */ len = target->len; - memcpy(new_buf, in_buf, split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); - in_buf = new_buf; + afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); + memcpy(afl->in_scratch_buf, in_buf, split_at); + memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + in_buf = afl->in_scratch_buf; + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); @@ -4569,7 +4472,7 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - munmap(orig_in, afl->queue_cur->len); + orig_in = NULL; if (afl->key_puppet == 1) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f224d851..c634328f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -31,11 +31,12 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { - u32 s = rand_below(afl, afl->queued_paths); + u32 s = rand_below(afl, afl->queued_paths); double p = rand_next_percent(afl); /* fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u" - " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < afl->alias_probability[s] ? s : afl->alias_table[s]); + " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < + afl->alias_probability[s] ? s : afl->alias_table[s]); */ return (p < afl->alias_probability[s] ? s : afl->alias_table[s]); @@ -55,7 +56,7 @@ void create_alias_table(afl_state_t *afl) { int * S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); int * L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); - if (!P || !S || !L) FATAL("could not aquire memory for alias table"); + if (!P || !S || !L) { FATAL("could not aquire memory for alias table"); } memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); @@ -65,7 +66,7 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; - if (!q->disabled) q->perf_score = calculate_score(afl, q); + if (!q->disabled) { q->perf_score = calculate_score(afl, q); } sum += q->perf_score; @@ -74,19 +75,23 @@ void create_alias_table(afl_state_t *afl) { for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - - P[i] = q->perf_score * n / sum; + P[i] = (q->perf_score * n) / sum; } int nS = 0, nL = 0, s; for (s = (s32)n - 1; s >= 0; --s) { - if (P[s] < 1) + if (P[s] < 1) { + S[nS++] = s; - else + + } else { + L[nL++] = s; + } + } while (nS && nL) { @@ -96,11 +101,16 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[a] = P[a]; afl->alias_table[a] = g; P[g] = P[g] + P[a] - 1; - if (P[g] < 1) + if (P[g] < 1) { + S[nS++] = g; - else + + } else { + L[nL++] = g; + } + } while (nL) @@ -110,11 +120,10 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[S[--nS]] = 1; /* - fprintf(stderr, " %-3s %-3s %-9s %-9s\n", "entry", "alias", "prob", "perf"); - for (u32 i = 0; i < n; ++i) - fprintf(stderr, " %3i %3i %9.7f %9.7f\n", i, afl->alias_table[i], - afl->alias_probability[i], afl->queue_buf[i]->perf_score); - + fprintf(stderr, " entry alias probability perf_score\n"); + for (u32 i = 0; i < n; ++i) + fprintf(stderr, " %5u %5u %11u %0.9f\n", i, afl->alias_table[i], + afl->alias_probability[i], afl->queue_buf[i]->perf_score); */ } @@ -860,3 +869,131 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } +void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, + u32 old_len) { + + if (likely(q->testcase_buf)) { + + free(q->testcase_buf); + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + u32 len = q->len; + q->testcase_buf = malloc(len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to mmap '%s' with len %d", q->fname, len); + + } + + close(fd); + afl->q_testcase_cache_size = afl->q_testcase_cache_size + q->len - old_len; + + } + +} + +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { + + u32 len = q->len; + + /* first handle if no testcase cache is configured */ + + if (unlikely(!afl->q_testcase_max_cache_size)) { + + u8 *buf; + + if (q == afl->queue_cur) { + + buf = afl_realloc((void **)&afl->testcase_buf, len); + + } else { + + buf = afl_realloc((void **)&afl->splicecase_buf, len); + + } + + if (unlikely(!buf)) { + + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + + } + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + ck_read(fd, buf, len, q->fname); + close(fd); + return buf; + + } + + /* now handle the testcase cache */ + + if (unlikely(!q->testcase_buf)) { + + /* Buf not cached, let's load it */ + u32 tid = 0; + + while (unlikely(afl->q_testcase_cache_size + len >= + afl->q_testcase_max_cache_size || + afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + + /* Cache full. We neet to evict one to map one. + Get a random one which is not in use */ + + do { + + tid = rand_below(afl, afl->q_testcase_max_cache_count); + + } while (afl->q_testcase_cache[tid] == NULL || + + afl->q_testcase_cache[tid] == afl->queue_cur); + + struct queue_entry *old_cached = afl->q_testcase_cache[tid]; + free(old_cached->testcase_buf); + old_cached->testcase_buf = NULL; + afl->q_testcase_cache_size -= old_cached->len; + afl->q_testcase_cache[tid] = NULL; + --afl->q_testcase_cache_count; + + } + + while (likely(afl->q_testcase_cache[tid] != NULL)) + ++tid; + + /* Map the test case into memory. */ + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + q->testcase_buf = malloc(len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + + } + + ck_read(fd, q->testcase_buf, len, q->fname); + close(fd); + + /* Register testcase as cached */ + afl->q_testcase_cache[tid] = q; + afl->q_testcase_cache_size += q->len; + ++afl->q_testcase_cache_count; + if (tid >= afl->q_testcase_max_cache_count) + afl->q_testcase_max_cache_count = tid + 1; + + } + + return q->testcase_buf; + +} + diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ee22b0f6..ab870319 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -692,6 +692,8 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { + u32 orig_len = q->len; + /* Custom mutator trimmer */ if (afl->custom_mutators_count) { @@ -709,6 +711,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { }); + if (orig_len != q->len) { queue_testcase_retake(afl, q, orig_len); } + if (custom_trimmed) return trimmed_case; } @@ -842,6 +846,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { close(fd); + if (orig_len != q->len) queue_testcase_retake(afl, q, orig_len); + memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); update_bitmap_score(afl, q); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index a0a2795e..0824b77f 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -103,6 +103,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_avg_exec = -1; afl->skip_deterministic = 1; afl->use_splicing = 1; + afl->q_testcase_max_cache_size = TESTCASE_CACHE * 1024000; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -353,6 +354,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_forksrv_init_tmout = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_TESTCACHE_SIZE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_testcache_size = + (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_HOST", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 76f24977..4f0cab4c 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -165,6 +165,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "edges_found : %u\n" "var_byte_count : %u\n" "havoc_expansion : %u\n" + "testcache_size : %llu\n" + "testcache_count : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -198,8 +200,9 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else -1, #endif - t_bytes, afl->var_byte_count, afl->expand_havoc, afl->use_banner, - afl->unicorn_mode ? "unicorn" : "", + t_bytes, afl->var_byte_count, afl->expand_havoc, + afl->q_testcase_cache_size, afl->q_testcase_cache_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 " : "", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6498eb30..a59abb7d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -196,11 +196,13 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" - "AFL_STATSD: enables StatsD metrics collection" - "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)" - "AFL_STATSD_PORT: change default statsd port (default: 8125)" - "AFL_STATSD_TAGS_FLAVOR: change default statsd tags format (default will disable tags)." - " Supported formats are: 'dogstatsd', 'librato', 'signalfx' and 'influxdb'" + "AFL_STATSD: enables StatsD metrics collection\n" + "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n" + "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" + "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n" + " Supported formats are: 'dogstatsd', 'librato', 'signalfx'\n" + " and 'influxdb'\n" + "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" @@ -885,7 +887,7 @@ int main(int argc, char **argv_orig, char **envp) { auto_sync = 1; afl->sync_id = ck_strdup("default"); afl->is_secondary_node = 1; - OKF("no -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); + OKF("No -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); } @@ -1006,6 +1008,21 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_testcache_size) { + + afl->q_testcase_max_cache_size = + (u64)atoi(afl->afl_env.afl_testcache_size) * 1024000; + OKF("Enabled testcache with %llu MB", + afl->q_testcase_max_cache_size / 1024000); + + } else { + + ACTF( + "No testcache was configured. it is recommended to use a testcache, it " + "improves performance: set AFL_TESTCACHE_SIZE=(value in MB)"); + + } + if (afl->afl_env.afl_forksrv_init_tmout) { afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout); diff --git a/src/afl-performance.c b/src/afl-performance.c index 6fa95dea..e070a05e 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -71,7 +71,7 @@ inline uint64_t rand_next(afl_state_t *afl) { inline double rand_next_percent(afl_state_t *afl) { - return (double)(((double)rand_next(afl)) / (double) 0xffffffffffffffff); + return (double)(((double)rand_next(afl)) / (double)0xffffffffffffffff); } diff --git a/test/test-custom-mutators.sh b/test/test-custom-mutators.sh index f7677ac5..d4d21048 100755 --- a/test/test-custom-mutators.sh +++ b/test/test-custom-mutators.sh @@ -1,4 +1,4 @@ -f#!/bin/sh +#!/bin/sh . ./test-pre.sh -- cgit 1.4.1 From 0e748ccda713708de6a501d23a58788aba9d0b03 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 23 Oct 2020 14:05:34 +0200 Subject: set max testcache entries automated if not specified by the user --- include/afl-fuzz.h | 7 ++++-- include/config.h | 10 ++++---- include/envs.h | 1 + src/afl-fuzz-queue.c | 11 +++++---- src/afl-fuzz-state.c | 10 +++++++- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 91 insertions(+), 18 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 220380b9..11feb9f7 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -366,7 +366,7 @@ typedef struct afl_env_vars { u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port, - *afl_statsd_tags_flavor, *afl_testcache_size; + *afl_statsd_tags_flavor, *afl_testcache_size, *afl_testcache_entries; } afl_env_vars_t; @@ -695,6 +695,9 @@ typedef struct afl_state { /* This is the user specified maximum size to use for the testcase cache */ u64 q_testcase_max_cache_size; + /* This is the user specified maximum entries in the testcase cache */ + u32 q_testcase_max_cache_entries; + /* How much of the testcase cache is used so far */ u64 q_testcase_cache_size; @@ -712,7 +715,7 @@ typedef struct afl_state { /* Refs to each queue entry with cached testcase (for eviction, if cache_count * is too large) */ - struct queue_entry *q_testcase_cache[TESTCASE_ENTRIES]; + struct queue_entry **q_testcase_cache; } afl_state_t; diff --git a/include/config.h b/include/config.h index b4f3a775..491d8132 100644 --- a/include/config.h +++ b/include/config.h @@ -295,14 +295,12 @@ #define RESEED_RNG 100000 -/* The maximum number of testcases to cache */ - -#define TESTCASE_ENTRIES 16384 - /* The default maximum testcase cache size in MB, 0 = disable. - A value between 50 and 250 is a good default value. */ + A value between 50 and 250 is a good default value. Note that the + number of entries will be auto assigned if not specified via the + AFL_TESTCACHE_ENTRIES env variable */ -#define TESTCASE_CACHE 0 +#define TESTCASE_CACHE_SIZE 50 /* Maximum line length passed from GCC to 'as' and used for parsing configuration files: */ diff --git a/include/envs.h b/include/envs.h index a1b3ad12..b753d5f8 100644 --- a/include/envs.h +++ b/include/envs.h @@ -140,6 +140,7 @@ static char *afl_environment_variables[] = { "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_TESTCACHE_SIZE", + "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index db387c33..baa80e61 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -978,9 +978,9 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Buf not cached, let's load it */ u32 tid = afl->q_testcase_max_cache_count; - while (unlikely(afl->q_testcase_cache_size + len >= - afl->q_testcase_max_cache_size || - afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + while (unlikely( + afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || + afl->q_testcase_cache_count >= afl->q_testcase_max_cache_entries - 1)) { /* Cache full. We neet to evict one or more to map one. Get a random one which is not in use */ @@ -1009,7 +1009,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { } - if (unlikely(tid >= TESTCASE_ENTRIES)) { + if (unlikely(tid >= afl->q_testcase_max_cache_entries)) { // uh we were full, so now we have to search from start tid = afl->q_testcase_smallest_free; @@ -1062,7 +1062,8 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, if (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || - afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + afl->q_testcase_cache_count >= + afl->q_testcase_max_cache_entries - 1)) { // no space? will be loaded regularly later. return; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 0824b77f..ae7d410b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -103,7 +103,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_avg_exec = -1; afl->skip_deterministic = 1; afl->use_splicing = 1; - afl->q_testcase_max_cache_size = TESTCASE_CACHE * 1024000; + afl->q_testcase_max_cache_size = TESTCASE_CACHE_SIZE * 1048576UL; + afl->q_testcase_max_cache_entries = 4096; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -361,6 +362,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_testcache_size = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_TESTCACHE_ENTRIES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_testcache_entries = + (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_HOST", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d213d054..bec90519 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1028,7 +1028,7 @@ void show_init_stats(afl_state_t *afl) { } - SAYF("\n"); + // SAYF("\n"); if (avg_us > ((afl->fsrv.qemu_mode || afl->unicorn_mode) ? 50000 : 10000)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7215ecec..637e1985 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -251,7 +251,7 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt, i, auto_sync = 0; + s32 opt, i, auto_sync = 0, user_set_cache = 0; u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; @@ -1015,6 +1015,22 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_testcache_entries) { + + afl->q_testcase_max_cache_entries = + (u32)atoi(afl->afl_env.afl_testcache_entries); + + user_set_cache = 1; + + } + + if (!afl->afl_env.afl_testcache_size || !afl->afl_env.afl_testcache_entries) { + + afl->afl_env.afl_testcache_entries = 0; + afl->afl_env.afl_testcache_size = 0; + + } + if (!afl->q_testcase_max_cache_size) { ACTF( @@ -1347,6 +1363,52 @@ int main(int argc, char **argv_orig, char **envp) { perform_dry_run(afl); + if (!user_set_cache && afl->q_testcase_max_cache_size) { + + /* The user defined not a fixed number of entries for the cache. + Hence we autodetect a good value. After the dry run inputs are + trimmed and we know the average and max size of the input seeds. + We use this information to set a fitting size to max entries + based on the cache size. */ + + struct queue_entry *q = afl->queue; + u64 size = 0, count = 0, avg = 0, max = 0; + + while (q) { + + ++count; + size += q->len; + if (max < q->len) { max = q->len; } + q = q->next; + + } + + if (count) { + + avg = size / count; + avg = ((avg + max) / 2) + 1; + + } + + if (avg < 10240) { avg = 10240; } + + afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_size / avg; + + if (afl->q_testcase_max_cache_entries > 32768) + afl->q_testcase_max_cache_entries = 32768; + + } + + if (afl->q_testcase_max_cache_entries) { + + OKF("Setting %u maximum entries for the testcase cache", + afl->q_testcase_max_cache_entries); + afl->q_testcase_cache = + ck_alloc(afl->q_testcase_max_cache_entries * sizeof(size_t)); + if (!afl->q_testcase_cache) { PFATAL("malloc failed for cache entries"); } + + } + cull_queue(afl); if (!afl->pending_not_fuzzed) @@ -1366,8 +1428,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->not_on_tty) { - sleep(4); - afl->start_time += 4000; + sleep(1); if (afl->stop_soon) { goto stop_fuzzing; } } @@ -1654,6 +1715,7 @@ stop_fuzzing: ck_free(afl->fsrv.target_path); ck_free(afl->fsrv.out_file); ck_free(afl->sync_id); + if (afl->q_testcase_cache) { ck_free(afl->q_testcase_cache); } afl_state_deinit(afl); free(afl); /* not tracked */ -- cgit 1.4.1 From e0ab846f7fd3e45bbf76e4ab82eef19d9aaf5494 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 15 Dec 2020 09:37:52 +0100 Subject: v3.00c --- README.md | 2 +- include/config.h | 2 +- src/afl-cc.c | 26 ++++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index dc009def..68b64ce6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) - Release Version: [2.68c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases) Github Version: 3.00a diff --git a/include/config.h b/include/config.h index 491d8132..93249ed9 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++3.00a" +#define VERSION "++3.00c" /****************************************************** * * diff --git a/src/afl-cc.c b/src/afl-cc.c index c43ac2c1..2aeb2178 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -69,6 +69,7 @@ enum { INSTRUMENT_INSTRIM = 3, INSTRUMENT_CFG = 3, INSTRUMENT_LTO = 4, + INSTRUMENT_LLVMNATIVE = 5, INSTRUMENT_OPT_CTX = 8, INSTRUMENT_OPT_NGRAM = 16 @@ -76,8 +77,9 @@ enum { char instrument_mode_string[18][18] = { - "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "", "", "CTX", "", - "", "", "", "", "", "", "NGRAM", "" + "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "PCGUARD-NATIVE", + "", "CTX", "", "", "", "", "", + "", "", "NGRAM", "" }; @@ -580,6 +582,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif #endif + } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) { + +#if LLVM_MAJOR >= 4 + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; +#else + FATAL("pcguard instrumentation requires llvm 4.0.1+"); +#endif + } else { cc_params[cc_par_cnt++] = "-Xclang"; @@ -1162,6 +1172,18 @@ int main(int argc, char **argv, char **envp) { } + // this is a hidden option + if (strncasecmp(ptr, "llvmnative", strlen("llvmnative")) == 0 || + strncasecmp(ptr, "llvm-native", strlen("llvm-native")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) + instrument_mode = INSTRUMENT_LLVMNATIVE; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { -- cgit 1.4.1 From 1fc0918ac0e79588f9c4aff0a274da0897fe1b88 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 15 Dec 2020 09:55:33 +0100 Subject: v3.01a init --- README.md | 2 +- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 68b64ce6..a0e7a7e4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 3.00a + Github Version: 3.01a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index d77c276b..a45eaad7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++3.01a (release) + - ... + + ### Version ++3.00c (release) - llvm_mode/ and gcc_plugin/ moved to instrumentation/ - examples/ renamed to utils/ diff --git a/include/config.h b/include/config.h index 93249ed9..1eb6bc5e 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++3.00c" +#define VERSION "++3.01a" /****************************************************** * * -- cgit 1.4.1 From 12ebb351dc2b5655b4174539e2b9ee59e4acf893 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 18 Dec 2020 21:10:39 +0100 Subject: apply nocolor changes --- docs/Changelog.md | 2 ++ docs/env_variables.md | 3 +++ include/config.h | 16 ++++++++++++ include/debug.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++----- include/envs.h | 4 +++ src/afl-fuzz-state.c | 16 ++++++++++++ src/afl-fuzz.c | 15 +++++++++++ 7 files changed, 122 insertions(+), 6 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index ac75c68d..ebc514f3 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -52,6 +52,8 @@ sending a mail to . - somewhere we broke -n dumb fuzzing, fixed - added afl_custom_describe to the custom mutator API to allow for easy mutation reproduction on crashing inputs + - new env. var. AFL_NO_COLOR (or AFL_NO_COLOUR) to suppress colored + console output (when configured with USE_COLOR and not ALWAYS_COLORED) - instrumentation - We received an enhanced gcc_plugin module from AdaCore, thank you very much!! diff --git a/docs/env_variables.md b/docs/env_variables.md index e203055f..74863d8d 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -381,6 +381,9 @@ checks or alter some of the more exotic semantics of the tool: some basic stats. This behavior is also automatically triggered when the output from afl-fuzz is redirected to a file or to a pipe. + - Setting `AFL_NO_COLOR` or `AFL_NO_COLOUR` will omit control sequences for + coloring console output when configured with USE_COLOR and not ALWAYS_COLORED. + - Setting `AFL_FORCE_UI` will force painting the UI on the screen even if no valid terminal was detected (for virtual consoles) diff --git a/include/config.h b/include/config.h index 1eb6bc5e..d57ef223 100644 --- a/include/config.h +++ b/include/config.h @@ -36,11 +36,27 @@ * * ******************************************************/ +/* console output colors: There are three ways to configure its behavior + * 1. default: colored outputs fixed on: defined USE_COLOR && defined ALWAYS_COLORED + * The env var. AFL_NO_COLOR will have no effect + * 2. defined USE_COLOR && !defined ALWAYS_COLORED + * -> depending on env var AFL_NO_COLOR=1 colors can be switched off + * at run-time. Default is to use colors. + * 3. colored outputs fixed off: !defined USE_COLOR + * The env var. AFL_NO_COLOR will have no effect +*/ + /* Comment out to disable terminal colors (note that this makes afl-analyze a lot less nice): */ #define USE_COLOR +#ifdef USE_COLOR +/* Comment in to always enable terminal colors */ +/* Comment out to enable runtime controlled terminal colors via AFL_NO_COLOR */ +#define ALWAYS_COLORED 1 +#endif + /* StatsD config Config can be adjusted via AFL_STATSD_HOST and AFL_STATSD_PORT environment variable. diff --git a/include/debug.h b/include/debug.h index 5512023c..7a1725b5 100644 --- a/include/debug.h +++ b/include/debug.h @@ -168,12 +168,72 @@ * Debug & error macros * ************************/ -/* Just print stuff to the appropriate stream. */ +#if defined USE_COLOR && !defined ALWAYS_COLORED +#include +#pragma GCC diagnostic ignored "-Wformat-security" +static inline const char * colorfilter(const char * x) { + static int once = 1; + static int disabled = 0; + + if (once) { + /* when there is no tty -> we always want filtering + * when AFL_NO_UI is set filtering depends on AFL_NO_COLOR + * otherwise we want always colors + */ + disabled = isatty(2) && (!getenv("AFL_NO_UI") || (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR"))); + once = 0; + } + if (likely(disabled)) return x; + + static char monochromestring[4096]; + char *d = monochromestring; + int in_seq = 0; + + while(*x) { + if (in_seq && *x == 'm') { + in_seq = 0; + } else { + if (!in_seq && *x == '\x1b') { in_seq = 1; } + if (!in_seq) { + *d++ = *x; + } + } + ++x; + } + + *d = '\0'; + return monochromestring; +} +#else +#define colorfilter(x) x /* no filtering necessary */ +#endif +/* macro magic to transform the first parameter to SAYF + * through colorfilter which strips coloring */ +#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,\ +_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,\ +_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,\ +_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,\ +NAME,...) NAME + +#define SAYF(...) GET_MACRO(__VA_ARGS__, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ +SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_1)(__VA_ARGS__) + +#define SAYF_1(x) MY_SAYF(colorfilter(x)) +#define SAYF_N(x,...) MY_SAYF(colorfilter(x), __VA_ARGS__) + +/* Just print stuff to the appropriate stream. */ #ifdef MESSAGES_TO_STDOUT - #define SAYF(x...) printf(x) + #define MY_SAYF(x...) printf(x) #else - #define SAYF(x...) fprintf(stderr, x) + #define MY_SAYF(x...) fprintf(stderr, x) #endif /* ^MESSAGES_TO_STDOUT */ /* Show a prefixed warning. */ @@ -222,7 +282,7 @@ do { \ \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \ __FILE__, __LINE__); \ exit(1); \ @@ -235,7 +295,7 @@ do { \ \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \ __FILE__, __LINE__); \ abort(); \ @@ -249,7 +309,7 @@ \ fflush(stdout); \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] SYSTEM ERROR : " cRST x); \ + "\n[-] SYSTEM ERROR : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \ __FILE__, __LINE__); \ SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ diff --git a/include/envs.h b/include/envs.h index c0f41ca5..f16e61f0 100644 --- a/include/envs.h +++ b/include/envs.h @@ -103,6 +103,10 @@ static char *afl_environment_variables[] = { "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN", +#if defined USE_COLOR && ! defined ALWAYS_COLORED + "AFL_NO_COLOR", + "AFL_NO_COLOUR", +#endif "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 9c51a3ef..e863c4c7 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -401,6 +401,22 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_crash_exitcode = (u8 *)get_afl_env(afl_environment_variables[i]); +#if defined USE_COLOR && ! defined ALWAYS_COLORED + } else if (!strncmp(env, "AFL_NO_COLOR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_NO_COLOUR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); +#endif + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 391d4c4f..e0d46f7e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -156,6 +156,12 @@ static void usage(u8 *argv0, int more_help) { if (more_help > 1) { +#if defined USE_COLOR && !defined ALWAYS_COLORED + #define DYN_COLOR "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" +#else + #define DYN_COLOR +#endif + SAYF( "Environment variables used:\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n" @@ -194,6 +200,9 @@ static void usage(u8 *argv0, int more_help) { "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" "AFL_NO_UI: switch status screen off\n" + + DYN_COLOR + "AFL_PATH: path to AFL support binaries\n" "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n" "AFL_QUIET: suppress forkserver status messages\n" @@ -298,6 +307,12 @@ int main(int argc, char **argv_orig, char **envp) { struct timeval tv; struct timezone tz; +#if defined USE_COLOR && defined ALWAYS_COLORED + if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) { + WARNF("Setting AFL_NO_COLOR has no effect (colors are configured on at compile time)"); + } +#endif + char **argv = argv_cpy_dup(argc, argv_orig); afl_state_t *afl = calloc(1, sizeof(afl_state_t)); -- cgit 1.4.1 From 98ee17bc47b1f1d4664be9955a72727fff8e51fa Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 20 Dec 2020 14:30:06 +0100 Subject: fix endless loop in afl-cc allow/blocklists starting a line with a comment --- docs/Changelog.md | 8 +++- include/config.h | 13 ++++--- include/debug.h | 76 ++++++++++++++++++++++---------------- include/envs.h | 4 +- instrumentation/afl-gcc-pass.so.cc | 6 ++- instrumentation/afl-llvm-common.cc | 6 ++- src/afl-cc.c | 2 +- src/afl-fuzz-state.c | 3 +- src/afl-fuzz.c | 14 +++++-- 9 files changed, 80 insertions(+), 52 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index ebc514f3..28b7e723 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,9 +10,13 @@ sending a mail to . ### Version ++3.01a (release) - - fix crash for very, very fast targets+systems, thanks for reporting @mhlakhani + - fix crash for very, very fast targets+systems (thanks to mhlakhani + for reporting) - added dummy Makefile to instrumentation/ - - allow instrumenting LLVMFuzzerTestOneInput + - afl-cc + - allow instrumenting LLVMFuzzerTestOneInput + - fixed endless loop for allow/blocklist lines starting with a + comment (thanks to Zherya for reporting) ### Version ++3.00c (release) diff --git a/include/config.h b/include/config.h index d57ef223..e8a49270 100644 --- a/include/config.h +++ b/include/config.h @@ -37,14 +37,14 @@ ******************************************************/ /* console output colors: There are three ways to configure its behavior - * 1. default: colored outputs fixed on: defined USE_COLOR && defined ALWAYS_COLORED - * The env var. AFL_NO_COLOR will have no effect + * 1. default: colored outputs fixed on: defined USE_COLOR && defined + * ALWAYS_COLORED The env var. AFL_NO_COLOR will have no effect * 2. defined USE_COLOR && !defined ALWAYS_COLORED * -> depending on env var AFL_NO_COLOR=1 colors can be switched off * at run-time. Default is to use colors. * 3. colored outputs fixed off: !defined USE_COLOR * The env var. AFL_NO_COLOR will have no effect -*/ + */ /* Comment out to disable terminal colors (note that this makes afl-analyze a lot less nice): */ @@ -52,9 +52,10 @@ #define USE_COLOR #ifdef USE_COLOR -/* Comment in to always enable terminal colors */ -/* Comment out to enable runtime controlled terminal colors via AFL_NO_COLOR */ -#define ALWAYS_COLORED 1 + /* Comment in to always enable terminal colors */ + /* Comment out to enable runtime controlled terminal colors via AFL_NO_COLOR + */ + #define ALWAYS_COLORED 1 #endif /* StatsD config diff --git a/include/debug.h b/include/debug.h index 7a1725b5..7f4a6be1 100644 --- a/include/debug.h +++ b/include/debug.h @@ -169,65 +169,77 @@ ************************/ #if defined USE_COLOR && !defined ALWAYS_COLORED -#include -#pragma GCC diagnostic ignored "-Wformat-security" -static inline const char * colorfilter(const char * x) { + #include + #pragma GCC diagnostic ignored "-Wformat-security" +static inline const char *colorfilter(const char *x) { + static int once = 1; static int disabled = 0; if (once) { + /* when there is no tty -> we always want filtering * when AFL_NO_UI is set filtering depends on AFL_NO_COLOR * otherwise we want always colors */ - disabled = isatty(2) && (!getenv("AFL_NO_UI") || (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR"))); + disabled = + isatty(2) && (!getenv("AFL_NO_UI") || + (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR"))); once = 0; + } + if (likely(disabled)) return x; static char monochromestring[4096]; - char *d = monochromestring; - int in_seq = 0; + char * d = monochromestring; + int in_seq = 0; + + while (*x) { - while(*x) { if (in_seq && *x == 'm') { + in_seq = 0; + } else { + if (!in_seq && *x == '\x1b') { in_seq = 1; } - if (!in_seq) { - *d++ = *x; - } + if (!in_seq) { *d++ = *x; } + } + ++x; + } *d = '\0'; return monochromestring; + } + #else -#define colorfilter(x) x /* no filtering necessary */ + #define colorfilter(x) x /* no filtering necessary */ #endif /* macro magic to transform the first parameter to SAYF * through colorfilter which strips coloring */ -#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,\ -_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,\ -_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,\ -_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,\ -NAME,...) NAME - -#define SAYF(...) GET_MACRO(__VA_ARGS__, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ -SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_1)(__VA_ARGS__) - -#define SAYF_1(x) MY_SAYF(colorfilter(x)) -#define SAYF_N(x,...) MY_SAYF(colorfilter(x), __VA_ARGS__) +#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, \ + _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, \ + _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, \ + _39, _40, NAME, ...) \ + NAME + +#define SAYF(...) \ + GET_MACRO(__VA_ARGS__, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ + SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ + SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ + SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ + SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \ + SAYF_N, SAYF_1) \ + (__VA_ARGS__) + +#define SAYF_1(x) MY_SAYF(colorfilter(x)) +#define SAYF_N(x, ...) MY_SAYF(colorfilter(x), __VA_ARGS__) /* Just print stuff to the appropriate stream. */ #ifdef MESSAGES_TO_STDOUT @@ -282,7 +294,7 @@ SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_1)(__VA_ARGS__) do { \ \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \ __FILE__, __LINE__); \ exit(1); \ @@ -295,7 +307,7 @@ SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_1)(__VA_ARGS__) do { \ \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \ __FILE__, __LINE__); \ abort(); \ @@ -309,7 +321,7 @@ SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_1)(__VA_ARGS__) \ fflush(stdout); \ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] SYSTEM ERROR : " cRST x); \ + "\n[-] SYSTEM ERROR : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \ __FILE__, __LINE__); \ SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ diff --git a/include/envs.h b/include/envs.h index f16e61f0..e4e49c4d 100644 --- a/include/envs.h +++ b/include/envs.h @@ -78,8 +78,8 @@ static char *afl_environment_variables[] = { "AFL_LLVM_CTX", "AFL_LLVM_DICT2FILE", "AFL_LLVM_DOCUMENT_IDS", - "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", + "AFL_LLVM_INSTRUMENT", "AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY", "AFL_LLVM_SKIPSINGLEBLOCK", @@ -103,7 +103,7 @@ static char *afl_environment_variables[] = { "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN", -#if defined USE_COLOR && ! defined ALWAYS_COLORED +#if defined USE_COLOR && !defined ALWAYS_COLORED "AFL_NO_COLOR", "AFL_NO_COLOUR", #endif diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc index c95ead8f..25437609 100644 --- a/instrumentation/afl-gcc-pass.so.cc +++ b/instrumentation/afl-gcc-pass.so.cc @@ -622,10 +622,11 @@ struct afl_pass : gimple_opt_pass { allowListFiles.push_back(line); else allowListFunctions.push_back(line); - getline(fileStream, line); } + getline(fileStream, line); + } if (debug) @@ -696,10 +697,11 @@ struct afl_pass : gimple_opt_pass { denyListFiles.push_back(line); else denyListFunctions.push_back(line); - getline(fileStream, line); } + getline(fileStream, line); + } if (debug) diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index 557939fd..a27c4069 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -168,10 +168,11 @@ void initInstrumentList() { allowListFiles.push_back(line); else allowListFunctions.push_back(line); - getline(fileStream, line); } + getline(fileStream, line); + } if (debug) @@ -242,10 +243,11 @@ void initInstrumentList() { denyListFiles.push_back(line); else denyListFunctions.push_back(line); - getline(fileStream, line); } + getline(fileStream, line); + } if (debug) diff --git a/src/afl-cc.c b/src/afl-cc.c index 2aeb2178..8593f9b8 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1432,7 +1432,7 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " "functions\n" - " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " + " AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST: enable " "instrument allow/\n" " deny listing (selective instrumentation)\n"); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e863c4c7..7053572b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -401,7 +401,8 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_crash_exitcode = (u8 *)get_afl_env(afl_environment_variables[i]); -#if defined USE_COLOR && ! defined ALWAYS_COLORED +#if defined USE_COLOR && !defined ALWAYS_COLORED + } else if (!strncmp(env, "AFL_NO_COLOR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e0d46f7e..2af374f2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -157,7 +157,8 @@ static void usage(u8 *argv0, int more_help) { if (more_help > 1) { #if defined USE_COLOR && !defined ALWAYS_COLORED - #define DYN_COLOR "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" + #define DYN_COLOR \ + "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" #else #define DYN_COLOR #endif @@ -307,11 +308,16 @@ int main(int argc, char **argv_orig, char **envp) { struct timeval tv; struct timezone tz; -#if defined USE_COLOR && defined ALWAYS_COLORED + #if defined USE_COLOR && defined ALWAYS_COLORED if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) { - WARNF("Setting AFL_NO_COLOR has no effect (colors are configured on at compile time)"); + + WARNF( + "Setting AFL_NO_COLOR has no effect (colors are configured on at " + "compile time)"); + } -#endif + + #endif char **argv = argv_cpy_dup(argc, argv_orig); -- cgit 1.4.1 From c6e038fe25789caa8da777f53154de1bd7b4e178 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 4 Jan 2021 20:40:53 +0100 Subject: code cleanups (shadowed vars, (un)signed type mismatches, format types, etc.) --- include/afl-fuzz.h | 4 +-- include/config.h | 46 +++++++++++++++--------------- src/afl-analyze.c | 4 +-- src/afl-cc.c | 74 ++++++++++++++++++++++++++++--------------------- src/afl-common.c | 20 ++++++------- src/afl-forkserver.c | 4 +-- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-extras.c | 6 ++-- src/afl-fuzz-mutators.c | 28 ++++++++++++------- src/afl-fuzz-one.c | 24 ++++++++-------- src/afl-fuzz-queue.c | 5 ++-- src/afl-fuzz-redqueen.c | 9 ++++-- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-stats.c | 8 +++--- src/afl-fuzz.c | 8 +++--- src/afl-ld-lto.c | 6 ++-- src/afl-showmap.c | 12 ++++---- src/afl-tmin.c | 4 +-- 18 files changed, 144 insertions(+), 122 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index d6a322cc..ede54f0e 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -573,7 +573,7 @@ typedef struct afl_state { u8 stage_name_buf[STAGE_BUF_SIZE]; /* reused stagename buf with len 64 */ - s32 stage_cur, stage_max; /* Stage progression */ + u32 stage_cur, stage_max; /* Stage progression */ s32 splicing_with; /* Splicing with which test case? */ u32 main_node_id, main_node_max; /* Main instance job splitting */ @@ -648,7 +648,7 @@ typedef struct afl_state { double last_avg_execs_saved; /* foreign sync */ -#define FOREIGN_SYNCS_MAX 32 +#define FOREIGN_SYNCS_MAX 32U u8 foreign_sync_cnt; struct foreign_sync foreign_syncs[FOREIGN_SYNCS_MAX]; diff --git a/include/config.h b/include/config.h index e8a49270..7c75e9c9 100644 --- a/include/config.h +++ b/include/config.h @@ -80,11 +80,11 @@ /* Default timeout for fuzzed code (milliseconds). This is the upper bound, also used for detecting hangs; the actual value is auto-scaled: */ -#define EXEC_TIMEOUT 1000 +#define EXEC_TIMEOUT 1000U /* Timeout rounding factor when auto-scaling (milliseconds): */ -#define EXEC_TM_ROUND 20 +#define EXEC_TM_ROUND 20U /* 64bit arch MACRO */ #if (defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__)) @@ -93,48 +93,48 @@ /* Default memory limit for child process (MB) 0 = disabled : */ -#define MEM_LIMIT 0 +#define MEM_LIMIT 0U /* Default memory limit when running in QEMU mode (MB) 0 = disabled : */ -#define MEM_LIMIT_QEMU 0 +#define MEM_LIMIT_QEMU 0U /* Default memory limit when running in Unicorn mode (MB) 0 = disabled : */ -#define MEM_LIMIT_UNICORN 0 +#define MEM_LIMIT_UNICORN 0U /* Number of calibration cycles per every new test case (and for test cases that show variable behavior): */ -#define CAL_CYCLES 8 -#define CAL_CYCLES_LONG 40 +#define CAL_CYCLES 8U +#define CAL_CYCLES_LONG 40U /* Number of subsequent timeouts before abandoning an input file: */ -#define TMOUT_LIMIT 250 +#define TMOUT_LIMIT 250U /* Maximum number of unique hangs or crashes to record: */ -#define KEEP_UNIQUE_HANG 500 -#define KEEP_UNIQUE_CRASH 5000 +#define KEEP_UNIQUE_HANG 500U +#define KEEP_UNIQUE_CRASH 5000U /* Baseline number of random tweaks during a single 'havoc' stage: */ -#define HAVOC_CYCLES 256 -#define HAVOC_CYCLES_INIT 1024 +#define HAVOC_CYCLES 256U +#define HAVOC_CYCLES_INIT 1024U /* Maximum multiplier for the above (should be a power of two, beware of 32-bit int overflows): */ -#define HAVOC_MAX_MULT 64 -#define HAVOC_MAX_MULT_MOPT 64 +#define HAVOC_MAX_MULT 64U +#define HAVOC_MAX_MULT_MOPT 64U /* Absolute minimum number of havoc cycles (after all adjustments): */ -#define HAVOC_MIN 12 +#define HAVOC_MIN 12U /* Power Schedule Divisor */ -#define POWER_BETA 1 +#define POWER_BETA 1U #define MAX_FACTOR (POWER_BETA * 32) /* Maximum stacking for havoc-stage tweaks. The actual value is calculated @@ -146,19 +146,19 @@ In other words, the default (n = 4) produces 2, 4, 8, 16 stacked tweaks: */ -#define HAVOC_STACK_POW2 4 +#define HAVOC_STACK_POW2 4U /* Caps on block sizes for cloning and deletion operations. Each of these ranges has a 33% probability of getting picked, except for the first two cycles where smaller blocks are favored: */ -#define HAVOC_BLK_SMALL 32 -#define HAVOC_BLK_MEDIUM 128 -#define HAVOC_BLK_LARGE 1500 +#define HAVOC_BLK_SMALL 32U +#define HAVOC_BLK_MEDIUM 128U +#define HAVOC_BLK_LARGE 1500U /* Extra-large blocks, selected very rarely (<5% of the time): */ -#define HAVOC_BLK_XL 32768 +#define HAVOC_BLK_XL 32768U /* Probabilities of skipping non-favored entries in the queue, expressed as percentages: */ @@ -188,11 +188,11 @@ /* Maximum size of input file, in bytes (keep under 100MB): */ -#define MAX_FILE (1 * 1024 * 1024) +#define MAX_FILE (1 * 1024 * 1024U) /* The same, for the test case minimizer: */ -#define TMIN_MAX_FILE (10 * 1024 * 1024) +#define TMIN_MAX_FILE (10 * 1024 * 1024U) /* Block normalization steps for afl-tmin: */ diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 6dac415b..8fc4434a 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -903,8 +903,8 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -f file - input file read by the tested program (stdin)\n" - " -t msec - timeout for each run (%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -t msec - timeout for each run (%u ms)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " diff --git a/src/afl-cc.c b/src/afl-cc.c index e6a6718e..180ab3c4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -120,8 +120,10 @@ char compiler_mode_string[7][12] = { u8 *getthecwd() { - static u8 fail[] = ""; - if (getcwd(cwd, sizeof(cwd)) == NULL) return fail; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + static u8 fail[] = ""; + return fail; + } return cwd; } @@ -654,9 +656,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - u32 idx; if (lto_mode && argc > 1) { + u32 idx; for (idx = 1; idx < argc; idx++) { if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1; @@ -1208,12 +1210,12 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_INSTRUMENT")) { - u8 *ptr = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); + u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); - while (ptr) { + while (ptr2) { - if (strncasecmp(ptr, "afl", strlen("afl")) == 0 || - strncasecmp(ptr, "classic", strlen("classic")) == 0) { + if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 || + strncasecmp(ptr2, "classic", strlen("classic")) == 0) { if (instrument_mode == INSTRUMENT_LTO) { @@ -1229,8 +1231,8 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || - strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) { + if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 || + strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) instrument_mode = INSTRUMENT_PCGUARD; @@ -1241,8 +1243,8 @@ int main(int argc, char **argv, char **envp) { } // this is a hidden option - if (strncasecmp(ptr, "llvmnative", strlen("llvmnative")) == 0 || - strncasecmp(ptr, "llvm-native", strlen("llvm-native")) == 0) { + if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 || + strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) instrument_mode = INSTRUMENT_LLVMNATIVE; @@ -1252,8 +1254,8 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || - strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { + if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 || + strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) { if (instrument_mode == INSTRUMENT_LTO) { @@ -1269,7 +1271,7 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "lto", strlen("lto")) == 0) { + if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) { lto_mode = 1; if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) @@ -1280,7 +1282,7 @@ int main(int argc, char **argv, char **envp) { } - if (strcasecmp(ptr, "gcc") == 0) { + if (strcasecmp(ptr2, "gcc") == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_GCC) instrument_mode = INSTRUMENT_GCC; @@ -1291,7 +1293,7 @@ int main(int argc, char **argv, char **envp) { } - if (strcasecmp(ptr, "clang") == 0) { + if (strcasecmp(ptr2, "clang") == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG) instrument_mode = INSTRUMENT_CLANG; @@ -1302,29 +1304,29 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { + if (strncasecmp(ptr2, "ctx", strlen("ctx")) == 0) { instrument_opt_mode |= INSTRUMENT_OPT_CTX; setenv("AFL_LLVM_CTX", "1", 1); } - if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { + if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { - ptr += strlen("ngram"); - while (*ptr && (*ptr < '0' || *ptr > '9')) - ptr++; + ptr2 += strlen("ngram"); + while (*ptr2 && (*ptr2 < '0' || *ptr2 > '9')) + ptr2++; - if (!*ptr) { + if (!*ptr2) { - if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) + if ((ptr2 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) FATAL( "you must set the NGRAM size with (e.g. for value 2) " "AFL_LLVM_INSTRUMENT=ngram-2"); } - ngram_size = atoi(ptr); + ngram_size = atoi(ptr2); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( "NGRAM instrumentation option must be between 2 and " @@ -1332,12 +1334,12 @@ int main(int argc, char **argv, char **envp) { "(%u)", NGRAM_SIZE_MAX); instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); - ptr = alloc_printf("%u", ngram_size); - setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); + ptr2 = alloc_printf("%u", ngram_size); + setenv("AFL_LLVM_NGRAM_SIZE", ptr2, 1); } - ptr = strtok(NULL, ":,;"); + ptr2 = strtok(NULL, ":,;"); } @@ -1448,20 +1450,28 @@ int main(int argc, char **argv, char **envp) { " The best is LTO but it often needs RANLIB and AR settings outside " "of afl-cc.\n\n"); +#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) +#define NATIVE_MSG \ + " NATIVE: use llvm's native PCGUARD instrumentation (less " \ + "performant)\n" +#else +#define NATIVE_MSG "" +#endif + SAYF( "Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best " "available)\n" " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" -#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - " NATIVE: use llvm's native PCGUARD instrumentation (less " - "performant)\n" -#endif + + NATIVE_MSG + " CLASSIC: decision target instrumentation (README.llvm.md)\n" " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " "((instrumentation/README.ngram.md)\n" " INSTRIM: Dominator tree (for LLVM <= 6.0) " "(instrumentation/README.instrim.md)\n\n"); +#undef NATIVE_MSG SAYF( "Features: (see documentation links)\n" @@ -1625,7 +1635,7 @@ int main(int argc, char **argv, char **envp) { if (!instrument_mode) { instrument_mode = INSTRUMENT_CFG; - ptr = instrument_mode_string[instrument_mode]; + //ptr = instrument_mode_string[instrument_mode]; } diff --git a/src/afl-common.c b/src/afl-common.c index 1928663d..21cb6ab4 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -696,16 +696,16 @@ u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) { u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - if (!event_ms) { snprintf(buf, len, "none seen yet"); } else { + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + delta = cur_ms - event_ms; t_d = delta / 1000 / 60 / 60 / 24; @@ -858,16 +858,16 @@ u8 *u_stringify_mem_size(u8 *buf, u64 val) { u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - if (!event_ms) { sprintf(buf, "none seen yet"); } else { + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + delta = cur_ms - event_ms; t_d = delta / 1000 / 60 / 60 / 24; @@ -895,8 +895,8 @@ u32 get_map_size(void) { map_size = atoi(ptr); if (map_size < 8 || map_size > (1 << 29)) { - FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8, - 1 << 29); + FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8U, + 1U << 29); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 90fa55e9..d6195cb5 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -213,7 +213,7 @@ restart_select: static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { unsigned char tmp[4] = {0, 0, 0, 0}; - pid_t child_pid = -1; + pid_t child_pid; if (!be_quiet) { ACTF("Using Fauxserver:"); } @@ -1104,7 +1104,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, "Unable to communicate with fork server. Some possible reasons:\n\n" " - You've run out of memory. Use -m to increase the the memory " "limit\n" - " to something higher than %lld.\n" + " to something higher than %llu.\n" " - The binary or one of the libraries it uses manages to " "create\n" " threads before the forkserver initializes.\n" diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 62a8211c..85a01f98 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -703,7 +703,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (!classified) { classify_counts(&afl->fsrv); - classified = 1; +// classified = 1; } diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 171cce96..04f0878c 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -266,7 +266,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, if (afl->extras_cnt > afl->max_det_extras) { - WARNF("More than %d tokens - will use them probabilistically.", + WARNF("More than %u tokens - will use them probabilistically.", afl->max_det_extras); } @@ -431,7 +431,6 @@ void dedup_extras(afl_state_t *afl) { /* Adds a new extra / dict entry. */ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { - u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; u32 i, found = 0; for (i = 0; i < afl->extras_cnt; i++) { @@ -451,6 +450,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len, mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); @@ -481,7 +481,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (afl->extras_cnt == afl->max_det_extras + 1) { - WARNF("More than %d tokens - will use them probabilistically.", + WARNF("More than %u tokens - will use them probabilistically.", afl->max_det_extras); } diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0c85458e..5da692d3 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -316,16 +316,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, /* Initialize trimming in the custom mutator */ afl->stage_cur = 0; - afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); - if (unlikely(afl->stage_max) < 0) { + s32 retval = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); + if (unlikely(retval) < 0) { - FATAL("custom_init_trim error ret: %d", afl->stage_max); + FATAL("custom_init_trim error ret: %d", retval); + } else { + + afl->stage_max = retval; + } if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, + SAYF("[Custom Trimming] START: Max %u iterations, %u bytes", afl->stage_max, q->len); } @@ -343,7 +347,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, if (unlikely(!retbuf)) { - FATAL("custom_trim failed (ret %zd)", retlen); + FATAL("custom_trim failed (ret %zu)", retlen); } else if (unlikely(retlen > orig_len)) { @@ -409,7 +413,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)", + SAYF("[Custom Trimming] SUCCESS: %u/%u iterations (now at %u bytes)", afl->stage_cur, afl->stage_max, q->len); } @@ -417,16 +421,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else { /* Tell the custom mutator that the trimming was unsuccessful */ - afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); - if (unlikely(afl->stage_cur < 0)) { + s32 retval2 = mutator->afl_custom_post_trim(mutator->data, 0); + if (unlikely(retval2 < 0)) { + + FATAL("Error ret in custom_post_trim: %d", retval2); + + } else { - FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); + afl->stage_cur = retval2; } if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, + SAYF("[Custom Trimming] FAILURE: %u/%u iterations", afl->stage_cur, afl->stage_max); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e6fa6064..f9509e86 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -368,7 +368,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, temp_len; + u32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -545,7 +545,7 @@ u8 fuzz_one_original(afl_state_t *afl) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score <= 0)) { goto abandon_entry; } + if (unlikely(perf_score == 0)) { goto abandon_entry; } if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { @@ -902,7 +902,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { /* Let's consult the effector map... */ @@ -945,7 +945,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; ++i) { + for (i = 0; i < len - 3; ++i) { /* Let's consult the effector map... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && @@ -1405,7 +1405,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -1493,7 +1493,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; i++) { + for (i = 0; i < len - 3; i++) { u32 orig = *(u32 *)(out_buf + i); @@ -1850,7 +1850,7 @@ custom_mutator_stage: if (unlikely(!mutated_buf)) { - FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); + FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size); } @@ -2026,7 +2026,7 @@ havoc_stage: el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); if (unlikely(!custom_havoc_buf)) { - FATAL("Error in custom_havoc (return %zd)", new_len); + FATAL("Error in custom_havoc (return %zu)", new_len); } @@ -2458,7 +2458,7 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if ((s32)extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -2476,7 +2476,7 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if ((s32)extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -2577,7 +2577,7 @@ havoc_stage: u32 copy_from, copy_to, copy_len; copy_len = choose_block_len(afl, new_len - 1); - if ((s32)copy_len > temp_len) copy_len = temp_len; + if (copy_len > temp_len) copy_len = temp_len; copy_from = rand_below(afl, new_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); @@ -2952,7 +2952,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score <= 0)) { goto abandon_entry; } + if (unlikely(perf_score == 0)) { goto abandon_entry; } if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 9a0d199e..cd41bafc 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -489,11 +489,12 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - struct queue_entry *q; u32 i; for (i = 0; i < afl->queued_paths; i++) { + struct queue_entry *q; + q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); @@ -996,7 +997,7 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (unlikely(!q->testcase_buf)) { - PFATAL("Unable to malloc '%s' with len %d", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index c5db8fa1..7dba1caa 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -445,6 +445,9 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u32 k; u8 cons_ff = 0, cons_0 = 0; + + if (shape > sizeof(v)) FATAL("shape is greater than %zu, please report!", sizeof(v)); + for (k = 0; k < shape; ++k) { if (b[k] == 0) { @@ -453,7 +456,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } else if (b[k] == 0xff) { - ++cons_0; + ++cons_ff; } else { @@ -667,12 +670,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u8 status = 0; // opt not in the paper - u32 fails = 0; +// u32 fails = 0; u8 found_one = 0; for (i = 0; i < loggeds; ++i) { - fails = 0; + u32 fails = 0; struct cmpfn_operands *o = &((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i]; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 339fb9c3..11d8204b 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -682,7 +682,7 @@ void sync_fuzzers(afl_state_t *afl) { // same time. If so, the first temporary main node running again will demote // themselves so this is not an issue - u8 path[PATH_MAX]; +// u8 path2[PATH_MAX]; afl->is_main_node = 1; sprintf(path, "%s/is_main_node", afl->out_dir); int fd = open(path, O_CREAT | O_RDWR, 0644); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 1c211da6..c8366174 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -31,7 +31,6 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { - char *val; u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); @@ -44,6 +43,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { for (i = 0; i < s_afl_env; ++i) { + char *val; if ((val = getenv(afl_environment_variables[i])) != NULL) { fprintf(f, "%s=%s\n", afl_environment_variables[i], val); @@ -228,7 +228,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, if (afl->virgin_bits[i] != 0xff) { - fprintf(f, " %d[%02x]", i, afl->virgin_bits[i]); + fprintf(f, " %u[%02x]", i, afl->virgin_bits[i]); } @@ -238,7 +238,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, fprintf(f, "var_bytes :"); for (i = 0; i < afl->fsrv.map_size; i++) { - if (afl->var_bytes[i]) { fprintf(f, " %d", i); } + if (afl->var_bytes[i]) { fprintf(f, " %u", i); } } @@ -1163,7 +1163,7 @@ void show_init_stats(afl_state_t *afl) { } else { - ACTF("-t option specified. We'll use an exec timeout of %d ms.", + ACTF("-t option specified. We'll use an exec timeout of %u ms.", afl->fsrv.exec_tmout); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 897c2f1e..e239b47f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -99,8 +99,8 @@ static void usage(u8 *argv0, int more_help) { " lin, quad> -- see docs/power_schedules.md\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, 0 = no limit)\n" + " -t msec - timeout for each run (auto-scaled, 50-%u ms)\n" + " -m megs - memory limit for child process (%u MB, 0 = no limit)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " @@ -299,7 +299,7 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/; u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; + u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = get_map_size(); u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; @@ -326,7 +326,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } - map_size = get_map_size(); +// map_size = get_map_size(); afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index fccdb1a5..1d54fda0 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -187,7 +187,7 @@ static void edit_params(int argc, char **argv) { if (debug) DEBUGF( - "passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s " + "passthrough=%s instrim=%u, gold_pos=%u, gold_present=%s " "inst_present=%s rt_present=%s rt_lto_present=%s\n", passthrough ? "true" : "false", instrim, gold_pos, gold_present ? "true" : "false", inst_present ? "true" : "false", @@ -253,10 +253,10 @@ static void edit_params(int argc, char **argv) { int main(int argc, char **argv) { s32 pid, i, status; - u8 * ptr; +// u8 * ptr; char thecwd[PATH_MAX]; - if ((ptr = getenv("AFL_LD_CALLER")) != NULL) { + if (getenv("AFL_LD_CALLER") != NULL) { FATAL("ld loop detected! Set AFL_REAL_LD!\n"); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 355b2dc3..c0223a07 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -662,7 +662,7 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -t msec - timeout for each run (none)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use Unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine mode)\n" @@ -1014,7 +1014,7 @@ int main(int argc, char **argv_orig, char **envp) { DIR * dir_in, *dir_out = NULL; struct dirent *dir_ent; - int done = 0; +// int done = 0; u8 infile[PATH_MAX], outfile[PATH_MAX]; u8 wait_for_gdb = 0; #if !defined(DT_REG) @@ -1090,11 +1090,11 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { - int i = optind; + int j = optind; DEBUGF("%s:", fsrv->target_path); - while (argv[i] != NULL) { + while (argv[j] != NULL) { - SAYF(" \"%s\"", argv[i++]); + SAYF(" \"%s\"", argv[j++]); } @@ -1143,7 +1143,7 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - while (done == 0 && (dir_ent = readdir(dir_in))) { + while ((dir_ent = readdir(dir_in))) { if (dir_ent->d_name[0] == '.') { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index ed928c7c..09d97f58 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -835,8 +835,8 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -f file - input file read by the tested program (stdin)\n" - " -t msec - timeout for each run (%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -t msec - timeout for each run (%u ms)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " -- cgit 1.4.1 From 251e72f13654b5259f57075c7dffcc3a43372449 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 4 Jan 2021 21:25:53 +0100 Subject: mehr code cleanup --- include/config.h | 2 +- include/types.h | 2 +- instrumentation/afl-compiler-rt.o.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 7c75e9c9..ba62d4c6 100644 --- a/include/config.h +++ b/include/config.h @@ -380,7 +380,7 @@ after changing this - otherwise, SEGVs may ensue. */ #define MAP_SIZE_POW2 16 -#define MAP_SIZE (1 << MAP_SIZE_POW2) +#define MAP_SIZE (1U << MAP_SIZE_POW2) /* Maximum allocator request size (keep well under INT_MAX): */ diff --git a/include/types.h b/include/types.h index 39f599a0..3e3bc953 100644 --- a/include/types.h +++ b/include/types.h @@ -50,7 +50,7 @@ typedef uint32_t u32; #define FS_OPT_SHDMEM_FUZZ 0x01000000 #define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000 // FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22 -#define FS_OPT_MAX_MAPSIZE ((0x00fffffe >> 1) + 1) +#define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1) #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) #define FS_OPT_SET_MAPSIZE(x) \ (x <= 1 || x > FS_OPT_MAX_MAPSIZE ? 0 : ((x - 1) << 1)) diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index cddde87c..0b6c6e47 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -683,7 +683,7 @@ static void __afl_start_forkserver(void) { #endif u8 tmp[4] = {0, 0, 0, 0}; - u32 status = 0; + u32 status_for_fsrv = 0; u32 already_read_first = 0; u32 was_killed; @@ -692,11 +692,11 @@ static void __afl_start_forkserver(void) { void (*old_sigchld_handler)(int) = 0; // = signal(SIGCHLD, SIG_DFL); if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); - if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT; - if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ; - if (status) status |= (FS_OPT_ENABLED); - memcpy(tmp, &status, 4); + status_for_fsrv |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); + if (__afl_dictionary_len && __afl_dictionary) status_for_fsrv |= FS_OPT_AUTODICT; + if (__afl_sharedmem_fuzzing != 0) status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; + if (status_for_fsrv) status_for_fsrv |= (FS_OPT_ENABLED); + memcpy(tmp, &status_for_fsrv, 4); /* Phone home and tell the parent that we're OK. If parent isn't there, assume we're not running in forkserver mode and just execute program. */ @@ -726,7 +726,6 @@ static void __afl_start_forkserver(void) { // great lets pass the dictionary through the forkserver FD u32 len = __afl_dictionary_len, offset = 0; - s32 ret; if (write(FORKSRV_FD + 1, &len, 4) != 4) { @@ -738,6 +737,7 @@ static void __afl_start_forkserver(void) { while (len != 0) { + s32 ret; ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); if (ret < 1) { -- cgit 1.4.1 From 6b54310452a1b743a90ad45fcc511f59dd7821ec Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 5 Jan 2021 12:30:26 +0100 Subject: selective instrumentation documented --- docs/Changelog.md | 5 ++- include/config.h | 4 ++- instrumentation/README.instrument_list.md | 53 ++++++++++++++++++++----------- src/afl-cc.c | 14 ++++++++ 4 files changed, 55 insertions(+), 21 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index 88dc74d2..03b8e036 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,8 +9,11 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++3.01a (release) +### Version ++3.01a (dev) - Mac OS ARM64 support + - New selective instrumentation option with __AFL_COVERAGE_... commands + to be placed in the source code. + Check out instrumentation/README.instrument_list.md - afl-fuzz - fix crash for very, very fast targets+systems (thanks to mhlakhani for reporting) diff --git a/include/config.h b/include/config.h index ba62d4c6..c0cd0ef1 100644 --- a/include/config.h +++ b/include/config.h @@ -186,7 +186,9 @@ #define TRIM_START_STEPS 16 #define TRIM_END_STEPS 1024 -/* Maximum size of input file, in bytes (keep under 100MB): */ +/* Maximum size of input file, in bytes (keep under 100MB, default 1MB): + (note that if this value is changed, several areas in afl-cc.c, afl-fuzz.c + and afl-fuzz-state.c have to be changed as well! */ #define MAX_FILE (1 * 1024 * 1024U) diff --git a/instrumentation/README.instrument_list.md b/instrumentation/README.instrument_list.md index 122be2b6..83197954 100644 --- a/instrumentation/README.instrument_list.md +++ b/instrumentation/README.instrument_list.md @@ -1,8 +1,9 @@ # Using afl++ with partial instrumentation - This file describes how to selectively instrument only source files - or functions that are of interest to you using the LLVM and GCC_PLUGIN - instrumentation provided by afl++. + This file describes two different mechanisms to selectively instrument + only specific parts in the target. + + Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc. ## 1) Description and purpose @@ -12,28 +13,42 @@ the program, leaving the rest uninstrumented. This helps to focus the fuzzer on the important parts of the program, avoiding undesired noise and disturbance by uninteresting code being exercised. -For this purpose, a "partial instrumentation" support en par with llvm sancov -is provided by afl++ that allows to specify on a source file and function -level which function should be compiled with or without instrumentation. +For this purpose, "partial instrumentation" support is provided by afl++ that +allows to specify what should be instrumented and what not. + +Both mechanisms can be used together. + +## 2) Selective instrumentation with __AFL_COVERAGE_... directives + +In this mechanism the selective instrumentation is done in the source code. -Note: When using PCGUARD mode - and llvm 12+ - you can use this instead: -https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation +After the includes a special define has to be made, eg.: + +``` +#include +#include +// ... + +__AFL_COVERAGE(); // <- required for this feature to work +``` -The llvm sancov list format is fully supported by afl++, however afl++ has -more flexibility. +If you want to disable the coverage at startup until you specify coverage +should be started, then add `__AFL_COVERAGE_START_OFF();` at that position. -## 2a) Building the LLVM module +From here on out you have the following macros available that you can use +in any function where you want: -The new code is part of the existing afl++ LLVM module in the instrumentation/ -subdirectory. There is nothing specifically to do for the build :) + * `__AFL_COVERAGE_ON();` - enable coverage from this point onwards + * `__AFL_COVERAGE_OFF();` - disable coverage from this point onwards + * `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point + * `__AFL_COVERAGE_ABORT();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it. -## 2b) Building the GCC module +## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST -The new code is part of the existing afl++ GCC_PLUGIN module in the -instrumentation/ subdirectory. There is nothing specifically to do for -the build :) +This feature is equivalent to llvm 12 sancov feature and allows to specify +on a filename and/or function name level to instrument these or skip them. -## 3) How to use the partial instrumentation mode +### 3a) How to use the partial instrumentation mode In order to build with partial instrumentation, you need to build with afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++. @@ -90,7 +105,7 @@ fun: MallocFoo ``` Note that whitespace is ignored and comments (`# foo`) are supported. -## 4) UNIX-style pattern matching +### 3b) UNIX-style pattern matching You can add UNIX-style pattern matching in the "instrument file list" entries. See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags. diff --git a/src/afl-cc.c b/src/afl-cc.c index db2dcd14..964df57f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -827,6 +827,20 @@ static void edit_params(u32 argc, char **argv, char **envp) { "extern unsigned char *__afl_fuzz_ptr;" "unsigned char __afl_fuzz_alt[1048576];" "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" + "void __afl_coverage_discard();" + "void __afl_coverage_abort();" + "void __afl_coverage_on();" + "void __afl_coverage_off();"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = " + "1;"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ON()=__afl_coverage_on()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; -- cgit 1.4.1 From 0b545aaeb45141e91273f2358ec457293c341c92 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 20:18:18 +0100 Subject: use enums, support cmplog map collisions --- include/cmplog.h | 8 +- include/config.h | 2 - include/types.h | 47 ++++--- instrumentation/afl-compiler-rt.o.c | 201 ++++++++++++++++++++++------ instrumentation/cmplog-instructions-pass.cc | 4 + instrumentation/llvm-ngram-coverage.h | 2 +- src/afl-fuzz-redqueen.c | 129 +++++++++++------- 7 files changed, 276 insertions(+), 117 deletions(-) (limited to 'include/config.h') diff --git a/include/cmplog.h b/include/cmplog.h index 6392c503..878ed60c 100644 --- a/include/cmplog.h +++ b/include/cmplog.h @@ -38,17 +38,17 @@ #define SHAPE_BYTES(x) (x + 1) -#define CMP_TYPE_INS 0 -#define CMP_TYPE_RTN 1 +#define CMP_TYPE_INS 1 +#define CMP_TYPE_RTN 2 struct cmp_header { unsigned hits : 24; unsigned id : 24; unsigned shape : 5; - unsigned type : 1; + unsigned type : 2; unsigned attribute : 4; - unsigned reserved : 6; + unsigned reserved : 5; } __attribute__((packed)); diff --git a/include/config.h b/include/config.h index c0cd0ef1..c9c4a677 100644 --- a/include/config.h +++ b/include/config.h @@ -23,8 +23,6 @@ #ifndef _HAVE_CONFIG_H #define _HAVE_CONFIG_H -#include "types.h" - /* Version string: */ // c = release, d = volatile github dev, e = experimental branch diff --git a/include/types.h b/include/types.h index d5c31597..7b94fb83 100644 --- a/include/types.h +++ b/include/types.h @@ -25,12 +25,15 @@ #include #include +#include "config.h" -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +#ifdef WORD_SIZE_64 typedef unsigned __int128 uint128_t; typedef uint128_t u128; +#endif /* Extended forkserver option values */ @@ -59,12 +62,14 @@ typedef uint128_t u128; typedef unsigned long long u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +#ifdef WORD_SIZE_64 typedef __int128 int128_t; typedef int128_t s128; +#endif #ifndef MIN #define MIN(a, b) \ @@ -119,19 +124,21 @@ typedef int128_t s128; }) // It is impossible to define 128 bit constants, so ... -#define SWAPN(_x, _l) \ - ({ \ - \ - u128 _res = (_x), _ret; \ - char *d = (char *)&_ret, *s = (char *)&_res; \ - int i; \ - for (i = 0; i < 16; i++) \ - d[15 - i] = s[i]; \ - u32 sr = 128U - ((_l) << 3U); \ - (_ret >>= sr); \ - (u128) _ret; \ - \ - }) +#ifdef WORD_SIZE_64 + #define SWAPN(_x, _l) \ + ({ \ + \ + u128 _res = (_x), _ret; \ + char *d = (char *)&_ret, *s = (char *)&_res; \ + int i; \ + for (i = 0; i < 16; i++) \ + d[15 - i] = s[i]; \ + u32 sr = 128U - ((_l) << 3U); \ + (_ret >>= sr); \ + (u128) _ret; \ + \ + }) +#endif #define SWAPNN(_x, _y, _l) \ ({ \ diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index edb635ae..0ce96673 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1218,15 +1218,22 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; + + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 0; - __afl_cmp_map->headers[k].shape = 0; + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = arg1; @@ -1242,13 +1249,28 @@ void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - __afl_cmp_map->headers[k].shape = 1; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 1; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (!__afl_cmp_map->headers[k].shape) { + + __afl_cmp_map->headers[k].shape = 1; + + } + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = arg1; @@ -1266,13 +1288,28 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; + + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { + + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 3; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].shape < 3) { - __afl_cmp_map->headers[k].shape = 3; + __afl_cmp_map->headers[k].shape = 3; + + } + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = arg1; @@ -1282,7 +1319,7 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) { void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) { - fprintf(stderr, "hook8 arg0=%lx arg1=%lx attr=%u\n", arg1, arg2, attr); + // fprintf(stderr, "hook8 arg0=%lx arg1=%lx attr=%u\n", arg1, arg2, attr); if (unlikely(!__afl_cmp_map || arg1 == arg2)) return; @@ -1290,13 +1327,28 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - __afl_cmp_map->headers[k].shape = 7; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 7; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (__afl_cmp_map->headers[k].shape < 7) { + + __afl_cmp_map->headers[k].shape = 7; + + } + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = arg1; @@ -1304,6 +1356,7 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) { } +#ifdef WORD_SIZE_64 // support for u24 to u120 via llvm _ExitInt(). size is in bytes minus 1 void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr, uint8_t size) { @@ -1318,13 +1371,28 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr, k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - __afl_cmp_map->headers[k].shape = size; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = size; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (__afl_cmp_map->headers[k].shape < size) { + + __afl_cmp_map->headers[k].shape = size; + + } + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = (u64)arg1; @@ -1347,13 +1415,28 @@ void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - __afl_cmp_map->headers[k].attribute = attr; + u32 hits; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - __afl_cmp_map->headers[k].shape = 15; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 15; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (__afl_cmp_map->headers[k].shape < 15) { + + __afl_cmp_map->headers[k].shape = 15; + + } + + } + + __afl_cmp_map->headers[k].attribute = attr; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = (u64)arg1; @@ -1363,6 +1446,8 @@ void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) { } +#endif + #if defined(__APPLE__) #pragma weak __sanitizer_cov_trace_const_cmp1 = __cmplog_ins_hook1 #pragma weak __sanitizer_cov_trace_const_cmp2 = __cmplog_ins_hook2 @@ -1384,8 +1469,10 @@ void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2) __attribute__((alias("__cmplog_ins_hook4"))); void __sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2) __attribute__((alias("__cmplog_ins_hook8"))); + #ifdef WORD_SIZE_64 void __sanitizer_cov_trace_const_cmp16(uint128_t arg1, uint128_t arg2) __attribute__((alias("__cmplog_ins_hook16"))); + #endif void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) __attribute__((alias("__cmplog_ins_hook1"))); @@ -1395,8 +1482,10 @@ void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) __attribute__((alias("__cmplog_ins_hook4"))); void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) __attribute__((alias("__cmplog_ins_hook8"))); + #ifdef WORD_SIZE_64 void __sanitizer_cov_trace_cmp16(uint128_t arg1, uint128_t arg2) __attribute__((alias("__cmplog_ins_hook16"))); + #endif #endif /* defined(__APPLE__) */ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { @@ -1409,12 +1498,28 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + u32 hits; - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { - __afl_cmp_map->headers[k].shape = 7; + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 7; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (__afl_cmp_map->headers[k].shape < 7) { + + __afl_cmp_map->headers[k].shape = 7; + + } + + } + + __afl_cmp_map->headers[k].attribute = 1; hits &= CMP_MAP_H - 1; __afl_cmp_map->log[k][hits].v0 = val; @@ -1448,12 +1553,26 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; - __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; + u32 hits; + + if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) { + + __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; + hits = 0; + __afl_cmp_map->headers[k].hits = 1; + __afl_cmp_map->headers[k].shape = 31; + + } else { + + hits = __afl_cmp_map->headers[k].hits++; + + if (__afl_cmp_map->headers[k].shape < 31) { - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; + __afl_cmp_map->headers[k].shape = 31; - __afl_cmp_map->headers[k].shape = 31; + } + + } hits &= CMP_MAP_RTN_H - 1; __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index a74fb6c8..6ce1832f 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -420,6 +420,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { IRB.CreateCall(cmplogHookIns8, args); break; case 128: +#ifdef WORD_SIZE_64 if (max_size == 128) { IRB.CreateCall(cmplogHookIns16, args); @@ -430,6 +431,9 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } +#endif + break; + default: break; } diff --git a/instrumentation/llvm-ngram-coverage.h b/instrumentation/llvm-ngram-coverage.h index 12b666e9..666839c8 100644 --- a/instrumentation/llvm-ngram-coverage.h +++ b/instrumentation/llvm-ngram-coverage.h @@ -1,7 +1,7 @@ #ifndef AFL_NGRAM_CONFIG_H #define AFL_NGRAM_CONFIG_H -#include "../config.h" +#include "types.h" #if (MAP_SIZE_POW2 <= 16) typedef u16 PREV_LOC_T; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index fe98f031..56022fa6 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -33,7 +33,26 @@ #define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER -///// Colorization +// CMP attribute enum +enum { + + IS_EQUAL = 1, + IS_GREATER = 2, + IS_LESSER = 4, + IS_FP = 8, + IS_FP_MOD = 16, + IS_INT_MOD = 32 + +}; + +// CMPLOG LVL +enum { + + LVL1 = 1, + LVL2 = 2, + LVL3 = 4 + +}; struct range { @@ -545,8 +564,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, unsigned long long unum; long long num; - // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl == 3 - if (lvl & 4) { + // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 + if (lvl & LVL3) { if (afl->queue_cur->is_ascii) { @@ -618,7 +637,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // we only allow this for ascii2integer (above) if (unlikely(pattern == o_pattern)) { return 0; } - if ((lvl & 1) || ((lvl & 2) && (attr >= 8 && attr <= 15)) || attr >= 16) { + if ((lvl & LVL1) || ((lvl & LVL2) && (attr >= IS_FP && attr < IS_FP_MOD)) || + attr >= IS_FP_MOD) { if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { @@ -632,8 +652,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - // due to a bug in llvm dynamic float bitcasts do not work :( // the value 16 means this is a +- 1.0 test case - if (its_len >= 8 && - ((*buf_64 == pattern && *o_buf_64 == o_pattern) || attr >= 16)) { + if (its_len >= 8 && ((*buf_64 == pattern && *o_buf_64 == o_pattern) || + attr >= IS_FP_MOD)) { u64 tmp_64 = *buf_64; *buf_64 = repl; @@ -674,7 +694,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 4 && ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u32 tmp_32 = *buf_32; *buf_32 = (u32)repl; @@ -708,7 +728,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 2 && ((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u16 tmp_16 = *buf_16; *buf_16 = (u16)repl; @@ -738,7 +758,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (*status != 1) { // u8 - // if (its_len >= 1 && (attr <= 1 || attr >= 8)) + // if (its_len >= 1) // fprintf(stderr, // "TestU8: %u>=1 (idx=%u attr=%u) %x==%x %x==%x <= %x<-%x\n", // its_len, idx, attr, *buf_8, (u8)pattern, *o_buf_8, @@ -746,7 +766,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 1 && ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u8 tmp_8 = *buf_8; *buf_8 = (u8)repl; @@ -769,10 +789,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // in original buffer) #ifdef ARITHMETIC_LESSER_GREATER - if (lvl < 4) { return 0; } + if (lvl < LVL3) { return 0; } // lesser/greater FP comparison - if ((attr & 6) && (attr >= 8 && attr < 16)) { + if ((attr & (IS_LESSER + IS_GREATER)) && + (attr >= IS_FP && attr < IS_FP_MOD)) { u64 repl_new; if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { @@ -869,7 +890,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - } else if ((attr & 6) && attr < 8) { + } else if ((attr & (IS_LESSER + IS_GREATER)) && attr < IS_FP) { // lesser/greater integer comparison @@ -903,6 +924,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } +#ifdef WORD_SIZE_64 + static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u128 pattern, u128 repl, u128 o_pattern, u128 changed_val, u8 attr, u32 idx, @@ -917,15 +940,15 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u8 backup[16]; u32 its_len = MIN(len - idx, taint_len); u32 shape = h->shape + 1; -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) size_t off = 0; -#else + #else size_t off = 16 - shape; -#endif + #endif if (its_len >= shape) { -#ifdef _DEBUG + #ifdef _DEBUG // fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ", // its_len, shape, len, idx, attr, off, do_reverse); u32 i; @@ -948,7 +971,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, for (i = 0; i < shape; i++) fprintf(stderr, "%02x", o_r[off + i]); fprintf(stderr, "\n"); -#endif + #endif if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) { @@ -957,15 +980,15 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE + #ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, r, shape); } -#endif + #endif memcpy(ptr, backup, shape); -#ifdef _DEBUG + #ifdef _DEBUG fprintf(stderr, "Status=%u\n", *status); -#endif + #endif } @@ -990,6 +1013,8 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, } +#endif + static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u8 *b = (u8 *)&v; @@ -1040,21 +1065,22 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } +#ifdef WORD_SIZE_64 static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { u8 *b = (u8 *)&v; u32 k; u8 cons_ff = 0, cons_0 = 0; -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) u32 off = 0; for (k = 0; k < size; ++k) { -#else - u32 off = 16 - size; + #else + u32 off = 16 - size; for (k = 16 - size; k < 16; ++k) { -#endif + #endif if (b[k] == 0) { ++cons_0; @@ -1077,6 +1103,8 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { } +#endif + static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { @@ -1091,11 +1119,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u8 found_one = 0; /* loop cmps are useless, detect and ignore them */ +#ifdef WORD_SIZE_64 u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; - u64 s_v0, s_v1; - u8 s_v0_fixed = 1, s_v1_fixed = 1; - u8 s_v0_inc = 1, s_v1_inc = 1; - u8 s_v0_dec = 1, s_v1_dec = 1; +#endif + u64 s_v0, s_v1; + u8 s_v0_fixed = 1, s_v1_fixed = 1; + u8 s_v0_inc = 1, s_v1_inc = 1; + u8 s_v0_dec = 1, s_v1_dec = 1; switch (SHAPE_BYTES(h->shape)) { @@ -1110,7 +1140,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } // FP handling only from lvl 2 onwards - if ((h->attribute & 8) && lvl < 2) return 0; + if ((h->attribute & IS_FP) && lvl < LVL2) return 0; for (i = 0; i < loggeds; ++i) { @@ -1162,6 +1192,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#ifdef WORD_SIZE_64 if (unlikely(is_n)) { s128_v0 = ((u128)o->v0) + (((u128)o->v0_128) << 64); @@ -1171,6 +1202,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#endif + for (idx = 0; idx < len; ++idx) { if (have_taint) { @@ -1195,6 +1228,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; +#ifdef WORD_SIZE_64 if (is_n) { // _ExtInt special case including u128 if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { @@ -1239,11 +1273,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#endif + // even for u128 and _ExtInt we do cmp_extend_encoding() because // if we got here their own special trials failed and it might just be // a cast from e.g. u64 to u128 from the input data. - if ((o->v0 != orig_o->v0 || lvl >= 4) && orig_o->v0 != orig_o->v1) { + if ((o->v0 != orig_o->v0 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) { if (unlikely(cmp_extend_encoding( afl, h, o->v0, o->v1, orig_o->v0, orig_o->v1, h->attribute, idx, @@ -1263,7 +1299,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } status = 0; - if ((o->v1 != orig_o->v1 || lvl >= 4) && orig_o->v0 != orig_o->v1) { + if ((o->v1 != orig_o->v1 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) { if (unlikely(cmp_extend_encoding( afl, h, o->v1, o->v0, orig_o->v1, orig_o->v0, h->attribute, idx, @@ -1521,13 +1557,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - // do it manually, forkserver clear only afl->fsrv.trace_bits - memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); - - if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } - - memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); - struct tainted *taint = NULL; if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) { @@ -1562,8 +1591,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { buf = afl->queue_cur->cmplog_colorinput; taint = afl->queue_cur->taint; - // reget the cmplog information - if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } } @@ -1583,9 +1610,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 cmp_locations = 0; #endif - // do it manually, forkserver clear only afl->fsrv.trace_bits - memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); - + // Generate the cmplog data + // manually clear the full cmp_map + memset(afl->shm.cmp_map, 0, sizeof(struct cmp_map)); + if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) { return 1; } + memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); + // manually clear just the headers + memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header)); if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } u64 orig_hit_cnt, new_hit_cnt; @@ -1602,7 +1633,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 cmplog_lvl = afl->cmplog_lvl; if (!cmplog_done) { - lvl = 1; + lvl = LVL1; } else { @@ -1610,8 +1641,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += 2; } - if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += 4; } + if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += LVL2; } + if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += LVL3; } #ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); @@ -1668,7 +1699,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - } else if (lvl & 1) { + } else if (lvl & LVL1) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, taint))) { -- cgit 1.4.1 From e2d9dc16e3d856b416aa7c84bf10242334c860c9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 18 Jan 2021 21:36:19 +0100 Subject: fix compiler warning avoid signess difference in comparisons --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index c0cd0ef1..973bbcbb 100644 --- a/include/config.h +++ b/include/config.h @@ -194,7 +194,7 @@ /* The same, for the test case minimizer: */ -#define TMIN_MAX_FILE (10 * 1024 * 1024U) +#define TMIN_MAX_FILE (10 * 1024 * 1024) /* Block normalization steps for afl-tmin: */ -- cgit 1.4.1 From 4018e7f8e5e45ccef83d740d7bc2514dc4f602f0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 16:23:40 +0100 Subject: mv cmplog options to config.h --- include/config.h | 28 +++++++++++++++++++++++++++- src/afl-fuzz-redqueen.c | 35 ++++++++++------------------------- src/afl-fuzz.c | 3 +-- 3 files changed, 38 insertions(+), 28 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index b5137553..60872785 100644 --- a/include/config.h +++ b/include/config.h @@ -34,6 +34,32 @@ * * ******************************************************/ +/* CMPLOG/REDQUEEN TUNING + * + * Here you can tuning and solving options for cmplog. + * Note that these are run-time options for afl-fuzz, no target + * recompilation required. + * + */ + +/* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */ +// #define CMPLOG_TRANSFORM + +/* if TRANSFORM is enabled, this additionally enables base64 en/decoding */ +// #define CMPLOG_TRANSFORM_BASE64 + +/* Minimum % of the corpus to perform cmplog on. Default: 20% */ +#define CMPLOG_CORPUS_PERCENT 20U + +/* Number of potential posititions from which we decide the cmplog becomes + useless, default 16384 */ +#define CMPLOG_POSITIONS_MAX 16384U + +/* Maximum allowed fails per CMP value. Default: 32 * 3 */ +#define CMPLOG_FAIL_MAX 96 + +/* Now non-cmplog configuration options */ + /* console output colors: There are three ways to configure its behavior * 1. default: colored outputs fixed on: defined USE_COLOR && defined * ALWAYS_COLORED The env var. AFL_NO_COLOR will have no effect @@ -67,7 +93,7 @@ /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ -//#define _WANT_ORIGINAL_AFL_ALLOC +// #define _WANT_ORIGINAL_AFL_ALLOC /* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */ diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 14a9b65d..8979be98 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -51,7 +51,7 @@ enum { enum { LVL1 = 1, // Integer solving - LVL2 = 2, // FP solving + LVL2 = 2, // unused except for setting the queue entry LVL3 = 4 // expensive tranformations }; @@ -986,11 +986,10 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, #endif - // we only allow this for ascii2integer (above) + // we only allow this for ascii2integer (above) so leave if this is the case if (unlikely(pattern == o_pattern)) { return 0; } - if ((lvl & LVL1) || ((lvl & LVL2) && (attr >= IS_FP && attr < IS_FP_MOD)) || - attr >= IS_FP_MOD) { + if ((lvl & LVL1) || attr >= IS_FP_MOD) { if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { @@ -1498,9 +1497,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - // FP handling only from lvl 2 onwards - if ((h->attribute & IS_FP) && lvl < LVL2) { return 0; } - struct tainted *t; u32 i, j, idx, taint_len, loggeds; u32 have_taint = 1, is_n = 0; @@ -2443,21 +2439,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { afl->stage_max = 0; afl->stage_cur = 0; - u32 lvl; - u32 cmplog_done = afl->queue_cur->colorized; - u32 cmplog_lvl = afl->cmplog_lvl; - if (!cmplog_done) { - - lvl = LVL1; - - } else { - - lvl = 0; - - } - - if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += LVL2; } - if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += LVL3; } + u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); #ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); @@ -2473,8 +2455,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { if (!afl->shm.cmp_map->headers[k].hits) { continue; } - if (afl->pass_stats[k].faileds >= 0x69 || - afl->pass_stats[k].total >= 0x69) { + if (afl->pass_stats[k].faileds >= CMPLOG_FAIL_MAX || + afl->pass_stats[k].total >= CMPLOG_FAIL_MAX) { #ifdef _DEBUG fprintf(stderr, "DISABLED %u\n", k); @@ -2542,9 +2524,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { exit_its: - afl->queue_cur->colorized = afl->cmplog_lvl; if (afl->cmplog_lvl == CMPLOG_LVL_MAX) { + afl->queue_cur->colorized = CMPLOG_LVL_MAX; + ck_free(afl->queue_cur->cmplog_colorinput); t = taint; while (taint) { @@ -2559,6 +2542,8 @@ exit_its: } else { + afl->queue_cur->colorized = LVL2; + if (!afl->queue_cur->taint) { afl->queue_cur->taint = taint; } if (!afl->queue_cur->cmplog_colorinput) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 008ba7d1..62560724 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -123,8 +123,7 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU, just use -c 0.\n" " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (integer+string), 2 (+FP) and 3 " - "(+transform)\n\n" + " Values: 1 (basic), 2 (larger files) and 3 (transform)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " -- cgit 1.4.1 From 17cbb03ba7d4fc0eb3b3b47911c58e25b567e89b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Feb 2021 09:18:24 +0100 Subject: more cmplog options in config.h --- include/config.h | 12 ++++++++--- src/afl-fuzz-redqueen.c | 56 ++++++++++++++++++++++--------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 60872785..25fa1142 100644 --- a/include/config.h +++ b/include/config.h @@ -36,17 +36,23 @@ /* CMPLOG/REDQUEEN TUNING * - * Here you can tuning and solving options for cmplog. + * Here you can modify tuning and solving options for CMPLOG. * Note that these are run-time options for afl-fuzz, no target * recompilation required. * */ +/* Enable arithmetic compare solving for both path */ +#define CMPLOG_SOLVE_ARITHMETIC + /* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */ -// #define CMPLOG_TRANSFORM +#define CMPLOG_SOLVE_TRANSFORM /* if TRANSFORM is enabled, this additionally enables base64 en/decoding */ -// #define CMPLOG_TRANSFORM_BASE64 +// #define CMPLOG_SOLVE_TRANSFORM_BASE64 + +/* If a redqueen pass finds more than one solve, try to combine them? */ +#define CMPLOG_COMBINE /* Minimum % of the corpus to perform cmplog on. Default: 20% */ #define CMPLOG_CORPUS_PERCENT 20U diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 002929c5..7844eedf 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,8 +30,7 @@ //#define _DEBUG //#define CMPLOG_INTROSPECTION -#define COMBINE -#define ARITHMETIC_LESSER_GREATER +#define CMPLOG_COMBINE // CMP attribute enum enum { @@ -496,7 +495,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -577,7 +576,7 @@ static int is_hex(const char *str) { } - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -717,7 +716,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (lvl & LVL3) { @@ -1009,7 +1008,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 tmp_64 = *buf_64; *buf_64 = repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_64, 8); } #endif *buf_64 = tmp_64; @@ -1050,7 +1049,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 tmp_32 = *buf_32; *buf_32 = (u32)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_32, 4); } #endif *buf_32 = tmp_32; @@ -1084,7 +1083,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u16 tmp_16 = *buf_16; *buf_16 = (u16)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_16, 2); } #endif *buf_16 = tmp_16; @@ -1122,7 +1121,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 tmp_8 = *buf_8; *buf_8 = (u8)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { cbuf[idx] = *buf_8; } #endif *buf_8 = tmp_8; @@ -1139,7 +1138,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) -#ifdef ARITHMETIC_LESSER_GREATER +#ifdef CMPLOG_SOLVE_ARITHMETIC if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { @@ -1304,7 +1303,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* ARITHMETIC_LESSER_GREATER */ +#endif /* CMPLOG_SOLVE_ARITHMETIC */ return 0; @@ -1366,7 +1365,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - #ifdef COMBINE + #ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, r, shape); } #endif @@ -1774,10 +1773,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u8 lvl, u8 *status) { -#ifndef COMBINE +#ifndef CMPLOG_COMBINE (void)(cbuf); #endif -#ifndef CMPLOG_TRANSFORM +#ifndef CMPLOG_SOLVE_TRANSFORM (void)(changed_val); #endif @@ -1847,7 +1846,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } #endif @@ -1859,14 +1858,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM if (*status == 1) return 0; if (lvl & LVL3) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; #endif u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; @@ -1964,7 +1963,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -2012,13 +2011,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, "from_0=%u from_slash=%u from_x=%u\n", idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, to_slash, to_x, from_0, from_slash, from_x); - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, fromb64); #endif #endif - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -2170,14 +2169,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef COMBINE + #ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); } #endif if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > (fromhex + from_0 + from_x + from_slash + 1) - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 && i > tob64 + 3 && i > fromb64 + 4 #endif )) || @@ -2469,7 +2468,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); -#ifdef COMBINE +#ifdef CMPLOG_COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); memcpy(cbuf, orig_buf, len); u8 *virgin_backup = afl_realloc((void **)&afl->ex_buf, afl->shm.map_size); @@ -2526,7 +2525,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM || (lvl & LVL3) #endif ) { @@ -2583,7 +2582,7 @@ exit_its: } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (afl->queued_paths + afl->unique_crashes > orig_hit_cnt + 1) { // copy the current virgin bits so we can recover the information @@ -2622,7 +2621,7 @@ exit_its: dump("COMB", cbuf, len); if (status == 1) { - fprintf(stderr, "NEW COMBINED\n"); + fprintf(stderr, "NEW CMPLOG_COMBINED\n"); } else { @@ -2671,8 +2670,3 @@ exit_its: return r; } - -#ifdef COMBINE - #undef COMBINE -#endif - -- cgit 1.4.1 From 756206e4d710b954759eaa97c50940825eff39f7 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Thu, 11 Feb 2021 20:26:02 +0100 Subject: typo --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 25fa1142..181285cd 100644 --- a/include/config.h +++ b/include/config.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Copyright 2019-2021 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ /* Minimum % of the corpus to perform cmplog on. Default: 20% */ #define CMPLOG_CORPUS_PERCENT 20U -/* Number of potential posititions from which we decide the cmplog becomes +/* Number of potential positions from which we decide if cmplog becomes useless, default 16384 */ #define CMPLOG_POSITIONS_MAX 16384U -- cgit 1.4.1 From 938512a6b9451000f40491b2554b5d360840cfe5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Feb 2021 09:48:04 +0100 Subject: minor fixes --- include/config.h | 4 ++-- include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 2 +- qemu_mode/README.md | 22 ++++++++++------------ qemu_mode/qemuafl | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 181285cd..9f7db04d 100644 --- a/include/config.h +++ b/include/config.h @@ -42,7 +42,7 @@ * */ -/* Enable arithmetic compare solving for both path */ +/* Enable arithmetic compare solving for both branches */ #define CMPLOG_SOLVE_ARITHMETIC /* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */ @@ -51,7 +51,7 @@ /* if TRANSFORM is enabled, this additionally enables base64 en/decoding */ // #define CMPLOG_SOLVE_TRANSFORM_BASE64 -/* If a redqueen pass finds more than one solve, try to combine them? */ +/* If a redqueen pass finds more than one solution, try to combine them? */ #define CMPLOG_COMBINE /* Minimum % of the corpus to perform cmplog on. Default: 20% */ diff --git a/include/envs.h b/include/envs.h index 4313e053..143979c6 100644 --- a/include/envs.h +++ b/include/envs.h @@ -131,6 +131,7 @@ static char *afl_environment_variables[] = { "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", "AFL_QEMU_DRIVER_NO_HOOK", + "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR", "AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 5fb715e2..dba4dc65 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1090,7 +1090,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) { if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; u8 *ptr; - ptr = (u8 *)malloc(2097152); + ptr = (u8 *)malloc(MAP_INITIAL_SIZE); if (ptr && (ssize_t)ptr != -1) { diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 9818846d..bc4c1d2c 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -17,7 +17,7 @@ The idea and much of the initial implementation comes from Andrew Griffiths. The actual implementation on current QEMU (shipped as qemuafl) is from Andrea Fioraldi. Special thanks to abiondo that re-enabled TCG chaining. -## 2) How to use +## 2) How to use qemu_mode The feature is implemented with a patched QEMU. The simplest way to build it is to run ./build_qemu_support.sh. The script will download, @@ -176,7 +176,12 @@ Comparative measurements of execution speed or instrumentation coverage will be fairly meaningless if the optimization levels or instrumentation scopes don't match. -## 12) Gotchas, feedback, bugs +## 12) Other features + +With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal +handlers of the target. + +## 13) Gotchas, feedback, bugs If you need to fix up checksums or do other cleanup on mutated test cases, see utils/custom_mutators/ for a viable solution. @@ -197,19 +202,12 @@ with -march=core2, can help. Beyond that, this is an early-stage mechanism, so fields reports are welcome. You can send them to . -## 13) Alternatives: static rewriting +## 14) Alternatives: static rewriting Statically rewriting binaries just once, instead of attempting to translate them at run time, can be a faster alternative. That said, static rewriting is fraught with peril, because it depends on being able to properly and fully model program control flow without actually executing each and every code path. -The best implementation is this one: - - https://github.com/vanhauser-thc/afl-dyninst - -The issue however is Dyninst which is not rewriting the binaries so that -they run stable. A lot of crashes happen, especially in C++ programs that -use throw/catch. Try it first, and if it works for you be happy as it is -2-3x as fast as qemu_mode, however usually not as fast as QEMU persistent mode. - +Checkout the "Fuzzing binary-only targets" section in our main README.md and +the docs/binaryonly_fuzzing.md document for more information and hints. diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index 9a258d5b..213f3b27 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit 9a258d5b7a38c045a6e385fcfcf80a746a60e557 +Subproject commit 213f3b27dd099ef352181c48cd75c0f20a73e3f0 -- cgit 1.4.1 From 974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 Feb 2021 17:53:09 +0100 Subject: cmplog config.h -> -l option --- include/afl-fuzz.h | 1 + include/config.h | 9 ++---- src/afl-common.c | 8 ++--- src/afl-fuzz-redqueen.c | 83 +++++++++++++++++++++++++------------------------ src/afl-fuzz.c | 46 ++++++++++++++++++++------- 5 files changed, 85 insertions(+), 62 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 1d5ec1f0..10d94fed 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -649,6 +649,7 @@ typedef struct afl_state { u32 cmplog_max_filesize; u32 cmplog_lvl; u32 colorize_success; + u8 cmplog_enable_arith, cmplog_enable_transform; struct afl_pass_stat *pass_stats; struct cmp_map * orig_cmp_map; diff --git a/include/config.h b/include/config.h index 9f7db04d..535ce0d3 100644 --- a/include/config.h +++ b/include/config.h @@ -42,13 +42,8 @@ * */ -/* Enable arithmetic compare solving for both branches */ -#define CMPLOG_SOLVE_ARITHMETIC - -/* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */ -#define CMPLOG_SOLVE_TRANSFORM - -/* if TRANSFORM is enabled, this additionally enables base64 en/decoding */ +/* if TRANSFORM is enabled with '-l T', this additionally enables base64 + encoding/decoding */ // #define CMPLOG_SOLVE_TRANSFORM_BASE64 /* If a redqueen pass finds more than one solution, try to combine them? */ diff --git a/src/afl-common.c b/src/afl-common.c index 531753c2..ce63c262 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -561,13 +561,13 @@ void print_suggested_envs(char *mispelled_env) { memcpy(env_name, mispelled_env + 4, env_name_len); char *seen = ck_alloc(sizeof(afl_environment_variables) / sizeof(char *)); - int found = 0; + int found = 0; int j; for (j = 0; afl_environment_variables[j] != NULL; ++j) { char *afl_env = afl_environment_variables[j] + 4; - int distance = string_distance_levenshtein(afl_env, env_name); + int distance = string_distance_levenshtein(afl_env, env_name); if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) { SAYF("Did you mean %s?\n", afl_environment_variables[j]); @@ -575,14 +575,14 @@ void print_suggested_envs(char *mispelled_env) { found = 1; } - + } if (found) goto cleanup; for (j = 0; afl_environment_variables[j] != NULL; ++j) { - char *afl_env = afl_environment_variables[j] + 4; + char * afl_env = afl_environment_variables[j] + 4; size_t afl_env_len = strlen(afl_env); char * reduced = ck_alloc(afl_env_len + 1); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index d77baf25..1ab5f996 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,7 +30,6 @@ //#define _DEBUG //#define CMPLOG_INTROSPECTION -#define CMPLOG_COMBINE // CMP attribute enum enum { @@ -523,7 +522,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -#ifdef CMPLOG_SOLVE_TRANSFORM +//#ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -608,7 +607,7 @@ static int is_hex(const char *str) { } - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -721,10 +720,10 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { } - #endif - #endif +//#endif + static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, u64 changed_val, u8 attr, u32 idx, u32 taint_len, @@ -748,9 +747,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); -#ifdef CMPLOG_SOLVE_TRANSFORM + //#ifdef CMPLOG_SOLVE_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 - if (lvl & LVL3) { + if (afl->cmplog_enable_transform && (lvl & LVL3)) { u8 * endptr; u8 use_num = 0, use_unum = 0; @@ -771,11 +770,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - #ifdef _DEBUG +#ifdef _DEBUG if (idx == 0) fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n", afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern); - #endif +#endif // num is likely not pattern as atoi("AAA") will be zero... if (use_num && ((u64)num == pattern || !num)) { @@ -1060,7 +1059,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif + //#endif // we only allow this for ascii2integer (above) so leave if this is the case if (unlikely(pattern == o_pattern)) { return 0; } @@ -1215,8 +1214,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) -#ifdef CMPLOG_SOLVE_ARITHMETIC - if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } + //#ifdef CMPLOG_SOLVE_ARITHMETIC + if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) { + + return 0; + + } if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { @@ -1321,11 +1324,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, double *f = (double *)&repl; float g = (float)*f; repl_new = 0; - #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) memcpy((char *)&repl_new, (char *)&g, 4); - #else +#else memcpy(((char *)&repl_new) + 4, (char *)&g, 4); - #endif +#endif changed_val = repl_new; h->shape = 3; // modify shape @@ -1380,7 +1383,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* CMPLOG_SOLVE_ARITHMETIC */ + //#endif /* CMPLOG_SOLVE_ARITHMETIC return 0; @@ -1539,7 +1542,7 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { for (k = 0; k < size; ++k) { #else - u32 off = 16 - size; + u32 off = 16 - size; for (k = 16 - size; k < 16; ++k) { #endif @@ -1857,9 +1860,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #ifndef CMPLOG_COMBINE (void)(cbuf); #endif -#ifndef CMPLOG_SOLVE_TRANSFORM - (void)(changed_val); -#endif + //#ifndef CMPLOG_SOLVE_TRANSFORM + // (void)(changed_val); + //#endif u8 save[40]; u32 saved_idx = idx, pre, from = 0, to = 0, i, j; @@ -1939,16 +1942,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef CMPLOG_SOLVE_TRANSFORM + //#ifdef CMPLOG_SOLVE_TRANSFORM if (*status == 1) return 0; - if (lvl & LVL3) { + if (afl->cmplog_enable_transform && (lvl & LVL3)) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; - #endif +#endif u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0; u8 xor_val[32], arith_val[32], tmp[48]; @@ -2044,7 +2047,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -2057,7 +2060,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #endif +#endif if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { @@ -2085,20 +2088,20 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef _DEBUG +#ifdef _DEBUG fprintf(stderr, "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u " "from_0=%u from_slash=%u from_x=%u\n", idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, to_slash, to_x, from_0, from_slash, from_x); - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, fromb64); - #endif #endif +#endif - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -2121,7 +2124,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #endif +#endif // input is converted to hex? convert repl to binary! if (i < 16 && tohex > i) { @@ -2250,16 +2253,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); } - #endif +#endif if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > (fromhex + from_0 + from_x + from_slash + 1) - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 && i > tob64 + 3 && i > fromb64 + 4 - #endif +#endif )) || repl[i] != changed_val[i] || *status == 1) { @@ -2273,7 +2276,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#endif + //#endif return 0; @@ -2606,9 +2609,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) -#ifdef CMPLOG_SOLVE_TRANSFORM - || (lvl & LVL3) -#endif + //#ifdef CMPLOG_SOLVE_TRANSFORM + || ((lvl & LVL3) && afl->cmplog_enable_transform) + //#endif ) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { @@ -2689,7 +2692,7 @@ exit_its: #else u32 *v = (u32 *)afl->virgin_bits; u32 *s = (u32 *)virgin_save; - u32 i; + u32 i; for (i = 0; i < (afl->shm.map_size >> 2); i++) { v[i] &= s[i]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e3e9007d..e2db029d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,7 +103,8 @@ static void usage(u8 *argv0, int more_help) { " quad -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" - " -t msec - timeout for each run (auto-scaled, 50-... ms, default %u ms)\n" + " -t msec - timeout for each run (auto-scaled, 50-... ms, default " + "%u ms)\n" " add a '+' to skip over seeds running longer.\n" " -m megs - memory limit for child process (%u MB, 0 = no limit " "[default])\n" @@ -123,10 +124,10 @@ static void usage(u8 *argv0, int more_help) { " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" " if using QEMU, just use -c 0.\n" - " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (basic), 2 (larger files) and 3 " - "(transform)\n\n" - + " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" + " 1=small files (default), 2=larger files, 3=all " + "files,\n" + " A=arithmetic solving, T=tranformational solving.\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " "random\n" @@ -813,13 +814,36 @@ int main(int argc, char **argv_orig, char **envp) { case 'l': { - if (optarg) { afl->cmplog_lvl = atoi(optarg); } - if (afl->cmplog_lvl < 1 || afl->cmplog_lvl > CMPLOG_LVL_MAX) { + if (!optarg) { FATAL("missing parameter for 'l'"); } + char *c = optarg; + while (*c) { - FATAL( - "Bad complog level value, accepted values are 1 (default), 2 and " - "%u.", - CMPLOG_LVL_MAX); + switch (*c) { + + case '0': + case '1': + afl->cmplog_lvl = 1; + break; + case '2': + afl->cmplog_lvl = 2; + break; + case '3': + afl->cmplog_lvl = 3; + break; + case 'a': + case 'A': + afl->cmplog_enable_arith = 1; + break; + case 't': + case 'T': + afl->cmplog_enable_transform = 1; + break; + default: + FATAL("Unknown option value '%c' in -l %s", *c, optarg); + + } + + ++c; } -- cgit 1.4.1 From fb2a6b6941ffb6cf575d2a772c6e0d47b49835ee Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 16:56:35 +0100 Subject: minimum sync time --- docs/Changelog.md | 1 + include/afl-fuzz.h | 1 + include/config.h | 5 +++++ src/afl-fuzz-run.c | 2 ++ src/afl-fuzz.c | 15 ++++++++++++--- 5 files changed, 21 insertions(+), 3 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index a006fccb..d8587334 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -35,6 +35,7 @@ sending a mail to . - fixed a few crashes - switched to an even faster RNG - added hghwng's patch for faster trace map analysis + - added minimum SYNC_TIME to include/config.h (30 minutes default) - afl-cc - allow instrumenting LLVMFuzzerTestOneInput - fixed endless loop for allow/blocklist lines starting with a diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 10d94fed..e191543a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -570,6 +570,7 @@ typedef struct afl_state { blocks_eff_total, /* Blocks subject to effector maps */ blocks_eff_select, /* Blocks selected as fuzzable */ start_time, /* Unix start time (ms) */ + last_sync_time, /* Time of last sync */ last_path_time, /* Time for most recent path (ms) */ last_crash_time, /* Time for most recent crash (ms) */ last_hang_time; /* Time for most recent hang (ms) */ diff --git a/include/config.h b/include/config.h index 535ce0d3..083cad23 100644 --- a/include/config.h +++ b/include/config.h @@ -280,6 +280,11 @@ #define SYNC_INTERVAL 8 +/* Sync time (minimum time between syncing in ms, time is halfed for -M main + nodes): */ + +#define SYNC_TIME 18000000LLU /* 18000000 = 30 minutes */ + /* Output directory reuse grace period (minutes): */ #define OUTPUT_GRACE 25 diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 97cb7415..0b84a542 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -707,6 +707,8 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0); + afl->last_sync_time = get_cur_time(); + } /* Trim all new test cases to save cycles when doing deterministic checks. The diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9137dc23..f83aac9e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1986,15 +1986,24 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->is_main_node)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { + if (unlikely(get_cur_time() > + (SYNC_TIME >> 1) + afl->last_sync_time)) { - sync_fuzzers(afl); + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { + + sync_fuzzers(afl); + + } } } else { - if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + if (unlikely(get_cur_time() > SYNC_TIME + afl->last_sync_time)) { + + if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + + } } -- cgit 1.4.1 From 4ab90e739ff4410f24c63d71dfffe333063c3b3a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 22:24:59 +0100 Subject: code format --- include/afl-fuzz.h | 2 +- include/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e191543a..d9dbad5a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -570,7 +570,7 @@ typedef struct afl_state { blocks_eff_total, /* Blocks subject to effector maps */ blocks_eff_select, /* Blocks selected as fuzzable */ start_time, /* Unix start time (ms) */ - last_sync_time, /* Time of last sync */ + last_sync_time, /* Time of last sync */ last_path_time, /* Time for most recent path (ms) */ last_crash_time, /* Time for most recent crash (ms) */ last_hang_time; /* Time for most recent hang (ms) */ diff --git a/include/config.h b/include/config.h index 083cad23..241b2e69 100644 --- a/include/config.h +++ b/include/config.h @@ -283,7 +283,7 @@ /* Sync time (minimum time between syncing in ms, time is halfed for -M main nodes): */ -#define SYNC_TIME 18000000LLU /* 18000000 = 30 minutes */ +#define SYNC_TIME 18000000LLU /* 18000000 = 30 minutes */ /* Output directory reuse grace period (minutes): */ -- cgit 1.4.1 From 564f4915665c8a68a97d71b7db812606ddec8c5b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 24 Feb 2021 09:29:19 +0100 Subject: redqueen settings opt --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 241b2e69..d2e9f889 100644 --- a/include/config.h +++ b/include/config.h @@ -50,14 +50,14 @@ #define CMPLOG_COMBINE /* Minimum % of the corpus to perform cmplog on. Default: 20% */ -#define CMPLOG_CORPUS_PERCENT 20U +#define CMPLOG_CORPUS_PERCENT 10U /* Number of potential positions from which we decide if cmplog becomes useless, default 16384 */ #define CMPLOG_POSITIONS_MAX 16384U /* Maximum allowed fails per CMP value. Default: 32 * 3 */ -#define CMPLOG_FAIL_MAX 96 +#define CMPLOG_FAIL_MAX 128 /* Now non-cmplog configuration options */ -- cgit 1.4.1 From e6ef2ee338d1da1d5fa8e23822247ee7837e1f54 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 24 Feb 2021 12:14:10 +0100 Subject: typo --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index d2e9f889..1c3370ad 100644 --- a/include/config.h +++ b/include/config.h @@ -281,9 +281,9 @@ #define SYNC_INTERVAL 8 /* Sync time (minimum time between syncing in ms, time is halfed for -M main - nodes): */ + nodes) - default is 30 minutes: */ -#define SYNC_TIME 18000000LLU /* 18000000 = 30 minutes */ +#define SYNC_TIME (30 * 60 * 1000) /* Output directory reuse grace period (minutes): */ -- cgit 1.4.1 From 5d181950eb48afa6f86bd4455fb9f55b09f5eb19 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 24 Feb 2021 21:17:58 +0100 Subject: fixes --- README.md | 6 +++--- include/config.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 59b1c143..0539752c 100644 --- a/README.md +++ b/README.md @@ -1170,12 +1170,12 @@ Thank you! ## Cite -If you use AFLplusplus in scientific work, consider citing [our paper](https://www.usenix.org/conference/woot20/presentation/fioraldi) presented at WOOT'20: - If you use AFLpluplus to compare to your work, please use either `afl-clang-lto` or `afl-clang-fast` with `AFL_LLVM_CMPLOG=1` for building targets and `afl-fuzz` with the command line option `-l 2` for fuzzing. -The most effective setup is the `aflplusplus` default fuzzer on Google's fuzzbench. +The most effective setup is the `aflplusplus` default configuration on Google's [fuzzbench](https://github.com/google/fuzzbench/tree/master/fuzzers/aflplusplus). + +If you use AFLplusplus in scientific work, consider citing [our paper](https://www.usenix.org/conference/woot20/presentation/fioraldi) presented at WOOT'20: + Andrea Fioraldi, Dominik Maier, Heiko Eißfeldt, and Marc Heuse. “AFL++: Combining incremental steps of fuzzing research”. In 14th USENIX Workshop on Offensive Technologies (WOOT 20). USENIX Association, Aug. 2020. diff --git a/include/config.h b/include/config.h index 1c3370ad..6120dcd6 100644 --- a/include/config.h +++ b/include/config.h @@ -49,15 +49,15 @@ /* If a redqueen pass finds more than one solution, try to combine them? */ #define CMPLOG_COMBINE -/* Minimum % of the corpus to perform cmplog on. Default: 20% */ +/* Minimum % of the corpus to perform cmplog on. Default: 10% */ #define CMPLOG_CORPUS_PERCENT 10U /* Number of potential positions from which we decide if cmplog becomes useless, default 16384 */ #define CMPLOG_POSITIONS_MAX 16384U -/* Maximum allowed fails per CMP value. Default: 32 * 3 */ -#define CMPLOG_FAIL_MAX 128 +/* Maximum allowed fails per CMP value. Default: 96 */ +#define CMPLOG_FAIL_MAX 96 /* Now non-cmplog configuration options */ -- cgit 1.4.1 From 5c239451cfd1562ce72a78eefc6886fd76f2c132 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Feb 2021 09:15:45 +0100 Subject: cmplog finetuning --- custom_mutators/honggfuzz/honggfuzz.h | 2 +- include/config.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/config.h') diff --git a/custom_mutators/honggfuzz/honggfuzz.h b/custom_mutators/honggfuzz/honggfuzz.h index eb6a3f11..c80cdd87 100644 --- a/custom_mutators/honggfuzz/honggfuzz.h +++ b/custom_mutators/honggfuzz/honggfuzz.h @@ -39,7 +39,7 @@ #include "libhfcommon/util.h" #define PROG_NAME "honggfuzz" -#define PROG_VERSION "2.3" +#define PROG_VERSION "2.4" /* Name of the template which will be replaced with the proper name of the file */ #define _HF_FILE_PLACEHOLDER "___FILE___" diff --git a/include/config.h b/include/config.h index 6120dcd6..439f4d2f 100644 --- a/include/config.h +++ b/include/config.h @@ -53,11 +53,11 @@ #define CMPLOG_CORPUS_PERCENT 10U /* Number of potential positions from which we decide if cmplog becomes - useless, default 16384 */ -#define CMPLOG_POSITIONS_MAX 16384U + useless, default 8096 */ +#define CMPLOG_POSITIONS_MAX 8096U -/* Maximum allowed fails per CMP value. Default: 96 */ -#define CMPLOG_FAIL_MAX 96 +/* Maximum allowed fails per CMP value. Default: 128 */ +#define CMPLOG_FAIL_MAX 128 /* Now non-cmplog configuration options */ -- cgit 1.4.1 From 3a461944ecac47627d3e9d2afcf1c28925e2355a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 26 Feb 2021 22:36:19 +0100 Subject: fine tune cmplog --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index 439f4d2f..b0b1f7b9 100644 --- a/include/config.h +++ b/include/config.h @@ -50,7 +50,7 @@ #define CMPLOG_COMBINE /* Minimum % of the corpus to perform cmplog on. Default: 10% */ -#define CMPLOG_CORPUS_PERCENT 10U +#define CMPLOG_CORPUS_PERCENT 5U /* Number of potential positions from which we decide if cmplog becomes useless, default 8096 */ -- cgit 1.4.1 From 0c38850f955a608529bdd02cc39dc68713ef8528 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 Mar 2021 09:43:35 +0100 Subject: 3.10c release --- README.md | 10 +++++----- docs/Changelog.md | 14 +++++++------- include/config.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 119426f6..800c2121 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ Logo - Release Version: [3.00c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [3.10c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 3.01a + Github Version: 3.11a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) @@ -25,14 +25,14 @@ For comparisons use the fuzzbench `aflplusplus` setup, or use `afl-clang-fast` with `AFL_LLVM_CMPLOG=1`. -## Major changes in afl++ 3.0 + 3.1 +## Major changes in afl++ 3.00 + 3.10 -With afl++ 3.1 we introduced the following changes from previous behaviours: +With afl++ 3.10 we introduced the following changes from previous behaviours: * The '+' feature of the '-t' option now means to auto-calculate the timeout with the value given being the maximum timeout. The original meaning of "skipping timeouts instead of abort" is now inherent to the -t option. -With afl++ 3.0 we introduced changes that break some previous afl and afl++ +With afl++ 3.00 we introduced changes that break some previous afl and afl++ behaviours and defaults: * There are no llvm_mode and gcc_plugin subdirectories anymore and there is diff --git a/docs/Changelog.md b/docs/Changelog.md index 192d6ee2..f3e15b6a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++3.01a (dev) +### Version ++3.10c (release) - Mac OS ARM64 support - Android support fixed and updated by Joey Jiaojg - thanks! - New selective instrumentation option with __AFL_COVERAGE_* commands @@ -49,10 +49,10 @@ sending a mail to . comment (thanks to Zherya for reporting) - cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit - cmplog/redqueen can now process basic libc++ and libstdc++ - std::string comparisons (though no position or length type variants) - - added support for __afl_coverage_interesting() for LTO and - and our own PCGUARD (llvm 10.0.1+), read more about this function - and selective coverage in instrumentation/README.instrument_list.md + std::string comparisons (no position or length type variants) + - added support for __afl_coverage_interesting() for LTO and our + own PCGUARD (llvm 10.0.1+), read more about this function and + selective coverage in instrumentation/README.instrument_list.md - added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard support (less performant than our own), GCC for old afl-gcc and CLANG for old afl-clang @@ -68,12 +68,12 @@ sending a mail to . - unicornafl - Substantial speed gains in python bindings for certain use cases - Improved rust bindings - - Added a new example harness to compare python, c, and rust bindings + - Added a new example harness to compare python, c and rust bindings - afl-cmin and afl-showmap now support the -f option - afl_plot now also generates a graph on the discovered edges - changed default: no memory limit for afl-cmin and afl-cmin.bash - warn on any _AFL and __AFL env vars. - - set AFL_IGNORE_UNKNOWN_ENVS to not warn on unknown AFL_... env vars. + - set AFL_IGNORE_UNKNOWN_ENVS to not warn on unknown AFL_... env vars - added dummy Makefile to instrumentation/ - Updated utils/afl_frida to be 5% faster, 7% on x86_x64 - Added `AFL_KILL_SIGNAL` env variable (thanks @v-p-b) diff --git a/include/config.h b/include/config.h index b0b1f7b9..c583f23b 100644 --- a/include/config.h +++ b/include/config.h @@ -25,8 +25,8 @@ /* Version string: */ -// c = release, d = volatile github dev, e = experimental branch -#define VERSION "++3.01a" +// c = release, a = volatile github dev, e = experimental branch +#define VERSION "++3.10c" /****************************************************** * * -- cgit 1.4.1 From 82c05630ba201bfc631e4e2335c6d8c2e76d91c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 Mar 2021 10:12:42 +0100 Subject: 3.11a init --- docs/Changelog.md | 3 +++ include/config.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index f3e15b6a..4e3eef16 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,6 +8,9 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++3.11a (dev) + - ... + ### Version ++3.10c (release) - Mac OS ARM64 support diff --git a/include/config.h b/include/config.h index c583f23b..a3aa9a4a 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++3.10c" +#define VERSION "++3.11a" /****************************************************** * * -- cgit 1.4.1 From 4bd0d4cbaf3a3de63f737ff86df5de0b809f6631 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 15:52:27 +0100 Subject: cmplog finetuning --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index a3aa9a4a..6ada0fbe 100644 --- a/include/config.h +++ b/include/config.h @@ -54,10 +54,10 @@ /* Number of potential positions from which we decide if cmplog becomes useless, default 8096 */ -#define CMPLOG_POSITIONS_MAX 8096U +#define CMPLOG_POSITIONS_MAX (12 * 1024) /* Maximum allowed fails per CMP value. Default: 128 */ -#define CMPLOG_FAIL_MAX 128 +#define CMPLOG_FAIL_MAX 96 /* Now non-cmplog configuration options */ -- cgit 1.4.1 From ac795ae1e154df87d422eb9a307ee1f40fcb701f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 Mar 2021 23:08:28 +0100 Subject: v3.11c release --- README.md | 4 ++-- docs/Changelog.md | 4 +++- include/config.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include/config.h') diff --git a/README.md b/README.md index 0deaca22..69e5bb74 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ Logo - Release Version: [3.10c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [3.11c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 3.11a + Github Version: 3.12a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 8f3e588c..1c735a70 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,9 +8,11 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++3.11a (dev) +### Version ++3.11c (release) - afl-fuzz: + - better auto detection of map size - fix sanitizer settings (bug since 3.10c) + - fix an off-by-one overwrite in cmplog - add non-unicode variants from unicode-looking dictionary entries - Rust custom mutator API improvements - Imported crash stats painted yellow on resume (only new ones are red) diff --git a/include/config.h b/include/config.h index 6ada0fbe..cc8024ea 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++3.11a" +#define VERSION "++3.11c" /****************************************************** * * -- cgit 1.4.1 From 1dcc3549b6ecc3925825c00ac63274b83e76ec8a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 Mar 2021 23:21:03 +0100 Subject: v3.12a init --- docs/Changelog.md | 5 ++++- include/config.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/config.h') diff --git a/docs/Changelog.md b/docs/Changelog.md index 1c735a70..8222f942 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,6 +8,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++3.12a (dev) + - ... + + ### Version ++3.11c (release) - afl-fuzz: - better auto detection of map size @@ -38,7 +42,6 @@ sending a mail to . - we no longer perform a "git drop" - afl-cmin: support filenames with spaces - ### Version ++3.10c (release) - Mac OS ARM64 support - Android support fixed and updated by Joey Jiaojg - thanks! diff --git a/include/config.h b/include/config.h index cc8024ea..b049fee0 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++3.11c" +#define VERSION "++3.12a" /****************************************************** * * -- cgit 1.4.1 From 5e2a5f1110e29c36f1c41fb4677ab698c5d571c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 10:26:02 +0100 Subject: shmem map size in config.h --- include/config.h | 9 ++++++ instrumentation/afl-compiler-rt.o.c | 6 ++-- src/afl-cc.c | 62 ++++++++++++++++++------------------- src/afl-common.c | 2 +- src/afl-fuzz.c | 24 +++++++++----- 5 files changed, 60 insertions(+), 43 deletions(-) (limited to 'include/config.h') diff --git a/include/config.h b/include/config.h index b049fee0..29225f6b 100644 --- a/include/config.h +++ b/include/config.h @@ -34,6 +34,15 @@ * * ******************************************************/ +/* Default shared memory map size. Most targets just need a coverage map + between 20-250kb. Plus there is an auto-detection feature in afl-fuzz. + However if a target has problematic constructors and init arrays then + this can fail. Hence afl-fuzz deploys a larger default map. The largest + map seen so far is the xlsx fuzzer for libreoffice which is 5MB. + At runtime this value can be overriden via AFL_MAP_SIZE. + Default: 8MB (defined in bytes) */ +#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024) + /* CMPLOG/REDQUEEN TUNING * * Here you can modify tuning and solving options for CMPLOG. diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 70148b78..c635ae63 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1774,14 +1774,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { */ if (unlikely(!__afl_cmp_map)) return; - //fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2); + // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2); int l1, l2; if ((l1 = area_is_valid(ptr1, 32)) <= 0 || (l2 = area_is_valid(ptr2, 32)) <= 0) return; int len = MIN(l1, l2); - //fprintf(stderr, "RTN2 %u\n", len); + // fprintf(stderr, "RTN2 %u\n", len); uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (k >> 4) ^ (k << 8); k &= CMP_MAP_W - 1; @@ -1812,7 +1812,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { ptr1, len); __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2, len); - //fprintf(stderr, "RTN3\n"); + // fprintf(stderr, "RTN3\n"); } diff --git a/src/afl-cc.c b/src/afl-cc.c index 206066fd..ebbd390c 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -959,63 +959,63 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode != GCC && compiler_mode != CLANG) { - switch (bit_mode) { + switch (bit_mode) { - case 0: - if (!shared_linking) + case 0: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt.o", obj_path); - if (lto_mode) - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); - break; + if (lto_mode) + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); + break; - case 32: - if (!shared_linking) + case 32: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m32 is not supported by your compiler"); - if (lto_mode) { - - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); - } + } - break; + break; - case 64: - if (!shared_linking) + case 64: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m64 is not supported by your compiler"); - if (lto_mode) { - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); - - } + } - break; + break; - } + } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif - } + } #if defined(USEMMAP) && !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; + cc_params[cc_par_cnt++] = "-lrt"; #endif #endif diff --git a/src/afl-common.c b/src/afl-common.c index 27b63434..7e56ce3f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1072,7 +1072,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { /* Reads the map size from ENV */ u32 get_map_size(void) { - uint32_t map_size = 8000000; // a very large default map + uint32_t map_size = DEFAULT_SHMEM_SIZE; char * ptr; if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2fde561c..8318a92e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1527,11 +1527,13 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - if (map_size <= 8000000 && !afl->non_instrumented_mode && + if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); + afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value + char vbuf[16]; + snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE); + setenv("AFL_MAP_SIZE", vbuf, 1); } @@ -1582,11 +1584,13 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - if (map_size <= 8000000 && !afl->non_instrumented_mode && + if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->cmplog_fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); + afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value + char vbuf[16]; + snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE); + setenv("AFL_MAP_SIZE", vbuf, 1); } @@ -1634,8 +1638,12 @@ int main(int argc, char **argv_orig, char **envp) { } if (afl->debug) { - printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); - fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); + + printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, + afl->cmplog_fsrv.map_size); + fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, + afl->cmplog_fsrv.map_size); + } load_auto(afl); -- cgit 1.4.1