add lto caller instrumentation

This commit is contained in:
vanhauser-thc
2024-02-03 15:53:54 +01:00
parent e1d7f4af35
commit dc151caa18
4 changed files with 35 additions and 5 deletions

View File

@ -7,6 +7,11 @@
- afl-fuzz: - afl-fuzz:
- the new deterministic fuzzing feature is now activated by default, - the new deterministic fuzzing feature is now activated by default,
deactivate with -z. Parameters -d and -D are ignored. deactivate with -z. Parameters -d and -D are ignored.
- afl-cc:
- added collision free caller instrumentation to LTO mode. activate with
`AFL_LLVM_LTO_CALLER=1`. You can set a max depth to go through single
block functions with `AFL_LLVM_LTO_CALLER_DEPTH` (default 0)
### Version ++4.10c (release) ### Version ++4.10c (release)
- afl-fuzz: - afl-fuzz:

View File

@ -248,6 +248,9 @@ use (which only ever the author of this LTO implementation will use). These are
used if several separated instrumentations are performed which are then later used if several separated instrumentations are performed which are then later
combined. combined.
- `AFL_LLVM_LTO_CALLER` activates collision free CALLER instrumentation
- `AFL_LLVM_LTO_CALLER` sets the maximum mumber of single block functions
to dig deeper into a real function. Default 0.
- `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given - `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given
to which function. This helps to identify functions with variable bytes or to which function. This helps to identify functions with variable bytes or
which functions were touched by an input. which functions were touched by an input.

View File

@ -251,6 +251,7 @@ class ModuleSanitizerCoverageLTO
uint32_t unhandled = 0; uint32_t unhandled = 0;
uint32_t select_cnt = 0; uint32_t select_cnt = 0;
uint32_t instrument_ctx = 0; uint32_t instrument_ctx = 0;
uint32_t instrument_ctx_max_depth = 0;
uint32_t extra_ctx_inst = 0; uint32_t extra_ctx_inst = 0;
uint64_t map_addr = 0; uint64_t map_addr = 0;
const char *skip_nozero = NULL; const char *skip_nozero = NULL;
@ -428,12 +429,31 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) { debug = 1; } if (getenv("AFL_DEBUG")) { debug = 1; }
if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { autodictionary_no_main = 1; } if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { autodictionary_no_main = 1; }
if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_CTX")) { if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_CTX") ||
getenv("AFL_LLVM_LTO_CALLER") || getenv("AFL_LLVM_LTO_CTX")) {
instrument_ctx = 1; instrument_ctx = 1;
} }
if (getenv("AFL_LLVM_LTO_CALLER_DEPTH")) {
instrument_ctx_max_depth = atoi(getenv("AFL_LLVM_LTO_CALLER_DEPTH"));
} else if (getenv("AFL_LLVM_LTO_CTX_DEPTH")) {
instrument_ctx_max_depth = atoi(getenv("AFL_LLVM_LTO_CTX_DEPTH"));
} else if (getenv("AFL_LLVM_CALLER_DEPTH")) {
instrument_ctx_max_depth = atoi(getenv("AFL_LLVM_CALLER_DEPTH"));
} else if (getenv("AFL_LLVM_CTX_DEPTH")) {
instrument_ctx_max_depth = atoi(getenv("AFL_LLVM_CTX_DEPTH"));
}
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
SAYF(cCYA "afl-llvm-lto" VERSION cRST SAYF(cCYA "afl-llvm-lto" VERSION cRST
@ -1406,11 +1426,12 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
call_counter = countCallers(caller); call_counter = countCallers(caller);
Function *callee = caller; Function *callee = caller;
if (call_counter == 1) { if (call_counter == 1 && instrument_ctx_max_depth) {
++call_depth; ++call_depth;
while (((caller = returnOnlyCaller(callee)) || 1 == 1) && while (instrument_ctx_max_depth >= call_depth &&
((caller = returnOnlyCaller(callee)) || 1 == 1) &&
(call_counter = countCallers(callee)) == 1) { (call_counter = countCallers(callee)) == 1) {
if (debug && caller && callee) if (debug && caller && callee)

View File

@ -2921,11 +2921,12 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
" AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding "
"functions\n" "functions\n"
" into this file (LTO mode)\n" " into this file (LTO mode)\n"
" AFL_LLVM_LTO_CALLER: activate CALLER/CTX instrumentation\n"
" AFL_LLVM_LTO_CALLER_DEPTH: skip how many empty functions\n"
" AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
"global var\n" "global var\n"
" AFL_LLVM_LTO_STARTID: from which ID to start counting from for " " AFL_LLVM_LTO_STARTID: from which ID to start counting from for "
"a " "a bb\n"
"bb\n"
" AFL_REAL_LD: use this lld linker instead of the compiled in " " AFL_REAL_LD: use this lld linker instead of the compiled in "
"path\n" "path\n"
" AFL_LLVM_LTO_SKIPINIT: don't inject initialization code " " AFL_LLVM_LTO_SKIPINIT: don't inject initialization code "