aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp108
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)