]> granicus.if.org Git - clang/commitdiff
[analyzer] Adding basic building blocks for taint propagation.
authorAnna Zaks <ganna@apple.com>
Wed, 16 Nov 2011 19:58:10 +0000 (19:58 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 16 Nov 2011 19:58:10 +0000 (19:58 +0000)
TaintTag.h will contain definitions of different taint kinds and their properties.
TaintManager will be responsible for implementing taint specific operations, storing taint.
ProgramState will provide API to add/remove taint.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144824 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h [new file with mode: 0644]
include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h [new file with mode: 0644]
lib/StaticAnalyzer/Core/ProgramState.cpp

index edae06e68c340e04808a173ba11bbfb0080654c2..d70600f299496f2e93a23336a069cd9789a47847 100644 (file)
@@ -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 (file)
index 0000000..4a5b31c
--- /dev/null
@@ -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 (file)
index 0000000..8ddc8b9
--- /dev/null
@@ -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
index 73788cc42efb3c3e226987b0d038d244679289e4..3ce3db7313bf8d9fb6e01b3b55b87580810863a9 100644 (file)
@@ -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;
+}