Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,8 @@ public void runTestStaticInitialization1() throws IOException, XmlPullParserExce

@Test(timeout=300000)
public void runTestStaticInitialization2() throws IOException, XmlPullParserException {
int expected = 1;
if (mode == TestResultMode.FLOWDROID_BACKWARDS || mode == TestResultMode.FLOWDROID_FORWARDS)
expected = 1;
InfoflowResults res = analyzeAPKFile("GeneralJava/StaticInitialization2.apk");
Assert.assertEquals(expected, res.size());
Assert.assertEquals(1, res.size());
}

@Test(timeout=300000)
Expand Down
5 changes: 5 additions & 0 deletions soot-infoflow/src/soot/jimple/infoflow/AbstractInfoflow.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
import soot.jimple.infoflow.solver.memory.DefaultMemoryManagerFactory;
import soot.jimple.infoflow.solver.memory.IMemoryManager;
import soot.jimple.infoflow.solver.memory.IMemoryManagerFactory;
import soot.jimple.infoflow.solver.sparseSolver.SparseInfoflowSolver;
import soot.jimple.infoflow.sourcesSinks.manager.DefaultSourceSinkManager;
import soot.jimple.infoflow.sourcesSinks.manager.IOneSourceAtATimeManager;
import soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager;
Expand Down Expand Up @@ -1233,6 +1234,10 @@ protected IInfoflowSolver createDataFlowSolver(InterruptableExecutor executor, A
case ContextFlowSensitive:
logger.info("Using context- and flow-sensitive solver");
return new soot.jimple.infoflow.solver.fastSolver.InfoflowSolver(problem, executor);
case SparseContextFlowSensitive:
InfoflowConfiguration.SparsePropagationStrategy opt = config.getSolverConfiguration().getSparsePropagationStrategy();
logger.info("Using sparse context-sensitive and flow-sensitive solver with sparsification " + opt.toString());
return new soot.jimple.infoflow.solver.sparseSolver.SparseInfoflowSolver(problem, executor, opt);
case FlowInsensitive:
logger.info("Using context-sensitive, but flow-insensitive solver");
return new soot.jimple.infoflow.solver.fastSolver.flowInsensitive.InfoflowSolver(problem, executor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ public static enum DataFlowSolver {
*/
ContextFlowSensitive,

/**
* Use a flow- and context-sensitive solver that propagates facts sparse
*/
SparseContextFlowSensitive,

/**
* Use a context-sensitive, but flow-insensitive solver
*/
Expand All @@ -136,6 +141,24 @@ public static enum DataFlowSolver {
GarbageCollecting
}

/**
* Enumeration containing the options for the SparseContextFlowSensitive solver
*/
public static enum SparsePropagationStrategy {
/**
* Propagate facts dense (use to test that the solver modifications don't break something)
*/
Dense,
/**
* Propagate facts sparse only based on the local
*/
Simple,
/**
* Propagate facts sparse, taking the first field of an access path into account
*/
Precise
}

public static enum DataFlowDirection {
/**
* Use the default forwards infoflow search
Expand Down Expand Up @@ -966,8 +989,8 @@ public boolean equals(Object obj) {
*
*/
public static class SolverConfiguration {

private DataFlowSolver dataFlowSolver = DataFlowSolver.ContextFlowSensitive;
private SparsePropagationStrategy sparsePropagationStrategy = SparsePropagationStrategy.Precise;
private int maxJoinPointAbstractions = 10;
private int maxCalleesPerCallSite = 75;
private int maxAbstractionPathLength = 100;
Expand All @@ -979,6 +1002,7 @@ public static class SolverConfiguration {
*/
public void merge(SolverConfiguration solverConfig) {
this.dataFlowSolver = solverConfig.dataFlowSolver;
this.sparsePropagationStrategy = solverConfig.sparsePropagationStrategy;
this.maxJoinPointAbstractions = solverConfig.maxJoinPointAbstractions;
this.maxCalleesPerCallSite = solverConfig.maxCalleesPerCallSite;
this.maxAbstractionPathLength = solverConfig.maxAbstractionPathLength;
Expand All @@ -1002,6 +1026,24 @@ public void setDataFlowSolver(DataFlowSolver solver) {
this.dataFlowSolver = solver;
}

/**
* Gets the propagation strategy used in sparsePropagation
*
* @return The data flow solver to be used for the taint analysis
*/
public SparsePropagationStrategy getSparsePropagationStrategy() {
return this.sparsePropagationStrategy;
}

/**
* Sets the data flow solver to be used for the taint analysis
*
* @param sparsePropagationStrategy The propagation strategy used for sparsification
*/
public void setSparsePropagationStrategy(SparsePropagationStrategy sparsePropagationStrategy) {
this.sparsePropagationStrategy = sparsePropagationStrategy;
}

/**
* Gets the maximum number of abstractions that shall be recorded per join
* point. In other words, enabling this option disables the recording of
Expand Down Expand Up @@ -1089,6 +1131,8 @@ public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dataFlowSolver == null) ? 0 : dataFlowSolver.hashCode());
if (dataFlowSolver == DataFlowSolver.SparseContextFlowSensitive)
result = prime * result + sparsePropagationStrategy.hashCode();
result = prime * result + maxCalleesPerCallSite;
result = prime * result + maxJoinPointAbstractions;
result = prime * result + maxAbstractionPathLength;
Expand All @@ -1106,6 +1150,9 @@ public boolean equals(Object obj) {
SolverConfiguration other = (SolverConfiguration) obj;
if (dataFlowSolver != other.dataFlowSolver)
return false;
if (dataFlowSolver == DataFlowSolver.SparseContextFlowSensitive)
if (sparsePropagationStrategy != other.sparsePropagationStrategy)
return false;
if (maxCalleesPerCallSite != other.maxCalleesPerCallSite)
return false;
if (maxJoinPointAbstractions != other.maxJoinPointAbstractions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public boolean autoAddZero() {
return false;
}

protected boolean isCallSiteActivatingTaint(Unit callSite, Unit activationUnit) {
public boolean isCallSiteActivatingTaint(Unit callSite, Unit activationUnit) {
if (!manager.getConfig().getFlowSensitiveAliasing())
return false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,6 @@ public Set<Abstraction> computeTargets(Abstraction d1, Abstraction source) {
}

private Set<Abstraction> computeTargetsInternal(Abstraction d1, Abstraction source) {
// If excluded or we do not anything about the callee,
// we just pass the taint over the statement
if (interproceduralCFG().getCalleesOfCallAt(callSite).isEmpty()) {
return Collections.singleton(source);
}

if (taintWrapper != null) {
if (taintWrapper.isExclusive(callStmt, source)) {
handOver(d1, callSite, source);
Expand All @@ -647,6 +641,12 @@ private Set<Abstraction> computeTargetsInternal(Abstraction d1, Abstraction sour
}
}

// If excluded or we do not anything about the callee,
// we just pass the taint over the statement
if (interproceduralCFG().getCalleesOfCallAt(callSite).isEmpty()) {
return Collections.singleton(source);
}

if (isExcluded(callee)) {
return Collections.singleton(source);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* Eric Bodden - initial API and implementation
* Marc-Andre Laverdiere-Papineau - Fixed race condition
Expand Down Expand Up @@ -55,7 +55,7 @@
/**
* A solver for an {@link IFDSTabulationProblem}. This solver is not based on
* the IDESolver implementation in Heros for performance reasons.
*
*
* @param <N> The type of nodes in the interprocedural control-flow graph.
* Typically {@link Unit}.
* @param <D> The type of data-flow facts to be computed by the tabulation
Expand Down Expand Up @@ -134,9 +134,9 @@ public enum ScheduleTarget {
protected boolean solverId;

private Set<IMemoryBoundedSolverStatusNotification> notificationListeners = new HashSet<>();
private ISolverTerminationReason killFlag = null;
protected ISolverTerminationReason killFlag = null;

private int maxCalleesPerCallSite = 75;
protected int maxCalleesPerCallSite = 75;
private int maxAbstractionPathLength = 100;

protected ISchedulingStrategy<N, D> schedulingStrategy = new DefaultSchedulingStrategy<N, D, I>(
Expand All @@ -154,14 +154,14 @@ public IFDSSolver(IFDSTabulationProblem<N, D, SootMethod, I> tabulationProblem)
* Creates a solver for the given problem, constructing caches with the given
* {@link CacheBuilder}. The solver must then be started by calling
* {@link #solve()}.
*
*
* @param tabulationProblem The tabulation problem to solve
* @param flowFunctionCacheBuilder A valid {@link CacheBuilder} or
* <code>null</code> if no caching is to be used
* for flow functions.
*/
public IFDSSolver(IFDSTabulationProblem<N, D, SootMethod, I> tabulationProblem,
@SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder) {
@SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder) {
if (logger.isDebugEnabled())
flowFunctionCacheBuilder = flowFunctionCacheBuilder.recordStats();
this.zeroValue = tabulationProblem.zeroValue();
Expand Down Expand Up @@ -265,7 +265,7 @@ private void runExecutorAndAwaitCompletion() {
/**
* Dispatch the processing of a given edge. It may be executed in a different
* thread.
*
*
* @param edge the edge to process
* @param scheduleTarget
*/
Expand All @@ -286,13 +286,13 @@ protected void scheduleEdgeProcessing(PathEdge<N, D> edge, ScheduleTarget schedu

/**
* Lines 13-20 of the algorithm; processing a call site in the caller's context.
*
*
* For each possible callee, registers incoming call edges. Also propagates
* call-to-return flows and summarized callee flows within the caller.
*
*
* @param edge an edge whose target node resembles a method call
*/
private void processCall(PathEdge<N, D> edge) {
protected void processCall(PathEdge<N, D> edge) {
final D d1 = edge.factAtSource();
final N n = edge.getTarget(); // a call node; line 14...

Expand Down Expand Up @@ -364,7 +364,7 @@ public void accept(SootMethod sCalledProcN) {

/**
* Callback to notify derived classes that an end summary has been applied
*
*
* @param n The call site where the end summary has been applied
* @param sCalledProc The callee
* @param d3 The callee-side incoming taint abstraction
Expand All @@ -373,7 +373,7 @@ protected void onEndSummaryApplied(N n, SootMethod sCalledProc, D d3) {
}

protected void applyEndSummaryOnCall(final D d1, final N n, final D d2, Collection<N> returnSiteNs,
SootMethod sCalledProcN, D d3) {
SootMethod sCalledProcN, D d3) {
// line 15.2
Set<EndSummary<N, D>> endSumm = endSummary(sCalledProcN, d3);

Expand Down Expand Up @@ -419,7 +419,7 @@ protected void applyEndSummaryOnCall(final D d1, final N n, final D d2, Collecti

/**
* Computes the call flow function for the given call-site abstraction
*
*
* @param callFlowFunction The call flow function to compute
* @param d1 The abstraction at the current method's start node.
* @param d2 The abstraction at the call site
Expand All @@ -431,7 +431,7 @@ protected Set<D> computeCallFlowFunction(FlowFunction<D> callFlowFunction, D d1,

/**
* Computes the call-to-return flow function for the given call-site abstraction
*
*
* @param callToReturnFlowFunction The call-to-return flow function to compute
* @param d1 The abstraction at the current method's start
* node.
Expand All @@ -444,10 +444,10 @@ protected Set<D> computeCallToReturnFlowFunction(FlowFunction<D> callToReturnFlo

/**
* Lines 21-32 of the algorithm.
*
*
* Stores callee-side summaries. Also, at the side of the caller, propagates
* intra-procedural flows to return sites using those newly computed summaries.
*
*
* @param edge an edge whose target node resembles a method exits
*/
protected void processExit(PathEdge<N, D> edge) {
Expand Down Expand Up @@ -543,7 +543,7 @@ protected void processExit(PathEdge<N, D> edge) {
/**
* Computes the return flow function for the given set of caller-side
* abstractions.
*
*
* @param retFunction The return flow function to compute
* @param d1 The abstraction at the beginning of the callee
* @param d2 The abstraction at the exit node in the callee
Expand All @@ -552,17 +552,17 @@ protected void processExit(PathEdge<N, D> edge) {
* @return The set of caller-side abstractions at the return site
*/
protected Set<D> computeReturnFlowFunction(FlowFunction<D> retFunction, D d1, D d2, N callSite,
Collection<D> callerSideDs) {
Collection<D> callerSideDs) {
return retFunction.computeTargets(d2);
}

/**
* Lines 33-37 of the algorithm. Simply propagate normal, intra-procedural
* flows.
*
*
* @param edge
*/
private void processNormalFlow(PathEdge<N, D> edge) {
protected void processNormalFlow(PathEdge<N, D> edge) {
final D d1 = edge.factAtSource();
final N n = edge.getTarget();
final D d2 = edge.factAtTarget();
Expand All @@ -589,7 +589,7 @@ private void processNormalFlow(PathEdge<N, D> edge) {
/**
* Computes the normal flow function for the given set of start and end
* abstractions.
*
*
* @param flowFunction The normal flow function to compute
* @param d1 The abstraction at the method's start node
* @param d2 The abstraction at the current node
Expand All @@ -601,7 +601,7 @@ protected Set<D> computeNormalFlowFunction(FlowFunction<D> flowFunction, D d1, D

/**
* Propagates the flow further down the exploded super graph.
*
*
* @param sourceVal the source value of the propagated summary edge
* @param target the target statement
* @param targetVal the target value at the target statement
Expand Down Expand Up @@ -652,7 +652,7 @@ protected void propagate(D sourceVal, N target, D targetVal,

/**
* Records a jump function. The source statement is implicit.
*
*
* @see PathEdge
*/
public D addFunction(PathEdge<N, D> edge) {
Expand Down Expand Up @@ -786,7 +786,7 @@ public boolean equals(Object obj) {
* Sets the maximum number of abstractions that shall be recorded per join
* point. In other words, enabling this option disables the recording of
* neighbors beyond the given count.
*
*
* @param maxJoinPointAbstractions The maximum number of abstractions per join
* point, or -1 to record an arbitrary number of
* join point abstractions
Expand All @@ -797,7 +797,7 @@ public void setMaxJoinPointAbstractions(int maxJoinPointAbstractions) {

/**
* Sets the memory manager that shall be used to manage the abstractions
*
*
* @param memoryManager The memory manager that shall be used to manage the
* abstractions
*/
Expand All @@ -807,7 +807,7 @@ public void setMemoryManager(IMemoryManager<D, N> memoryManager) {

/**
* Gets the memory manager used by this solver to reduce memory consumption
*
*
* @return The memory manager registered with this solver
*/
public IMemoryManager<D, N> getMemoryManager() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
public class InfoflowSolver extends IFDSSolver<Unit, Abstraction, BiDiInterproceduralCFG<Unit, SootMethod>>
implements IInfoflowSolver {

private IFollowReturnsPastSeedsHandler followReturnsPastSeedsHandler = null;
private final AbstractInfoflowProblem problem;
protected IFollowReturnsPastSeedsHandler followReturnsPastSeedsHandler = null;
protected final AbstractInfoflowProblem problem;

public InfoflowSolver(AbstractInfoflowProblem problem, InterruptableExecutor executor) {
super(problem);
Expand Down
Loading