Skip to content

False negative when handling field abstraction in backward alias analysis #414

@flankerhqd

Description

@flankerhqd

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!

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions