Skip to content

Commit 1cce25e

Browse files
committed
Remove getMorePreciseType from SummaryTaintWrapper because Soot now has the type hierarchy
1 parent c68bfb7 commit 1cce25e

7 files changed

Lines changed: 56 additions & 162 deletions

File tree

soot-infoflow-integration/test/soot/jimple/infoflow/integration/test/junit/AndroidRegressionTests.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
import org.xmlpull.v1.XmlPullParserException;
66
import soot.jimple.infoflow.InfoflowConfiguration;
77
import soot.jimple.infoflow.android.SetupApplication;
8-
import soot.jimple.infoflow.methodSummary.data.provider.EagerSummaryProvider;
9-
import soot.jimple.infoflow.methodSummary.taintWrappers.SummaryTaintWrapper;
108
import soot.jimple.infoflow.methodSummary.taintWrappers.TaintWrapperFactory;
119
import soot.jimple.infoflow.results.InfoflowResults;
1210
import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper;
11+
import soot.jimple.infoflow.util.DebugFlowFunctionTaintPropagationHandler;
1312

1413
import javax.xml.stream.XMLStreamException;
1514
import java.io.IOException;
16-
import java.net.URISyntaxException;
1715
import java.util.Collections;
1816

1917
/**
@@ -43,4 +41,18 @@ public void testFlowSensitivityWithOverwrite() throws XmlPullParserException, IO
4341
Assert.assertEquals(2, results.size());
4442
Assert.assertEquals(2, results.getResultSet().size());
4543
}
44+
45+
46+
/**
47+
* Tests that StubDroid correctly narrows the type when the summary is in a superclass.
48+
* See also the comment in SummaryTaintWrapper#getSummaryDeclaringClass().
49+
*/
50+
@Test
51+
public void testTypeHierarchyFromSummary() throws XmlPullParserException, IOException {
52+
SetupApplication app = initApplication("testAPKs/TypeHierarchyTest.apk");
53+
app.setTaintPropagationHandler(new DebugFlowFunctionTaintPropagationHandler());
54+
InfoflowResults results = app.runInfoflow("../soot-infoflow-android/SourcesAndSinks.txt");
55+
Assert.assertEquals(1, results.size());
56+
Assert.assertEquals(1, results.getResultSet().size());
57+
}
4658
}
5.25 MB
Binary file not shown.

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/taintWrappers/SummaryTaintWrapper.java

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import soot.jimple.infoflow.solver.IFollowReturnsPastSeedsHandler;
3939
import soot.jimple.infoflow.taintWrappers.IReversibleTaintWrapper;
4040
import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper;
41-
import soot.jimple.infoflow.typing.ITypeChecker;
4241
import soot.jimple.infoflow.typing.TypeUtils;
4342
import soot.jimple.infoflow.util.ByReferenceBoolean;
4443
import soot.jimple.infoflow.util.SootMethodRepresentationParser;
@@ -53,7 +52,7 @@
5352
* @author Steven Arzt
5453
*
5554
*/
56-
public class SummaryTaintWrapper implements IReversibleTaintWrapper, ITypeChecker {
55+
public class SummaryTaintWrapper implements IReversibleTaintWrapper {
5756

5857
private InfoflowManager manager;
5958
private AtomicInteger wrapperHits = new AtomicInteger();
@@ -207,9 +206,6 @@ public void initialize(InfoflowManager manager) {
207206
// If we have a fallback wrapper, we need to initialize that one as well
208207
if (fallbackWrapper != null)
209208
fallbackWrapper.initialize(manager);
210-
211-
// We need to query the summaries in case we have no proper type information
212-
manager.getTypeUtils().registerTypeChecker(this);
213209
}
214210

215211
public Collection<PreAnalysisHandler> getPreAnalysisHandlers() {
@@ -1826,53 +1822,4 @@ public Set<Abstraction> getInverseTaintsForMethod(Stmt stmt, Abstraction d1, Abs
18261822
return resAbs;
18271823
}
18281824

1829-
@Override
1830-
public Type getMorePreciseType(Type tp1, Type tp2) {
1831-
// We query the summaries to establish a type hierarchy beyond the Soot scene
1832-
if (tp1 instanceof RefType && tp2 instanceof RefType) {
1833-
RefType rt1 = (RefType) tp1;
1834-
RefType rt2 = (RefType) tp2;
1835-
1836-
SootClass sc1 = rt1.getSootClass();
1837-
SootClass sc2 = rt2.getSootClass();
1838-
1839-
if (sc1.isPhantom() || sc2.isPhantom()) {
1840-
String sc1Name = sc1.getName();
1841-
String sc2Name = sc2.getName();
1842-
1843-
ClassMethodSummaries cs1 = flows.getClassFlows(sc1.getName());
1844-
ClassMethodSummaries cs2 = flows.getClassFlows(sc2.getName());
1845-
1846-
// Type1 may be a superclass or interface of cs2
1847-
if (cs2 != null) {
1848-
ClassMethodSummaries curSummaries = cs2;
1849-
while (curSummaries != null) {
1850-
if (sc1Name.equals(curSummaries.getSuperClass()))
1851-
return tp2;
1852-
for (String intf : curSummaries.getInterfaces()) {
1853-
if (intf.equals(sc1Name))
1854-
return tp2;
1855-
}
1856-
curSummaries = flows.getClassFlows(curSummaries.getSuperClass());
1857-
}
1858-
}
1859-
1860-
// Type2 may be a superclass or interface of cs1
1861-
if (cs1 != null) {
1862-
ClassMethodSummaries curSummaries = cs1;
1863-
while (curSummaries != null) {
1864-
if (sc2Name.equals(curSummaries.getSuperClass()))
1865-
return tp1;
1866-
for (String intf : curSummaries.getInterfaces()) {
1867-
if (intf.equals(sc2Name))
1868-
return tp1;
1869-
}
1870-
curSummaries = flows.getClassFlows(curSummaries.getSuperClass());
1871-
}
1872-
}
1873-
}
1874-
}
1875-
return null;
1876-
}
1877-
18781825
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ protected void runAnalysis(final ISourceSinkManager sourcesSinks, final Set<Stri
593593
// Initialize the abstraction configuration
594594
Abstraction.initialize(config);
595595

596-
preProcessors.addAll(getTaintWrapper().getPreAnalysisHandlers());
596+
if (taintWrapper != null)
597+
preProcessors.addAll(taintWrapper.getPreAnalysisHandlers());
597598

598599
// Build the callgraph
599600
long beforeCallgraph = System.nanoTime();

soot-infoflow/src/soot/jimple/infoflow/typing/ITypeChecker.java

Lines changed: 0 additions & 23 deletions
This file was deleted.

soot-infoflow/src/soot/jimple/infoflow/typing/SootBasedTypeChecker.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

soot-infoflow/src/soot/jimple/infoflow/typing/TypeUtils.java

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package soot.jimple.infoflow.typing;
22

3-
import java.util.ArrayList;
43
import java.util.List;
54
import java.util.stream.Collectors;
65

@@ -22,7 +21,6 @@
2221
import soot.Type;
2322
import soot.jimple.infoflow.InfoflowManager;
2423
import soot.jimple.infoflow.data.AccessPath;
25-
import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper;
2624

2725
/**
2826
* Class containing various utility methods for dealing with type information
@@ -33,13 +31,9 @@
3331
public class TypeUtils {
3432

3533
private final InfoflowManager manager;
36-
private final List<ITypeChecker> typeCheckers = new ArrayList<>();
3734

3835
public TypeUtils(InfoflowManager manager) {
3936
this.manager = manager;
40-
41-
// We want to query the standard Soot type hierarchy first
42-
typeCheckers.add(new SootBasedTypeChecker());
4337
}
4438

4539
/**
@@ -192,10 +186,44 @@ public boolean hasCompatibleTypesForCall(AccessPath apBase, SootClass dest) {
192186
* @return The more precise one of the two given types
193187
*/
194188
public Type getMorePreciseType(Type tp1, Type tp2) {
195-
for (ITypeChecker checker : this.typeCheckers) {
196-
Type tp = checker.getMorePreciseType(tp1, tp2);
197-
if (tp != null)
198-
return tp;
189+
final FastHierarchy fastHierarchy = Scene.v().getOrMakeFastHierarchy();
190+
191+
if (tp1 == null)
192+
return tp2;
193+
else if (tp2 == null)
194+
return tp1;
195+
else if (tp1 == tp2)
196+
return tp1;
197+
else if (TypeUtils.isObjectLikeType(tp1))
198+
return tp2;
199+
else if (TypeUtils.isObjectLikeType(tp2))
200+
return tp1;
201+
else if (tp1 instanceof PrimType && tp2 instanceof PrimType)
202+
return tp1; // arbitrary choice
203+
else if (fastHierarchy.canStoreType(tp2, tp1))
204+
return tp2;
205+
else if (fastHierarchy.canStoreType(tp1, tp2))
206+
return tp1;
207+
else {
208+
// If one type is an array type and the other one is the base type,
209+
// we still accept the cast
210+
if (tp1 instanceof ArrayType && tp2 instanceof ArrayType) {
211+
ArrayType at1 = (ArrayType) tp1;
212+
ArrayType at2 = (ArrayType) tp2;
213+
if (at1.numDimensions != at2.numDimensions)
214+
return null;
215+
Type preciseType = getMorePreciseType(at1.getElementType(), at2.getElementType());
216+
if (preciseType == null)
217+
return null;
218+
219+
return ArrayType.v(preciseType, at1.numDimensions);
220+
} else if (tp1 instanceof ArrayType) {
221+
ArrayType at = (ArrayType) tp1;
222+
return getMorePreciseType(at.getElementType(), tp2);
223+
} else if (tp2 instanceof ArrayType) {
224+
ArrayType at = (ArrayType) tp2;
225+
return getMorePreciseType(tp1, at.getElementType());
226+
}
199227
}
200228
return null;
201229
}
@@ -289,16 +317,6 @@ public static Type buildArrayOrAddDimension(Type type, Type arrayType) {
289317
return ArrayType.v(type, 1);
290318
}
291319

292-
/**
293-
* Registers an additional type checker implementation with the typing
294-
* infrastructure
295-
*
296-
* @param checker The type checker to register
297-
*/
298-
public void registerTypeChecker(ITypeChecker checker) {
299-
this.typeCheckers.add(checker);
300-
}
301-
302320
/**
303321
* Gets all classes that inherit from the given class or that transitively
304322
* implement the given interface

0 commit comments

Comments
 (0)