clang  3.9.0
CastToStructChecker.cpp
Go to the documentation of this file.
1 //=== CastToStructChecker.cpp - Fixed address usage 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 CastToStructChecker, a builtin checker that checks for
11 // cast from non-struct pointer to struct pointer.
12 // This check corresponds to CWE-588.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "ClangSACheckers.h"
21 
22 using namespace clang;
23 using namespace ento;
24 
25 namespace {
26 class CastToStructChecker : public Checker< check::PreStmt<CastExpr> > {
27  mutable std::unique_ptr<BuiltinBug> BT;
28 
29 public:
30  void checkPreStmt(const CastExpr *CE, CheckerContext &C) const;
31 };
32 }
33 
34 void CastToStructChecker::checkPreStmt(const CastExpr *CE,
35  CheckerContext &C) const {
36  const Expr *E = CE->getSubExpr();
37  ASTContext &Ctx = C.getASTContext();
38  QualType OrigTy = Ctx.getCanonicalType(E->getType());
39  QualType ToTy = Ctx.getCanonicalType(CE->getType());
40 
41  const PointerType *OrigPTy = dyn_cast<PointerType>(OrigTy.getTypePtr());
42  const PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr());
43 
44  if (!ToPTy || !OrigPTy)
45  return;
46 
47  QualType OrigPointeeTy = OrigPTy->getPointeeType();
48  QualType ToPointeeTy = ToPTy->getPointeeType();
49 
50  if (!ToPointeeTy->isStructureOrClassType())
51  return;
52 
53  // We allow cast from void*.
54  if (OrigPointeeTy->isVoidType())
55  return;
56 
57  // Now the cast-to-type is struct pointer, the original type is not void*.
58  if (!OrigPointeeTy->isRecordType()) {
60  if (!BT)
61  BT.reset(
62  new BuiltinBug(this, "Cast from non-struct type to struct type",
63  "Casting a non-structure type to a structure type "
64  "and accessing a field can lead to memory access "
65  "errors or data corruption."));
66  auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
67  R->addRange(CE->getSourceRange());
68  C.emitReport(std::move(R));
69  }
70  }
71 }
72 
73 void ento::registerCastToStructChecker(CheckerManager &mgr) {
74  mgr.registerChecker<CastToStructChecker>();
75 }
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2179
A (possibly-)qualified type.
Definition: Type.h:598
bool isRecordType() const
Definition: Type.h:5539
bool isVoidType() const
Definition: Type.h:5680
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
bool isStructureOrClassType() const
Definition: Type.cpp:378
Expr * getSubExpr()
Definition: Expr.h:2684
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2632
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:415
Expr - This represents one expression.
Definition: Expr.h:105
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 Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5259
QualType getPointeeType() const
Definition: Type.h:2193
QualType getType() const
Definition: Expr.h:126
detail::InMemoryDirectory::const_iterator E
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:1966