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