24 using namespace clang;
29 class MmapWriteExecChecker :
public Checker<check::PreCall> {
30 CallDescription MmapFn;
31 CallDescription MprotectFn;
35 mutable std::unique_ptr<BugType> BT;
37 MmapWriteExecChecker() : MmapFn(
"mmap", 6), MprotectFn(
"mprotect", 3) {}
38 void checkPreCall(
const CallEvent &Call, CheckerContext &C)
const;
44 int MmapWriteExecChecker::ProtWrite = 0x02;
45 int MmapWriteExecChecker::ProtExec = 0x04;
46 int MmapWriteExecChecker::ProtRead = 0x01;
48 void MmapWriteExecChecker::checkPreCall(
const CallEvent &Call,
49 CheckerContext &C)
const {
50 if (Call.isCalled(MmapFn) || Call.isCalled(MprotectFn)) {
51 SVal ProtVal = Call.getArgSVal(2);
53 int64_t Prot = ProtLoc->getValue().getSExtValue();
54 if (ProtExecOv != ProtExec)
55 ProtExec = ProtExecOv;
56 if (ProtReadOv != ProtRead)
57 ProtRead = ProtReadOv;
60 if (ProtRead == ProtExec)
63 if ((Prot & (ProtWrite | ProtExec)) == (ProtWrite | ProtExec)) {
65 BT.reset(
new BugType(
this,
"W^X check fails, Write Exec prot flags set",
"Security"));
67 ExplodedNode *N = C.generateNonFatalErrorNode();
71 auto Report = llvm::make_unique<BugReport>(
72 *BT,
"Both PROT_WRITE and PROT_EXEC flags are set. This can " 73 "lead to exploitable memory regions, which could be overwritten " 74 "with malicious code", N);
75 Report->addRange(Call.getArgSourceRange(2));
76 C.emitReport(std::move(Report));
81 void ento::registerMmapWriteExecChecker(CheckerManager &mgr) {
82 MmapWriteExecChecker *Mwec =
83 mgr.registerChecker<MmapWriteExecChecker>();
85 mgr.getAnalyzerOptions()
86 .getCheckerIntegerOption(
"MmapProtExec", 0x04, Mwec);
88 mgr.getAnalyzerOptions()
89 .getCheckerIntegerOption(
"MmapProtRead", 0x01, Mwec);
Dataflow Directional Tag Classes.