LTO: make dynamic map the default

This commit is contained in:
van Hauser
2020-08-10 23:42:33 +02:00
parent 7b5a18428e
commit 701fb95d24
4 changed files with 40 additions and 28 deletions

View File

@ -28,6 +28,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
sancov, and also supports function matching! sancov, and also supports function matching!
- fixes for laf-intel float splitting (thanks to mark-griffin for - fixes for laf-intel float splitting (thanks to mark-griffin for
reporting) reporting)
- LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
for a fixed map address (eg. 0x10000)
- LTO: autodictionary mode is a default - LTO: autodictionary mode is a default
- LTO: instrim instrumentation disabled, only classic support used - LTO: instrim instrumentation disabled, only classic support used
as it is always better as it is always better

View File

@ -17,9 +17,6 @@ This version requires a current llvm 11+ compiled from the github master.
5. If any problems arise be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`. 5. If any problems arise be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`.
Some targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`. Some targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`.
6. If a target uses _init functions or early constructors then additionally
set `AFL_LLVM_MAP_DYNAMIC=1` as your target will crash otherwise!
## Introduction and problem description ## Introduction and problem description
A big issue with how afl/afl++ works is that the basic block IDs that are A big issue with how afl/afl++ works is that the basic block IDs that are
@ -128,14 +125,14 @@ on start. This improves coverage statistically by 5-10% :)
## Fixed memory map ## Fixed memory map
To speed up fuzzing, the shared memory map is hard set to a specific address, To speed up fuzzing, it is possible to set a fixed shared memory map.
by default 0x10000. In most cases this will work without any problems. Recommened is the value 0x10000.
In most cases this will work without any problems. However if a target uses
early constructors, ifuncs or a deferred forkserver this can crash the target.
On unusual operating systems/processors/kernels or weird libraries this might On unusual operating systems/processors/kernels or weird libraries this might
fail so to change the fixed address at compile time set fail so to change the fixed address at compile time set
AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address
to be dynamic - the original afl way, which is slower). to be dynamic - the original afl way, which is slower).
AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
is safer but also slower).
## Document edge IDs ## Document edge IDs
@ -262,15 +259,6 @@ If this succeeeds then there is an issue with afl-clang-lto. Please report at
Even some targets where clang-12 fails can be build if the fail is just in Even some targets where clang-12 fails can be build if the fail is just in
`./configure`, see `Solving difficult targets` above. `./configure`, see `Solving difficult targets` above.
### Target crashes immediately
If the target is using early constructors (priority values smaller than 6)
or have their own _init/.init functions and these are instrumented then the
target will likely crash when started. This can be avoided by compiling with
`AFL_LLVM_MAP_DYNAMIC=1` .
This can e.g. happen with OpenSSL.
## History ## History
This was originally envisioned by hexcoder- in Summer 2019, however we saw no This was originally envisioned by hexcoder- in Summer 2019, however we saw no

View File

@ -49,6 +49,7 @@
#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/IR/Constants.h"
#include "afl-llvm-common.h" #include "afl-llvm-common.h"
@ -135,7 +136,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1; if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1;
if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0; // we make this the default as the fixed map has problems with
// defered forkserver, early constructors, ifuncs and maybe more
/*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
map_addr = 0;
if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2; if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2;
@ -196,7 +200,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
ConstantInt *One = ConstantInt::get(Int8Ty, 1); ConstantInt *One = ConstantInt::get(Int8Ty, 1);
/* This dumps all inialized global strings - might be useful in the future // This dumps all inialized global strings - might be useful in the future
/*
for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) { for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) {
GlobalVariable &GV=*G; GlobalVariable &GV=*G;
@ -212,7 +217,21 @@ bool AFLLTOPass::runOnModule(Module &M) {
} }
*/ */
if (map_addr)
for (GlobalIFunc &IF : M.ifuncs()) {
// No clue how to follow these up and find the resolver function.
// If we would know that resolver function name we could just skip
// instrumenting it and everything would be fine :-(
// StringRef ifunc_name = IF.getName();
// Constant *r = IF.getResolver();
FATAL(
"Target uses ifunc attribute, dynamic map cannot be used, remove "
"AFL_LLVM_MAP_DYNAMIC");
}
/* Instrument all the things! */ /* Instrument all the things! */
@ -220,8 +239,12 @@ bool AFLLTOPass::runOnModule(Module &M) {
for (auto &F : M) { for (auto &F : M) {
// fprintf(stderr, "DEBUG: Module %s Function %s\n", /*For debugging
// M.getName().str().c_str(), F.getName().str().c_str()); AttributeSet X = F.getAttributes().getFnAttributes();
fprintf(stderr, "DEBUG: Module %s Function %s attributes %u\n",
M.getName().str().c_str(), F.getName().str().c_str(),
X.getNumAttributes());
*/
if (F.size() < function_minimum_size) continue; if (F.size() < function_minimum_size) continue;
if (isIgnoreFunction(&F)) continue; if (isIgnoreFunction(&F)) continue;

View File

@ -293,8 +293,8 @@ static void report_error_and_exit(int error) {
FATAL( FATAL(
"the fuzzing target reports that hardcoded map address might be the " "the fuzzing target reports that hardcoded map address might be the "
"reason the mmap of the shared memory failed. Solution: recompile " "reason the mmap of the shared memory failed. Solution: recompile "
"the target with either afl-clang-lto and the environment variable " "the target with either afl-clang-lto and do not set "
"AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast."); "AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.");
break; break;
case FS_ERROR_SHM_OPEN: case FS_ERROR_SHM_OPEN:
FATAL("the fuzzing target reports that the shm_open() call failed."); FATAL("the fuzzing target reports that the shm_open() call failed.");
@ -828,8 +828,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Hmm, looks like the target binary terminated before we could" "Hmm, looks like the target binary terminated before we could"
" complete a handshake with the injected code.\n" " complete a handshake with the injected code.\n"
"If the target was compiled with afl-clang-lto then recompiling with" "If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR"
" AFL_LLVM_MAP_DYNAMIC might solve your problem.\n" " then recompiling without this parameter.\n"
"Otherwise there is a horrible bug in the fuzzer.\n" "Otherwise there is a horrible bug in the fuzzer.\n"
"Poke <afl-users@googlegroups.com> for troubleshooting tips.\n"); "Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
@ -860,9 +860,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
" - the target was compiled with afl-clang-lto and a constructor " " - the target was compiled with afl-clang-lto and a constructor "
"was\n" "was\n"
" instrumented, recompiling with AFL_LLVM_MAP_DYNAMIC might solve " " instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve "
"your\n" "your problem\n\n"
" problem\n\n"
" - Less likely, there is a horrible bug in the fuzzer. If other " " - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n" "options\n"