blob: 94542be7dd7ca731b569406dd54347723624071a [file] [log] [blame]
Zhongxing Xu6c306c82009-11-09 06:52:44 +00001//=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Zhongxing Xu6c306c82009-11-09 06:52:44 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This files defines FixedAddressChecker, a builtin checker that checks for
10// assignment of a fixed address to a pointer.
11// This check corresponds to CWE-587.
12//
13//===----------------------------------------------------------------------===//
14
Kristof Umann76a21502018-12-15 16:23:51 +000015#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000016#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000017#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis507ff532011-02-17 21:39:17 +000018#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Argyrios Kyrtzidisdff865d2011-02-23 01:05:36 +000019#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Zhongxing Xu6c306c82009-11-09 06:52:44 +000020
21using namespace clang;
Ted Kremenek98857c92010-12-23 07:20:52 +000022using namespace ento;
Zhongxing Xu6c306c82009-11-09 06:52:44 +000023
24namespace {
Ted Kremenek3a0678e2015-09-08 03:50:52 +000025class FixedAddressChecker
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000026 : public Checker< check::PreStmt<BinaryOperator> > {
Ahmed Charlesb8984322014-03-07 20:03:18 +000027 mutable std::unique_ptr<BuiltinBug> BT;
Argyrios Kyrtzidisdff865d2011-02-23 01:05:36 +000028
Zhongxing Xu6c306c82009-11-09 06:52:44 +000029public:
Argyrios Kyrtzidisdff865d2011-02-23 01:05:36 +000030 void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
Zhongxing Xu6c306c82009-11-09 06:52:44 +000031};
32}
33
Argyrios Kyrtzidisdff865d2011-02-23 01:05:36 +000034void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
35 CheckerContext &C) const {
Zhongxing Xu6c306c82009-11-09 06:52:44 +000036 // Using a fixed address is not portable because that address will probably
37 // not be valid in all environments or platforms.
38
John McCalle3027922010-08-25 11:45:40 +000039 if (B->getOpcode() != BO_Assign)
Zhongxing Xu6c306c82009-11-09 06:52:44 +000040 return;
41
42 QualType T = B->getType();
43 if (!T->isPointerType())
44 return;
45
George Karpenkovd703ec92018-01-17 20:27:29 +000046 SVal RV = C.getSVal(B->getRHS());
Zhongxing Xu6c306c82009-11-09 06:52:44 +000047
48 if (!RV.isConstant() || RV.isZeroConstant())
49 return;
50
Devin Coughline39bd402015-09-16 22:03:05 +000051 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
Zhongxing Xu6c306c82009-11-09 06:52:44 +000052 if (!BT)
Alexander Kornienko4aca9b12014-02-11 21:49:21 +000053 BT.reset(
54 new BuiltinBug(this, "Use fixed address",
55 "Using a fixed address is not portable because that "
56 "address will probably not be valid in all "
57 "environments or platforms."));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +000058 auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
Zhongxing Xu6c306c82009-11-09 06:52:44 +000059 R->addRange(B->getRHS()->getSourceRange());
Aaron Ballman8d3a7a52015-06-23 13:15:32 +000060 C.emitReport(std::move(R));
Zhongxing Xu6c306c82009-11-09 06:52:44 +000061 }
62}
63
Argyrios Kyrtzidis507ff532011-02-17 21:39:17 +000064void ento::registerFixedAddressChecker(CheckerManager &mgr) {
Argyrios Kyrtzidisdff865d2011-02-23 01:05:36 +000065 mgr.registerChecker<FixedAddressChecker>();
Argyrios Kyrtzidis507ff532011-02-17 21:39:17 +000066}
Kristof Umann058a7a42019-01-26 14:23:08 +000067
68bool ento::shouldRegisterFixedAddressChecker(const LangOptions &LO) {
69 return true;
70}