10b57cec5SDimitry Andric //=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This files defines FixedAddressChecker, a builtin checker that checks for 100b57cec5SDimitry Andric // assignment of a fixed address to a pointer. 110b57cec5SDimitry Andric // This check corresponds to CWE-587. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" 160b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 170b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/Checker.h" 180b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/CheckerManager.h" 190b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace clang; 220b57cec5SDimitry Andric using namespace ento; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace { 250b57cec5SDimitry Andric class FixedAddressChecker 260b57cec5SDimitry Andric : public Checker< check::PreStmt<BinaryOperator> > { 27*de8261c4SDimitry Andric const BugType BT{this, "Use fixed address"}; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric public: 300b57cec5SDimitry Andric void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; 310b57cec5SDimitry Andric }; 320b57cec5SDimitry Andric } 330b57cec5SDimitry Andric checkPreStmt(const BinaryOperator * B,CheckerContext & C) const340b57cec5SDimitry Andricvoid FixedAddressChecker::checkPreStmt(const BinaryOperator *B, 350b57cec5SDimitry Andric CheckerContext &C) const { 360b57cec5SDimitry Andric // Using a fixed address is not portable because that address will probably 370b57cec5SDimitry Andric // not be valid in all environments or platforms. 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric if (B->getOpcode() != BO_Assign) 400b57cec5SDimitry Andric return; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric QualType T = B->getType(); 430b57cec5SDimitry Andric if (!T->isPointerType()) 440b57cec5SDimitry Andric return; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric SVal RV = C.getSVal(B->getRHS()); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric if (!RV.isConstant() || RV.isZeroConstant()) 490b57cec5SDimitry Andric return; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric if (ExplodedNode *N = C.generateNonFatalErrorNode()) { 52c9157d92SDimitry Andric // FIXME: improve grammar in the following strings: 53c9157d92SDimitry Andric constexpr llvm::StringLiteral Msg = 54c9157d92SDimitry Andric "Using a fixed address is not portable because that address will " 55c9157d92SDimitry Andric "probably not be valid in all environments or platforms."; 56*de8261c4SDimitry Andric auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N); 570b57cec5SDimitry Andric R->addRange(B->getRHS()->getSourceRange()); 580b57cec5SDimitry Andric C.emitReport(std::move(R)); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric registerFixedAddressChecker(CheckerManager & mgr)620b57cec5SDimitry Andricvoid ento::registerFixedAddressChecker(CheckerManager &mgr) { 630b57cec5SDimitry Andric mgr.registerChecker<FixedAddressChecker>(); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric shouldRegisterFixedAddressChecker(const CheckerManager & mgr)665ffd83dbSDimitry Andricbool ento::shouldRegisterFixedAddressChecker(const CheckerManager &mgr) { 670b57cec5SDimitry Andric return true; 680b57cec5SDimitry Andric } 69