clang  7.0.0svn
PointerSubChecker.cpp
Go to the documentation of this file.
1 //=== PointerSubChecker.cpp - Pointer subtraction 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 PointerSubChecker, a builtin checker that checks for
11 // pointer subtractions on two pointers pointing to different memory chunks.
12 // This check corresponds to CWE-469.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "ClangSACheckers.h"
21 
22 using namespace clang;
23 using namespace ento;
24 
25 namespace {
26 class PointerSubChecker
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 PointerSubChecker::checkPreStmt(const BinaryOperator *B,
36  CheckerContext &C) const {
37  // When doing pointer subtraction, if the two pointers do not point to the
38  // same memory chunk, emit a warning.
39  if (B->getOpcode() != BO_Sub)
40  return;
41 
42  SVal LV = C.getSVal(B->getLHS());
43  SVal RV = C.getSVal(B->getRHS());
44 
45  const MemRegion *LR = LV.getAsRegion();
46  const MemRegion *RR = RV.getAsRegion();
47 
48  if (!(LR && RR))
49  return;
50 
51  const MemRegion *BaseLR = LR->getBaseRegion();
52  const MemRegion *BaseRR = RR->getBaseRegion();
53 
54  if (BaseLR == BaseRR)
55  return;
56 
57  // Allow arithmetic on different symbolic regions.
58  if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR))
59  return;
60 
62  if (!BT)
63  BT.reset(
64  new BuiltinBug(this, "Pointer subtraction",
65  "Subtraction of two pointers that do not point to "
66  "the same memory chunk may cause incorrect result."));
67  auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
68  R->addRange(B->getSourceRange());
69  C.emitReport(std::move(R));
70  }
71 }
72 
73 void ento::registerPointerSubChecker(CheckerManager &mgr) {
74  mgr.registerChecker<PointerSubChecker>();
75 }
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
Opcode getOpcode() const
Definition: Expr.h:3039
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2998
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
const MemRegion * getAsRegion() const
Definition: SVals.cpp:140
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
Expr * getLHS() const
Definition: Expr.h:3042
Dataflow Directional Tag Classes.
const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1093
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:265
Expr * getRHS() const
Definition: Expr.h:3044