-
Notifications
You must be signed in to change notification settings - Fork 313
Description
Hi:
There's a false negative when handling field abstraction in backward alias analysis, lead to missing of taints which was seen in quite a few real world code snippets. Consider the following example, which is provided as in #415 as a failed test case aliasWithOverwriteTest1:
class D {
E e;
public void read() {
e = new E();
e.read();
}
}
class E {
String str;
public void read() {
str = ""; //comment out this line passes the test
str = str + TelephonyManager.getDeviceId(); // or simply `str = TelephonyManager.getDeviceId();`
}
}
public void aliasWithOverwriteTest1() {
D d = new D();
d.read();
ConnectionManager cm = new ConnectionManager();
cm.publish(d.e.str);
}In the read function of class E, when the field str is tainted, a backward alias analysis is triggered as a taint with abstraction statement and pops upwards. Normally, this backward taint should reach out of the original method and walks all the way up and then reverse again to forward solver and finally taints this.d.e.str.
However, since there is an overwrite statement 'str = ""' above, the current BackwardsInfoFlowProblem.computeAliases logic will consider the left side overwritten completely, and refuses to pass the taint upwards.
// Check whether the left side of the assignment matches our
// current taint abstraction
final boolean leftSideMatches = Aliasing.baseMatches(leftValue, source);
if (!leftSideMatches)
res.add(source);
else {
// The left side is overwritten completely
// If we have an assignment to the base local of the current
// taint, all taint propagations must be below that point,
// so this is the right point to turn around.
for (Unit u : interproceduralCFG().getPredsOf(defStmt))
manager.getForwardSolver().processEdge(new PathEdge<Unit, Abstraction>(d1, u, source));
}And the InfoFlowProblem forward solver does not trigger alias analysis when the function returns. This taint thus disappears from this.d.e, and then missing fro the final sink cm.publish(d.e.str);, which is of course incorrect.
It can be tackled by forcing forward solver to trigger alias analysis when return, i.e. forcing true in aliasing.getAliasingStrategy().requiresAnalysisOnReturn
if ((abs.isImplicit() && !callerD1sConditional)
|| aliasing.getAliasingStrategy().requiresAnalysisOnReturn()) {
for (Abstraction d1 : callerD1s) {
aliasing.computeAliases(d1, iCallStmt, null, res,
interproceduralCFG().getMethodOf(callSite), abs);
}
}but I suspect this will introduce huge performance impact and may lead to other false positives.
I'm wondering what's the better solutions for this situation?
Thanks!