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/CheckerManager.h" 18 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 19 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h" 20 21 using namespace clang; 22 using namespace ento; 23 24 namespace { 25 class FixedAddressChecker 26 : public CheckerVisitor<FixedAddressChecker> { 27 BuiltinBug *BT; 28 public: 29 FixedAddressChecker() : BT(0) {} 30 static void *getTag(); 31 void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B); 32 }; 33 } 34 35 void *FixedAddressChecker::getTag() { 36 static int x; 37 return &x; 38 } 39 40 void FixedAddressChecker::PreVisitBinaryOperator(CheckerContext &C, 41 const BinaryOperator *B) { 42 // Using a fixed address is not portable because that address will probably 43 // not be valid in all environments or platforms. 44 45 if (B->getOpcode() != BO_Assign) 46 return; 47 48 QualType T = B->getType(); 49 if (!T->isPointerType()) 50 return; 51 52 const GRState *state = C.getState(); 53 54 SVal RV = state->getSVal(B->getRHS()); 55 56 if (!RV.isConstant() || RV.isZeroConstant()) 57 return; 58 59 if (ExplodedNode *N = C.generateNode()) { 60 if (!BT) 61 BT = new BuiltinBug("Use fixed address", 62 "Using a fixed address is not portable because that " 63 "address will probably not be valid in all " 64 "environments or platforms."); 65 RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N); 66 R->addRange(B->getRHS()->getSourceRange()); 67 C.EmitReport(R); 68 } 69 } 70 71 static void RegisterFixedAddressChecker(ExprEngine &Eng) { 72 Eng.registerCheck(new FixedAddressChecker()); 73 } 74 75 void ento::registerFixedAddressChecker(CheckerManager &mgr) { 76 mgr.addCheckerRegisterFunction(RegisterFixedAddressChecker); 77 } 78