Skip to content

Commit 58131c3

Browse files
committed
Sparse IFDS solver
1 parent 2057f6a commit 58131c3

File tree

16 files changed

+813
-41
lines changed

16 files changed

+813
-41
lines changed

soot-infoflow-android/test/soot/jimple/infoflow/android/test/droidBench/GeneralJavaTest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,8 @@ public void runTestStaticInitialization1() throws IOException, XmlPullParserExce
135135

136136
@Test(timeout=300000)
137137
public void runTestStaticInitialization2() throws IOException, XmlPullParserException {
138-
int expected = 1;
139-
if (mode == TestResultMode.FLOWDROID_BACKWARDS || mode == TestResultMode.FLOWDROID_FORWARDS)
140-
expected = 1;
141138
InfoflowResults res = analyzeAPKFile("GeneralJava/StaticInitialization2.apk");
142-
Assert.assertEquals(expected, res.size());
139+
Assert.assertEquals(1, res.size());
143140
}
144141

145142
@Test(timeout=300000)

soot-infoflow/src/soot/jimple/infoflow/AbstractInfoflow.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
import soot.jimple.infoflow.solver.memory.DefaultMemoryManagerFactory;
102102
import soot.jimple.infoflow.solver.memory.IMemoryManager;
103103
import soot.jimple.infoflow.solver.memory.IMemoryManagerFactory;
104+
import soot.jimple.infoflow.solver.sparseSolver.SparseInfoflowSolver;
104105
import soot.jimple.infoflow.sourcesSinks.manager.DefaultSourceSinkManager;
105106
import soot.jimple.infoflow.sourcesSinks.manager.IOneSourceAtATimeManager;
106107
import soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager;
@@ -1233,6 +1234,10 @@ protected IInfoflowSolver createDataFlowSolver(InterruptableExecutor executor, A
12331234
case ContextFlowSensitive:
12341235
logger.info("Using context- and flow-sensitive solver");
12351236
return new soot.jimple.infoflow.solver.fastSolver.InfoflowSolver(problem, executor);
1237+
case SparseContextFlowSensitive:
1238+
InfoflowConfiguration.SparsePropagationStrategy opt = config.getSolverConfiguration().getSparsePropagationStrategy();
1239+
logger.info("Using sparse context-sensitive and flow-sensitive solver with sparsification " + opt.toString());
1240+
return new soot.jimple.infoflow.solver.sparseSolver.SparseInfoflowSolver(problem, executor, opt);
12361241
case FlowInsensitive:
12371242
logger.info("Using context-sensitive, but flow-insensitive solver");
12381243
return new soot.jimple.infoflow.solver.fastSolver.flowInsensitive.InfoflowSolver(problem, executor);

soot-infoflow/src/soot/jimple/infoflow/InfoflowConfiguration.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ public static enum DataFlowSolver {
125125
*/
126126
ContextFlowSensitive,
127127

128+
/**
129+
* Use a flow- and context-sensitive solver that propagates facts sparse
130+
*/
131+
SparseContextFlowSensitive,
132+
128133
/**
129134
* Use a context-sensitive, but flow-insensitive solver
130135
*/
@@ -136,6 +141,24 @@ public static enum DataFlowSolver {
136141
GarbageCollecting
137142
}
138143

144+
/**
145+
* Enumeration containing the options for the SparseContextFlowSensitive solver
146+
*/
147+
public static enum SparsePropagationStrategy {
148+
/**
149+
* Propagate facts dense (use to test that the solver modifications don't break something)
150+
*/
151+
Dense,
152+
/**
153+
* Propagate facts sparse only based on the local
154+
*/
155+
Simple,
156+
/**
157+
* Propagate facts sparse, taking the first field of an access path into account
158+
*/
159+
Precise
160+
}
161+
139162
public static enum DataFlowDirection {
140163
/**
141164
* Use the default forwards infoflow search
@@ -966,8 +989,8 @@ public boolean equals(Object obj) {
966989
*
967990
*/
968991
public static class SolverConfiguration {
969-
970992
private DataFlowSolver dataFlowSolver = DataFlowSolver.ContextFlowSensitive;
993+
private SparsePropagationStrategy sparsePropagationStrategy = SparsePropagationStrategy.Precise;
971994
private int maxJoinPointAbstractions = 10;
972995
private int maxCalleesPerCallSite = 75;
973996
private int maxAbstractionPathLength = 100;
@@ -979,6 +1002,7 @@ public static class SolverConfiguration {
9791002
*/
9801003
public void merge(SolverConfiguration solverConfig) {
9811004
this.dataFlowSolver = solverConfig.dataFlowSolver;
1005+
this.sparsePropagationStrategy = solverConfig.sparsePropagationStrategy;
9821006
this.maxJoinPointAbstractions = solverConfig.maxJoinPointAbstractions;
9831007
this.maxCalleesPerCallSite = solverConfig.maxCalleesPerCallSite;
9841008
this.maxAbstractionPathLength = solverConfig.maxAbstractionPathLength;
@@ -1002,6 +1026,24 @@ public void setDataFlowSolver(DataFlowSolver solver) {
10021026
this.dataFlowSolver = solver;
10031027
}
10041028

1029+
/**
1030+
* Gets the propagation strategy used in sparsePropagation
1031+
*
1032+
* @return The data flow solver to be used for the taint analysis
1033+
*/
1034+
public SparsePropagationStrategy getSparsePropagationStrategy() {
1035+
return this.sparsePropagationStrategy;
1036+
}
1037+
1038+
/**
1039+
* Sets the data flow solver to be used for the taint analysis
1040+
*
1041+
* @param sparsePropagationStrategy The propagation strategy used for sparsification
1042+
*/
1043+
public void setSparsePropagationStrategy(SparsePropagationStrategy sparsePropagationStrategy) {
1044+
this.sparsePropagationStrategy = sparsePropagationStrategy;
1045+
}
1046+
10051047
/**
10061048
* Gets the maximum number of abstractions that shall be recorded per join
10071049
* point. In other words, enabling this option disables the recording of

soot-infoflow/src/soot/jimple/infoflow/problems/AbstractInfoflowProblem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public boolean autoAddZero() {
139139
return false;
140140
}
141141

142-
protected boolean isCallSiteActivatingTaint(Unit callSite, Unit activationUnit) {
142+
public boolean isCallSiteActivatingTaint(Unit callSite, Unit activationUnit) {
143143
if (!manager.getConfig().getFlowSensitiveAliasing())
144144
return false;
145145

soot-infoflow/src/soot/jimple/infoflow/problems/BackwardsAliasProblem.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,6 @@ public Set<Abstraction> computeTargets(Abstraction d1, Abstraction source) {
621621
}
622622

623623
private Set<Abstraction> computeTargetsInternal(Abstraction d1, Abstraction source) {
624-
// If excluded or we do not anything about the callee,
625-
// we just pass the taint over the statement
626-
if (interproceduralCFG().getCalleesOfCallAt(callSite).isEmpty()) {
627-
return Collections.singleton(source);
628-
}
629-
630624
if (taintWrapper != null) {
631625
if (taintWrapper.isExclusive(callStmt, source)) {
632626
handOver(d1, callSite, source);
@@ -647,6 +641,12 @@ private Set<Abstraction> computeTargetsInternal(Abstraction d1, Abstraction sour
647641
}
648642
}
649643

644+
// If excluded or we do not anything about the callee,
645+
// we just pass the taint over the statement
646+
if (interproceduralCFG().getCalleesOfCallAt(callSite).isEmpty()) {
647+
return Collections.singleton(source);
648+
}
649+
650650
if (isExcluded(callee)) {
651651
return Collections.singleton(source);
652652
}

soot-infoflow/src/soot/jimple/infoflow/solver/fastSolver/IFDSSolver.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* are made available under the terms of the GNU Lesser Public License v2.1
66
* which accompanies this distribution, and is available at
77
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8-
*
8+
*
99
* Contributors:
1010
* Eric Bodden - initial API and implementation
1111
* Marc-Andre Laverdiere-Papineau - Fixed race condition
@@ -55,7 +55,7 @@
5555
/**
5656
* A solver for an {@link IFDSTabulationProblem}. This solver is not based on
5757
* the IDESolver implementation in Heros for performance reasons.
58-
*
58+
*
5959
* @param <N> The type of nodes in the interprocedural control-flow graph.
6060
* Typically {@link Unit}.
6161
* @param <D> The type of data-flow facts to be computed by the tabulation
@@ -134,9 +134,9 @@ public enum ScheduleTarget {
134134
protected boolean solverId;
135135

136136
private Set<IMemoryBoundedSolverStatusNotification> notificationListeners = new HashSet<>();
137-
private ISolverTerminationReason killFlag = null;
137+
protected ISolverTerminationReason killFlag = null;
138138

139-
private int maxCalleesPerCallSite = 75;
139+
protected int maxCalleesPerCallSite = 75;
140140
private int maxAbstractionPathLength = 100;
141141

142142
protected ISchedulingStrategy<N, D> schedulingStrategy = new DefaultSchedulingStrategy<N, D, I>(
@@ -154,14 +154,14 @@ public IFDSSolver(IFDSTabulationProblem<N, D, SootMethod, I> tabulationProblem)
154154
* Creates a solver for the given problem, constructing caches with the given
155155
* {@link CacheBuilder}. The solver must then be started by calling
156156
* {@link #solve()}.
157-
*
157+
*
158158
* @param tabulationProblem The tabulation problem to solve
159159
* @param flowFunctionCacheBuilder A valid {@link CacheBuilder} or
160160
* <code>null</code> if no caching is to be used
161161
* for flow functions.
162162
*/
163163
public IFDSSolver(IFDSTabulationProblem<N, D, SootMethod, I> tabulationProblem,
164-
@SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder) {
164+
@SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder) {
165165
if (logger.isDebugEnabled())
166166
flowFunctionCacheBuilder = flowFunctionCacheBuilder.recordStats();
167167
this.zeroValue = tabulationProblem.zeroValue();
@@ -265,7 +265,7 @@ private void runExecutorAndAwaitCompletion() {
265265
/**
266266
* Dispatch the processing of a given edge. It may be executed in a different
267267
* thread.
268-
*
268+
*
269269
* @param edge the edge to process
270270
* @param scheduleTarget
271271
*/
@@ -286,13 +286,13 @@ protected void scheduleEdgeProcessing(PathEdge<N, D> edge, ScheduleTarget schedu
286286

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

@@ -364,7 +364,7 @@ public void accept(SootMethod sCalledProcN) {
364364

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

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

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

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

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

445445
/**
446446
* Lines 21-32 of the algorithm.
447-
*
447+
*
448448
* Stores callee-side summaries. Also, at the side of the caller, propagates
449449
* intra-procedural flows to return sites using those newly computed summaries.
450-
*
450+
*
451451
* @param edge an edge whose target node resembles a method exits
452452
*/
453453
protected void processExit(PathEdge<N, D> edge) {
@@ -543,7 +543,7 @@ protected void processExit(PathEdge<N, D> edge) {
543543
/**
544544
* Computes the return flow function for the given set of caller-side
545545
* abstractions.
546-
*
546+
*
547547
* @param retFunction The return flow function to compute
548548
* @param d1 The abstraction at the beginning of the callee
549549
* @param d2 The abstraction at the exit node in the callee
@@ -552,17 +552,17 @@ protected void processExit(PathEdge<N, D> edge) {
552552
* @return The set of caller-side abstractions at the return site
553553
*/
554554
protected Set<D> computeReturnFlowFunction(FlowFunction<D> retFunction, D d1, D d2, N callSite,
555-
Collection<D> callerSideDs) {
555+
Collection<D> callerSideDs) {
556556
return retFunction.computeTargets(d2);
557557
}
558558

559559
/**
560560
* Lines 33-37 of the algorithm. Simply propagate normal, intra-procedural
561561
* flows.
562-
*
562+
*
563563
* @param edge
564564
*/
565-
private void processNormalFlow(PathEdge<N, D> edge) {
565+
protected void processNormalFlow(PathEdge<N, D> edge) {
566566
final D d1 = edge.factAtSource();
567567
final N n = edge.getTarget();
568568
final D d2 = edge.factAtTarget();
@@ -589,7 +589,7 @@ private void processNormalFlow(PathEdge<N, D> edge) {
589589
/**
590590
* Computes the normal flow function for the given set of start and end
591591
* abstractions.
592-
*
592+
*
593593
* @param flowFunction The normal flow function to compute
594594
* @param d1 The abstraction at the method's start node
595595
* @param d2 The abstraction at the current node
@@ -601,7 +601,7 @@ protected Set<D> computeNormalFlowFunction(FlowFunction<D> flowFunction, D d1, D
601601

602602
/**
603603
* Propagates the flow further down the exploded super graph.
604-
*
604+
*
605605
* @param sourceVal the source value of the propagated summary edge
606606
* @param target the target statement
607607
* @param targetVal the target value at the target statement
@@ -652,7 +652,7 @@ protected void propagate(D sourceVal, N target, D targetVal,
652652

653653
/**
654654
* Records a jump function. The source statement is implicit.
655-
*
655+
*
656656
* @see PathEdge
657657
*/
658658
public D addFunction(PathEdge<N, D> edge) {
@@ -786,7 +786,7 @@ public boolean equals(Object obj) {
786786
* Sets the maximum number of abstractions that shall be recorded per join
787787
* point. In other words, enabling this option disables the recording of
788788
* neighbors beyond the given count.
789-
*
789+
*
790790
* @param maxJoinPointAbstractions The maximum number of abstractions per join
791791
* point, or -1 to record an arbitrary number of
792792
* join point abstractions
@@ -797,7 +797,7 @@ public void setMaxJoinPointAbstractions(int maxJoinPointAbstractions) {
797797

798798
/**
799799
* Sets the memory manager that shall be used to manage the abstractions
800-
*
800+
*
801801
* @param memoryManager The memory manager that shall be used to manage the
802802
* abstractions
803803
*/
@@ -807,7 +807,7 @@ public void setMemoryManager(IMemoryManager<D, N> memoryManager) {
807807

808808
/**
809809
* Gets the memory manager used by this solver to reduce memory consumption
810-
*
810+
*
811811
* @return The memory manager registered with this solver
812812
*/
813813
public IMemoryManager<D, N> getMemoryManager() {

soot-infoflow/src/soot/jimple/infoflow/solver/fastSolver/InfoflowSolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
public class InfoflowSolver extends IFDSSolver<Unit, Abstraction, BiDiInterproceduralCFG<Unit, SootMethod>>
4242
implements IInfoflowSolver {
4343

44-
private IFollowReturnsPastSeedsHandler followReturnsPastSeedsHandler = null;
45-
private final AbstractInfoflowProblem problem;
44+
protected IFollowReturnsPastSeedsHandler followReturnsPastSeedsHandler = null;
45+
protected final AbstractInfoflowProblem problem;
4646

4747
public InfoflowSolver(AbstractInfoflowProblem problem, InterruptableExecutor executor) {
4848
super(problem);

0 commit comments

Comments
 (0)