aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-12-05 18:58:01 +0000
committerAnna Zaks <ganna@apple.com>2011-12-05 18:58:01 +0000
commita50b7ab5af79690855af68f1fff7897291ba9535 (patch)
tree4899e1a2bd97369438bbedd24cb6419d28979b35
parent5845717880d1b0ecaf68c58093681eb18ace9237 (diff)
[analyzer] Add a debug checker to test for tainted data.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145827 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt1
-rw-r--r--lib/StaticAnalyzer/Checkers/Checkers.td4
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp62
-rw-r--r--test/Analysis/taint-tester.c15
4 files changed, 82 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 293e01ba4b..75f57ace88 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -52,6 +52,7 @@ add_clang_library(clangStaticAnalyzerCheckers
ReturnUndefChecker.cpp
StackAddrEscapeChecker.cpp
StreamChecker.cpp
+ TaintTesterChecker.cpp
UndefBranchChecker.cpp
UndefCapturedBlockVarChecker.cpp
UndefResultChecker.cpp
diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td
index 786bcb052a..2e763f6032 100644
--- a/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -392,5 +392,9 @@ def AnalyzerStatsChecker : Checker<"Stats">,
HelpText<"Emit warnings with analyzer statistics">,
DescFile<"AnalyzerStatsChecker.cpp">;
+def TaintTesterChecker : Checker<"TaintTest">,
+ HelpText<"Mark tainted symbols as such.">,
+ DescFile<"TaintTesterChecker.cpp">;
+
} // end "debug"
diff --git a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
new file mode 100644
index 0000000000..0819e86253
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
@@ -0,0 +1,62 @@
+//== TaintTesterChecker.cpp ----------------------------------- -*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker can be used for testing how taint data is propagated.
+//
+//===----------------------------------------------------------------------===//
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class TaintTesterChecker : public Checker< check::PostStmt<Expr> > {
+
+ mutable llvm::OwningPtr<BugType> BT;
+ void initBugType() const;
+
+ /// Given a pointer argument, get the symbol of the value it contains
+ /// (points to).
+ SymbolRef getPointedToSymbol(CheckerContext &C,
+ const Expr* Arg,
+ bool IssueWarning = true) const;
+
+public:
+ void checkPostStmt(const Expr *E, CheckerContext &C) const;
+};
+}
+
+inline void TaintTesterChecker::initBugType() const {
+ if (!BT)
+ BT.reset(new BugType("Tainted data", "General"));
+}
+
+void TaintTesterChecker::checkPostStmt(const Expr *E,
+ CheckerContext &C) const {
+ const ProgramState *State = C.getState();
+ if (!State)
+ return;
+
+ if (E && State->isTainted(E)) {
+ if (ExplodedNode *N = C.addTransition()) {
+ initBugType();
+ BugReport *report = new BugReport(*BT, "tainted",N);
+ report->addRange(E->getSourceRange());
+ C.EmitReport(report);
+ }
+ }
+}
+
+void ento::registerTaintTesterChecker(CheckerManager &mgr) {
+ mgr.registerChecker<TaintTesterChecker>();
+}
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
new file mode 100644
index 0000000000..54480beabc
--- /dev/null
+++ b/test/Analysis/taint-tester.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,debug.TaintTest -verify %s
+
+int scanf(const char *restrict format, ...);
+int getchar(void);
+
+#define BUFSIZE 10
+int Buffer[BUFSIZE];
+
+void bufferScanfAssignment(int x) {
+ int n;
+ int *addr = &Buffer[0];
+ scanf("%d", &n);
+ addr += n;// expected-warning {{tainted}}
+ *addr = n; // expected-warning {{tainted}}
+}