Add function call level granularity for coverage accounting (#552)
* Add func call level granularity for coverage accounting * code linting
This commit is contained in:
parent
04c8e96923
commit
df84d39242
@ -1,6 +1,8 @@
|
|||||||
use libafl_cc::{ClangWrapper, CompilerWrapper, LLVMPasses};
|
use libafl_cc::{ClangWrapper, CompilerWrapper, LLVMPasses};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
const GRANULARITY: &str = "FUNC";
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
@ -25,6 +27,7 @@ pub fn main() {
|
|||||||
.link_staticlib(&dir, "libfuzzer_libpng")
|
.link_staticlib(&dir, "libfuzzer_libpng")
|
||||||
.add_arg("-fsanitize-coverage=trace-pc-guard")
|
.add_arg("-fsanitize-coverage=trace-pc-guard")
|
||||||
.add_pass(LLVMPasses::CoverageAccounting)
|
.add_pass(LLVMPasses::CoverageAccounting)
|
||||||
|
.add_passes_arg(format!("-granularity={}", GRANULARITY))
|
||||||
.run()
|
.run()
|
||||||
.expect("Failed to run the wrapped compiler")
|
.expect("Failed to run the wrapped compiler")
|
||||||
{
|
{
|
||||||
|
@ -23,8 +23,7 @@ pub fn main() {
|
|||||||
.parse_args(&args)
|
.parse_args(&args)
|
||||||
.expect("Failed to parse the command line")
|
.expect("Failed to parse the command line")
|
||||||
.add_pass(LLVMPasses::AFLCoverage)
|
.add_pass(LLVMPasses::AFLCoverage)
|
||||||
.add_arg("-mllvm")
|
.add_passes_arg("-ctx") // Context sensitive coverage
|
||||||
.add_arg("-ctx") // Context sensitive coverage
|
|
||||||
.link_staticlib(&dir, "libfuzzer_libpng")
|
.link_staticlib(&dir, "libfuzzer_libpng")
|
||||||
.run()
|
.run()
|
||||||
.expect("Failed to run the wrapped compiler")
|
.expect("Failed to run the wrapped compiler")
|
||||||
|
@ -77,6 +77,7 @@ pub struct ClangWrapper {
|
|||||||
cc_args: Vec<String>,
|
cc_args: Vec<String>,
|
||||||
link_args: Vec<String>,
|
link_args: Vec<String>,
|
||||||
passes: Vec<LLVMPasses>,
|
passes: Vec<LLVMPasses>,
|
||||||
|
passes_args: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::match_same_arms)] // for the linking = false wip for "shared"
|
#[allow(clippy::match_same_arms)] // for the linking = false wip for "shared"
|
||||||
@ -264,6 +265,10 @@ impl CompilerWrapper for ClangWrapper {
|
|||||||
args.push("-Xclang".into());
|
args.push("-Xclang".into());
|
||||||
args.push(pass.path().into_os_string().into_string().unwrap());
|
args.push(pass.path().into_os_string().into_string().unwrap());
|
||||||
}
|
}
|
||||||
|
for passes_arg in &self.passes_args {
|
||||||
|
args.push("-mllvm".into());
|
||||||
|
args.push(passes_arg.into());
|
||||||
|
}
|
||||||
if self.linking {
|
if self.linking {
|
||||||
if self.x_set {
|
if self.x_set {
|
||||||
args.push("-x".into());
|
args.push("-x".into());
|
||||||
@ -325,6 +330,7 @@ impl ClangWrapper {
|
|||||||
cc_args: vec![],
|
cc_args: vec![],
|
||||||
link_args: vec![],
|
link_args: vec![],
|
||||||
passes: vec![],
|
passes: vec![],
|
||||||
|
passes_args: vec![],
|
||||||
is_silent: false,
|
is_silent: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,6 +365,15 @@ impl ClangWrapper {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add LLVM pass arguments
|
||||||
|
pub fn add_passes_arg<S>(&mut self, arg: S) -> &'_ mut Self
|
||||||
|
where
|
||||||
|
S: AsRef<str>,
|
||||||
|
{
|
||||||
|
self.passes_args.push(arg.as_ref().to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set if linking
|
/// Set if linking
|
||||||
pub fn linking(&mut self, value: bool) -> &'_ mut Self {
|
pub fn linking(&mut self, value: bool) -> &'_ mut Self {
|
||||||
self.linking = value;
|
self.linking = value;
|
||||||
|
@ -54,14 +54,61 @@ typedef uint32_t prev_loc_t;
|
|||||||
|
|
||||||
#define MAP_SIZE LIBAFL_ACCOUNTING_MAP_SIZE
|
#define MAP_SIZE LIBAFL_ACCOUNTING_MAP_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
#define SECURITY_SENSITIVE_FUNCS(CF) static CF securitySensitiveFunctions[] = {\
|
||||||
|
CF("memcpy"), \
|
||||||
|
CF("strlen"), \
|
||||||
|
CF("ReadImage"), \
|
||||||
|
CF("memmove"), \
|
||||||
|
CF("free"), \
|
||||||
|
CF("memset"), \
|
||||||
|
CF("delete"), \
|
||||||
|
CF("memcmp"), \
|
||||||
|
CF("getString"), \
|
||||||
|
CF("vsprintf"), \
|
||||||
|
CF("GET_COLOR"), \
|
||||||
|
CF("read"), \
|
||||||
|
CF("load_bmp"), \
|
||||||
|
CF("huffcode"), \
|
||||||
|
CF("strcmp"), \
|
||||||
|
CF("new"), \
|
||||||
|
CF("getName"), \
|
||||||
|
CF("strncat"), \
|
||||||
|
CF("png_load"), \
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
enum AccountingGranularity {
|
||||||
|
BB_GRAN,
|
||||||
|
FUNC_GRAN,
|
||||||
|
// LOOP,
|
||||||
|
UKNOWN_GRAN
|
||||||
|
};
|
||||||
|
|
||||||
static cl::opt<bool> Debug("debug", cl::desc("Debug prints"), cl::init(false), cl::NotHidden);
|
static cl::opt<bool> Debug("debug", cl::desc("Debug prints"), cl::init(false), cl::NotHidden);
|
||||||
|
static cl::opt<std::string> GranularityStr("granularity", cl::desc("Granularity of accounting (BB, FUNC)"), cl::init(std::string("BB")), cl::NotHidden);
|
||||||
static cl::opt<uint32_t> InstRatio("inst_ratio", cl::desc("Instrumentation ratio in percentage"), cl::init(100), cl::NotHidden);
|
static cl::opt<uint32_t> InstRatio("inst_ratio", cl::desc("Instrumentation ratio in percentage"), cl::init(100), cl::NotHidden);
|
||||||
static cl::opt<bool> ThreadSafe("thread_safe", cl::desc("Use the thread safe instrumentation"), cl::init(false), cl::NotHidden);
|
static cl::opt<bool> ThreadSafe("thread_safe", cl::desc("Use the thread safe instrumentation"), cl::init(false), cl::NotHidden);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
SECURITY_SENSITIVE_FUNCS(StringRef)
|
||||||
|
|
||||||
|
bool isSecuritySensitiveFunction(Function* F) {
|
||||||
|
if (!F) return 0;
|
||||||
|
auto func_name = F->getName();
|
||||||
|
for (auto name : securitySensitiveFunctions) {
|
||||||
|
if (func_name.contains(name)) {
|
||||||
|
if (Debug)
|
||||||
|
fprintf(stderr, "Counted %s as security sensitive", func_name.str().c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_NEW_PM
|
#ifdef USE_NEW_PM
|
||||||
class AFLCoverage : public PassInfoMixin<AFLCoverage> {
|
class AFLCoverage : public PassInfoMixin<AFLCoverage> {
|
||||||
public:
|
public:
|
||||||
@ -72,7 +119,10 @@ class AFLCoverage : public ModulePass {
|
|||||||
static char ID;
|
static char ID;
|
||||||
AFLCoverage() : ModulePass(ID) {
|
AFLCoverage() : ModulePass(ID) {
|
||||||
#endif
|
#endif
|
||||||
|
granularity = StringSwitch<AccountingGranularity>(GranularityStr)
|
||||||
|
.Case("BB", BB_GRAN)
|
||||||
|
.Case("FUNC", FUNC_GRAN)
|
||||||
|
.Default(UKNOWN_GRAN);
|
||||||
// initInstrumentList();
|
// initInstrumentList();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -86,6 +136,7 @@ class AFLCoverage : public ModulePass {
|
|||||||
protected:
|
protected:
|
||||||
uint32_t map_size = MAP_SIZE;
|
uint32_t map_size = MAP_SIZE;
|
||||||
uint32_t function_minimum_size = 1;
|
uint32_t function_minimum_size = 1;
|
||||||
|
AccountingGranularity granularity;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,12 +247,20 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
|
|
||||||
// Start with 1 to implicitly track edge coverage too
|
// Start with 1 to implicitly track edge coverage too
|
||||||
uint32_t MemCnt = 1;
|
uint32_t MemCnt = 1;
|
||||||
|
|
||||||
for (auto &I : BB) {
|
for (auto &I : BB) {
|
||||||
if (I.mayReadFromMemory() || I.mayWriteToMemory())
|
switch (granularity) {
|
||||||
|
case BB_GRAN:
|
||||||
|
if (I.mayReadFromMemory() || I.mayWriteToMemory())
|
||||||
++MemCnt;
|
++MemCnt;
|
||||||
|
break;
|
||||||
|
case FUNC_GRAN:
|
||||||
|
if (auto *C = dyn_cast<CallInst>(&I)) {
|
||||||
|
auto F = C->getCalledFunction();
|
||||||
|
MemCnt += isSecuritySensitiveFunction(F);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make up cur_loc */
|
/* Make up cur_loc */
|
||||||
|
|
||||||
cur_loc = RandBelow(map_size);
|
cur_loc = RandBelow(map_size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user