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

[First Cycle] - Basic Test: Add Context #27

Open
wants to merge 14 commits into
base: enable_passed_test_for_flowdroid_benchmark
Choose a base branch
from
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ This project use some of the [FlowDroid](https://github.com/secure-software-engi

###### failed: 33, passed: 71, ignored: 0 of 104 test (Original Benchmark)

> failed: 0, passed: 64, ignored: 40 of 104 test (61.53%)
> failed: 0, passed: 66, ignored: 38 of 104 test (63.46%)

- **AliasingTest** - failed: 0, passed: 5, ignored: 1 of 6 test `(83.33%)`
- [5]
Expand All @@ -79,14 +79,12 @@ This project use some of the [FlowDroid](https://github.com/secure-software-engi
- [9]
- [10]

- **BasicTest** - failed: 0, passed: 38, ignored: 5 of 42 test `(90.48%)`
- [17]
- **BasicTest** - failed: 0, passed: 39, ignored: 3 of 42 test `(92.85%)`
- [36]
- [38]
- [42]

- **CollectionTest** - failed: 0, passed: 1, ignored: 14 of 15 test `(6.67%)`
- [2]
- **CollectionTest** - failed: 0, passed: 3, ignored: 12 of 15 test `(20%)`
- [3]
- [4]
- [5]
Expand All @@ -99,10 +97,9 @@ This project use some of the [FlowDroid](https://github.com/secure-software-engi
- [11b]
- [12]
- [13]
- [14]

- **DataStructureTest** - failed: 0, passed: 5, ignored: 1 of 6 test `(83.33%)`
- [2]
- [5]

- **FactoryTest** - failed: 0, passed: 2, ignored: 1 of 3 test `(66.66%)`
- [3]
Expand All @@ -120,7 +117,8 @@ This project use some of the [FlowDroid](https://github.com/secure-software-engi
- [2]
- [3]

- **StrongUpdateTest** - failed: 0, passed: 4, ignored: 1 of 5 test `(80%)`
- **StrongUpdateTest** - failed: 0, passed: 3, ignored: 2 of 5 test `(60%)`
- [3]
- [4]


29 changes: 24 additions & 5 deletions src/main/scala/br/unb/cic/soot/graph/Graph.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ case class StringLabel(label: String) extends EdgeLabel {
override val labelType: LabelType = SimpleLabel
}

case class ContextSensitiveRegion(statement: Statement, calleeMethod: String)
case class ContextSensitiveRegion(statement: Statement, calleeMethod: String, context: Set[String])

case class CallSiteLabel(csRegion: ContextSensitiveRegion, labelType: CallSiteLabelType) extends EdgeLabel {
override type T = ContextSensitiveRegion
Expand Down Expand Up @@ -411,6 +411,11 @@ class Graph() {
}
})

// check if there path has only one context
if (! isValidContext(csOpen, csClose)) {
return false
}

// Get all the cs) without a (cs
val unopenedCS = getUnmatchedCallSites(csClose, csOpen)
// Get all the cs) without a (cs
Expand All @@ -429,6 +434,20 @@ class Graph() {
return validCS
}

def isValidContext(csOpen: List[CallSiteLabel], csClose: List[CallSiteLabel]): Boolean = {
var cs: Set[String] = Set()

val csOpenAndClose = csOpen ++ csClose

csOpenAndClose.foreach(open => {
if (open.value.context.nonEmpty) {
cs = cs + open.value.context.head
}
})

cs.size <= 1
}

def nodes(): scala.collection.Set[GraphNode] = graph.nodes.map(node => node.toOuter).toSet

def edges(): scala.collection.Set[GraphEdge] = graph.edges.map(edge => {
Expand Down Expand Up @@ -498,10 +517,10 @@ class Graph() {
var l = e.label
val label: String = e.label match {
case c: CallSiteLabel => {
// if (c.labelType == CallSiteOpenLabel) { "[label=\"cs(\"]" }
// else { "[label=\"cs)\"]" }
if (c.labelType == CallSiteOpenLabel) { "[label=\"cs(:" + c.value.statement.stmt + "\"]" }
else { "[label=\"cs):" + c.value.statement.stmt + "\"]" }
if (c.labelType == CallSiteOpenLabel) { s"""[label="CS([${ if (c.value.context.nonEmpty) c.value.context.head }]"]""" }
else { s"""[label="CS)[${ if (c.value.context.nonEmpty) c.value.context.head }]"]""" }
// if (c.labelType == CallSiteOpenLabel) { s"""[label="CS(${c.value.statement.stmt} [${c.value.context.head}]"]""" }
// else { s"""[label="CS)${c.value.statement.stmt} [${c.value.context.head}]"]""" }
}
case c: TrueLabelType =>{ "[penwidth=3][label=\"T\"]" }
case c: FalseLabelType => { "[penwidth=3][label=\"F\"]" }
Expand Down
79 changes: 59 additions & 20 deletions src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import br.unb.cic.soot.svfa.jimple.dsl.{DSL, LanguageParser}
import br.unb.cic.soot.svfa.{SVFA, SourceSinkDef}
import com.typesafe.scalalogging.LazyLogging
import soot.jimple._
import soot.jimple.internal.{JArrayRef, JAssignStmt}
import soot.jimple.internal.{AbstractInvokeExpr, JArrayRef, JAssignStmt}
import soot.jimple.spark.ondemand.DemandCSPointsTo
import soot.jimple.spark.pag
import soot.jimple.spark.pag.{AllocNode, PAG}
Expand Down Expand Up @@ -203,6 +203,7 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
override def internalTransform(phaseName: String, options: util.Map[String, String]): Unit = {
pointsToAnalysis = Scene.v().getPointsToAnalysis
initAllocationSites()
// println(allocationSites.foreach(println(_)))
Scene.v().getEntryPoints.forEach(method => {
traverse(method)
methods = methods + 1
Expand Down Expand Up @@ -310,7 +311,7 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
pmtCount = pmtCount + 1
}
else if(isAssignReturnLocalStmt(callStmt.base, s)) { // return "<variable>"
defsToCallSite(caller, callee, calleeDefs, callStmt.base, s) // create an 'edge' FROM the stmt where the return variable is defined TO "call site stmt"
defsToCallSite(caller, callee, calleeDefs, callStmt.base, s, callStmt, defs, exp) // create an 'edge' FROM the stmt where the return variable is defined TO "call site stmt"
}
else if(isReturnStringStmt(callStmt.base, s)) { // return "<string>"
stringToCallSite(caller, callee, callStmt.base, s) // create an 'edge' FROM "return string stmt" TO "call site stmt"
Expand Down Expand Up @@ -388,22 +389,22 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
}
// default case
if(base.isInstanceOf[Local]) {
var allocationNodes = findAllocationSites(base.asInstanceOf[Local], false, ref.getField)
var allocationNodes = findFieldStores(base.asInstanceOf[Local], ref.getField)

if (allocationNodes.isEmpty) {
allocationNodes = findAllocationSites(base.asInstanceOf[Local], true, ref.getField)
allocationNodes = findAllocationSites(base.asInstanceOf[Local], false, ref.getField)
}

if (allocationNodes.isEmpty) {
allocationNodes = findFieldStores(base.asInstanceOf[Local], ref.getField)
allocationNodes = findAllocationSites(base.asInstanceOf[Local], true, ref.getField)
}

allocationNodes.foreach(source => {
val target = createNode(method, stmt)
updateGraph(source, target) // update 'edge' FROM allocationNode? stmt TO load rule stmt (current stmt)
svg.getAdjacentNodes(source).get.foreach(s => {
updateGraph(s, target) // update 'edge' FROM adjacent node of allocationNode? stmt TO load rule stmt (current stmt)
}) // add comment
// svg.getAdjacentNodes(source).get.foreach(s => {
// updateGraph(s, target) // update 'edge' FROM adjacent node of allocationNode? stmt TO load rule stmt (current stmt)
// }) // add comment
})

// create an edge from the base defs to target
Expand Down Expand Up @@ -508,22 +509,33 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
* CASE 2
* ??
*/
private def defsToCallSite(caller: SootMethod, callee: SootMethod, calleeDefs: SimpleLocalDefs, callStmt: soot.Unit, retStmt: soot.Unit) = {
private def defsToCallSite(caller: SootMethod, callee: SootMethod, calleeDefs: SimpleLocalDefs, callStmt: soot.Unit, retStmt: soot.Unit, stmt: Statement, defs: SimpleLocalDefs, exp: InvokeExpr) = {

// CASE 1
val target = createNode(caller, callStmt)
val local = retStmt.asInstanceOf[ReturnStmt].getOp.asInstanceOf[Local]

val allocationSites = getAllocationSites(exp)

calleeDefs.getDefsOfAt(local, retStmt).forEach(sourceStmt => {
val source = createNode(callee, sourceStmt)
val csCloseLabel = createCSCloseLabel(caller, callStmt, callee)
svg.addEdge(source, target, csCloseLabel) // create an EDGE FROM "definition stmt from return variable " TO "call site stmt"


if (allocationSites.nonEmpty) {
allocationSites.foreach(al => {
val csCloseLabel = createCSCloseLabel(caller, callStmt, callee, Set(al.show()))
svg.addEdge(source, target, csCloseLabel) // create an EDGE FROM "definition stmt from return variable " TO "call site stmt"
})
} else {
val csCloseLabel = createCSCloseLabel(caller, callStmt, callee, Set())
svg.addEdge(source, target, csCloseLabel) // create an EDGE FROM "definition stmt from return variable " TO "call site stmt"
}

// CASE 2
if(local.getType.isInstanceOf[ArrayType]) {
val stores = arrayStores.getOrElseUpdate(local, List())
stores.foreach(sourceStmt => {
val source = createNode(callee, sourceStmt)
val csCloseLabel = createCSCloseLabel(caller, callStmt, callee)
val csCloseLabel = createCSCloseLabel(caller, callStmt, callee, Set())
svg.addEdge(source, target, csCloseLabel) // add comment
})
}
Expand Down Expand Up @@ -566,9 +578,12 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
val target = createNode(callee, targetStmt)

val base = invokeExpr.getBase.asInstanceOf[Local]

// val al = getAllocationSites(callStatement, expr, calleeDefs)

calleeDefs.getDefsOfAt(base, callStatement.base).forEach(sourceStmt => {
val source = createNode(caller, sourceStmt)
val csOpenLabel = createCSOpenLabel(caller, callStatement.base, callee)
val csOpenLabel = createCSOpenLabel(caller, callStatement.base, callee, Set())
svg.addEdge(source, target, csOpenLabel) // create 'Edge' FROM the stmt where the object that calls the method was instanced TO the this definition in callee method
})
}
Expand All @@ -589,13 +604,37 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
val target = createNode(callee, assignStmt)

val local = exp.getArg(pmtCount).asInstanceOf[Local]

val allocationSites = getAllocationSites(exp)

defs.getDefsOfAt(local, stmt.base).forEach(sourceStmt => {
val source = createNode(caller, sourceStmt)
val csOpenLabel = createCSOpenLabel(caller, stmt.base, callee) //
svg.addEdge(source, target, csOpenLabel) // creates an 'edge' FROM stmt where the variable is defined TO stmt where the variable is loaded

if (allocationSites.nonEmpty) {
allocationSites.foreach(al => {
val csOpenLabel = createCSOpenLabel(caller, stmt.base, callee, Set(al.show())) //
svg.addEdge(source, target, csOpenLabel) // creates an 'edge' FROM stmt where the variable is defined TO stmt where the variable is loaded
})
} else {
val csOpenLabel = createCSOpenLabel(caller, stmt.base, callee, Set()) //
svg.addEdge(source, target, csOpenLabel) // creates an 'edge' FROM stmt where the variable is defined TO stmt where the variable is loaded
}
})
}

private def getAllocationSites(invokeExpr: InvokeExpr): ListBuffer[GraphNode] = invokeExpr match {
case exp: VirtualInvokeExpr => exp.getBase match {
case base: Local => getAllocationSites(base)
case _ => ListBuffer[GraphNode]()
}
case _ => ListBuffer[GraphNode]()
}

private def getAllocationSites(base: Local): ListBuffer[GraphNode] = findAllocationSites(base, false) match {
case v if v.isEmpty => findAllocationSites(base)
case v => v
}

/**
* CASE 1:
* UPDATE EDGE(S)
Expand Down Expand Up @@ -653,16 +692,16 @@ abstract class JSVFA extends SVFA with Analysis with FieldSensitiveness with Obj
svg.createNode(method, stmt, analyze)


def createCSOpenLabel(method: SootMethod, stmt: soot.Unit, callee: SootMethod): CallSiteLabel = {
def createCSOpenLabel(method: SootMethod, stmt: soot.Unit, callee: SootMethod, context: Set[String]): CallSiteLabel = {
val statement = br.unb.cic.soot.graph.Statement(method.getDeclaringClass.toString, method.getSignature, stmt.toString,
stmt.getJavaSourceStartLineNumber, stmt, method)
CallSiteLabel(ContextSensitiveRegion(statement, callee.toString), CallSiteOpenLabel)
CallSiteLabel(ContextSensitiveRegion(statement, callee.toString, context), CallSiteOpenLabel)
}

def createCSCloseLabel(method: SootMethod, stmt: soot.Unit, callee: SootMethod): CallSiteLabel = {
def createCSCloseLabel(method: SootMethod, stmt: soot.Unit, callee: SootMethod, context: Set[String]): CallSiteLabel = {
val statement = br.unb.cic.soot.graph.Statement(method.getDeclaringClass.toString, method.getSignature, stmt.toString,
stmt.getJavaSourceStartLineNumber, stmt, method)
CallSiteLabel(ContextSensitiveRegion(statement, callee.toString), CallSiteCloseLabel)
CallSiteLabel(ContextSensitiveRegion(statement, callee.toString, context), CallSiteCloseLabel)
}

def isThisInitStmt(expr: InvokeExpr, unit: soot.Unit) : Boolean =
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/samples/context/Context1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package samples.context;

public class Context1 {

public static void main(String args[]) {

String s1, s1Aux;

IdentityClass o1 = new IdentityClass();

s1 = source();
s1Aux = o1.identity(s1);
sink(s1Aux);
}

public static String source() {
return "secret";
}

public static void sink(String s) {
System.out.println(s);
}
}

class IdentityClass {

public static String identity(String s) {
return s;
}
}
37 changes: 37 additions & 0 deletions src/test/java/samples/context/Context2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package samples.context;

public class Context2 {

public static void main(String args[]) {

String s1, s1Aux;
String s2, s2Aux;

IdentityClass2 o1 = new IdentityClass2();
s1 = source();
s1Aux = o1.identity(s1);


IdentityClass2 o2 = new IdentityClass2();
s2 = "abc";
s2Aux = o2.identity(s2);

sink(s1Aux);
sink(s2Aux);
}

public static String source() {
return "secret";
}

public static void sink(String s) {
System.out.println(s);
}
}

class IdentityClass2 {

public static String identity(String s) {
return s;
}
}
38 changes: 38 additions & 0 deletions src/test/java/samples/context/Context3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package samples.context;

public class Context3 {

public static void main(String args[]) {

String s1, s1Aux;
OnceCallFancy o1 = new OnceCallFancy();

s1 = source();
o1.setInformation(s1);
s1Aux = o1.getInformation();

sink(s1Aux);
}

public static String source() {
return "secret";
}

public static void sink(String s) {
System.out.println(s);
}
}

class OnceCallFancy {

public String information;
public void setInformation(String _information)
{
this.information = _information;
}

public String getInformation()
{
return this.information;
}
}
Loading