mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 10:08:07 +00:00
LTO: make dynamic map the default
This commit is contained in:
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
Reference in New Issue
Block a user