Skip to content

Commit 15d0de1

Browse files
committed
added some helper methods
1 parent eee57b2 commit 15d0de1

7 files changed

Lines changed: 173 additions & 115 deletions

File tree

soot-infoflow-android/src/soot/jimple/infoflow/android/source/AccessPathBasedSourceSinkManager.java

Lines changed: 113 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,16 @@
1010
import soot.SootMethod;
1111
import soot.Unit;
1212
import soot.Value;
13-
import soot.jimple.*;
13+
import soot.jimple.AssignStmt;
14+
import soot.jimple.Constant;
15+
import soot.jimple.DefinitionStmt;
16+
import soot.jimple.IdentityStmt;
17+
import soot.jimple.InstanceInvokeExpr;
18+
import soot.jimple.InvokeExpr;
19+
import soot.jimple.InvokeStmt;
20+
import soot.jimple.ParameterRef;
21+
import soot.jimple.ReturnStmt;
22+
import soot.jimple.Stmt;
1423
import soot.jimple.infoflow.InfoflowManager;
1524
import soot.jimple.infoflow.android.InfoflowAndroidConfiguration;
1625
import soot.jimple.infoflow.android.callbacks.AndroidCallbackDefinition;
@@ -70,7 +79,8 @@ public AccessPathBasedSourceSinkManager(Collection<? extends ISourceSinkDefiniti
7079
}
7180

