CheckSecuritySyntaxOnly.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //==- CheckSecuritySyntaxOnly.cpp - Basic security checks --------*- 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 file defines a set of flow-insensitive security checks.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Analysis/PathSensitive/BugReporter.h"
  14. #include "clang/Analysis/LocalCheckers.h"
  15. #include "clang/AST/StmtVisitor.h"
  16. #include "llvm/Support/Compiler.h"
  17. using namespace clang;
  18. namespace {
  19. class VISIBILITY_HIDDEN WalkAST : public StmtVisitor<WalkAST> {
  20. BugReporter &BR;
  21. public:
  22. WalkAST(BugReporter &br) : BR(br) {}
  23. // Statement visitor methods.
  24. void VisitDoStmt(DoStmt *S);
  25. void VisitWhileStmt(WhileStmt *S);
  26. void VisitForStmt(ForStmt *S);
  27. void VisitChildren(Stmt *S);
  28. void VisitStmt(Stmt *S) { VisitChildren(S); }
  29. // Checker-specific methods.
  30. void CheckLoopConditionForFloat(Stmt *Loop, Expr *Condition);
  31. };
  32. } // end anonymous namespace
  33. //===----------------------------------------------------------------------===//
  34. // AST walking.
  35. //===----------------------------------------------------------------------===//
  36. void WalkAST::VisitChildren(Stmt *S) {
  37. for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
  38. if (Stmt *child = *I)
  39. Visit(child);
  40. }
  41. void WalkAST::VisitDoStmt(DoStmt *S) {
  42. CheckLoopConditionForFloat(S, S->getCond());
  43. VisitChildren(S);
  44. }
  45. void WalkAST::VisitForStmt(ForStmt *S) {
  46. if (Expr *Cond = S->getCond())
  47. CheckLoopConditionForFloat(S, Cond);
  48. VisitChildren(S);
  49. }
  50. void WalkAST::VisitWhileStmt(WhileStmt *S) {
  51. CheckLoopConditionForFloat(S, S->getCond());
  52. VisitChildren(S);
  53. }
  54. //===----------------------------------------------------------------------===//
  55. // Checking logic.
  56. //===----------------------------------------------------------------------===//
  57. static Expr* IsFloatCondition(Expr *Condition) {
  58. while (Condition) {
  59. Condition = Condition->IgnoreParenCasts();
  60. if (Condition->getType()->isFloatingType())
  61. return Condition;
  62. switch (Condition->getStmtClass()) {
  63. case Stmt::BinaryOperatorClass: {
  64. BinaryOperator *B = cast<BinaryOperator>(Condition);
  65. Expr *LHS = B->getLHS();
  66. if (LHS->getType()->isFloatingType())
  67. return LHS;
  68. Expr *RHS = B->getRHS();
  69. if (RHS->getType()->isFloatingType())
  70. return RHS;
  71. return NULL;
  72. }
  73. case Stmt::UnaryOperatorClass: {
  74. UnaryOperator *U = cast<UnaryOperator>(Condition);
  75. if (U->isArithmeticOp()) {
  76. Condition = U->getSubExpr();
  77. continue;
  78. }
  79. return NULL;
  80. }
  81. default:
  82. break;
  83. }
  84. }
  85. return NULL;
  86. }
  87. void WalkAST::CheckLoopConditionForFloat(Stmt *Loop, Expr *Condition) {
  88. if ((Condition = IsFloatCondition(Condition))) {
  89. const char *bugType = "Floating point value used in loop condition";
  90. SourceRange R = Condition->getSourceRange();
  91. BR.EmitBasicReport(bugType, "Security", bugType, Loop->getLocStart(),&R, 1);
  92. }
  93. }
  94. //===----------------------------------------------------------------------===//
  95. // Entry point for check.
  96. //===----------------------------------------------------------------------===//
  97. void clang::CheckSecuritySyntaxOnly(Decl *D, BugReporter &BR) {
  98. WalkAST walker(BR);
  99. walker.Visit(D->getBody());
  100. }