From 06264df16891070a09a31cd981a9dcaaf01de7c7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 17:28:21 +0200 Subject: rename whitelist -> instrumentlist --- gcc_plugin/GNUmakefile | 2 +- gcc_plugin/Makefile | 2 +- gcc_plugin/README.instrument_file.md | 73 +++++++++++++++++++++++++++ gcc_plugin/README.whitelist.md | 73 --------------------------- gcc_plugin/afl-gcc-fast.c | 95 +++++++++++++++++++----------------- gcc_plugin/afl-gcc-pass.so.cc | 37 ++++++++------ 6 files changed, 146 insertions(+), 136 deletions(-) create mode 100644 gcc_plugin/README.instrument_file.md delete mode 100644 gcc_plugin/README.whitelist.md (limited to 'gcc_plugin') diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile index 60f04bb7..bf5c53e0 100644 --- a/gcc_plugin/GNUmakefile +++ b/gcc_plugin/GNUmakefile @@ -156,7 +156,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 7eff326a..f720112f 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -152,7 +152,7 @@ install: all install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 diff --git a/gcc_plugin/README.instrument_file.md b/gcc_plugin/README.instrument_file.md new file mode 100644 index 00000000..d0eaf6ff --- /dev/null +++ b/gcc_plugin/README.instrument_file.md @@ -0,0 +1,73 @@ +======================================== +Using afl++ with partial instrumentation +======================================== + + This file describes how you can selectively instrument only the source files + that are interesting to you using the gcc instrumentation provided by + afl++. + + Plugin by hexcoder-. + + +## 1) Description and purpose + +When building and testing complex programs where only a part of the program is +the fuzzing target, it often helps to only instrument the necessary parts of +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, I have added a "partial instrumentation" support to the gcc +plugin of AFLFuzz that allows you to specify on a source file level which files +should be compiled with or without instrumentation. + + +## 2) Building the gcc plugin + +The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ +subdirectory. There is nothing specifically to do :) + + +## 3) How to use the partial instrumentation mode + +In order to build with partial instrumentation, you need to build with +afl-gcc-fast and afl-g++-fast respectively. The only required change is +that you need to set the environment variable AFL_GCC_INSTRUMENT_FILE when calling +the compiler. + +The environment variable must point to a file containing all the filenames +that should be instrumented. For matching, the filename that is being compiled +must end in the filename entry contained in this instrument list (to avoid breaking +the matching when absolute paths are used during compilation). + +For example if your source tree looks like this: + +``` +project/ +project/feature_a/a1.cpp +project/feature_a/a2.cpp +project/feature_b/b1.cpp +project/feature_b/b2.cpp +``` + +and you only want to test feature_a, then create a instrument list file containing: + +``` +feature_a/a1.cpp +feature_a/a2.cpp +``` + +However if the instrument list file contains only this, it works as well: + +``` +a1.cpp +a2.cpp +``` + +but it might lead to files being unwantedly instrumented if the same filename +exists somewhere else in the project directories. + +The created instrument list file is then set to AFL_GCC_INSTRUMENT_FILE when you compile +your program. For each file that didn't match the instrument list, the compiler will +issue a warning at the end stating that no blocks were instrumented. If you +didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/README.whitelist.md b/gcc_plugin/README.whitelist.md deleted file mode 100644 index 8ad2068d..00000000 --- a/gcc_plugin/README.whitelist.md +++ /dev/null @@ -1,73 +0,0 @@ -======================================== -Using afl++ with partial instrumentation -======================================== - - This file describes how you can selectively instrument only the source files - that are interesting to you using the gcc instrumentation provided by - afl++. - - Plugin by hexcoder-. - - -## 1) Description and purpose - -When building and testing complex programs where only a part of the program is -the fuzzing target, it often helps to only instrument the necessary parts of -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, I have added a "partial instrumentation" support to the gcc -plugin of AFLFuzz that allows you to specify on a source file level which files -should be compiled with or without instrumentation. - - -## 2) Building the gcc plugin - -The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ -subdirectory. There is nothing specifically to do :) - - -## 3) How to use the partial instrumentation mode - -In order to build with partial instrumentation, you need to build with -afl-gcc-fast and afl-g++-fast respectively. The only required change is -that you need to set the environment variable AFL_GCC_WHITELIST when calling -the compiler. - -The environment variable must point to a file containing all the filenames -that should be instrumented. For matching, the filename that is being compiled -must end in the filename entry contained in this whitelist (to avoid breaking -the matching when absolute paths are used during compilation). - -For example if your source tree looks like this: - -``` -project/ -project/feature_a/a1.cpp -project/feature_a/a2.cpp -project/feature_b/b1.cpp -project/feature_b/b2.cpp -``` - -and you only want to test feature_a, then create a whitelist file containing: - -``` -feature_a/a1.cpp -feature_a/a2.cpp -``` - -However if the whitelist file contains only this, it works as well: - -``` -a1.cpp -a2.cpp -``` - -but it might lead to files being unwantedly instrumented if the same filename -exists somewhere else in the project directories. - -The created whitelist file is then set to AFL_GCC_WHITELIST when you compile -your program. For each file that didn't match the whitelist, the compiler will -issue a warning at the end stating that no blocks were instrumented. If you -didn't intend to instrument that file, then you can safely ignore that warning. diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index bd780b40..af0beca7 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -306,47 +306,47 @@ int main(int argc, char **argv, char **envp) { if (argc < 2 || strcmp(argv[1], "-h") == 0) { - printf( - cCYA - "afl-gcc-fast" VERSION cRST - " initially by , maintainer: hexcoder-\n" - "\n" - "afl-gcc-fast [options]\n" - "\n" - "This is a helper application for afl-fuzz. It serves as a drop-in " - "replacement\n" - "for gcc, letting you recompile third-party code with the required " - "runtime\n" - "instrumentation. A common use pattern would be one of the " - "following:\n\n" - - " CC=%s/afl-gcc-fast ./configure\n" - " CXX=%s/afl-g++-fast ./configure\n\n" - - "In contrast to the traditional afl-gcc tool, this version is " - "implemented as\n" - "a GCC plugin and tends to offer improved performance with slow " - "programs\n" - "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" - - "Environment variables used:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_DEBUG: enable developer debugging output\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - "AFL_GCC_WHITELIST: enable whitelisting (selective instrumentation)\n" - - "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " - "\"%s\".\n\n", - BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); + printf(cCYA + "afl-gcc-fast" VERSION cRST + " initially by , maintainer: hexcoder-\n" + "\n" + "afl-gcc-fast [options]\n" + "\n" + "This is a helper application for afl-fuzz. It serves as a drop-in " + "replacement\n" + "for gcc, letting you recompile third-party code with the required " + "runtime\n" + "instrumentation. A common use pattern would be one of the " + "following:\n\n" + + " CC=%s/afl-gcc-fast ./configure\n" + " CXX=%s/afl-g++-fast ./configure\n\n" + + "In contrast to the traditional afl-gcc tool, this version is " + "implemented as\n" + "a GCC plugin and tends to offer improved performance with slow " + "programs\n" + "(similarly to the LLVM plugin used by afl-clang-fast).\n\n" + + "Environment variables used:\n" + "AFL_CC: path to the C compiler to use\n" + "AFL_CXX: path to the C++ compiler to use\n" + "AFL_PATH: path to instrumenting pass and runtime (afl-gcc-rt.*o)\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_DEBUG: enable developer debugging output\n" + "AFL_HARDEN: adds code hardening to catch memory bugs\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + "AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " + "filename\n" + + "\nafl-gcc-fast was built for gcc %s with the gcc binary path of " + "\"%s\".\n\n", + BIN_PATH, BIN_PATH, GCC_VERSION, GCC_BINDIR); exit(1); @@ -357,12 +357,15 @@ int main(int argc, char **argv, char **envp) { SAYF(cCYA "afl-gcc-fast" VERSION cRST " initially by , maintainer: hexcoder-\n"); - if (getenv("AFL_GCC_WHITELIST") == NULL) { + if (getenv("AFL_GCC_INSTRUMENT_FILE") == NULL && + getenv("AFL_GCC_WHITELIST") == NULL) { - SAYF(cYEL "Warning:" cRST - " using afl-gcc-fast without using AFL_GCC_WHITELIST currently " - "produces worse results than afl-gcc. Even better, use " - "llvm_mode for now.\n"); + SAYF( + cYEL + "Warning:" cRST + " using afl-gcc-fast without using AFL_GCC_INSTRUMENT_FILE currently " + "produces worse results than afl-gcc. Even better, use " + "llvm_mode for now.\n"); } diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc index 08f7d748..c5614aca 100644 --- a/gcc_plugin/afl-gcc-pass.so.cc +++ b/gcc_plugin/afl-gcc-pass.so.cc @@ -2,7 +2,7 @@ // There are some TODOs in this file: // - fix instrumentation via external call // - fix inline instrumentation -// - implement whitelist feature +// - implement instrument list feature // - dont instrument blocks that are uninteresting // - implement neverZero // @@ -95,7 +95,7 @@ static int be_quiet = 0; static unsigned int inst_ratio = 100; static bool inst_ext = true; -static std::list myWhitelist; +static std::list myInstrumentList; static unsigned int ext_call_instrument(function *fun) { @@ -414,7 +414,7 @@ class afl_pass : public gimple_opt_pass { unsigned int execute(function *fun) override { - if (!myWhitelist.empty()) { + if (!myInstrumentList.empty()) { bool instrumentBlock = false; std::string instFilename; @@ -436,8 +436,8 @@ class afl_pass : public gimple_opt_pass { /* Continue only if we know where we actually are */ if (!instFilename.empty()) { - for (std::list::iterator it = myWhitelist.begin(); - it != myWhitelist.end(); ++it) { + for (std::list::iterator it = myInstrumentList.begin(); + it != myInstrumentList.end(); ++it) { /* We don't check for filename equality here because * filenames might actually be full paths. Instead we @@ -462,13 +462,14 @@ class afl_pass : public gimple_opt_pass { } /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. */ + * not in the instrument list, so we skip instrumentation. */ if (!instrumentBlock) { if (!be_quiet) { if (!instFilename.empty()) - SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n", + SAYF(cYEL "[!] " cBRI + "Not in instrument list, skipping %s line %u...\n", instFilename.c_str(), instLine); else SAYF(cYEL "[!] " cBRI "No filename information found, skipping it"); @@ -562,26 +563,32 @@ int plugin_init(struct plugin_name_args * plugin_info, } - char *instWhiteListFilename = getenv("AFL_GCC_WHITELIST"); - if (instWhiteListFilename) { + char *instInstrumentListFilename = getenv("AFL_GCC_INSTRUMENT_FILE"); + if (!instInstrumentListFilename) + instInstrumentListFilename = getenv("AFL_GCC_WHITELIST"); + if (instInstrumentListFilename) { std::string line; std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) PFATAL("Unable to open AFL_GCC_WHITELIST"); + fileStream.open(instInstrumentListFilename); + if (!fileStream) PFATAL("Unable to open AFL_GCC_INSTRUMENT_FILE"); getline(fileStream, line); while (fileStream) { - myWhitelist.push_back(line); + myInstrumentList.push_back(line); getline(fileStream, line); } - } else if (!be_quiet && getenv("AFL_LLVM_WHITELIST")) + } else if (!be_quiet && (getenv("AFL_LLVM_WHITELIST") || + + getenv("AFL_LLVM_INSTRUMENT_FILE"))) { SAYF(cYEL "[-] " cRST - "AFL_LLVM_WHITELIST environment variable detected - did you mean " - "AFL_GCC_WHITELIST?\n"); + "AFL_LLVM_INSTRUMENT_FILE environment variable detected - did " + "you mean AFL_GCC_INSTRUMENT_FILE?\n"); + + } /* Go go gadget */ register_callback(plugin_info->base_name, PLUGIN_INFO, NULL, -- cgit 1.4.1