Skip to content

Commit 93f1fd4

Browse files
committed
Handover aliases early
1 parent fac07f5 commit 93f1fd4

3 files changed

Lines changed: 158 additions & 34 deletions

File tree

soot-infoflow/src/soot/jimple/infoflow/problems/AliasProblem.java

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,6 @@ private Set<Abstraction> computeAliases(final DefinitionStmt defStmt, Value left
120120

121121
final Set<Abstraction> res = new MutableTwoElementSet<Abstraction>();
122122

123-
// Check whether the left side of the assignment matches our
124-
// current taint abstraction
125-
final boolean leftSideMatches = Aliasing.baseMatches(leftValue, source);
126-
if (!leftSideMatches)
127-
res.add(source);
128-
else {
129-
// The left side is overwritten completely
130-
131-
// If we have an assignment to the base local of the current
132-
// taint, all taint propagations must be below that point,
133-
// so this is the right point to turn around.
134-
for (Unit u : interproceduralCFG().getPredsOf(defStmt))
135-
manager.getMainSolver().processEdge(new PathEdge<Unit, Abstraction>(d1, u, source));
136-
}
137-
138123
// We only handle assignments and identity statements
139124
if (defStmt instanceof IdentityStmt) {
140125
res.add(source);
@@ -143,6 +128,12 @@ private Set<Abstraction> computeAliases(final DefinitionStmt defStmt, Value left
143128
if (!(defStmt instanceof AssignStmt))
144129
return res;
145130

131+
// Check whether the left side of the assignment matches our
132+
// current taint abstraction
133+
final boolean leftSideMatches = Aliasing.baseMatches(leftValue, source);
134+
if (!leftSideMatches)
135+
res.add(source);
136+
146137
// Get the right side of the assignment
147138
final Value rightValue = BaseSelector.selectBase(defStmt.getRightOp(), false);
148139

@@ -240,21 +231,12 @@ else if (defStmt.getRightOp() instanceof LengthExpr) {
240231
newLeftAbs = checkAbstraction(source.deriveNewAbstraction(ap, defStmt));
241232
}
242233

243-
if (newLeftAbs != null) {
244-
// If we ran into a new abstraction that points to a
245-
// primitive value, we can remove it
246-
if (newLeftAbs.getAccessPath().getLastFieldType() instanceof PrimType)
247-
return res;
248-
249-
if (!newLeftAbs.getAccessPath().equals(source.getAccessPath())) {
250-
// Propagate the new alias upwards
251-
res.add(newLeftAbs);
252-
253-
// Inject the new alias into the forward solver
254-
for (Unit u : interproceduralCFG().getPredsOf(defStmt))
255-
manager.getMainSolver()
256-
.processEdge(new PathEdge<Unit, Abstraction>(d1, u, newLeftAbs));
257-
}
234+
if (newLeftAbs != null && !newLeftAbs.getAccessPath().equals(source.getAccessPath())) {
235+
// Only inject the new alias into the forward solver but never propagate it upwards
236+
// because the alias was created at this program point and won't be valid above.
237+
for (Unit u : interproceduralCFG().getPredsOf(defStmt))
238+
manager.getMainSolver()
239+
.processEdge(new PathEdge<Unit, Abstraction>(d1, u, newLeftAbs));
258240
}
259241
}
260242

@@ -734,6 +716,42 @@ public Set<Abstraction> computeTargets(Abstraction source, Abstraction d1,
734716
if (abs != null) {
735717
res.add(abs);
736718
registerActivationCallSite(callSite, callee, abs);
719+
720+
// Check whether the call site created an alias by having two equal
721+
// arguments, e.g. caller(o, o);. If yes, inject the other parameter
722+
// back into the callee.
723+
for (int argIndex = 0; !isReflectiveCallSite && argIndex < ie.getArgCount(); argIndex++) {
724+
if (i != argIndex && originalCallArg == ie.getArg(argIndex)) {
725+
AccessPath aliasAp = manager.getAccessPathFactory().copyWithNewValue(
726+
source.getAccessPath(), paramLocals[argIndex],
727+
source.getAccessPath().getBaseType(),
728+
false);
729+
Abstraction aliasAbs = checkAbstraction(
730+
source.deriveNewAbstraction(aliasAp, (Stmt) exitStmt));
731+
732+
manager.getMainSolver()
733+
.processEdge(new PathEdge<>(d1, exitStmt, aliasAbs));
734+
}
735+
}
736+
737+
// A foo(A a) {
738+
// return a;
739+
// }
740+
// A b = foo(a);
741+
// An alias is created using the returned value. If no assignment
742+
// happen inside the method, also no handover is triggered. Thus,
743+
// for this special case, we hand over the current taint and let the
744+
// forward analysis find out whether the return value actually created
745+
// an alias or not.
746+
for (Unit u : manager.getICFG().getStartPointsOf(callee)) {
747+
if (!(u instanceof ReturnStmt))
748+
continue;
749+
750+
if (paramLocals[i] == ((ReturnStmt) u).getOp()) {
751+
manager.getMainSolver().processEdge(new PathEdge<>(d1, exitStmt, source));
752+
break;
753+
}
754+
}
737755
}
738756
}
739757
}

soot-infoflow/test/soot/jimple/infoflow/test/HeapTestCode.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,24 @@ public void singleAliasTest() {
793793
cm.publish(b.b);
794794
}
795795

796+
public void negativeSingleAliasTest() {
797+
A a = new A();
798+
A b = fakeAlias(a);
799+
a.b = TelephonyManager.getDeviceId();
800+
ConnectionManager cm = new ConnectionManager();
801+
cm.publish(b.b);
802+
}
803+
804+
public A doNotFold() {
805+
A a = new A();
806+
System.out.println("XXX");
807+
return a;
808+
}
809+
810+
private A fakeAlias(A a) {
811+
return doNotFold();
812+
}
813+
796814
private int intData;
797815

798816
private void setIntData() {
@@ -1611,4 +1629,43 @@ public void activationStatementTest1() {
16111629
cm.publish(specialName);
16121630
}
16131631

1632+
public void callSiteCreatesAlias() {
1633+
String tainted = TelephonyManager.getDeviceId();
1634+
1635+
Book book1 = new Book();
1636+
leakingCallee(tainted, new Book(), book1);
1637+
leakingCallee(tainted, book1, book1);
1638+
}
1639+
1640+
void leakingCallee(String tainted, Book book1, Book book2) {
1641+
book1.name = tainted;
1642+
ConnectionManager cm = new ConnectionManager();
1643+
cm.publish(book2.name);
1644+
}
1645+
1646+
public Book alias;
1647+
public void lhsNotUpwardsInAliasFlow() {
1648+
alias = new Book();
1649+
1650+
Book book = new Book();
1651+
Book alias2 = alias;
1652+
alias = book; // alias only aliases book downwards from this program point
1653+
book.name = TelephonyManager.getDeviceId();
1654+
ConnectionManager cm = new ConnectionManager();
1655+
cm.publish(alias2.name);
1656+
}
1657+
1658+
public void identityStmtIsNotAGoodHandoverPoint() {
1659+
Book book = new Book();
1660+
// No need to propagate book forward again
1661+
callee(book);
1662+
book.name = TelephonyManager.getDeviceId();
1663+
1664+
ConnectionManager cm = new ConnectionManager();
1665+
cm.publish(book.name);
1666+
}
1667+
1668+
void callee(Book b) {
1669+
System.out.println(b);
1670+
}
16141671
}

soot-infoflow/test/soot/jimple/infoflow/test/junit/HeapTests.java

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@
2020
import org.junit.Ignore;
2121
import org.junit.Test;
2222

23-
import soot.RefType;
24-
import soot.Scene;
25-
import soot.SootField;
26-
import soot.SootMethod;
23+
import soot.*;
2724
import soot.jimple.AssignStmt;
2825
import soot.jimple.DefinitionStmt;
2926
import soot.jimple.InstanceInvokeExpr;
@@ -38,6 +35,7 @@
3835
import soot.jimple.infoflow.data.SootMethodAndClass;
3936
import soot.jimple.infoflow.entryPointCreators.DefaultEntryPointCreator;
4037
import soot.jimple.infoflow.entryPointCreators.SequentialEntryPointCreator;
38+
import soot.jimple.infoflow.handlers.TaintPropagationHandler;
4139
import soot.jimple.infoflow.results.InfoflowResults;
4240
import soot.jimple.infoflow.sourcesSinks.definitions.MethodSourceSinkDefinition;
4341
import soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager;
@@ -674,6 +672,19 @@ public void singleAliasTest() {
674672
checkInfoflow(infoflow, 1);
675673
}
676674

675+
@Test(timeout = 300000)
676+
public void negativeSingleAliasTest() {
677+
IInfoflow infoflow = initInfoflow();
678+
infoflow.getConfig().setInspectSources(false);
679+
infoflow.getConfig().setInspectSinks(false);
680+
infoflow.getConfig().setWriteOutputFiles(true);
681+
682+
List<String> epoints = new ArrayList<String>();
683+
epoints.add("<soot.jimple.infoflow.test.HeapTestCode: void negativeSingleAliasTest()>");
684+
infoflow.computeInfoflow(appPath, libPath, epoints, sources, sinks);
685+
negativeCheckInfoflow(infoflow);
686+
}
687+
677688
@Test(timeout = 300000)
678689
public void intAliasTest() {
679690
IInfoflow infoflow = initInfoflow();
@@ -1269,4 +1280,42 @@ public void activationStatementTest1() {
12691280
negativeCheckInfoflow(infoflow);
12701281
}
12711282

1283+
1284+
@Test(timeout = 300000)
1285+
public void callSiteCreatesAlias() {
1286+
IInfoflow infoflow = initInfoflow();
1287+
List<String> epoints = new ArrayList<String>();
1288+
epoints.add("<soot.jimple.infoflow.test.HeapTestCode: void callSiteCreatesAlias()>");
1289+
infoflow.computeInfoflow(appPath, libPath, epoints, sources, sinks);
1290+
checkInfoflow(infoflow, 1);
1291+
}
1292+
1293+
@Test(timeout = 300000)
1294+
public void lhsNotUpwardsInAliasFlow() {
1295+
IInfoflow infoflow = initInfoflow();
1296+
List<String> epoints = new ArrayList<String>();
1297+
epoints.add("<soot.jimple.infoflow.test.HeapTestCode: void lhsNotUpwardsInAliasFlow()>");
1298+
infoflow.computeInfoflow(appPath, libPath, epoints, sources, sinks);
1299+
negativeCheckInfoflow(infoflow);
1300+
}
1301+
1302+
@Test(timeout = 300000)
1303+
public void identityStmtIsNotAGoodHandoverPoint() {
1304+
IInfoflow infoflow = initInfoflow();
1305+
List<String> epoints = new ArrayList<String>();
1306+
infoflow.setTaintPropagationHandler(new TaintPropagationHandler() {
1307+
@Override
1308+
public void notifyFlowIn(Unit stmt, Abstraction taint, InfoflowManager manager, FlowFunctionType type) {
1309+
Assert.assertTrue(taint.isAbstractionActive());
1310+
}
1311+
1312+
@Override
1313+
public Set<Abstraction> notifyFlowOut(Unit stmt, Abstraction d1, Abstraction incoming, Set<Abstraction> outgoing, InfoflowManager manager, FlowFunctionType type) {
1314+
return outgoing;
1315+
}
1316+
});
1317+
epoints.add("<soot.jimple.infoflow.test.HeapTestCode: void identityStmtIsNotAGoodHandoverPoint()>");
1318+
infoflow.computeInfoflow(appPath, libPath, epoints, sources, sinks);
1319+
checkInfoflow(infoflow, 1);
1320+
}
12721321
}

0 commit comments

Comments
 (0)