Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConfluentTaintedAnalysis Implemented #6

Merged
merged 7 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}