Skip to content

Commit

Permalink
Merge pull request #6 from LSinzker/master
Browse files Browse the repository at this point in the history
ConfluentTaintedAnalysis Implemented
  • Loading branch information
rbonifacio authored Apr 27, 2020
2 parents 210776b + 77714f5 commit 895b690
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 14 deletions.
75 changes: 75 additions & 0 deletions src/main/java/br/unb/cic/analysis/df/ConfluentTaintedAnalysis.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package br.unb.cic.analysis.df;

import br.unb.cic.analysis.AbstractMergeConflictDefinition;
import br.unb.cic.analysis.model.Conflict;
import br.unb.cic.analysis.model.ConfluenceConflictReport;
import br.unb.cic.analysis.model.Statement;
import soot.Body;
import soot.Local;
import soot.Unit;
import soot.toolkits.scalar.ArraySparseSet;
import soot.toolkits.scalar.FlowSet;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ConfluentTaintedAnalysis extends ReachDefinitionAnalysis {

public ConfluentTaintedAnalysis(Body methodBody, AbstractMergeConflictDefinition definition) {
super(methodBody, definition);
}

@Override
protected FlowSet<DataFlowAbstraction> gen(Unit u, FlowSet<DataFlowAbstraction> in) {
FlowSet<DataFlowAbstraction> res = new ArraySparseSet<>();
if(isSourceStatement(u) || isSinkStatement(u)) {
for(Local local: getDefVariables(u)) {
Statement stmt = isSourceStatement(u) ? findSourceStatement(u) : findSinkStatement(u);
res.add(new DataFlowAbstraction(local, stmt));
}
}
else if (u.getDefBoxes().size() > 0) {
u.getUseBoxes().stream().filter(v -> v.getValue() instanceof Local).forEach(v -> {
Local local = (Local) v.getValue();
in.forEach(sourceDefs -> {
if(sourceDefs.getLocal().equals(local)){ //if variable in the analyzed stmt is present in IN
u.getDefBoxes().stream()
.filter(def -> def.getValue() instanceof Local)
.forEach(def -> {
res.add(new DataFlowAbstraction((Local)def.getValue(), findStatement(u))); //add variable assigned as the stmt to IN
});
}
});
});
}
return res;
}

@Override
protected void detectConflict(FlowSet<DataFlowAbstraction> in, Unit u){
if(isSourceStatement(u) || isSinkStatement(u)){
return;
}
List<Statement> sources = new ArrayList<>();
List<Statement> sinks = new ArrayList<>();

for(Local local: getUseVariables(u)){
sources.addAll(in.toList().stream()
.filter(element -> element.getStmt().getType().equals(Statement.Type.SOURCE)
&& element.getLocal().equals(local))
.map(item -> item.getStmt()).collect(Collectors.toList()));
sinks.addAll(in.toList().stream()
.filter(element -> element.getStmt().getType().equals(Statement.Type.SINK)
&& element.getLocal().equals(local))
.map(item -> item.getStmt()).collect(Collectors.toList()));
}

for(Statement source: sources){
for(Statement sink: sinks){
Conflict c = new ConfluenceConflictReport(source, sink, findStatement(u));
Collector.instance().addConflict(c);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import br.unb.cic.analysis.AbstractMergeConflictDefinition;
import br.unb.cic.analysis.model.Conflict;
import br.unb.cic.analysis.model.DoubleSourceConflict;
import br.unb.cic.analysis.model.ConfluenceConflictReport;
import br.unb.cic.analysis.model.Statement;
import soot.Body;
import soot.Local;
Expand Down Expand Up @@ -56,7 +56,7 @@ protected void detectConflict(FlowSet<DataFlowAbstraction> in, Unit u) {
//report the conflicts
for(Statement source: sources) {
for(Statement sink: sinks) {
Conflict c = new DoubleSourceConflict(source, sink, findStatement(u));
Conflict c = new ConfluenceConflictReport(source, sink, findStatement(u));
Collector.instance().addConflict(c);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import java.util.Objects;

public class DoubleSourceConflict extends Conflict {
public class ConfluenceConflictReport extends Conflict {

protected String targetClassName;
protected String targetMethodName;
protected Integer targetLineNumber;

public DoubleSourceConflict(Statement source, Statement sink, Statement target) {
public ConfluenceConflictReport(Statement source, Statement sink, Statement target) {
super(source, sink);
targetClassName = target.getSootClass().getName();
targetMethodName = target.getSootMethod().getName();
Expand All @@ -20,7 +20,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
DoubleSourceConflict that = (DoubleSourceConflict) o;
ConfluenceConflictReport that = (ConfluenceConflictReport) o;
return Objects.equals(targetClassName, that.targetClassName) &&
Objects.equals(targetMethodName, that.targetMethodName) &&
Objects.equals(targetLineNumber, that.targetLineNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
import org.junit.Before;
import org.junit.Test;
import soot.*;
import soot.options.Options;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TaintedAnalysisConfluentTest {
public class ConfluenceWithTransitivityTest {

private TaintedAnalysis analysis;
private ConfluentTaintedAnalysis analysis;

@Before
public void configure() {
Expand All @@ -26,17 +27,17 @@ public void configure() {
protected Map<String, List<Integer>> sourceDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(8);
res.put("br.unb.cic.analysis.samples.DoubleSourceSample", lines);
lines.add(9);
res.put("br.unb.cic.analysis.samples.ConfluenceWithTransitivitySample", lines);
return res;
}

@Override
protected Map<String, List<Integer>> sinkDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(12);
res.put("br.unb.cic.analysis.samples.DoubleSourceSample", lines);
lines.add(13);
res.put("br.unb.cic.analysis.samples.ConfluenceWithTransitivitySample", lines);
return res;
}
};
Expand All @@ -45,17 +46,19 @@ protected Map<String, List<Integer>> sinkDefinitions() {
new Transform("jtp.zeroConflict", new BodyTransformer() {
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
analysis = new TaintedAnalysis(body, definition);
analysis = new ConfluentTaintedAnalysis(body, definition);
}
}));
String cp = "target/test-classes";
String targetClass = "br.unb.cic.analysis.samples.DoubleSourceSample";
String targetClass = "br.unb.cic.analysis.samples.ConfluenceWithTransitivitySample";

PhaseOptions.v().setPhaseOption("jb", "use-original-names:true");

SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute();
}

@Test
public void testDataFlowAnalysisExpectingOneConflict() {
Assert.assertEquals(0, analysis.getConflicts().size());
Assert.assertEquals(1, analysis.getConflicts().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package br.unb.cic.analysis.df;

import br.unb.cic.analysis.AbstractMergeConflictDefinition;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import soot.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SourceSinkConfluenceAnalysisMethodCallTest {

private SourceSinkConfluenceAnalysis analysis;

@Before
public void configure() {
G.reset();
Collector.instance().clear();

AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() {
@Override
protected Map<String, List<Integer>> sourceDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(8);
res.put("br.unb.cic.analysis.samples.SourceSinkMethodCallSample", lines);
return res;
}

@Override
protected Map<String, List<Integer>> sinkDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(10);
res.put("br.unb.cic.analysis.samples.SourceSinkMethodCallSample", lines);
return res;
}
};

PackManager.v().getPack("jtp").add(
new Transform("jtp.zeroConflict", new BodyTransformer() {
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
analysis = new SourceSinkConfluenceAnalysis(body, definition);
}
}));
String cp = "target/test-classes";
String targetClass = "br.unb.cic.analysis.samples.SourceSinkMethodCallSample";

Main.main(new String[] {"-w", "-allow-phantom-refs", "-f", "J", "-keep-line-number", "-cp", cp, targetClass});
}

@Test
public void testDataFlowAnalysisExpectingOneConflict() {
Assert.assertEquals(1, analysis.getConflicts().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package br.unb.cic.analysis.df;

import br.unb.cic.analysis.AbstractMergeConflictDefinition;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import soot.*;
import soot.options.Options;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SourceSinkConfluenceAnalysisVariableAttributionTest {

private SourceSinkConfluenceAnalysis analysis2;

@Before
public void configure() {
G.reset();
Collector.instance().clear();

AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() {
@Override
protected Map<String, List<Integer>> sourceDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(18);
res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionSample", lines);
return res;
}

@Override
protected Map<String, List<Integer>> sinkDefinitions() {
Map<String, List<Integer>> res = new HashMap<>();
List<Integer> lines = new ArrayList<>();
lines.add(20);
res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionSample", lines);
return res;
}
};

PackManager.v().getPack("jtp").add(
new Transform("jtp.zeroConflict", new BodyTransformer() {
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
analysis2 = new SourceSinkConfluenceAnalysis(body, definition);
}
}));
String cp = "target/test-classes";
String targetClass = "br.unb.cic.analysis.samples.SourceSinkVariableAttributionSample";

Options.v().setPhaseOption("jb", "optimize:false");

Main.main(new String[] {"-w", "-allow-phantom-refs", "-f", "J", "-keep-line-number", "-cp", cp, targetClass});
}

@Test
public void testDataFlowAnalysisExpectingOneConflict() {
Assert.assertEquals(1, analysis2.getConflicts().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package br.unb.cic.analysis.samples;

public class ConfluenceWithTransitivitySample {
public void foo(){
int x = 1;
int y = 2;
int z = 3;

x = 10; //left

z = x+1;

y++; //right

//addThese(z, y);
System.out.println(z+y);
}
/*private int addThese(int a1, int a2){
return a1+a2;
}*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package br.unb.cic.analysis.samples;

public class SourceSinkMethodCallSample {
public void foo(){
int x = 10;
int y = 20;

x = one(); //right

y = two(); //left

System.out.println(x+y);
}
private int one(){return 1;}
private int two(){return 2;}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package br.unb.cic.analysis.samples;

/**
* with the current analysis setup Soot,
* when optimizing the code, ends up erasing
* variable references that have a constant
* attributed to them, preventing the conflict
* detection by the analyzer if such attribution
* happens to be a line of interest(source or sink).
* **/

public class SourceSinkVariableAttributionSample {
public void foo() {
int x = 0;
int y = 0;
int z = 10;

x = 10; //left

y = z+2; //right

addThese(x, y); //Confluence Line

}
private int addThese(int a0, int a1){
return a0 + a1;
}
}

0 comments on commit 895b690

Please sign in to comment.