private static void RunDependencyAnalysis(Program program, DependencyVisitor visitor, string kind, bool printTaint = false) { visitor.Visit(program); var deps = visitor.ProcDependencies; if (printTaint && changeLog.Count > 0) { // extract taint from dependencies and print var taintedBlocks = Utils.ExtractTaint(visitor); program.Implementations.Iter(impl => PopulateTaintLog(impl, taintedBlocks)); } if (Prune) { Utils.DependenciesUtils.PruneProcDependencies(program, deps); } program.Implementations.Iter(impl => PopulateDependencyLog(impl, deps[impl.Proc], kind)); //if (changeLog.Count > 0) // remove the special taint var //deps.Values.Iter(dep => dep.Values.Iter(d => { d.Remove(Utils.VariableUtils.BottomUpTaintVar); d.Remove(Utils.VariableUtils.TopDownTaintVar); })); if (PrintStats) { program.Implementations.Iter(impl => deps[impl.Proc].Iter(dep => PopulateStatsLog(kind, impl, dep.Key, dep.Value))); } }
internal void RunFixedPoint(DependencyVisitor visitor, Implementation node) { Dictionary <Absy, int> visitCount = new Dictionary <Absy, int>(); //VarSet.allSets.Clear(); Absy entry = Utils.GetImplEntry(node); workList.Add(entry); cmdBlocks[entry] = node.Blocks[0]; while (workList.Count > 0) { var cmd = workList[0]; workList.RemoveAt(0); //#if DBG if (!visitCount.Keys.Contains(cmd)) { visitCount[cmd] = 0; } ++visitCount[cmd]; //Console.WriteLine("Visiting (" + visitCount[cmd] + ") L" + cmd.Line + ": " + cmd); //#endif //if (cmd is ReturnCmd || visitCount[cmd] <= 1) //if (visitCount[cmd] < 5) visitor.Visit(cmd); //else //{ // stateSpace[cmd].SetTop(node); // if (!(cmd is ReturnCmd)) // Propagate(cmd); //} //else //SimpleTransform(cmd); //Console.WriteLine("State size is {0} (over {1} program locations)", stateSpace.Sum(s => (s.Value as Dependencies).Sum(vd => vd.Value.Count)), stateSpace.Keys.Count); #if DBG if (stateSpace.ContainsKey(cmd)) { Console.WriteLine(stateSpace[cmd].ToString()); } Console.ReadLine(); #endif } //HashSet<Dependencies> deps = new HashSet<Dependencies>(); //int redundant = 0, overall = 0; //stateSpace.Values.Iter(d => { var dd = d as Dependencies; if (!deps.Add(dd)) redundant++; }); //Console.WriteLine("{0} redundant dependiences in {1} locations", redundant, stateSpace.Keys.Count); //HashSet<VarSet> sets = new HashSet<VarSet>(); //stateSpace.Values.Iter(d => (d as Dependencies).Values.Iter(s => { overall++; if (sets.Any(ss => ss.SetEquals(s))) redundant++; sets.Add(s); })); //Console.WriteLine("{0} redundant var sets out of {1}, size of allsets = {2}", redundant, overall, VarSet.allSets.Count); }
private static void RunRefinedDepAnalysis(string filename, Program program, Dictionary <Procedure, Dependencies> lowerBound, Dictionary <Procedure, Dependencies> upperBound) { //turn asserts/requires/ensures to free counterparts (assume/free req/free ens) //removing it from dependncy main path, as it screws up later analysis that just needs the dependency Utils.StripContracts(program); // remove the special taint var lowerBound.Values.Iter(dep => dep.Values.Iter(d => { d.Remove(Utils.VariableUtils.BottomUpTaintVar); d.Remove(Utils.VariableUtils.TopDownTaintVar); })); upperBound.Values.Iter(dep => dep.Values.Iter(d => { d.Remove(Utils.VariableUtils.BottomUpTaintVar); d.Remove(Utils.VariableUtils.TopDownTaintVar); })); var refineDepsWL = new RefineDependencyWL(filename, program, lowerBound, upperBound, StackBound); Utils.LogStopwatch(sw, "Initial analysis", Analysis.Timeout); refineDepsWL.RunFixedPoint(sw); Utils.LogStopwatch(sw, "After refined dependency analysis", Analysis.Timeout); // print refineDepsWL.currDependencies.Iter(pd => PopulateDependencyLog(program.Implementations.SingleOrDefault(i => i.Proc.Name == pd.Key.Name), pd.Value, Utils.StatisticsHelper.Refined)); // stats refineDepsWL.currDependencies.Iter(pd => { var impl = program.Implementations.SingleOrDefault(i => i.Proc.Name == pd.Key.Name); if (impl != null) { pd.Value.Iter(dep => PopulateStatsLog(Utils.StatisticsHelper.Refined, impl, dep.Key, dep.Value)); } }); //taint if (changeLog.Count > 0) { DependencyVisitor visitor = new DependencyVisitor(filename, program, changeLog, Timeout); visitor.ProcDependencies = refineDepsWL.currDependencies; visitor.Visit(program); // reminder: taint is essentially a dependecy analysis // extract taint from dependencies and print program.Implementations.Iter(impl => PopulateTaintLog(impl, Utils.ExtractTaint(visitor))); } }
private static void RunReadSetAnalysis(Program program, ProcReadSetVisitor rsVisitor, DependencyVisitor depVisitor = null) { rsVisitor.Visit(program); // prune if (Prune) { rsVisitor.ProcReadSet.Keys.Iter(p => Utils.VariableUtils.PruneLocals(program.Implementations.SingleOrDefault(i => i.Proc.Name == p.Name), rsVisitor.ProcReadSet[p])); } // create a dependency set \foreach r \in ReadSet: r <- ReadSet Dictionary <Procedure, Dependencies> rsProcDeps = new Dictionary <Procedure, Dependencies>(); rsVisitor.ProcReadSet.Keys.Iter(p => { rsProcDeps[p] = new Dependencies(); rsVisitor.ProcReadSet[p].Iter(r => rsProcDeps[p][r] = rsVisitor.ProcReadSet[p]); }); // print program.Implementations.Iter(impl => PopulateDependencyLog(impl, rsProcDeps[impl.Proc], Utils.StatisticsHelper.ReadSet)); // taint if (changeLog.Count > 0) { depVisitor.ProcDependencies = rsProcDeps; depVisitor.Visit(program); // reminder: taint is essentially a dependecy analysis // extract taint from dependencies and print program.Implementations.Iter(impl => PopulateTaintLog(impl, Utils.ExtractTaint(depVisitor))); // remove the special taint var rsProcDeps.Values.Iter(dep => dep.Values.Iter(d => { d.Remove(Utils.VariableUtils.BottomUpTaintVar); d.Remove(Utils.VariableUtils.TopDownTaintVar); })); } // stats if (PrintStats) { rsVisitor.ProcReadSet.Iter(prs => { var proc = prs.Key; var readSet = prs.Value; var impl = program.Implementations.SingleOrDefault(i => i.Proc.Name == proc.Name); if (impl != null) // conservatively each output\global is dependent on all of the readset { readSet.Where(v => v is GlobalVariable || impl.OutParams.Contains(v) || /* just to be safe: */ proc.OutParams.Contains(v)).Iter(v => PopulateStatsLog(Utils.StatisticsHelper.ReadSet, impl, v, readSet)); } }); } }
private static void RunAnalysis(string filename, Program program) { var dataDepVisitor = new DependencyVisitor(filename, program, changeLog, Timeout, Prune, true); var dataDeps = dataDepVisitor.ProcDependencies; if (Refine || BothDependencies || DataOnly) { RunDependencyAnalysis(program, dataDepVisitor, Utils.StatisticsHelper.DataOnly, DataOnly); if (DataOnly) { return; } } dataDepVisitor.worklist.stateSpace.Clear(); // helping the garbage collector GC.Collect(); var allDepVisitor = new DependencyVisitor(filename, program, changeLog, Timeout, Prune, DataOnly); var allDeps = allDepVisitor.ProcDependencies; if (Refine || !ReadSet) { RunDependencyAnalysis(program, allDepVisitor, Utils.StatisticsHelper.DataAndControl, !ReadSet); // !ReadSet in the case we want to compute taint using the read set as the baseline dependency } //// test SB deps //Random rnd = new Random(); //foreach (var impl in program.Implementations) //{ // Console.WriteLine("Deps[" + impl + "] = " + allDeps[impl.Proc]); // Console.WriteLine("Superblock = " + Utils.DependenciesUtils.SuperBlockDependencies(impl.Blocks, allDepVisitor.worklist.stateSpace[impl.Blocks.Last().TransferCmd], allDeps)); // int start = rnd.Next(0, impl.Blocks.Count); // int num = rnd.Next(1, impl.Blocks.Count - start); // var superBlock = impl.Blocks.GetRange(start, num); // var exitBlock = superBlock.Last(); // if (!allDepVisitor.worklist.stateSpace.ContainsKey(exitBlock.TransferCmd)) // { // Console.WriteLine("Block " + impl.Blocks[start + num] + " not in statspace"); // Debug.Assert(false); // } // var deps = Utils.DependenciesUtils.SuperBlockDependencies(superBlock, allDepVisitor.worklist.stateSpace[exitBlock.TransferCmd], allDeps); // Console.Write("Deps for ["); // impl.Blocks.GetRange(start, num).Iter(b => Console.Write(b + ",")); // Console.Write("]:"); // Console.WriteLine(deps); //} allDepVisitor.worklist.stateSpace.Clear(); // helping the garbage collector GC.Collect(); #region Control+Data dependencies must contain the Data dependencies Debug.Assert(dataDeps.All(pd => { var proc = pd.Key; var ddeps = pd.Value; var adeps = allDeps[proc]; return(ddeps.Keys.All(v => { if (!adeps.Keys.Contains(v)) { Console.WriteLine("{2}: {0} not contained in {1}", v, adeps.ToString(), proc); return false; } if (!adeps[v].IsSupersetOf(ddeps[v])) { Console.WriteLine("{3}: {0} not superset of {1} for {2}", adeps.ToString(), ddeps.ToString(), v, proc); return false; } return true; })); })); #endregion //output dependency in a bpl file if (AnnotateDependencies) { Utils.DependenciesUtils.PruneProcDependencies(program, allDeps); //for now we prune it (new DependencyWriter(program, allDeps, allDepVisitor.procEntryTDTaint, allDepVisitor.procExitTDTaint)).Visit(program); var depFileName = filename + "_w_dep.bpl"; Utils.PrintProgram(program, depFileName); Console.WriteLine("Adding dependencies to program to {0}", depFileName); return; } ProcReadSetVisitor rsVisitor = new ProcReadSetVisitor(); if (ReadSet) { RunReadSetAnalysis(program, rsVisitor, new DependencyVisitor(filename, program, changeLog, Timeout, Prune, DataOnly)); #region ReadSet must contain the Control+Data dependencies Debug.Assert(rsVisitor.ProcReadSet.All(prs => { var proc = prs.Key; var readSet = prs.Value; if (!allDeps.ContainsKey(proc)) { return(true); } var deps = allDeps[proc]; return(deps.Keys.All(v => { if (!(readSet.Contains(v) && readSet.IsSupersetOf(deps[v]))) { Console.WriteLine("Failed for " + v + " in proc " + proc); Console.WriteLine("RS:"); readSet.Iter(r => Console.WriteLine(" " + r)); Console.WriteLine("Deps[" + v + "]:"); deps[v].Iter(r => Console.WriteLine(" " + r)); return false; } return true; })); })); #endregion } if (Refine) { RunRefinedDepAnalysis(filename, program, dataDeps, allDeps); } // TODO: create tainted blocks and block dependencies if (AbstractNonTainted) { throw new NotImplementedException("AbstractNonTainted is not tested currently"); Utils.DependenciesUtils.PruneProcDependencies(program, allDeps); //for now we prune it var antc = new AbstractNonTaintProgram(program, allDeps, null, null); antc.AbstractNonTaintedImplementations(); var absFilename = filename + ".taintAbstract.bpl"; Utils.PrintProgram(program, absFilename); Console.WriteLine("Printing non-taint abstracted program to {0}", absFilename); } //Refined statement taint if (RefinedStmtTaintAnalysis) { //TODO: pass the modified set of methods (new RefinedStmtTaintInstrumentation(program, new HashSet <Implementation>())).Instrument(); var outFile = filename.Replace(".bpl", "") + "_stmtTaintInstr.bpl"; Utils.PrintProgram(program, outFile); Console.WriteLine("Printing stmt taint instrumented program to {0}", outFile); } }