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 checkPreStmt(const BinaryOperator * B,CheckerContext & C) const35void 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 ProgramStateRef state = C.getState(); 48 SVal RV = state->getSVal(B->getRHS(), C.getLocationContext()); 49 50 if (!RV.isConstant() || RV.isZeroConstant()) 51 return; 52 53 if (ExplodedNode *N = C.addTransition()) { 54 if (!BT) 55 BT.reset( 56 new BuiltinBug(this, "Use fixed address", 57 "Using a fixed address is not portable because that " 58 "address will probably not be valid in all " 59 "environments or platforms.")); 60 BugReport *R = new BugReport(*BT, BT->getDescription(), N); 61 R->addRange(B->getRHS()->getSourceRange()); 62 C.emitReport(R); 63 } 64 } 65 registerFixedAddressChecker(CheckerManager & mgr)66void ento::registerFixedAddressChecker(CheckerManager &mgr) { 67 mgr.registerChecker<FixedAddressChecker>(); 68 } 69