Skip to content

Commit 7a86149

Browse files
committed
added support for __afl_coverage_interesting
1 parent 893cd47 commit 7a86149

File tree

6 files changed

+76
-13
lines changed

6 files changed

+76
-13
lines changed

docs/Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ sending a mail to <[email protected]>.
3636
- cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit
3737
- cmplog/redqueen can now process basic libc++ and libstdc++
3838
std::string comparisons (though no position or length type variants)
39+
- added support for __afl_coverage_interesting() for LTO and
40+
and our own PCGUARD (llvm 10.0.1+), read more about this function
41+
and selective coverage in instrumentation/README.instrument_list.md
3942
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
4043
support (less performant than our own), GCC for old afl-gcc and
4144
CLANG for old afl-clang

instrumentation/README.instrument_list.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ in any function where you want:
4343
* `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
4444
* `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
4545

46+
A special function is `__afl_coverage_interesting`.
47+
To use this, you must define `void __afl_coverage_interesting(u8 val, u32 id);`.
48+
Then you can use this function globally, where the `val` parameter can be set
49+
by you, the `id` parameter is for afl-fuzz and will be overwritten.
50+
Note that useful parameters are for `val` are: 1, 2, 3, 4, 8, 16, 32, 64, 128.
51+
A value of e.g. 33 will be seen as 32 for coverage purposes.
52+
4653
## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
4754

4855
This feature is equivalent to llvm 12 sancov feature and allows to specify

instrumentation/SanitizerCoverageLTO.so.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,25 @@ void ModuleSanitizerCoverage::instrumentFunction(
12371237

12381238
for (auto &BB : F) {
12391239

1240+
for (auto &IN : BB) {
1241+
1242+
CallInst *callInst = nullptr;
1243+
1244+
if ((callInst = dyn_cast<CallInst>(&IN))) {
1245+
1246+
Function *Callee = callInst->getCalledFunction();
1247+
if (!Callee) continue;
1248+
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
1249+
StringRef FuncName = Callee->getName();
1250+
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
1251+
1252+
Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
1253+
callInst->setOperand(1, val);
1254+
1255+
}
1256+
1257+
}
1258+
12401259
if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
12411260
BlocksToInstrument.push_back(&BB);
12421261
for (auto &Inst : BB) {
@@ -1338,6 +1357,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
13381357

13391358
if (AllBlocks.empty()) return false;
13401359
CreateFunctionLocalArrays(F, AllBlocks);
1360+
13411361
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
13421362

13431363
// afl++ START

instrumentation/SanitizerCoveragePCGUARD.so.cc

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ class ModuleSanitizerCoverage {
311311
Function &F, Type *Ty,
312312
const char *Section);
313313
GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
314-
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
314+
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks,
315+
uint32_t special);
315316
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
316317
bool IsLeafFunc = true);
317318
Function *CreateInitCallsForSections(Module &M, const char *CtorName,
@@ -970,11 +971,11 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
970971
}
971972

972973
void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
973-
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
974+
Function &F, ArrayRef<BasicBlock *> AllBlocks, uint32_t special) {
974975

975976
if (Options.TracePCGuard)
976977
FunctionGuardArray = CreateFunctionLocalArrayInSection(
977-
AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName);
978+
AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName);
978979

979980
if (Options.Inline8bitCounters)
980981
Function8bitCounterArray = CreateFunctionLocalArrayInSection(
@@ -993,9 +994,38 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
993994
bool IsLeafFunc) {
994995

995996
if (AllBlocks.empty()) return false;
996-
CreateFunctionLocalArrays(F, AllBlocks);
997+
998+
uint32_t special = 0;
999+
for (auto &BB : F) {
1000+
1001+
for (auto &IN : BB) {
1002+
1003+
CallInst *callInst = nullptr;
1004+
1005+
if ((callInst = dyn_cast<CallInst>(&IN))) {
1006+
1007+
Function *Callee = callInst->getCalledFunction();
1008+
StringRef FuncName = Callee->getName();
1009+
if (!Callee) continue;
1010+
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
1011+
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
1012+
1013+
uint32_t id = 1 + instr + (uint32_t)AllBlocks.size() + special++;
1014+
Value * val = ConstantInt::get(Int32Ty, id);
1015+
callInst->setOperand(1, val);
1016+
1017+
}
1018+
1019+
}
1020+
1021+
}
1022+
1023+
CreateFunctionLocalArrays(F, AllBlocks, special);
9971024
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
9981025
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
1026+
1027+
instr += special;
1028+
9991029
return true;
10001030

10011031
}

src/afl-cc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
572572

573573
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
574574

575-
if (instrument_mode == INSTRUMENT_CFG)
575+
if (instrument_mode == INSTRUMENT_CFG ||
576+
instrument_mode == INSTRUMENT_PCGUARD)
576577
cc_params[cc_par_cnt++] = alloc_printf(
577578
"-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
578579
else
@@ -1670,15 +1671,16 @@ int main(int argc, char **argv, char **envp) {
16701671
if (compiler_mode == LTO) {
16711672

16721673
if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO ||
1673-
instrument_mode == INSTRUMENT_CFG) {
1674+
instrument_mode == INSTRUMENT_CFG ||
1675+
instrument_mode == INSTRUMENT_PCGUARD) {
16741676

16751677
lto_mode = 1;
1676-
if (!instrument_mode) {
1678+
// force CFG
1679+
// if (!instrument_mode) {
16771680

1678-
instrument_mode = INSTRUMENT_CFG;
1679-
// ptr = instrument_mode_string[instrument_mode];
1680-
1681-
}
1681+
instrument_mode = INSTRUMENT_PCGUARD;
1682+
// ptr = instrument_mode_string[instrument_mode];
1683+
// }
16821684

16831685
} else if (instrument_mode == INSTRUMENT_LTO ||
16841686

src/afl-fuzz.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ static void usage(u8 *argv0, int more_help) {
145145

146146
"Other stuff:\n"
147147
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
148-
" -M auto-sets -D, -Z (use -d to disable -D) and no trimming\n"
148+
" -M auto-sets -D, -Z (use -d to disable -D) and no "
149+
"trimming\n"
149150
" -F path - sync to a foreign fuzzer queue directory (requires "
150151
"-M, can\n"
151152
" be specified up to %u times)\n"
@@ -502,7 +503,7 @@ int main(int argc, char **argv_orig, char **envp) {
502503
afl->sync_id = ck_strdup(optarg);
503504
afl->skip_deterministic = 0; // force deterministic fuzzing
504505
afl->old_seed_selection = 1; // force old queue walking seed selection
505-
afl->disable_trim = 1; // disable trimming
506+
afl->disable_trim = 1; // disable trimming
506507

507508
if ((c = strchr(afl->sync_id, ':'))) {
508509

0 commit comments

Comments
 (0)