78 lines · cpp
1//=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This files defines FixedAddressChecker, a builtin checker that checks for10// assignment of a fixed address to a pointer.11// This check corresponds to CWE-587.12//13//===----------------------------------------------------------------------===//14 15#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"16#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"17#include "clang/StaticAnalyzer/Core/Checker.h"18#include "clang/StaticAnalyzer/Core/CheckerManager.h"19#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"20 21using namespace clang;22using namespace ento;23 24namespace {25class FixedAddressChecker26 : public Checker< check::PreStmt<BinaryOperator> > {27 const BugType BT{this, "Use fixed address"};28 29public:30 void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;31};32}33 34void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,35 CheckerContext &C) const {36 // Using a fixed address is not portable because that address will probably37 // not be valid in all environments or platforms.38 39 if (B->getOpcode() != BO_Assign)40 return;41 42 QualType T = B->getType();43 if (!T->isPointerType())44 return;45 46 // Omit warning if the RHS has already pointer type. Without this passing47 // around one fixed value in several pointer variables would produce several48 // redundant warnings.49 if (B->getRHS()->IgnoreParenCasts()->getType()->isPointerType())50 return;51 52 SVal RV = C.getSVal(B->getRHS());53 54 if (!RV.isConstant() || RV.isZeroConstant())55 return;56 57 if (C.getSourceManager().isInSystemMacro(B->getRHS()->getBeginLoc()))58 return;59 60 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {61 // FIXME: improve grammar in the following strings:62 constexpr llvm::StringLiteral Msg =63 "Using a fixed address is not portable because that address will "64 "probably not be valid in all environments or platforms.";65 auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);66 R->addRange(B->getRHS()->getSourceRange());67 C.emitReport(std::move(R));68 }69}70 71void ento::registerFixedAddressChecker(CheckerManager &mgr) {72 mgr.registerChecker<FixedAddressChecker>();73}74 75bool ento::shouldRegisterFixedAddressChecker(const CheckerManager &mgr) {76 return true;77}78