mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-18 20:48:07 +00:00
LTO whitelist functionality rewritten, now anything can be skipped
This commit is contained in:
@ -25,6 +25,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
which needs 3.8.0)
|
which needs 3.8.0)
|
||||||
- small change to cmplog to make it work with current llvm 11-dev
|
- small change to cmplog to make it work with current llvm 11-dev
|
||||||
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
|
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
|
||||||
|
- LTO whitelist functionality rewritten, now main, _init etc functions
|
||||||
|
need not to be whitelisted anymore
|
||||||
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in
|
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in
|
||||||
the same second
|
the same second
|
||||||
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
|
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
|
||||||
|
@ -190,11 +190,6 @@ target will likely crash when started. This can be avoided by compiling with
|
|||||||
|
|
||||||
This can e.g. happen with OpenSSL.
|
This can e.g. happen with OpenSSL.
|
||||||
|
|
||||||
## Upcoming Work
|
|
||||||
|
|
||||||
1. Currently the LTO whitelist feature does not allow to instrument main,
|
|
||||||
start and init functions
|
|
||||||
|
|
||||||
## 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
|
||||||
|
@ -561,6 +561,17 @@ struct InsTrimLTO : public ModulePass {
|
|||||||
if (F.size() < function_minimum_size) continue;
|
if (F.size() < function_minimum_size) continue;
|
||||||
if (isBlacklisted(&F)) continue;
|
if (isBlacklisted(&F)) continue;
|
||||||
|
|
||||||
|
// whitelist check
|
||||||
|
AttributeList Attrs = F.getAttributes();
|
||||||
|
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(stderr, "DEBUG: Function %s is not whitelisted\n",
|
||||||
|
F.getName().str().c_str());
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::unordered_set<BasicBlock *> MS;
|
std::unordered_set<BasicBlock *> MS;
|
||||||
if (!MarkSetOpt) {
|
if (!MarkSetOpt) {
|
||||||
|
|
||||||
|
@ -197,6 +197,17 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
if (F.size() < function_minimum_size) continue;
|
if (F.size() < function_minimum_size) continue;
|
||||||
if (isBlacklisted(&F)) continue;
|
if (isBlacklisted(&F)) continue;
|
||||||
|
|
||||||
|
// whitelist check
|
||||||
|
AttributeList Attrs = F.getAttributes();
|
||||||
|
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(stderr, "DEBUG: Function %s is not whitelisted\n",
|
||||||
|
F.getName().str().c_str());
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<BasicBlock *> InsBlocks;
|
std::vector<BasicBlock *> InsBlocks;
|
||||||
|
|
||||||
if (autodictionary) {
|
if (autodictionary) {
|
||||||
|
@ -122,64 +122,65 @@ bool AFLwhitelist::runOnModule(Module &M) {
|
|||||||
|
|
||||||
for (auto &F : M) {
|
for (auto &F : M) {
|
||||||
|
|
||||||
|
if (F.size() < 1) continue;
|
||||||
|
// fprintf(stderr, "F:%s\n", F.getName().str().c_str());
|
||||||
if (isBlacklisted(&F)) continue;
|
if (isBlacklisted(&F)) continue;
|
||||||
|
|
||||||
for (auto &BB : F) {
|
BasicBlock::iterator IP = F.getEntryBlock().getFirstInsertionPt();
|
||||||
|
IRBuilder<> IRB(&(*IP));
|
||||||
|
|
||||||
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
if (!myWhitelist.empty()) {
|
||||||
IRBuilder<> IRB(&(*IP));
|
|
||||||
|
|
||||||
if (!myWhitelist.empty()) {
|
bool instrumentFunction = false;
|
||||||
|
|
||||||
bool instrumentBlock = false;
|
/* Get the current location using debug information.
|
||||||
|
* For now, just instrument the block if we are not able
|
||||||
|
* to determine our location. */
|
||||||
|
DebugLoc Loc = IP->getDebugLoc();
|
||||||
|
if (Loc) {
|
||||||
|
|
||||||
/* Get the current location using debug information.
|
DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
|
||||||
* For now, just instrument the block if we are not able
|
|
||||||
* to determine our location. */
|
|
||||||
DebugLoc Loc = IP->getDebugLoc();
|
|
||||||
if (Loc) {
|
|
||||||
|
|
||||||
DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
|
unsigned int instLine = cDILoc->getLine();
|
||||||
|
StringRef instFilename = cDILoc->getFilename();
|
||||||
|
|
||||||
unsigned int instLine = cDILoc->getLine();
|
if (instFilename.str().empty()) {
|
||||||
StringRef instFilename = cDILoc->getFilename();
|
|
||||||
|
|
||||||
if (instFilename.str().empty()) {
|
/* If the original location is empty, try using the inlined location
|
||||||
|
*/
|
||||||
|
DILocation *oDILoc = cDILoc->getInlinedAt();
|
||||||
|
if (oDILoc) {
|
||||||
|
|
||||||
/* If the original location is empty, try using the inlined location
|
instFilename = oDILoc->getFilename();
|
||||||
*/
|
instLine = oDILoc->getLine();
|
||||||
DILocation *oDILoc = cDILoc->getInlinedAt();
|
|
||||||
if (oDILoc) {
|
|
||||||
|
|
||||||
instFilename = oDILoc->getFilename();
|
|
||||||
instLine = oDILoc->getLine();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)instLine;
|
}
|
||||||
|
|
||||||
/* Continue only if we know where we actually are */
|
(void)instLine;
|
||||||
if (!instFilename.str().empty()) {
|
|
||||||
|
|
||||||
for (std::list<std::string>::iterator it = myWhitelist.begin();
|
if (debug)
|
||||||
it != myWhitelist.end(); ++it) {
|
SAYF(cMGN "[D] " cRST "function %s is in file %s\n",
|
||||||
|
F.getName().str().c_str(), instFilename.str().c_str());
|
||||||
|
/* Continue only if we know where we actually are */
|
||||||
|
if (!instFilename.str().empty()) {
|
||||||
|
|
||||||
/* We don't check for filename equality here because
|
for (std::list<std::string>::iterator it = myWhitelist.begin();
|
||||||
* filenames might actually be full paths. Instead we
|
it != myWhitelist.end(); ++it) {
|
||||||
* check that the actual filename ends in the filename
|
|
||||||
* specified in the list. */
|
|
||||||
if (instFilename.str().length() >= it->length()) {
|
|
||||||
|
|
||||||
if (instFilename.str().compare(
|
/* We don't check for filename equality here because
|
||||||
instFilename.str().length() - it->length(),
|
* filenames might actually be full paths. Instead we
|
||||||
it->length(), *it) == 0) {
|
* check that the actual filename ends in the filename
|
||||||
|
* specified in the list. */
|
||||||
|
if (instFilename.str().length() >= it->length()) {
|
||||||
|
|
||||||
instrumentBlock = true;
|
if (instFilename.str().compare(
|
||||||
break;
|
instFilename.str().length() - it->length(), it->length(),
|
||||||
|
*it) == 0) {
|
||||||
|
|
||||||
}
|
instrumentFunction = true;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,43 +190,35 @@ bool AFLwhitelist::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Either we couldn't figure out our location or the location is
|
}
|
||||||
* not whitelisted, so we skip instrumentation.
|
|
||||||
* We do this by renaming the function. */
|
|
||||||
if (!instrumentBlock) {
|
|
||||||
|
|
||||||
if (F.getName().compare("main") == 0 ||
|
/* Either we couldn't figure out our location or the location is
|
||||||
F.getName().compare("start") == 0 ||
|
* not whitelisted, so we skip instrumentation.
|
||||||
F.getName().compare("_start") == 0 ||
|
* We do this by renaming the function. */
|
||||||
F.getName().compare("init") == 0 ||
|
if (instrumentFunction == true) {
|
||||||
F.getName().compare("_init") == 0) {
|
|
||||||
|
|
||||||
// We do not honor be_quiet for this one
|
|
||||||
WARNF("Cannot ignore functions main/init/start");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// StringRef newName = StringRef("ign.") + F.getName();
|
|
||||||
if (debug)
|
|
||||||
SAYF(cMGN "[D] " cRST "renamed %s to ign.%s\n",
|
|
||||||
F.getName().str().c_str(), F.getName().str().c_str());
|
|
||||||
Function *_F(&F);
|
|
||||||
_F->setName("ign." + F.getName());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (debug)
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
SAYF(cMGN "[D] " cRST "function %s is in whitelist\n",
|
SAYF(cMGN "[D] " cRST "function %s is in whitelist\n",
|
||||||
F.getName().str().c_str());
|
F.getName().str().c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
PFATAL("Whitelist is empty");
|
if (debug)
|
||||||
|
SAYF(cMGN "[D] " cRST "function %s is NOT in whitelist\n",
|
||||||
|
F.getName().str().c_str());
|
||||||
|
|
||||||
|
auto & Ctx = F.getContext();
|
||||||
|
AttributeList Attrs = F.getAttributes();
|
||||||
|
AttrBuilder NewAttrs;
|
||||||
|
NewAttrs.addAttribute("skipinstrument");
|
||||||
|
F.setAttributes(
|
||||||
|
Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
} else {
|
||||||
|
|
||||||
|
PFATAL("Whitelist is empty");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user