1 //=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This files defines FixedAddressChecker, a builtin checker that checks for 11 // assignment of a fixed address to a pointer. 12 // This check corresponds to CWE-587. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "ClangSACheckers.h" 17 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 18 #include "clang/StaticAnalyzer/Core/Checker.h" 19 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 21 22 using namespace clang; 23 using namespace ento; 24 25 namespace { 26 class FixedAddressChecker 27 : public Checker< check::PreStmt<BinaryOperator> > { 28 mutable std::unique_ptr<BuiltinBug> BT; 29 30 public: 31 void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; 32 }; 33 } 34 35 void FixedAddressChecker::checkPreStmt(const BinaryOperator *B, 36 CheckerContext &C) const { 37 // Using a fixed address is not portable because that address will probably 38 // not be valid in all environments or platforms. 39 40 if (B->getOpcode() != BO_Assign) 41 return; 42 43 QualType T = B->getType(); 44 if (!T->isPointerType()) 45 return; 46 47 SVal RV = C.getSVal(B->getRHS()); 48 49 if (!RV.isConstant() || RV.isZeroConstant()) 50 return; 51 52 if (ExplodedNode *N = C.generateNonFatalErrorNode()) { 53 if (!BT) 54 BT.reset( 55 new BuiltinBug(this, "Use fixed address", 56 "Using a fixed address is not portable because that " 57 "address will probably not be valid in all " 58 "environments or platforms.")); 59 auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N); 60 R->addRange(B->getRHS()->getSourceRange()); 61 C.emitReport(std::move(R)); 62 } 63 } 64 65 void ento::registerFixedAddressChecker(CheckerManager &mgr) { 66 mgr.registerChecker<FixedAddressChecker>(); 67 } 68