7281
@Override
73-
protected Collection<Pair<AccessPath, ISourceSinkDefinition>> createSourceInfoPairs(Stmt sCallSite, InfoflowManager manager, Collection<ISourceSinkDefinition> defs) {
82+
protected Collection<Pair<AccessPath, ISourceSinkDefinition>> createSourceInfoPairs(Stmt sCallSite,
83+
InfoflowManager manager, Collection<ISourceSinkDefinition> defs) {
7484
HashSet<ISourceSinkDefinition> delegateToSuper = new HashSet<>();
7585
HashSet<Pair<AccessPath, ISourceSinkDefinition>> matchingDefs = new HashSet<>();
7686
for (ISourceSinkDefinition def : defs) {
@@ -97,61 +107,61 @@ protected Collection<Pair<AccessPath, ISourceSinkDefinition>> createSourceInfoPa
97107

98108
// For parameters in callback methods, we need special handling
99109
switch (methodDef.getCallType()) {
100-
case Callback:
101-
if (sCallSite instanceof IdentityStmt) {
102-
IdentityStmt is = (IdentityStmt) sCallSite;
103-
if (is.getRightOp() instanceof ParameterRef) {
104-
ParameterRef paramRef = (ParameterRef) is.getRightOp();
105-
if (methodDef.getParameters() != null
106-
&& methodDef.getParameters().length > paramRef.getIndex()) {
107-
for (AccessPathTuple apt : methodDef.getParameters()[paramRef.getIndex()]) {
108-
aps.add(apt.toAccessPath(is.getLeftOp(), manager, false));
109-
apTuples.add(apt);
110-
}
110+
case Callback:
111+
if (sCallSite instanceof IdentityStmt) {
112+
IdentityStmt is = (IdentityStmt) sCallSite;
113+
if (is.getRightOp() instanceof ParameterRef) {
114+
ParameterRef paramRef = (ParameterRef) is.getRightOp();
115+
if (methodDef.getParameters() != null
116+
&& methodDef.getParameters().length > paramRef.getIndex()) {
117+
for (AccessPathTuple apt : methodDef.getParameters()[paramRef.getIndex()]) {
118+
aps.add(apt.toAccessPath(is.getLeftOp(), manager, false));
119+
apTuples.add(apt);
111120
}
112121
}
113122
}
114-
break;
115-
case MethodCall:
116-
// Check whether we need to taint the base object
117-
if (sCallSite instanceof InvokeStmt && sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr
118-
&& methodDef.getBaseObjects() != null) {
119-
Value baseVal = ((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase();
120-
for (AccessPathTuple apt : methodDef.getBaseObjects()) {
121-
if (apt.getSourceSinkType().isSource()) {
122-
aps.add(apt.toAccessPath(baseVal, manager, true));
123-
apTuples.add(apt);
124-
}
123+
}
124+
break;
125+
case MethodCall:
126+
// Check whether we need to taint the base object
127+
if (sCallSite instanceof InvokeStmt && sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr
128+
&& methodDef.getBaseObjects() != null) {
129+
Value baseVal = ((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase();
130+
for (AccessPathTuple apt : methodDef.getBaseObjects()) {
131+
if (apt.getSourceSinkType().isSource()) {
132+
aps.add(apt.toAccessPath(baseVal, manager, true));
133+
apTuples.add(apt);
125134
}
126135
}
136+
}
127137

128-
// Check whether we need to taint the return object
129-
if (sCallSite instanceof DefinitionStmt && methodDef.getReturnValues() != null) {
130-
Value returnVal = ((DefinitionStmt) sCallSite).getLeftOp();
131-
for (AccessPathTuple apt : methodDef.getReturnValues()) {
132-
if (apt.getSourceSinkType().isSource()) {
133-
aps.add(apt.toAccessPath(returnVal, manager, false));
134-
apTuples.add(apt);
135-
}
138+
// Check whether we need to taint the return object
139+
if (sCallSite instanceof DefinitionStmt && methodDef.getReturnValues() != null) {
140+
Value returnVal = ((DefinitionStmt) sCallSite).getLeftOp();
141+
for (AccessPathTuple apt : methodDef.getReturnValues()) {
142+
if (apt.getSourceSinkType().isSource()) {
143+
aps.add(apt.toAccessPath(returnVal, manager, false));
144+
apTuples.add(apt);
136145
}
137146
}
147+
}
138148

139-
// Check whether we need to taint parameters
140-
if (sCallSite.containsInvokeExpr() && methodDef.getParameters() != null
141-
&& methodDef.getParameters().length > 0)
142-
for (int i = 0; i < sCallSite.getInvokeExpr().getArgCount(); i++) {
143-
if (methodDef.getParameters().length > i) {
144-
for (AccessPathTuple apt : methodDef.getParameters()[i]) {
145-
if (apt.getSourceSinkType().isSource()) {
146-
aps.add(apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager, true));
147-
apTuples.add(apt);
148-
}
149+
// Check whether we need to taint parameters
150+
if (sCallSite.containsInvokeExpr() && methodDef.getParameters() != null
151+
&& methodDef.getParameters().length > 0)
152+
for (int i = 0; i < sCallSite.getInvokeExpr().getArgCount(); i++) {
153+
if (methodDef.getParameters().length > i) {
154+
for (AccessPathTuple apt : methodDef.getParameters()[i]) {
155+
if (apt.getSourceSinkType().isSource()) {
156+
aps.add(apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager, true));
157+
apTuples.add(apt);
149158
}
150159
}
151160
}
152-
break;
153-
default:
154-
return null;
161+
}
162+
break;
163+
default:
164+
return null;
155165
}
156166
} else if (def instanceof FieldSourceSinkDefinition) {
157167
// Check whether we need to taint the left side of the assignment
@@ -368,10 +378,12 @@ public SourceInfo getInverseSinkInfo(Stmt sCallSite, InfoflowManager manager) {
368378
matchingDefs.add(new Pair<>(ap, methodDef));
369379
}
370380
// Check whether the base object matches our definition
371-
else if (sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr && methodDef.getBaseObjects() != null) {
381+
else if (sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr
382+
&& methodDef.getBaseObjects() != null) {
372383
for (AccessPathTuple apt : methodDef.getBaseObjects()) {
373384
if (apt.getSourceSinkType().isSink()) {
374-
AccessPath ap = apt.toAccessPath(((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase(), manager, true);
385+
AccessPath ap = apt.toAccessPath(((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase(),
386+
manager, true);
375387
matchingDefs.add(new Pair<>(ap, def));
376388
break;
377389
}
@@ -389,7 +401,8 @@ else if (methodDef.getParameters() != null && methodDef.getParameters().length >
389401
if (methodDef.getParameters().length > i) {
390402
for (AccessPathTuple apt : methodDef.getParameters()[i]) {
391403
if (apt.getSourceSinkType().isSink()) {
392-
AccessPath ap = apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager, true);
404+
AccessPath ap = apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager,
405+
true);
393406
aps.add(ap);
394407
apts.add(apt);
395408
}
@@ -478,73 +491,74 @@ public SinkInfo getInverseSourceInfo(Stmt sCallSite, InfoflowManager manager, Ac
478491

479492
// For parameters in callback methods, we need special handling
480493
switch (methodDef.getCallType()) {
481-
case Callback:
482-
if (sCallSite instanceof IdentityStmt) {
483-
IdentityStmt is = (IdentityStmt) sCallSite;
484-
if (is.getRightOp() instanceof ParameterRef) {
485-
ParameterRef paramRef = (ParameterRef) is.getRightOp();
486-
if (methodDef.getParameters() != null
487-
&& methodDef.getParameters().length > paramRef.getIndex()) {
488-
for (AccessPathTuple apt : methodDef.getParameters()[paramRef.getIndex()]) {
489-
AccessPath ap = apt.toAccessPath(is.getLeftOp(), manager, false);
490-
if (accessPathMatches(sourceAccessPath, apt)) {
491-
aps.add(ap);
492-
apTuples.add(apt);
493-
}
494-
}
495-
}
496-
}
497-
}
498-
break;
499-
case MethodCall:
500-
// Check whether we need to taint the base object
501-
if (sCallSite instanceof InvokeStmt && sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr
502-
&& methodDef.getBaseObjects() != null) {
503-
Value baseVal = ((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase();
504-
for (AccessPathTuple apt : methodDef.getBaseObjects()) {
505-
if (apt.getSourceSinkType().isSource()) {
506-
AccessPath ap = apt.toAccessPath(baseVal, manager, true);
494+
case Callback:
495+
if (sCallSite instanceof IdentityStmt) {
496+
IdentityStmt is = (IdentityStmt) sCallSite;
497+
if (is.getRightOp() instanceof ParameterRef) {
498+
ParameterRef paramRef = (ParameterRef) is.getRightOp();
499+
if (methodDef.getParameters() != null
500+
&& methodDef.getParameters().length > paramRef.getIndex()) {
501+
for (AccessPathTuple apt : methodDef.getParameters()[paramRef.getIndex()]) {
502+
AccessPath ap = apt.toAccessPath(is.getLeftOp(), manager, false);
507503
if (accessPathMatches(sourceAccessPath, apt)) {
508504
aps.add(ap);
509505
apTuples.add(apt);
510506
}
511507
}
512508
}
513509
}
510+
}
511+
break;
512+
case MethodCall:
513+
// Check whether we need to taint the base object
514+
if (sCallSite instanceof InvokeStmt && sCallSite.getInvokeExpr() instanceof InstanceInvokeExpr
515+
&& methodDef.getBaseObjects() != null) {
516+
Value baseVal = ((InstanceInvokeExpr) sCallSite.getInvokeExpr()).getBase();
517+
for (AccessPathTuple apt : methodDef.getBaseObjects()) {
518+
if (apt.getSourceSinkType().isSource()) {
519+
AccessPath ap = apt.toAccessPath(baseVal, manager, true);
520+
if (accessPathMatches(sourceAccessPath, apt)) {
521+
aps.add(ap);
522+
apTuples.add(apt);
523+
}
524+
}
525+
}
526+
}
514527

515-
// Check whether we need to taint the return object
516-
if (sCallSite instanceof DefinitionStmt && methodDef.getReturnValues() != null) {
517-
Value returnVal = ((DefinitionStmt) sCallSite).getLeftOp();
518-
for (AccessPathTuple apt : methodDef.getReturnValues()) {
519-
if (apt.getSourceSinkType().isSource()) {
520-
AccessPath ap = apt.toAccessPath(returnVal, manager, false);
521-
if (accessPathMatches(sourceAccessPath, apt)) {
522-
aps.add(ap);
523-
apTuples.add(apt);
524-
}
528+
// Check whether we need to taint the return object
529+
if (sCallSite instanceof DefinitionStmt && methodDef.getReturnValues() != null) {
530+
Value returnVal = ((DefinitionStmt) sCallSite).getLeftOp();
531+
for (AccessPathTuple apt : methodDef.getReturnValues()) {
532+
if (apt.getSourceSinkType().isSource()) {
533+
AccessPath ap = apt.toAccessPath(returnVal, manager, false);
534+
if (accessPathMatches(sourceAccessPath, apt)) {
535+
aps.add(ap);
536+
apTuples.add(apt);
525537
}
526538
}
527539
}
540+
}
528541

529-
// Check whether we need to taint parameters
530-
if (sCallSite.containsInvokeExpr() && methodDef.getParameters() != null
531-
&& methodDef.getParameters().length > 0)
532-
for (int i = 0; i < sCallSite.getInvokeExpr().getArgCount(); i++) {
533-
if (methodDef.getParameters().length > i) {
534-
for (AccessPathTuple apt : methodDef.getParameters()[i]) {
535-
if (apt.getSourceSinkType().isSource()) {
536-
AccessPath ap = apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager, true);
537-
if (accessPathMatches(sourceAccessPath, apt)) {
538-
aps.add(ap);
539-
apTuples.add(apt);
540-
}
542+
// Check whether we need to taint parameters
543+
if (sCallSite.containsInvokeExpr() && methodDef.getParameters() != null
544+
&& methodDef.getParameters().length > 0)
545+
for (int i = 0; i < sCallSite.getInvokeExpr().getArgCount(); i++) {
546+
if (methodDef.getParameters().length > i) {
547+
for (AccessPathTuple apt : methodDef.getParameters()[i]) {
548+
if (apt.getSourceSinkType().isSource()) {
549+
AccessPath ap = apt.toAccessPath(sCallSite.getInvokeExpr().getArg(i), manager,
550+
true);
551+
if (accessPathMatches(sourceAccessPath, apt)) {
552+
aps.add(ap);
553+
apTuples.add(apt);
541554
}
542555
}
543556
}
544557
}
545-
break;
546-
default:
547-
return null;
558+
}
559+
break;
560+
default:
561+
return null;
548562
}
549563
} else if (def instanceof FieldSourceSinkDefinition) {
550564
// Check whether we need to taint the left side of the assignment

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/postProcessor/SummaryPathBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public SummarySourceInfo() {
5252

5353
public SummarySourceInfo(AccessPath source, Stmt context, Object userData, AccessPath sourceAP, boolean isAlias,
5454
boolean isInCallee, boolean pathAgnosticResults) {
55-
super(null, source, context, userData, null, null, null, pathAgnosticResults);
55+
super(null, source, context, userData, (Stmt[]) null, null, null, pathAgnosticResults);
5656
this.sourceAP = sourceAP;
5757
this.isAlias = isAlias;
5858
this.isInCallee = isInCallee;

soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ public int numConnections() {
115115
return num;
116116
}
117117

118+
/**
119+
* Gets the total number of additional data flows that can be used for filtering
120+
* context-sensitive sinks. The technique for counting flows is equivalent to
121+
* numConnections().
122+
*
123+
* @return The number of source-to-sink connections in the additional data flows
124+
*/
125+
public int numAdditionalFlows() {
126+
int num = 0;
127+
if (this.additionalResults != null)
128+
for (ResultSinkInfo sink : this.additionalResults.keySet())
129+
num += this.additionalResults.get(sink).size();
130+
return num;
131+
}
132+
118133
/**
119134
* Gets whether this result object is empty, i.e. contains no information flows
120135
*

soot-infoflow/src/soot/jimple/infoflow/results/ResultSourceInfo.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ public ResultSourceInfo(ISourceSinkDefinition definition, AccessPath source, Stm
4848
this.pathAgnosticResults = pathAgnosticResults;
4949
}
5050

51+
public ResultSourceInfo(ISourceSinkDefinition definition, AccessPath source, Stmt context, Object userData,
52+
Stmt[] path, AccessPath[] pathAPs, Stmt[] pathCallSites, boolean pathAgnosticResults) {
53+
super(definition, source, context, userData);
54+
55+
this.path = path;
56+
this.pathAPs = pathAPs;
57+
this.pathCallSites = pathCallSites;
58+
this.pathAgnosticResults = pathAgnosticResults;
59+
}
60+
5161
public Stmt[] getPath() {
5262
return this.path;
5363
}

soot-infoflow/src/soot/jimple/infoflow/river/ConditionalFlowPostProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public InfoflowResults onResultsAvailable(InfoflowResults results, IInfoflowCFG
3434
if (results.size() == 0)
3535
return results;
3636

37-
logger.info("Filtering conditional flows, starting with {} flows...", results.numConnections());
37+
logger.info("Filtering conditional flows, starting with {} normal flows and {} additional flows...",
38+
results.numConnections(), results.numAdditionalFlows());
3839
HashSet<ResultSinkInfo> tbr = new HashSet<>();
3940

4041
for (DataFlowResult dfRes : results.getResultSet()) {

soot-infoflow/src/soot/jimple/infoflow/river/ConditionalSecondarySourceDefinition.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,31 @@
44
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinition;
55

66
/**
7-
* Special source definition for sources of secondary flows that are also conditional sinks.
7+
* Special source definition for sources of secondary flows that are also
8+
* conditional sinks.
89
*
910
* @author Tim Lange
1011
*/
1112
public class ConditionalSecondarySourceDefinition extends AbstractSourceSinkDefinition {
12-
public static ConditionalSecondarySourceDefinition INSTANCE = new ConditionalSecondarySourceDefinition();
13+
public static ConditionalSecondarySourceDefinition INSTANCE = new ConditionalSecondarySourceDefinition();
1314

14-
@Override
15-
public ISourceSinkDefinition getSourceOnlyDefinition() {
16-
return null;
17-
}
15+
private ConditionalSecondarySourceDefinition() {
16+
//
17+
}
1818

19-
@Override
20-
public ISourceSinkDefinition getSinkOnlyDefinition() {
21-
return null;
22-
}
19+
@Override
20+
public ISourceSinkDefinition getSourceOnlyDefinition() {
21+
return null;
22+
}
2323

24-
@Override
25-
public boolean isEmpty() {
26-
return false;
27-
}
24+
@Override
25+
public ISourceSinkDefinition getSinkOnlyDefinition() {
26+
return null;
27+
}
28+
29+
@Override
30+
public boolean isEmpty() {
31+
return false;
32+
}
2833

2934
}

0 commit comments

Comments
 (0)