Home | History | Annotate | Download | only in Checkers
      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   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.generateNonFatalErrorNode()) {
     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     auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
     61     R->addRange(B->getRHS()->getSourceRange());
     62     C.emitReport(std::move(R));
     63   }
     64 }
     65 
     66 void ento::registerFixedAddressChecker(CheckerManager &mgr) {
     67   mgr.registerChecker<FixedAddressChecker>();
     68 }
     69