1d99bd55aSTed Kremenek //=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===//
2d99bd55aSTed Kremenek //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d99bd55aSTed Kremenek //
7d99bd55aSTed Kremenek //===----------------------------------------------------------------------===//
8d99bd55aSTed Kremenek //
9d99bd55aSTed Kremenek // This files defines FixedAddressChecker, a builtin checker that checks for
10d99bd55aSTed Kremenek // assignment of a fixed address to a pointer.
11d99bd55aSTed Kremenek // This check corresponds to CWE-587.
12d99bd55aSTed Kremenek //
13d99bd55aSTed Kremenek //===----------------------------------------------------------------------===//
14d99bd55aSTed Kremenek 
1576a21502SKristof Umann #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
163a02247dSChandler Carruth #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
176a5674ffSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/Checker.h"
18507ff53eSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19dff865d1SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20d99bd55aSTed Kremenek 
21d99bd55aSTed Kremenek using namespace clang;
22d99bd55aSTed Kremenek using namespace ento;
23d99bd55aSTed Kremenek 
24d99bd55aSTed Kremenek namespace {
25d99bd55aSTed Kremenek class FixedAddressChecker
266a5674ffSArgyrios Kyrtzidis   : public Checker< check::PreStmt<BinaryOperator> > {
27b8984329SAhmed Charles   mutable std::unique_ptr<BuiltinBug> BT;
28dff865d1SArgyrios Kyrtzidis 
29d99bd55aSTed Kremenek public:
30dff865d1SArgyrios Kyrtzidis   void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
31d99bd55aSTed Kremenek };
32d99bd55aSTed Kremenek }
33d99bd55aSTed Kremenek 
checkPreStmt(const BinaryOperator * B,CheckerContext & C) const34dff865d1SArgyrios Kyrtzidis void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
35dff865d1SArgyrios Kyrtzidis                                        CheckerContext &C) const {
36d99bd55aSTed Kremenek   // Using a fixed address is not portable because that address will probably
37d99bd55aSTed Kremenek   // not be valid in all environments or platforms.
38d99bd55aSTed Kremenek 
39d99bd55aSTed Kremenek   if (B->getOpcode() != BO_Assign)
40d99bd55aSTed Kremenek     return;
41d99bd55aSTed Kremenek 
42d99bd55aSTed Kremenek   QualType T = B->getType();
43d99bd55aSTed Kremenek   if (!T->isPointerType())
44d99bd55aSTed Kremenek     return;
45d99bd55aSTed Kremenek 
46d703ec94SGeorge Karpenkov   SVal RV = C.getSVal(B->getRHS());
47d99bd55aSTed Kremenek 
48d99bd55aSTed Kremenek   if (!RV.isConstant() || RV.isZeroConstant())
49d99bd55aSTed Kremenek     return;
50d99bd55aSTed Kremenek 
51e39bd407SDevin Coughlin   if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
52d99bd55aSTed Kremenek     if (!BT)
534aca9b1cSAlexander Kornienko       BT.reset(
544aca9b1cSAlexander Kornienko           new BuiltinBug(this, "Use fixed address",
55d99bd55aSTed Kremenek                          "Using a fixed address is not portable because that "
56d99bd55aSTed Kremenek                          "address will probably not be valid in all "
57dff865d1SArgyrios Kyrtzidis                          "environments or platforms."));
582f169e7cSArtem Dergachev     auto R =
592f169e7cSArtem Dergachev         std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
60d99bd55aSTed Kremenek     R->addRange(B->getRHS()->getSourceRange());
618d3a7a56SAaron Ballman     C.emitReport(std::move(R));
62d99bd55aSTed Kremenek   }
63d99bd55aSTed Kremenek }
64d99bd55aSTed Kremenek 
registerFixedAddressChecker(CheckerManager & mgr)65507ff53eSArgyrios Kyrtzidis void ento::registerFixedAddressChecker(CheckerManager &mgr) {
66dff865d1SArgyrios Kyrtzidis   mgr.registerChecker<FixedAddressChecker>();
67507ff53eSArgyrios Kyrtzidis }
68058a7a45SKristof Umann 
shouldRegisterFixedAddressChecker(const CheckerManager & mgr)69*bda3dd0dSKirstóf Umann bool ento::shouldRegisterFixedAddressChecker(const CheckerManager &mgr) {
70058a7a45SKristof Umann   return true;
71058a7a45SKristof Umann }
72