Skip to content

Commit

Permalink
Release version
Browse files Browse the repository at this point in the history
  • Loading branch information
CaelmBleidd committed Sep 19, 2023
1 parent ceb15dd commit 7a07cd4
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ class TaintAnalysis(
) : TaintTarget(location)
// TODO add field source targets

class TaintIntermediateTarget(location: JcInst) : TaintTarget(location)
class TaintIntermediateTarget(location: JcInst) : TaintTarget(location) {

}

// TODO is it important? Or we track every possible mark?
class TaintMethodSinkTarget(
Expand Down
24 changes: 24 additions & 0 deletions usvm-jvm/src/samples/java/org/usvm/samples/taint/Taint.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ public int simpleTaint(boolean x) {
return value.length();
}

public int simpleFalsePositive(boolean x) {
String value = stringProducer(x);
String[] array = new String[2];

array[0] = value;
array[1] = "safe_data";

consumerOfInjections(array[1]);

return value.length();
}

public int simpleTruePositive(boolean x, int i) {
String value = stringProducer(x);
String[] array = new String[2];

array[0] = value;
array[1] = "safe_data";

consumerOfInjections(array[i]);

return value.length();
}

public int taintWithReturningValue(boolean x) {
String value = stringProducer(x);

Expand Down
198 changes: 179 additions & 19 deletions usvm-jvm/src/test/kotlin/org/usvm/samples/taint/TaintTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import org.usvm.api.targets.TaintMethodSink
import org.usvm.api.targets.TaintMethodSource
import org.usvm.api.targets.TaintPassThrough
import org.usvm.samples.JavaMethodTestRunner
import org.usvm.test.util.checkers.eq
import org.usvm.test.util.checkers.ignoreNumberOfAnalysisResults
import org.usvm.util.Options
import org.usvm.util.UsvmTest
Expand All @@ -35,23 +34,55 @@ import kotlin.test.assertTrue

class TaintTest : JavaMethodTestRunner() {
@UsvmTest([Options([PathSelectionStrategy.TARGETED])])
fun testTaintedEntrySource(options: UMachineOptions) {
fun testSimpleTaint(options: UMachineOptions) {
withOptions(options) {
checkDiscoveredProperties(
Taint::taintedEntrySource,
eq(2)
)
val sampleAnalysis = constructSampleTaintAnalysis(cp)

withTargets(sampleAnalysis.targets.toList().cast(), sampleAnalysis) {
checkDiscoveredProperties(
Taint::simpleTaint,
ignoreNumberOfAnalysisResults,
)
}

val collectedStates = sampleAnalysis.collectedStates
assertEquals(expected = 1, actual = collectedStates.size)

val reachedTargets = collectedStates.single().reachedTerminalTargets.singleOrNull() as? JcTarget<*>

assertNotNull(reachedTargets)
assertTrue { reachedTargets.isTerminal }
assertTrue { reachedTargets.isRemoved }
assertTrue { reachedTargets is TaintAnalysis.TaintMethodSinkTarget }
assertTrue { reachedTargets.parent is TaintAnalysis.TaintMethodSourceTarget }
}
}

@UsvmTest([Options([PathSelectionStrategy.TARGETED])])
fun testSimpleTaint(options: UMachineOptions) {
fun testSimpleFalsePositive(options: UMachineOptions) {
withOptions(options) {
val sampleAnalysis = constructSampleTaintAnalysis(cp)

withTargets(sampleAnalysis.targets.toList().cast(), sampleAnalysis) {
checkDiscoveredProperties(
Taint::simpleTaint,
Taint::simpleFalsePositive,
ignoreNumberOfAnalysisResults,
)
}

val collectedStates = sampleAnalysis.collectedStates
assertEquals(expected = 0, actual = collectedStates.size)
}
}

@UsvmTest([Options([PathSelectionStrategy.TARGETED])])
fun testSimpleTruePositive(options: UMachineOptions) {
withOptions(options) {
val sampleAnalysis = constructSampleTaintAnalysis(cp)

withTargets(sampleAnalysis.targets.toList().cast(), sampleAnalysis) {
checkDiscoveredProperties(
Taint::simpleTruePositive,
ignoreNumberOfAnalysisResults,
)
}
Expand All @@ -65,33 +96,53 @@ class TaintTest : JavaMethodTestRunner() {
assertTrue { reachedTargets.isTerminal }
assertTrue { reachedTargets.isRemoved }
assertTrue { reachedTargets is TaintAnalysis.TaintMethodSinkTarget }
assertTrue { reachedTargets.parent is TaintAnalysis.TaintMethodSourceTarget }
}
}

@UsvmTest([Options([PathSelectionStrategy.TARGETED])])
fun testTaintWithReturningValue(options: UMachineOptions) {
withOptions(options) {
checkDiscoveredProperties(
Taint::taintWithReturningValue,
eq(2)
)
val sampleAnalysis = constructSampleTaintAnalysis(cp)

withTargets(sampleAnalysis.targets.toList().cast(), sampleAnalysis) {
checkDiscoveredProperties(
Taint::taintWithReturningValue,
ignoreNumberOfAnalysisResults
)
}

val collectedStates = sampleAnalysis.collectedStates
assertEquals(expected = 1, actual = collectedStates.size)

val reachedTargets = collectedStates.single().reachedTerminalTargets.singleOrNull() as? JcTarget<*>

assertNotNull(reachedTargets)
assertTrue { reachedTargets.isTerminal }
assertTrue { reachedTargets.isRemoved }
assertTrue { reachedTargets is TaintAnalysis.TaintMethodSinkTarget }
assertTrue { reachedTargets.parent is TaintAnalysis.TaintMethodSourceTarget }
}
}

@UsvmTest([Options([PathSelectionStrategy.TARGETED])])
fun testGoThroughCleaner(options: UMachineOptions) {
withOptions(options) {
checkDiscoveredProperties(
Taint::goThroughCleaner,
eq(2)
)
val sampleAnalysis = constructSampleTaintAnalysis(cp)

withTargets(sampleAnalysis.targets.toList().cast(), sampleAnalysis) {
checkDiscoveredProperties(
Taint::goThroughCleaner,
ignoreNumberOfAnalysisResults
)
}

val collectedStates = sampleAnalysis.collectedStates
assertEquals(expected = 0, actual = collectedStates.size)
}
}


// TODO separate cleaning actions
// TODO for demonstration purposes only, must be either moved to another place or removed completely
// TODO for demonstration purposes only, must be either moved to another place or removed completely
fun sampleConfiguration(cp: JcClasspath): TaintConfiguration {
fun findMethod(className: String, methodName: String) = cp
.findClassOrNull(className)!!
Expand Down Expand Up @@ -235,9 +286,118 @@ class TaintTest : JavaMethodTestRunner() {
sourceTargetForSimpleTaint.addChild(sinkTargetForSimpleTaint)


val sourceTargetForFalsePositive = TaintAnalysis.TaintMethodSourceTarget(
findMethod(sampleClassName, "simpleFalsePositive")
.instList
.first { "stringProducer" in it.toString() },
stringProducerRule.conditionWithAction.first,
stringProducerRule
)

val intermediateTarget = TaintAnalysis.TaintIntermediateTarget(
findMethod(sampleClassName, "simpleFalsePositive")
.instList
.first { "[0]" in it.toString() },
)

val secondIntermediateTarget = TaintAnalysis.TaintIntermediateTarget(
findMethod(sampleClassName, "simpleFalsePositive")
.instList
.first { "[1]" in it.toString() },
)

val sinkTargetForFalsePositive = TaintAnalysis.TaintMethodSinkTarget(
findMethod(sampleClassName, "simpleFalsePositive")
.instList
.first { "consumerOfInjections" in it.toString() },
consumerSinkRule.condition,
consumerSinkRule
)

secondIntermediateTarget.addChild(sinkTargetForFalsePositive)
intermediateTarget.addChild(secondIntermediateTarget)
sourceTargetForFalsePositive.addChild(intermediateTarget)

val sourceTargetForTruePositive = TaintAnalysis.TaintMethodSourceTarget(
findMethod(sampleClassName, "simpleTruePositive")
.instList
.first { "stringProducer" in it.toString() },
stringProducerRule.conditionWithAction.first,
stringProducerRule
)

val intermediateTargetTruePositive = TaintAnalysis.TaintIntermediateTarget(
findMethod(sampleClassName, "simpleTruePositive")
.instList
.first { "[0]" in it.toString() },
)

val secondIntermediateTargetTruePositive = TaintAnalysis.TaintIntermediateTarget(
findMethod(sampleClassName, "simpleTruePositive")
.instList
.first { "[1]" in it.toString() },
)

val sinkTargetForTruePositive = TaintAnalysis.TaintMethodSinkTarget(
findMethod(sampleClassName, "simpleTruePositive")
.instList
.first { "consumerOfInjections" in it.toString() },
consumerSinkRule.condition,
consumerSinkRule
)

secondIntermediateTargetTruePositive.addChild(sinkTargetForTruePositive)
intermediateTargetTruePositive.addChild(secondIntermediateTargetTruePositive)
sourceTargetForTruePositive.addChild(intermediateTargetTruePositive)


val sourceTaintWithReturningValue = TaintAnalysis.TaintMethodSourceTarget(
findMethod(sampleClassName, "taintWithReturningValue")
.instList
.first { "stringProducer" in it.toString() },
stringProducerRule.conditionWithAction.first,
stringProducerRule
)

val consumerWithReturningValue = findMethod(sampleClassName, "consumerWithReturningValue")
val consumerWithReturningValueSinkRule = configuration.methodSinks[consumerWithReturningValue]!!.first()

val sinkTaintWithRetuningValue = TaintAnalysis.TaintMethodSinkTarget(
findMethod(sampleClassName, "taintWithReturningValue")
.instList
.first { "consumerWithReturningValue" in it.toString() },
consumerWithReturningValueSinkRule.condition,
consumerWithReturningValueSinkRule
)

sourceTaintWithReturningValue.addChild(sinkTaintWithRetuningValue)


val sourceTaintGoThroughCleaner = TaintAnalysis.TaintMethodSourceTarget(
findMethod(sampleClassName, "goThroughCleaner")
.instList
.first { "stringProducer" in it.toString() },
stringProducerRule.conditionWithAction.first,
stringProducerRule
)

val sinkTaintGoThroughCleaner = TaintAnalysis.TaintMethodSinkTarget(
findMethod(sampleClassName, "goThroughCleaner")
.instList
.first { "consumerOfInjections" in it.toString() },
consumerSinkRule.condition,
consumerSinkRule
)

sourceTaintGoThroughCleaner.addChild(sinkTaintGoThroughCleaner)

return TaintAnalysis(configuration)
.addTarget(targetForTaintedEntrySink)
.addTarget(sourceTargetForSimpleTaint)
.addTarget(sourceTargetForFalsePositive)
.addTarget(sourceTargetForTruePositive)
.addTarget(sourceTaintWithReturningValue)
.addTarget(sourceTaintGoThroughCleaner)
}
}

0 comments on commit 7a07cd4

Please sign in to comment.