Open
Description
I think I've found a case where Boomerang misses some dataflow (3.1.2).
The reproducer below is based on FlowDroid Listing 2 (PLDI '14), but uses a static setter/getter instead of direct field writes.
boomerangPDS/src/main/java/boomerang/example/BoomerangExampleTarget1.java
public class BoomerangExampleTarget1 {
public static void main(String... args) {
Data p = new Data();
taintIt(customSource(), p);
}
private static String customSource() { return "I'm tainted"; }
private static void customSink(String sunk) { System.out.println(sunk); }
private static void taintIt(String in, Data out) {
Data x = out;
Data.setter(x, in);
customSink(Data.getter(out));
}
static class Data {
private String f;
static void setter(Data self, String value) {
self.f = value;
}
static String getter(Data self) {
return self.f;
}
}
}
If I change Data.setter(x, in);
to Data.setter(out, in);
, then I get a path from the source to the sink.
boomerangPDS/src/main/java/boomerang/example/ExampleMain1.java: createAnalysisTransformer()
private static Transformer createAnalysisTransformer() {
return new SceneTransformer() {
protected void internalTransform(
String phaseName, @SuppressWarnings("rawtypes") Map options) {
SootCallGraph sootCallGraph = new SootCallGraph();
AnalysisScope scope =
new AnalysisScope(sootCallGraph) {
@Override
protected Collection<? extends Query> generate(Edge cfgEdge) {
Statement statement = cfgEdge.getStart();
if (statement.toString().contains("customSource") && statement.containsInvokeExpr()) {
Val arg = statement.getLeftOp();
return Collections.singleton(new ForwardQuery(cfgEdge,
new AllocVal(arg, statement, arg)));
}
return Collections.emptySet();
}
};
Boomerang solver =
new Boomerang(
sootCallGraph, SootDataFlowScope.make(Scene.v()), new DefaultBoomerangOptions() {
@Override
public int analysisTimeoutMS() {
return 10000;
}
});
Collection<Query> seeds = scope.computeSeeds();
for (Query query : seeds) {
System.out.println("Solving query: " + query);
ForwardBoomerangResults<Weight.NoWeight> res = solver.solve((ForwardQuery) query);
if (res.isTimedout()) {
throw new RuntimeException("Timed out");
}
res.asStatementValWeightTable().cellSet().forEach(cell -> {
if (cell.getRowKey().getStart().containsInvokeExpr() &&
cell.getRowKey().getStart().getInvokeExpr().getMethod().getName().contains("customSink") &&
cell.getRowKey().getStart().uses(cell.getColumnKey())) {
System.out.println("SOURCE: " + query.cfgEdge().getStart().toString());
System.out.println("SINK: " + cell.getRowKey().getStart().toString());
}
});
}
}
};
}
Metadata
Metadata
Assignees
Labels
No labels