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