diff options
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 415d3ecc39b5..45768b2cdf76 100644 --- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -46,8 +46,18 @@ struct ChecksFilter { DefaultBool check_vfork; DefaultBool check_FloatLoopCounter; DefaultBool check_UncheckedReturn; + + CheckName checkName_gets; + CheckName checkName_getpw; + CheckName checkName_mktemp; + CheckName checkName_mkstemp; + CheckName checkName_strcpy; + CheckName checkName_rand; + CheckName checkName_vfork; + CheckName checkName_FloatLoopCounter; + CheckName checkName_UncheckedReturn; }; - + class WalkAST : public StmtVisitor<WalkAST> { BugReporter &BR; AnalysisDeclContext* AC; @@ -139,7 +149,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { .Case("rand_r", &WalkAST::checkCall_rand) .Case("random", &WalkAST::checkCall_random) .Case("vfork", &WalkAST::checkCall_vfork) - .Default(NULL); + .Default(nullptr); // If the callee isn't defined, it is not of security concern. // Check and evaluate the call. @@ -179,7 +189,7 @@ getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) { if (const BinaryOperator *B = dyn_cast<BinaryOperator>(expr)) { if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() || B->getOpcode() == BO_Comma)) - return NULL; + return nullptr; if (const DeclRefExpr *lhs = getIncrementedVar(B->getLHS(), x, y)) return lhs; @@ -187,19 +197,19 @@ getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) { if (const DeclRefExpr *rhs = getIncrementedVar(B->getRHS(), x, y)) return rhs; - return NULL; + return nullptr; } if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(expr)) { const NamedDecl *ND = DR->getDecl(); - return ND == x || ND == y ? DR : NULL; + return ND == x || ND == y ? DR : nullptr; } if (const UnaryOperator *U = dyn_cast<UnaryOperator>(expr)) return U->isIncrementDecrementOp() - ? getIncrementedVar(U->getSubExpr(), x, y) : NULL; + ? getIncrementedVar(U->getSubExpr(), x, y) : nullptr; - return NULL; + return nullptr; } /// CheckLoopConditionForFloat - This check looks for 'for' statements that @@ -243,14 +253,14 @@ void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) { dyn_cast<DeclRefExpr>(B->getRHS()->IgnoreParenLValueCasts()); // Does at least one of the variables have a floating point type? - drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : NULL; - drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : NULL; + drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : nullptr; + drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : nullptr; if (!drLHS && !drRHS) return; - const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : NULL; - const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : NULL; + const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : nullptr; + const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : nullptr; if (!vdLHS && !vdRHS) return; @@ -281,7 +291,7 @@ void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) { PathDiagnosticLocation FSLoc = PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter, bugType, "Security", os.str(), FSLoc, ranges); } @@ -302,11 +312,11 @@ void WalkAST::checkCall_gets(const CallExpr *CE, const FunctionDecl *FD) { return; // Verify that the function takes a single argument. - if (FPT->getNumArgs() != 1) + if (FPT->getNumParams() != 1) return; // Is the argument a 'char*'? - const PointerType *PT = FPT->getArgType(0)->getAs<PointerType>(); + const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>(); if (!PT) return; @@ -316,7 +326,7 @@ void WalkAST::checkCall_gets(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets, "Potential buffer overflow in call to 'gets'", "Security", "Call to function 'gets' is extremely insecure as it can " @@ -338,15 +348,15 @@ void WalkAST::checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD) { return; // Verify that the function takes two arguments. - if (FPT->getNumArgs() != 2) + if (FPT->getNumParams() != 2) return; // Verify the first argument type is integer. - if (!FPT->getArgType(0)->isIntegralOrUnscopedEnumerationType()) + if (!FPT->getParamType(0)->isIntegralOrUnscopedEnumerationType()) return; // Verify the second argument type is char*. - const PointerType *PT = FPT->getArgType(1)->getAs<PointerType>(); + const PointerType *PT = FPT->getParamType(1)->getAs<PointerType>(); if (!PT) return; @@ -356,7 +366,7 @@ void WalkAST::checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw, "Potential buffer overflow in call to 'getpw'", "Security", "The getpw() function is dangerous as it may overflow the " @@ -382,11 +392,11 @@ void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) { return; // Verify that the function takes a single argument. - if (FPT->getNumArgs() != 1) + if (FPT->getNumParams() != 1) return; // Verify that the argument is Pointer Type. - const PointerType *PT = FPT->getArgType(0)->getAs<PointerType>(); + const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>(); if (!PT) return; @@ -394,10 +404,10 @@ void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) { if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy) return; - // Issue a waring. + // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp, "Potential insecure temporary file in call 'mktemp'", "Security", "Call to function 'mktemp' is insecure as it always " @@ -483,7 +493,7 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) { out << " used as a suffix"; } out << ')'; - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp, "Insecure temporary file creation", "Security", out.str(), CELoc, strArg->getSourceRange()); } @@ -504,7 +514,7 @@ void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy, "Potential insecure memory buffer bounds restriction in " "call 'strcpy'", "Security", @@ -531,7 +541,7 @@ void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy, "Potential insecure memory buffer bounds restriction in " "call 'strcat'", "Security", @@ -551,14 +561,14 @@ bool WalkAST::checkCall_strCommon(const CallExpr *CE, const FunctionDecl *FD) { return false; // Verify the function takes two arguments, three in the _chk version. - int numArgs = FPT->getNumArgs(); + int numArgs = FPT->getNumParams(); if (numArgs != 2 && numArgs != 3) return false; // Verify the type for both arguments. for (int i = 0; i < 2; i++) { // Verify that the arguments are pointers. - const PointerType *PT = FPT->getArgType(i)->getAs<PointerType>(); + const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>(); if (!PT) return false; @@ -584,17 +594,16 @@ void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) { if (!FTP) return; - if (FTP->getNumArgs() == 1) { + if (FTP->getNumParams() == 1) { // Is the argument an 'unsigned short *'? // (Actually any integer type is allowed.) - const PointerType *PT = FTP->getArgType(0)->getAs<PointerType>(); + const PointerType *PT = FTP->getParamType(0)->getAs<PointerType>(); if (!PT) return; if (! PT->getPointeeType()->isIntegralOrUnscopedEnumerationType()) return; - } - else if (FTP->getNumArgs() != 0) + } else if (FTP->getNumParams() != 0) return; // Issue a warning. @@ -610,8 +619,9 @@ void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) { PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(), - CELoc, CE->getCallee()->getSourceRange()); + BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(), + "Security", os2.str(), CELoc, + CE->getCallee()->getSourceRange()); } //===----------------------------------------------------------------------===// @@ -628,13 +638,13 @@ void WalkAST::checkCall_random(const CallExpr *CE, const FunctionDecl *FD) { return; // Verify that the function takes no argument. - if (FTP->getNumArgs() != 0) + if (FTP->getNumParams() != 0) return; // Issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, "'random' is not a secure random number generator", "Security", "The 'random' function produces a sequence of values that " @@ -654,7 +664,7 @@ void WalkAST::checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD) { // All calls to vfork() are insecure, issue a warning. PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), + BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork, "Potential insecure implementation-specific behavior in " "call 'vfork'", "Security", @@ -678,7 +688,7 @@ void WalkAST::checkUncheckedReturnValue(CallExpr *CE) { if (!FD) return; - if (II_setid[0] == NULL) { + if (II_setid[0] == nullptr) { static const char * const identifiers[num_setids] = { "setuid", "setgid", "seteuid", "setegid", "setreuid", "setregid" @@ -704,12 +714,12 @@ void WalkAST::checkUncheckedReturnValue(CallExpr *CE) { // Verify that the function takes one or two arguments (depending on // the function). - if (FTP->getNumArgs() != (identifierid < 4 ? 1 : 2)) + if (FTP->getNumParams() != (identifierid < 4 ? 1 : 2)) return; // The arguments must be integers. - for (unsigned i = 0; i < FTP->getNumArgs(); i++) - if (! FTP->getArgType(i)->isIntegralOrUnscopedEnumerationType()) + for (unsigned i = 0; i < FTP->getNumParams(); i++) + if (!FTP->getParamType(i)->isIntegralOrUnscopedEnumerationType()) return; // Issue a warning. @@ -725,8 +735,9 @@ void WalkAST::checkUncheckedReturnValue(CallExpr *CE) { PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(), - CELoc, CE->getCallee()->getSourceRange()); + BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(), + "Security", os2.str(), CELoc, + CE->getCallee()->getSourceRange()); } //===----------------------------------------------------------------------===// @@ -746,10 +757,13 @@ public: }; } -#define REGISTER_CHECKER(name) \ -void ento::register##name(CheckerManager &mgr) {\ - mgr.registerChecker<SecuritySyntaxChecker>()->filter.check_##name = true;\ -} +#define REGISTER_CHECKER(name) \ + void ento::register##name(CheckerManager &mgr) { \ + SecuritySyntaxChecker *checker = \ + mgr.registerChecker<SecuritySyntaxChecker>(); \ + checker->filter.check_##name = true; \ + checker->filter.checkName_##name = mgr.getCurrentCheckName(); \ + } REGISTER_CHECKER(gets) REGISTER_CHECKER(getpw) |