diff --git a/soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/handler/SummaryTaintPropagationHandler.java b/soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/handler/SummaryTaintPropagationHandler.java index 4382f6391..f47f49e19 100644 --- a/soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/handler/SummaryTaintPropagationHandler.java +++ b/soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/handler/SummaryTaintPropagationHandler.java @@ -1,6 +1,5 @@ package soot.jimple.infoflow.methodSummary.handler; -import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -201,16 +200,18 @@ protected void addResult(Abstraction abs, Stmt stmt) { } @Override - public Set notifyFlowOut(Unit u, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit u, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { // Do not propagate through excluded methods SootMethod sm = manager.getICFG().getMethodOf(u); - if (excludedMethods.contains(sm)) - return Collections.emptySet(); - if (type == FlowFunctionType.ReturnFlowFunction && !followReturnsPastSeeds && sm == method) - return Collections.emptySet(); - - return outgoing; + if (excludedMethods.contains(sm)) { + return true; + } + if (type == FlowFunctionType.ReturnFlowFunction && !followReturnsPastSeeds && sm == method) { + outgoing.clear(); + return true; + } + return false; } public MultiMap getResult() { diff --git a/soot-infoflow/src/soot/jimple/infoflow/collections/strategies/widening/WideningTaintPropagationHandler.java b/soot-infoflow/src/soot/jimple/infoflow/collections/strategies/widening/WideningTaintPropagationHandler.java index a8e3f7af4..6629e7260 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/collections/strategies/widening/WideningTaintPropagationHandler.java +++ b/soot-infoflow/src/soot/jimple/infoflow/collections/strategies/widening/WideningTaintPropagationHandler.java @@ -1,6 +1,8 @@ package soot.jimple.infoflow.collections.strategies.widening; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Set; import java.util.function.Function; @@ -37,22 +39,23 @@ public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, } @Override - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { if (type != FlowFunctionType.CallToReturnFlowFunction) - return outgoing; + return false; - Set newOutgoing = outgoing; WideningStrategy wideningStrategy = getWideningStrategy(manager); - for (Abstraction abs : outgoing) { + List toAdd = new ArrayList<>(); + Iterator it = outgoing.iterator(); + while (it.hasNext()) { + Abstraction abs = it.next(); Abstraction widened = wideningStrategy.widen(incoming, abs, stmt); if (widened != abs) { - if (newOutgoing == outgoing) - newOutgoing = new HashSet<>(outgoing); - newOutgoing.add(widened); - newOutgoing.remove(abs); + toAdd.add(widened); + it.remove(); } } - return newOutgoing; + outgoing.addAll(toAdd); + return false; } } diff --git a/soot-infoflow/src/soot/jimple/infoflow/data/pathBuilders/ContextSensitivePathBuilder.java b/soot-infoflow/src/soot/jimple/infoflow/data/pathBuilders/ContextSensitivePathBuilder.java index 85e1152f9..64a57029c 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/data/pathBuilders/ContextSensitivePathBuilder.java +++ b/soot-infoflow/src/soot/jimple/infoflow/data/pathBuilders/ContextSensitivePathBuilder.java @@ -220,10 +220,10 @@ protected boolean checkForSource(Abstraction abs, SourceContextAndPath scap) { // A source should normally never have neighbors, but it can happen // with ICCTA - if (abs.getNeighbors() != null) { - // we ignore this issue for now, because the neighbor's source - // contexts seem to be equal to our own one - } + //if (abs.getNeighbors() != null) { + // we ignore this issue for now, because the neighbor's source + // contexts seem to be equal to our own one + //} // Register the source that we have found SourceContext sourceContext = abs.getSourceContext(); diff --git a/soot-infoflow/src/soot/jimple/infoflow/handlers/SequentialTaintPropagationHandler.java b/soot-infoflow/src/soot/jimple/infoflow/handlers/SequentialTaintPropagationHandler.java index 93be7b0a6..f64cbd586 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/handlers/SequentialTaintPropagationHandler.java +++ b/soot-infoflow/src/soot/jimple/infoflow/handlers/SequentialTaintPropagationHandler.java @@ -1,7 +1,6 @@ package soot.jimple.infoflow.handlers; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -63,18 +62,17 @@ public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, } @Override - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { if (innerHandlers.isEmpty()) - return outgoing; + return false; - Set resultSet = new HashSet<>(); + boolean killed = false; for (TaintPropagationHandler handler : innerHandlers) { - Set handlerResults = handler.notifyFlowOut(stmt, d1, incoming, outgoing, manager, type); - if (handlerResults != null && !handlerResults.isEmpty()) - resultSet.addAll(handlerResults); + if (handler.notifyFlowOut(stmt, d1, incoming, outgoing, manager, type)) + killed = true; } - return resultSet; + return killed; } /** diff --git a/soot-infoflow/src/soot/jimple/infoflow/handlers/TaintPropagationHandler.java b/soot-infoflow/src/soot/jimple/infoflow/handlers/TaintPropagationHandler.java index a80a4060a..a3e981fc3 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/handlers/TaintPropagationHandler.java +++ b/soot-infoflow/src/soot/jimple/infoflow/handlers/TaintPropagationHandler.java @@ -53,11 +53,9 @@ public enum FlowFunctionType { * The manager object that gives access to the data flow engine * @param type * The type of data flow edge being processed - * @return The new abstractions to be propagated on. If you do not want to - * change the normal propagation behavior, just return the value of the - * "taints" parameter as-is. + * @return Whether to kill the outgoing set */ - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type); } diff --git a/soot-infoflow/src/soot/jimple/infoflow/problems/AbstractInfoflowProblem.java b/soot-infoflow/src/soot/jimple/infoflow/problems/AbstractInfoflowProblem.java index 1f788928c..07b1fc387 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/problems/AbstractInfoflowProblem.java +++ b/soot-infoflow/src/soot/jimple/infoflow/problems/AbstractInfoflowProblem.java @@ -42,7 +42,6 @@ import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper; import soot.jimple.infoflow.util.SystemClassHandler; import soot.jimple.toolkits.ide.DefaultJimpleIFDSTabulationProblem; -import soot.jimple.toolkits.ide.icfg.BiDiInterproceduralCFG; /** * abstract super class which - concentrates functionality used by @@ -50,8 +49,7 @@ * pollute the naturally large InfofflowProblems * */ -public abstract class AbstractInfoflowProblem - extends DefaultJimpleIFDSTabulationProblem { +public abstract class AbstractInfoflowProblem extends DefaultJimpleIFDSTabulationProblem { protected final InfoflowManager manager; @@ -321,8 +319,11 @@ protected boolean isExceptionHandler(Unit u) { */ protected Set notifyOutFlowHandlers(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, FlowFunctionType functionType) { - if (taintPropagationHandler != null && outgoing != null && !outgoing.isEmpty()) - outgoing = taintPropagationHandler.notifyFlowOut(stmt, d1, incoming, outgoing, manager, functionType); + if (taintPropagationHandler != null && outgoing != null && !outgoing.isEmpty()) { + boolean res = taintPropagationHandler.notifyFlowOut(stmt, d1, incoming, outgoing, manager, functionType); + if (res) + return null; + } return outgoing; } diff --git a/soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java b/soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java index 801569a5a..3d22d11e5 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java +++ b/soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java @@ -171,8 +171,7 @@ public Collection> addResult( if (propagationPath != null) { stmtPath = new ArrayList<>(propagationPath.size()); apPath = new ArrayList<>(propagationPath.size()); - if (!manager.getConfig().getPathAgnosticResults()) - csPath = new ArrayList<>(propagationPath.size()); + csPath = new ArrayList<>(propagationPath.size()); for (Abstraction pathAbs : propagationPath) { if (pathAbs.getCurrentStmt() != null) { stmtPath.add(pathAbs.getCurrentStmt()); diff --git a/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowGenerator.java b/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowGenerator.java index b3c3779cc..aae6fdd0a 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowGenerator.java +++ b/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowGenerator.java @@ -5,7 +5,10 @@ import java.util.Set; import heros.solver.PathEdge; -import soot.*; +import soot.RefType; +import soot.Unit; +import soot.Value; +import soot.ValueBox; import soot.jimple.InstanceInvokeExpr; import soot.jimple.Stmt; import soot.jimple.infoflow.InfoflowManager; @@ -52,15 +55,15 @@ public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, } @Override - public Set notifyFlowOut(Unit unit, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit unit, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { // We only need to handle CallToReturn edges if (type != FlowFunctionType.CallToReturnFlowFunction) - return outgoing; + return false; // Check whether any use matches the incoming taint if (!isReadAt(unit, incoming.getAccessPath())) - return outgoing; + return false; ensureCondFlowManager(manager); @@ -82,15 +85,15 @@ public Set notifyFlowOut(Unit unit, Abstraction d1, Abstraction inc } // Check for usage contexts - for (AdditionalFlowInfoSpecification spec : manager.getUsageContextProvider().needsAdditionalInformation(stmt, outgoing)) + for (AdditionalFlowInfoSpecification spec : manager.getUsageContextProvider().needsAdditionalInformation(stmt, + outgoing)) additionalAbsSet.add(createAdditionalFlowAbstraction(spec, stmt, manager)); // Query the backward analysis for (Abstraction addAbs : additionalAbsSet) for (Unit pred : manager.getICFG().getPredsOf(unit)) manager.additionalManager.getMainSolver().processEdge(new PathEdge<>(d1, pred, addAbs)); - - return outgoing; + return false; } /** @@ -117,7 +120,8 @@ protected Abstraction createAdditionalFlowAbstraction(Abstraction baseTaint, Stm * @param manager Infoflow Manager * @return New abstraction */ - protected Abstraction createAdditionalFlowAbstraction(AdditionalFlowInfoSpecification spec, Stmt stmt, InfoflowManager manager) { + protected Abstraction createAdditionalFlowAbstraction(AdditionalFlowInfoSpecification spec, Stmt stmt, + InfoflowManager manager) { AccessPath ap = spec.toAccessPath(manager); ISourceSinkDefinition def = spec.getDefinition(); Abstraction newAbs = new Abstraction(Collections.singleton(def), ap, stmt, null, false, false); diff --git a/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowListener.java b/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowListener.java index f4e9b092c..33d08f26d 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowListener.java +++ b/soot-infoflow/src/soot/jimple/infoflow/river/SecondaryFlowListener.java @@ -7,8 +7,8 @@ import soot.jimple.infoflow.InfoflowManager; import soot.jimple.infoflow.data.Abstraction; import soot.jimple.infoflow.handlers.TaintPropagationHandler; -import soot.jimple.infoflow.problems.rules.PropagationRuleManager; import soot.jimple.infoflow.problems.rules.ITaintPropagationRule; +import soot.jimple.infoflow.problems.rules.PropagationRuleManager; /** * TaintPropagationHandler to record which statements secondary flows reach. @@ -37,7 +37,8 @@ private void ensureSourcePropagationRule(InfoflowManager manager) { } } - throw new IllegalStateException("Enabled additional flows but no IConditionalFlowSinkPropagationRule in place!"); + throw new IllegalStateException( + "Enabled additional flows but no IConditionalFlowSinkPropagationRule in place!"); } @Override @@ -59,10 +60,10 @@ public void notifyFlowIn(Unit unit, Abstraction incoming, InfoflowManager manage } @Override - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { // NO-OP - return outgoing; + return false; } } diff --git a/soot-infoflow/src/soot/jimple/infoflow/util/DebugFlowFunctionTaintPropagationHandler.java b/soot-infoflow/src/soot/jimple/infoflow/util/DebugFlowFunctionTaintPropagationHandler.java index b496b2d0f..bdc17f99a 100644 --- a/soot-infoflow/src/soot/jimple/infoflow/util/DebugFlowFunctionTaintPropagationHandler.java +++ b/soot-infoflow/src/soot/jimple/infoflow/util/DebugFlowFunctionTaintPropagationHandler.java @@ -55,10 +55,10 @@ public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, } @Override - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { if (this.filter != null && !this.filter.evaluate(manager.getICFG().getMethodOf(stmt).toString())) - return outgoing; + return false; String typeString = ""; switch (type) { @@ -88,7 +88,7 @@ public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction inc } else System.out.println(this.prefix + " " + typeString + " @ " + stmt + ":\n\tIn: " + incoming + "\n\tOut: " + outgoing + "\n"); + return false; - return outgoing; } } diff --git a/soot-infoflow/test/soot/jimple/infoflow/test/junit/HeapTests.java b/soot-infoflow/test/soot/jimple/infoflow/test/junit/HeapTests.java index 2787b8772..dbff82201 100644 --- a/soot-infoflow/test/soot/jimple/infoflow/test/junit/HeapTests.java +++ b/soot-infoflow/test/soot/jimple/infoflow/test/junit/HeapTests.java @@ -1309,8 +1309,8 @@ public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, } @Override - public Set notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { - return outgoing; + public boolean notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set outgoing, InfoflowManager manager, FlowFunctionType type) { + return false; } }); epoints.add("");