aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h40
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h27
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp50
4 files changed, 131 insertions, 0 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index edae06e68c..d70600f299 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -19,6 +19,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
@@ -288,6 +289,19 @@ public:
scanReachableSymbols(const MemRegion * const *beg,
const MemRegion * const *end) const;
+ /// Create a new state in which the statement is marked as tainted.
+ const ProgramState* addTaint(const Stmt *S,
+ TaintTagType Kind = TaintTagGeneric) const;
+
+ /// Create a new state in which the symbol is marked as tainted.
+ const ProgramState* addTaint(SymbolRef S,
+ TaintTagType Kind = TaintTagGeneric) const;
+
+ /// Check if the statement is tainted in the current state.
+ bool isTainted(const Stmt *S, TaintTagType Kind = TaintTagGeneric) const;
+ bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
+ bool isTainted(const SymExpr* Sym, TaintTagType Kind = TaintTagGeneric) const;
+
//==---------------------------------------------------------------------==//
// Accessing the Generic Data Map (GDM).
//==---------------------------------------------------------------------==//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
new file mode 100644
index 0000000000..4a5b31cb9b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -0,0 +1,40 @@
+//== TaintManager.h - Managing taint --------------------------- -*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides APIs for adding, removing, querying symbol taint.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TAINTMANAGER_H
+#define LLVM_CLANG_TAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
+
+namespace clang {
+namespace ento {
+
+/// The GDM component containing the tainted root symbols. We lazily infer the
+/// taint of the dependednt symbols. Currently, this is a map from a symbol to
+/// tag kind. TODO: Should support multiple tag kinds.
+struct TaintMap {};
+typedef llvm::ImmutableMap<SymbolRef, TaintTagType> TaintMapImpl;
+template<> struct ProgramStateTrait<TaintMap>
+ : public ProgramStatePartialTrait<TaintMapImpl> {
+ static void *GDMIndex() { static int index = 0; return &index; }
+};
+
+class TaintManager {
+
+ TaintManager() {}
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
new file mode 100644
index 0000000000..8ddc8b9d6f
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
@@ -0,0 +1,27 @@
+//== TaintTag.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a set of taint tags. Several tags are used to differentiate kinds
+// of taint.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TAINTTAG_H
+#define LLVM_CLANG_TAINTTAG_H
+
+namespace clang {
+namespace ento {
+
+/// The type of taint, which helps to differentiate between different types of
+/// taint.
+typedef unsigned TaintTagType;
+static const TaintTagType TaintTagGeneric = 0;
+
+}}
+
+#endif
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 73788cc42e..3ce3db7313 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -15,6 +15,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -623,3 +624,52 @@ bool ProgramState::scanReachableSymbols(const MemRegion * const *I,
}
return true;
}
+
+const ProgramState* ProgramState::addTaint(const Stmt *S,
+ TaintTagType Kind) const {
+ SymbolRef Sym = getSVal(S).getAsSymbol();
+ assert(Sym && "Cannot add taint to statements whose value is not a symbol");
+ return addTaint(Sym, Kind);
+}
+
+const ProgramState* ProgramState::addTaint(SymbolRef Sym,
+ TaintTagType Kind) const {
+ const ProgramState *NewState = set<TaintMap>(Sym, Kind);
+ assert(NewState);
+ return NewState;
+}
+
+bool ProgramState::isTainted(const Stmt *S, TaintTagType Kind) const {
+ return isTainted(getSVal(S), Kind);
+}
+
+bool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
+ const SymExpr* Sym = V.getAsSymbol();
+ if (!Sym)
+ Sym = V.getAsSymbolicExpression();
+ if (!Sym)
+ return false;
+ return isTainted(Sym, Kind);
+}
+
+bool ProgramState::isTainted(const SymExpr* Sym, TaintTagType Kind) const {
+ // Check taint on derived symbols.
+ if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(Sym))
+ return isTainted(SD->getParentSymbol(), Kind);
+
+ if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(Sym))
+ return isTainted(SIE->getLHS(), Kind);
+
+ if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym))
+ return (isTainted(SSE->getLHS(), Kind) || isTainted(SSE->getRHS(), Kind));
+
+ // Check taint on the current symbol.
+ if (const SymbolData *SymR = dyn_cast<SymbolData>(Sym)) {
+ const TaintTagType *Tag = get<TaintMap>(SymR);
+ return (Tag && *Tag == Kind);
+ }
+
+ // TODO: Remove llvm unreachable.
+ llvm_unreachable("We do not know show to check taint on this symbol.");
+ return false;
+}