예제 #1
0
        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);
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 public TaintSet(TaintSet t) : base(t)
 {
 }