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!
- fixes for laf-intel float splitting (thanks to mark-griffin for
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: instrim instrumentation disabled, only classic support used
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`.
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
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
To speed up fuzzing, the shared memory map is hard set to a specific address,
by default 0x10000. In most cases this will work without any problems.
To speed up fuzzing, it is possible to set a fixed shared memory map.
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
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
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
@ -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
`./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
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/ValueTracking.h"
#include "llvm/Pass.h"
#include "llvm/IR/Constants.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_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;
@ -196,7 +200,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
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++) {
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! */
@ -220,8 +239,12 @@ bool AFLLTOPass::runOnModule(Module &M) {
for (auto &F : M) {
// fprintf(stderr, "DEBUG: Module %s Function %s\n",
// M.getName().str().c_str(), F.getName().str().c_str());
/*For debugging
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 (isIgnoreFunction(&F)) continue;

View File

@ -293,8 +293,8 @@ static void report_error_and_exit(int error) {
FATAL(
"the fuzzing target reports that hardcoded map address might be the "
"reason the mmap of the shared memory failed. Solution: recompile "
"the target with either afl-clang-lto and the environment variable "
"AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast.");
"the target with either afl-clang-lto and do not set "
"AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.");
break;
case FS_ERROR_SHM_OPEN:
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
"Hmm, looks like the target binary terminated before we could"
" complete a handshake with the injected code.\n"
"If the target was compiled with afl-clang-lto then recompiling with"
" AFL_LLVM_MAP_DYNAMIC might solve your problem.\n"
"If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR"
" then recompiling without this parameter.\n"
"Otherwise there is a horrible bug in the fuzzer.\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 "
"was\n"
" instrumented, recompiling with AFL_LLVM_MAP_DYNAMIC might solve "
"your\n"
" problem\n\n"
" instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve "
"your problem\n\n"
" - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n"