public override Cmd VisitAssignCmd(AssignCmd node) { // gather state from all predecesors Block currBlock = worklist.cmdBlocks[node]; var predTaintSet = worklist.GatherPredecessorsState(node, currBlock); var taintSet = new TaintSet(predTaintSet); // the assignment has the potential to cleanse the taint taintSet.RemoveWhere(v => node.Lhss.Exists(l => Utils.VariableUtils.ExtractVars(l).Contains(v))); if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock) || // native taint InferDominatorTaint(currBlock)) // control taint { node.Lhss.Iter(lhs => taintSet.Add(Utils.VariableUtils.ExtractVars(lhs).First())); } else // data taint { for (int i = 0; i < node.Lhss.Count; ++i) { var lhs = Utils.VariableUtils.ExtractVars(node.Lhss[i]).First(); // TODO: stuff like: Mem_T.INT4[in_prio] := out_tempBoogie0 var rhsVars = Utils.VariableUtils.ExtractVars(node.Rhss[i]); if (rhsVars.Intersect(predTaintSet).Count() > 0) // if RHS is tainted { taintSet.Add(lhs); // so is LHS } } } if (worklist.Assign(node, taintSet)) { worklist.Propagate(node); } return(node); }
// returns ( (this |_| ias) > this ) i.e. whether ias had tainted variables that did not exist in this public bool JoinWith(IAbstractState ias) { TaintSet t = (TaintSet)ias; bool added = false; foreach (var v in t) { if (!Contains(v)) { this.Add(v); added = true; } } return(added); }
public void Prune(Implementation impl) { var proc = impl.Proc; var result = new TaintSet(); foreach (var v in this) { // leave only globals and outputs if (v is GlobalVariable || proc.OutParams.Contains(v)) { result.Add(v); } } Clear(); JoinWith(result); }
public override ReturnCmd VisitReturnCmd(ReturnCmd node) { Block currBlock = worklist.cmdBlocks[node]; var taintSet = worklist.GatherPredecessorsState(node, currBlock); if (worklist.Assign(node, taintSet)) { worklist.Propagate(node, nodeToImpl[node].Proc); } // set the taint result for the procedure var proc = nodeToImpl[node].Proc; if (!ProcTaint.ContainsKey(proc)) { ProcTaint[proc] = new TaintSet(); } ProcTaint[proc].JoinWith(worklist.stateSpace[node]); Utils.VariableUtils.FixFormals(nodeToImpl[node], ProcTaint[proc]); return(node); }
public override Cmd VisitHavocCmd(HavocCmd node) { // gather state from all predecesors Block currBlock = worklist.cmdBlocks[node]; var predTaintSet = worklist.GatherPredecessorsState(node, currBlock); var taintSet = new TaintSet(predTaintSet); // the assignment has the potential to cleanse the taint taintSet.RemoveWhere(v => node.Vars.Exists(o => o.Decl == v)); if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock) || // native taint InferDominatorTaint(currBlock)) // control taint { node.Vars.Iter(v => taintSet.Add(v.Decl)); } if (worklist.Assign(node, taintSet)) { worklist.Propagate(node); } return(node); }
public override Cmd VisitCallCmd(CallCmd node) { var callee = node.Proc; var deps = procDependencies[callee]; Debug.Assert(callee.Modifies.All(m => Utils.VariableUtils.ExtractVars(m).All(v => deps.Keys.Contains(v)))); // sanity check // gather state from all predecesors Block currBlock = worklist.cmdBlocks[node]; var predTaintSet = worklist.GatherPredecessorsState(node, currBlock); var taintSet = new TaintSet(predTaintSet); // the assignment has the potential to cleanse the taint taintSet.RemoveWhere(v => node.Outs.Exists(o => o.Decl == v)); taintSet.RemoveWhere(g => deps.ModSet().Contains(g)); if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock) || // native taint InferDominatorTaint(currBlock)) // control taint { node.Outs.Iter(lhs => taintSet.Add(lhs.Decl)); deps.ModSet().Where(v => v is GlobalVariable).Iter(g => taintSet.Add(g)); } else { if (!ProcTaint.ContainsKey(callee)) { // this will be continued once the callee gets analyzed if (worklist.Assign(node, new TaintSet())) { worklist.Propagate(node); } return(node); } //TODO: remove code dup here and review again! // data taint for outputs for (int i = 0; i < node.Outs.Count; ++i) { var lhs = node.Outs[i].Decl; var formalOut = node.Proc.OutParams[i]; if (ProcTaint[callee].Contains(formalOut) || // callee's output is natively tainted predTaintSet.FirstOrDefault(g => g is GlobalVariable && deps[formalOut].Contains(g)) != null) // callee's output depends on a tainted global { taintSet.Add(lhs); continue; } for (int j = 0; j < node.Ins.Count; ++j) { if (Utils.VariableUtils.ExtractVars(node.Ins[j]).Intersect(predTaintSet).Count() == 0) { continue; } var formalIn = node.Proc.InParams[j]; if (deps[formalOut].Contains(formalIn)) // callee's output depends on a tainted input { taintSet.Add(lhs); break; } } } // data taint for globals foreach (var g in deps.ModSet().Where(v => v is GlobalVariable)) { if (ProcTaint[callee].Contains(g) || // callee's global is natively tainted deps[g].Intersect(predTaintSet).Count() > 0) // callee's global depends on a tainted global { taintSet.Add(g); continue; } for (int j = 0; j < node.Ins.Count; ++j) { if (Utils.VariableUtils.ExtractVars(node.Ins[j]).Intersect(predTaintSet).Count() == 0) { continue; } var formalIn = node.Proc.InParams[j]; if (deps[g].Contains(formalIn)) // callee's global depends on a tainted input { taintSet.Add(g); break; } } } } Console.WriteLine("Taint after calling " + node + " = " + taintSet); if (worklist.Assign(node, taintSet)) { worklist.Propagate(node); } return(node); }
public TaintSet(TaintSet t) : base(t) { }