diff options
author | Anna Zaks <ganna@apple.com> | 2012-01-20 20:28:31 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-01-20 20:28:31 +0000 |
commit | 02019f7134e69e39e33c5a938183fd492410464c (patch) | |
tree | 62b0cab89408c205668ba6023243305c3faf9ea3 | |
parent | 86f960143c73f573919255c4465de71f85793c2e (diff) |
[analyzer] Add taint awareness to DivZeroChecker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148566 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp | 37 | ||||
-rw-r--r-- | test/Analysis/taint-generic.c | 11 |
2 files changed, 34 insertions, 14 deletions
diff --git a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 12fd6f4e76..b9ed384e0a 100644 --- a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -24,11 +24,31 @@ using namespace ento; namespace { class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > { mutable llvm::OwningPtr<BuiltinBug> BT; + void reportBug(const char *Msg, + const ProgramState *StateZero, + CheckerContext &C) const ; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; } // end anonymous namespace +void DivZeroChecker::reportBug(const char *Msg, + const ProgramState *StateZero, + CheckerContext &C) const { + if (ExplodedNode *N = C.generateSink(StateZero)) { + if (!BT) + BT.reset(new BuiltinBug(Msg)); + + BugReport *R = + new BugReport(*BT, BT->getDescription(), N); + + R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, + bugreporter::GetDenomExpr(N))); + + C.EmitReport(R); + } +} + void DivZeroChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { BinaryOperator::Opcode Op = B->getOpcode(); @@ -57,18 +77,13 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B, if (!stateNotZero) { assert(stateZero); - if (ExplodedNode *N = C.generateSink(stateZero)) { - if (!BT) - BT.reset(new BuiltinBug("Division by zero")); - - BugReport *R = - new BugReport(*BT, BT->getDescription(), N); - - R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, - bugreporter::GetDenomExpr(N))); + reportBug("Division by zero", stateZero, C); + return; + } - C.EmitReport(R); - } + bool TaintedD = C.getState()->isTainted(*DV); + if ((stateNotZero && stateZero && TaintedD)) { + reportBug("Division by a tainted value, possibly zero", stateZero, C); return; } diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c index 47bdb4e4c9..65e519e6ae 100644 --- a/test/Analysis/taint-generic.c +++ b/test/Analysis/taint-generic.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,experimental.security.ArrayBoundV2 -Wno-format-security -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,core,experimental.security.ArrayBoundV2 -Wno-format-security -verify %s int scanf(const char *restrict format, ...); int getchar(void); @@ -49,7 +49,7 @@ void bufferScanfArithmetic1(int x) { void bufferScanfArithmetic2(int x) { int n; scanf("%d", &n); - int m = 100 / (n + 3) * x; + int m = 100 - (n + 3) * x; Buffer[m] = 1; // expected-warning {{Out of bound memory access }} } @@ -64,7 +64,7 @@ void bufferScanfAssignment(int x) { } void scanfArg() { - int t; + int t = 0; scanf("%d", t); // expected-warning {{conversion specifies type 'int *' but the argument has type 'int'}} } @@ -171,3 +171,8 @@ void testSocket() { execl(buffer, "filename", 0); // no-warning } +int testDivByZero() { + int x; + scanf("%d", &x); + return 5/x; // expected-warning {{Division by a tainted value, possibly zero}} +} |