add CFI sanitizer

This commit is contained in:
van Hauser 2020-03-27 12:09:06 +01:00 committed by Dominik Maier
parent 762421b355
commit 34c090a31d
9 changed files with 29 additions and 6 deletions

View File

@ -259,7 +259,7 @@ superior to blind fuzzing or coverage-only tools.
## Instrumenting programs for use with AFL
PLEASE NOTE: llvm_mode compilation with afl-clang-fast/afl-clang-fast++
instead of afl-gcc/afl-g++ is much faster and has a few cool features.
instead of afl-gcc/afl-g++ is much faster and has many cool features.
See llvm_mode/ - however few code does not compile with llvm.
We support llvm versions 3.8.0 to 11.

View File

@ -31,6 +31,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
the last 5 queue entries
- rare: puts focus on queue entries that hits rare branches, also ignores
runtime
- llvm_mode: added Control Flow Integrity sanatizer (AFL_USE_CFISAN)
- LTO collision free instrumented added in llvm_mode with afl-clang-lto -
note that this mode is amazing, but quite some targets won't compile
- Added llvm_mode NGRAM prev_loc coverage by Adrean Herrera

View File

@ -31,7 +31,9 @@ tools make fairly broad use of environmental variables:
(You can also enable MSAN via AFL_USE_MSAN; ASAN and MSAN come with the
same gotchas; the modes are mutually exclusive. UBSAN can be enabled
similarly by setting the environment variable AFL_USE_UBSAN=1)
similarly by setting the environment variable AFL_USE_UBSAN=1. Finally
there is the Control Flow Integrity sanitizer that can be activated by
AFL_USE_CFISAN=1)
- Setting AFL_CC, AFL_CXX, and AFL_AS lets you use alternate downstream
compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries

View File

@ -29,7 +29,7 @@ Note that ASAN is incompatible with -static, so be mindful of that.
(You can also use AFL_USE_MSAN=1 to enable MSAN instead.)
NOTE: if you run several slaves only one should run the target compiled with
ASAN (and UBSAN), the others should run the target with no sanitizers
ASAN (and UBSAN, CFISAN), the others should run the target with no sanitizers
compiled in.
There is also the option of generating a corpus using a non-ASAN binary, and

View File

@ -513,6 +513,7 @@ struct InsTrim : public ModulePass {
getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
getenv("AFL_USE_ASAN") ? ", ASAN" : "",
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
OKF("Instrumented %u locations (%llu, %llu) (%s mode)\n", total_instr,

View File

@ -135,7 +135,7 @@ static void find_obj(u8 *argv0) {
/* Copy argv to cc_params, making the necessary edits. */
static void edit_params(u32 argc, char **argv) {
static void edit_params(u32 argc, char **argv, char **envp) {
u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0;
u8 has_llvm_config = 0;
@ -395,6 +395,22 @@ static void edit_params(u32 argc, char **argv) {
}
if (getenv("AFL_USE_CFISAN")) {
if (!lto_mode) {
uint32_t i = 0, found = 0;
while (envp[i] != NULL && !found)
if (strncmp("-flto", envp[i++], 5) == 0)
found = 1;
if (!found) cc_params[cc_par_cnt++] = "-flto";
}
cc_params[cc_par_cnt++] = "-fsanitize=cfi";
cc_params[cc_par_cnt++] = "-fvisibility=hidden";
}
#ifdef USE_TRACE_PC
if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
@ -596,6 +612,7 @@ int main(int argc, char **argv, char **envp) {
"AFL_USE_ASAN: activate address sanitizer\n"
"AFL_USE_MSAN: activate memory sanitizer\n"
"AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
"AFL_USE_CFISAN: activate control flow sanitizer\n"
"AFL_LLVM_WHITELIST: enable whitelisting (selective "
"instrumentation)\n"
"AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
@ -685,7 +702,7 @@ int main(int argc, char **argv, char **envp) {
find_obj(argv[0]);
#endif
edit_params(argc, argv);
edit_params(argc, argv, envp);
if (debug) {

View File

@ -396,6 +396,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
getenv("AFL_USE_ASAN") ? ", ASAN" : "",
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
OKF("Instrumented %u locations with no collisions (on average %llu "
"collisions would be in afl-gcc/afl-clang-fast) (%s mode).",

View File

@ -572,6 +572,7 @@ bool AFLCoverage::runOnModule(Module &M) {
getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
getenv("AFL_USE_ASAN") ? ", ASAN" : "",
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
OKF("Instrumented %u locations (%s mode, ratio %u%%).", inst_blocks,
modeline, inst_ratio);

View File

@ -73,7 +73,7 @@ char * afl_environment_variables[] = {
"AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ",
"AFL_SKIP_CRASHES", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE",
"AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC",
"AFL_USE_UBSAN", "AFL_WINE_PATH", NULL};
"AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", NULL};
void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {