diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp | 18 | ||||
-rw-r--r-- | test/Analysis/taint-generic.c | 14 |
2 files changed, 27 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp index 59733564fb..041e74e764 100644 --- a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -153,9 +153,17 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad, const ProgramState *state_exceedsUpperBound, *state_withinUpperBound; llvm::tie(state_exceedsUpperBound, state_withinUpperBound) = state->assume(*upperboundToCheck); + + // If we are under constrained and the index variables are tainted, report. + if (state_exceedsUpperBound && state_withinUpperBound) { + if (state->isTainted(rawOffset.getByteOffset())) + reportOOB(checkerContext, state_exceedsUpperBound, OOB_Excedes); + return; + } - // Are we constrained enough to definitely exceed the upper bound? - if (state_exceedsUpperBound && !state_withinUpperBound) { + // If we are constrained enough to definitely exceed the upper bound, report. + if (state_exceedsUpperBound) { + assert(!state_withinUpperBound); reportOOB(checkerContext, state_exceedsUpperBound, OOB_Excedes); return; } @@ -277,9 +285,9 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(const ProgramState *state, offset = addValue(state, getValue(offset, svalBuilder), scaleValue(state, - cast<NonLoc>(index), - astContext.getTypeSizeInChars(elemType), - svalBuilder), + cast<NonLoc>(index), + astContext.getTypeSizeInChars(elemType), + svalBuilder), svalBuilder); if (offset.isUnknownOrUndef()) diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c new file mode 100644 index 0000000000..9179a57dad --- /dev/null +++ b/test/Analysis/taint-generic.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,experimental.security.ArrayBoundV2 -verify %s + +int scanf(const char *restrict format, ...); +int getchar(void); + +#define BUFSIZE 10 + +int Buffer[BUFSIZE]; +void bufferFoo1(void) +{ + int n; + scanf("%d", &n); + Buffer[n] = 1; // expected-warning {{Out of bound memory access }} +} |