]> granicus.if.org Git - clang/commitdiff
[analyzer] Propagate taint through MemRegions.
authorAnna Zaks <ganna@apple.com>
Wed, 7 Dec 2011 01:09:52 +0000 (01:09 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 7 Dec 2011 01:09:52 +0000 (01:09 +0000)
SVal can be not only a symbol, but a MemRegion. Add support for such
cases.

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

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
lib/StaticAnalyzer/Core/ProgramState.cpp
test/Analysis/taint-tester.c

index 8b646f42744a2b971f9b8df0d9ba6ed60310f643..242b49e75f50390451f0ce7298d7710b675532d2 100644 (file)
@@ -301,6 +301,7 @@ public:
   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;
+  bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
 
   //==---------------------------------------------------------------------==//
   // Accessing the Generic Data Map (GDM).
index 2f9a3929e8a8ebcb985aa781bcee51ffe5044db4..bad14c459bb8e3f673c5d1709a0ba51d704ff532 100644 (file)
@@ -664,18 +664,41 @@ const ProgramState* ProgramState::addTaint(SymbolRef Sym,
 }
 
 bool ProgramState::isTainted(const Stmt *S, TaintTagType Kind) const {
+  SVal val = getSVal(S);
   return isTainted(getSVal(S), Kind);
 }
 
 bool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
-  return isTainted(V.getAsSymExpr(), Kind);
+  if (const SymExpr *Sym = V.getAsSymExpr())
+    return isTainted(Sym, Kind);
+  if (loc::MemRegionVal *RegVal = dyn_cast<loc::MemRegionVal>(&V))
+    return isTainted(RegVal->getRegion(), Kind);
+  return false;
+}
+
+bool ProgramState::isTainted(const MemRegion *Reg, TaintTagType K) const {
+  if (!Reg)
+    return false;
+
+  // Element region (array element) is tainted if either the base or the offset
+  // are tainted.
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg))
+    return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
+
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg))
+    return isTainted(SR->getSymbol(), K);
+
+  if (const SubRegion *ER = dyn_cast<SubRegion>(Reg))
+    return isTainted(ER->getSuperRegion(), K);
+
+  return false;
 }
 
 bool ProgramState::isTainted(const SymExpr* Sym, TaintTagType Kind) const {
   if (!Sym)
     return false;
   
-  // Travese all the symbols this symbol depends on to see if any are tainted.
+  // Traverse all the symbols this symbol depends on to see if any are tainted.
   bool Tainted = false;
   for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end();
        SI != SE; ++SI) {
index eb05f577d1b74739e1e4aad4dfca5c0091cdf31d..23b5744f8c842fa3ec2bfe7032328d979efc755f 100644 (file)
@@ -6,18 +6,29 @@ int getchar(void);
 #define BUFSIZE 10
 int Buffer[BUFSIZE];
 
-void bufferScanfAssignment(int x) {
+struct XYStruct {
+  int x;
+  float y;
+};
+
+void taintTracking(int x) {
   int n;
   int *addr = &Buffer[0];
   scanf("%d", &n);
-  addr += n;// expected-warning {{tainted}}
-  *addr = n; // expected-warning 2 {{tainted}}
+  addr += n;// expected-warning {{tainted}}
+  *addr = n; // expected-warning 3 {{tainted}}
 
   double tdiv = n / 30; // expected-warning 3 {{tainted}}
   char *loc_cast = (char *) n; // expected-warning {{tainted}}
   char tinc = tdiv++; // expected-warning {{tainted}}
   int tincdec = (char)tinc--; // expected-warning 2 {{tainted}}
-  int tprtarithmetic1 = *(addr+1);
 
+  // Tainted ptr arithmetic/array element address.
+  int tprtarithmetic1 = *(addr+1); // expected-warning 2 {{tainted}}
 
+  // Tainted struct address, casts.
+  struct XYStruct *xyPtr = 0;
+  scanf("%p", &xyPtr);
+  void *tXYStructPtr = xyPtr; // expected-warning 2 {{tainted}}
+  struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning 2 {{tainted}}
 }