diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -205,10 +205,9 @@ // If we are under constrained and the index variables are tainted, report. if (state_exceedsUpperBound && state_withinUpperBound) { - SVal ByteOffset = rawOffset.getByteOffset(); - if (isTainted(state, ByteOffset)) { + if (isTainted(state, *upperboundToCheck)) { reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted, - std::make_unique(ByteOffset)); + std::make_unique(*upperboundToCheck)); return; } } else if (state_exceedsUpperBound) { diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c b/clang/test/Analysis/taint-diagnostic-visitor.c --- a/clang/test/Analysis/taint-diagnostic-visitor.c +++ b/clang/test/Analysis/taint-diagnostic-visitor.c @@ -1,9 +1,12 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core,unix.Malloc,alpha.security.ArrayBoundV2 -analyzer-output=text -verify %s // This file is for testing enhanced diagnostics produced by the GenericTaintChecker int scanf(const char *restrict format, ...); int system(const char *command); +typedef __typeof(sizeof(int)) size_t; +void *malloc(size_t size); +void free(void *ptr); void taintDiagnostic(void) { @@ -34,3 +37,18 @@ int vla[x]; // expected-warning {{Declared variable-length array (VLA) has tainted size}} // expected-note@-1 {{Declared variable-length array (VLA) has tainted size}} } + +void taintDiagnosticMalloc(int conj) { + int x; + scanf("%d", &x); + // expected-note@-1 2 {{Taint originated here}} Once for malloc(tainted), once for BoundsV2. + + int *p = (int *)malloc(x + conj); // Generic taint checker forbids tainted allocation. + // expected-warning@-1 {{Untrusted data is used to specify the buffer size}} + // expected-note@-2 {{Untrusted data is used to specify the buffer size}} + + p[1] = 1; // BoundsV2 checker can not prove that the access is safe. + // expected-warning@-1 {{Out of bound memory access (index is tainted)}} + // expected-note@-2 {{Out of bound memory access (index is tainted)}} + free(p); +}