Skip to content

Commit 1d3d51a

Browse files
committed
[analyzer] Add a complexity bound on history tracking.
(Currently, this is only relevant for tainted data.) llvm-svn: 156050
1 parent 7124b4b commit 1d3d51a

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class SymExpr : public llvm::FoldingSetNode {
9494
return symbol_iterator(this);
9595
}
9696
static symbol_iterator symbol_end() { return symbol_iterator(); }
97+
98+
unsigned computeComplexity() const;
9799
};
98100

99101
typedef const SymExpr* SymbolRef;

clang/lib/StaticAnalyzer/Core/SValBuilder.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,19 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
204204

205205
const SymExpr *symLHS = LHS.getAsSymExpr();
206206
const SymExpr *symRHS = RHS.getAsSymExpr();
207+
// TODO: When the Max Complexity is reached, we should conjure a symbol
208+
// instead of generating an Unknown value and propagate the taint info to it.
209+
const unsigned MaxComp = 10000; // 100000 28X
207210

208-
if (symLHS && symRHS)
211+
if (symLHS && symRHS &&
212+
(symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp)
209213
return makeNonLoc(symLHS, Op, symRHS, ResultTy);
210214

211-
if (symLHS)
215+
if (symLHS && symLHS->computeComplexity() < MaxComp)
212216
if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS))
213217
return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
214218

215-
if (symRHS)
219+
if (symRHS && symRHS->computeComplexity() < MaxComp)
216220
if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS))
217221
return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
218222

clang/lib/StaticAnalyzer/Core/SymbolManager.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ void SymExpr::symbol_iterator::expand() {
164164
llvm_unreachable("unhandled expansion case");
165165
}
166166

167+
unsigned SymExpr::computeComplexity() const {
168+
unsigned R = 0;
169+
for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I)
170+
R++;
171+
return R;
172+
}
173+
167174
const SymbolRegionValue*
168175
SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
169176
llvm::FoldingSetNodeID profile;

clang/test/Analysis/taint-generic.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,23 @@ void testTaintedVLASize() {
183183
scanf("%d", &x);
184184
int vla[x]; // expected-warning{{Declared variable-length array (VLA) has tainted size}}
185185
}
186+
187+
// This computation used to take a very long time.
188+
#define longcmp(a,b,c) { \
189+
a -= c; a ^= c; c += b; b -= a; b ^= (a<<6) | (a >> (32-b)); a += c; c -= b; c ^= b; b += a; \
190+
a -= c; a ^= c; c += b; b -= a; b ^= a; a += c; c -= b; c ^= b; b += a; }
191+
192+
unsigned radar11369570_hanging(const unsigned char *arr, int l) {
193+
unsigned a, b, c;
194+
a = b = c = 0x9899e3 + l;
195+
while (l >= 6) {
196+
unsigned t;
197+
scanf("%d", &t);
198+
a += b;
199+
a ^= a;
200+
a += (arr[3] + ((unsigned) arr[2] << 8) + ((unsigned) arr[1] << 16) + ((unsigned) arr[0] << 24));
201+
longcmp(a, t, c);
202+
l -= 12;
203+
}
204+
return 5/a; // expected-warning {{Division by a tainted value, possibly zero}}
205+
}

0 commit comments

Comments
 (0)