summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp48
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp20
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp11
3 files changed, 72 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 639dd72e9d1..9eb7edffe6d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -982,6 +982,9 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// void *memcpy(void *restrict dst, const void *restrict src, size_t n);
// The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0);
@@ -991,6 +994,9 @@ void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
// The return value is a pointer to the byte following the last written byte.
const Expr *Dest = CE->getArg(0);
@@ -1000,6 +1006,9 @@ void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// void *memmove(void *dst, const void *src, size_t n);
// The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0);
@@ -1009,12 +1018,18 @@ void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// void bcopy(const void *src, void *dst, size_t n);
evalCopyCommon(C, CE, C.getState(),
CE->getArg(2), CE->getArg(1), CE->getArg(0));
}
void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// int memcmp(const void *s1, const void *s2, size_t n);
CurrentFunctionDescription = "memory comparison function";
@@ -1089,12 +1104,18 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
void CStringChecker::evalstrLength(CheckerContext &C,
const CallExpr *CE) const {
+ if (CE->getNumArgs() < 1)
+ return;
+
// size_t strlen(const char *s);
evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
}
void CStringChecker::evalstrnLength(CheckerContext &C,
const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
// size_t strnlen(const char *s, size_t maxlen);
evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
}
@@ -1225,6 +1246,9 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
}
void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
// char *strcpy(char *restrict dst, const char *restrict src);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
@@ -1233,6 +1257,9 @@ void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
// char *strncpy(char *restrict dst, const char *restrict src, size_t n);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
@@ -1241,6 +1268,9 @@ void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
// char *stpcpy(char *restrict dst, const char *restrict src);
evalStrcpyCommon(C, CE,
/* returnEnd = */ true,
@@ -1249,6 +1279,9 @@ void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
//char *strcat(char *restrict s1, const char *restrict s2);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
@@ -1257,6 +1290,9 @@ void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
}
void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
//char *strncat(char *restrict s1, const char *restrict s2, size_t n);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
@@ -1568,23 +1604,35 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
}
void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
//int strcmp(const char *s1, const char *s2);
evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
}
void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
//int strncmp(const char *s1, const char *s2, size_t n);
evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
}
void CStringChecker::evalStrcasecmp(CheckerContext &C,
const CallExpr *CE) const {
+ if (CE->getNumArgs() < 2)
+ return;
+
//int strcasecmp(const char *s1, const char *s2);
evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
}
void CStringChecker::evalStrncasecmp(CheckerContext &C,
const CallExpr *CE) const {
+ if (CE->getNumArgs() < 3)
+ return;
+
//int strncasecmp(const char *s1, const char *s2, size_t n);
evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true);
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 4490ddbcc0c..135b81dda4a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -350,6 +350,8 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
// The arguments are pointer arguments. The data they are pointing at is
// tainted after the call.
+ if (CE->getNumArgs() < (ArgNum + 1))
+ return false;
const Expr* Arg = CE->getArg(ArgNum);
SymbolRef Sym = getPointedToSymbol(C, Arg);
if (Sym)
@@ -458,7 +460,8 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
break;
}
- assert(ArgNum < CE->getNumArgs());
+ if (CE->getNumArgs() < (ArgNum + 1))
+ return State;
if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(ArgNum), State, C)))
break;
}
@@ -525,9 +528,10 @@ ProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE,
// If argument 0(protocol domain) is network, the return value should get taint.
ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE,
- CheckerContext &C) const {
- assert(CE->getNumArgs() >= 3);
+ CheckerContext &C) const {
ProgramStateRef State = C.getState();
+ if (CE->getNumArgs() < 3)
+ return State;
SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
@@ -542,7 +546,9 @@ ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE,
ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
- assert(CE->getNumArgs() >= 2);
+ if (CE->getNumArgs() < 2)
+ return State;
+
SVal x = State->getSVal(CE->getArg(1), C.getLocationContext());
// All arguments except for the very first one should get taint.
for (unsigned int i = 1; i < CE->getNumArgs(); ++i) {
@@ -557,7 +563,7 @@ ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE,
}
ProgramStateRef GenericTaintChecker::postRetTaint(const CallExpr *CE,
- CheckerContext &C) const {
+ CheckerContext &C) const {
return C.getState()->addTaint(CE, C.getLocationContext());
}
@@ -677,7 +683,7 @@ bool GenericTaintChecker::checkSystemCall(const CallExpr *CE,
.Case("dlopen", 0)
.Default(UINT_MAX);
- if (ArgNum == UINT_MAX)
+ if (ArgNum == UINT_MAX || CE->getNumArgs() < (ArgNum + 1))
return false;
if (generateReportIfTainted(CE->getArg(ArgNum),
@@ -722,7 +728,7 @@ bool GenericTaintChecker::checkTaintedBufferSize(const CallExpr *CE,
ArgNum = 2;
}
- if (ArgNum != InvalidArgIndex &&
+ if (ArgNum != InvalidArgIndex && CE->getNumArgs() > ArgNum &&
generateReportIfTainted(CE->getArg(ArgNum), MsgTaintedBufferSize, C))
return true;
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 7456af23441..8bce88a7697 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -368,6 +368,8 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
ProgramStateRef State = C.getState();
if (FunI == II_malloc || FunI == II_valloc) {
+ if (CE->getNumArgs() < 1)
+ return;
State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
} else if (FunI == II_realloc) {
State = ReallocMem(C, CE, false);
@@ -490,6 +492,9 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
ProgramStateRef state,
unsigned Num,
bool Hold) const {
+ if (CE->getNumArgs() < (Num + 1))
+ return 0;
+
const Expr *ArgExpr = CE->getArg(Num);
SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
if (!isa<DefinedOrUnknownSVal>(ArgVal))
@@ -710,6 +715,9 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
const CallExpr *CE,
bool FreesOnFail) const {
+ if (CE->getNumArgs() < 2)
+ return 0;
+
ProgramStateRef state = C.getState();
const Expr *arg0Expr = CE->getArg(0);
const LocationContext *LCtx = C.getLocationContext();
@@ -795,6 +803,9 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
}
ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
+ if (CE->getNumArgs() < 2)
+ return 0;
+
ProgramStateRef state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
const LocationContext *LCtx = C.getLocationContext();
OpenPOWER on IntegriCloud