Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import org.opentaint.dataflow.ap.ifds.ElementAccessor
import org.opentaint.dataflow.ap.ifds.FieldAccessor
import org.opentaint.dataflow.ap.ifds.access.FinalFactAp
import org.opentaint.dataflow.ap.ifds.access.InitialFactAp
import org.opentaint.dataflow.ap.ifds.analysis.alias.applyAlias
import org.opentaint.dataflow.ap.ifds.analysis.alias.forEachAliasAtStatement
import org.opentaint.dataflow.ap.ifds.analysis.alias.forEachAliasAtStatementAmongBases
import org.opentaint.dataflow.ap.ifds.analysis.alias.forEachHeapAliasBeforeStatement
Expand All @@ -25,17 +24,6 @@ fun JIRLocalAliasAnalysis.forEachAliasAtStatement(statement: JIRInst, fact: Fina
fun JIRLocalAliasAnalysis.forEachAliasAtStatement(statement: JIRInst, fact: InitialFactAp, body: (InitialFactAp) -> Unit) =
forEachAliasAtStatement(statement, fact, AliasInfo::relevantApInfo, AliasAccessor::apAccessor, body)

fun JIRLocalAliasAnalysis.forEachAliasAfterCallStatement(statement: JIRInst, fact: FinalFactAp, body: (FinalFactAp) -> Unit) {
val base = fact.base as? AccessPathBase.LocalVar ?: return
val aliasesBefore = findAlias(base, statement) ?: return
val aliasesAfter = findAliasAfterStatement(base, statement)?.toSet() ?: return
val aliasesPersistedThroughCall = aliasesBefore.filter { it in aliasesAfter }

aliasesPersistedThroughCall
.filterIsInstance<AliasApInfo>()
.filterNot { alias -> alias.base is AccessPathBase.Constant }
.forEach { alias -> applyAlias(fact, alias, AliasAccessor::apAccessor, body) }
}

fun JIRLocalAliasAnalysis.forEachHeapAliasBeforeStatement(statement: JIRInst, fact: FinalFactAp, body: (FinalFactAp) -> Unit) =
forEachHeapAliasBeforeStatement(statement, fact, Accessor::aliasAccessor, AliasInfo::relevantApInfo, AliasAccessor::apAccessor, body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ class JIRMethodCallFlowFunction(
return
}

analysisContext.aliasAnalysis?.forEachAliasAfterCallStatement(statement, this) { aliased ->
analysisContext.aliasAnalysis?.forEachHeapAliasBeforeStatement(statement, this) { aliased ->
body(aliased)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class JIRMethodCallSummaryHandler(
}

private fun applyCallAliases(fact: FinalFactAp, body: (FinalFactAp) -> Unit) {
analysisContext.aliasAnalysis?.forEachAliasAfterCallStatement(statement, fact) { aliased ->
analysisContext.aliasAnalysis?.forEachHeapAliasBeforeStatement(statement, fact) { aliased ->
body(aliased)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.opentaint.dataflow.jvm.ap.ifds.JIRMethodCallFactMapper.factIsRelevant
import org.opentaint.dataflow.jvm.ap.ifds.MethodFlowFunctionUtils
import org.opentaint.dataflow.jvm.ap.ifds.TaintConfigUtils.accept
import org.opentaint.dataflow.jvm.ap.ifds.analysis.JIRMethodAnalysisContext
import org.opentaint.dataflow.jvm.ap.ifds.analysis.forEachAliasAtStatement
import org.opentaint.dataflow.jvm.ap.ifds.analysis.forEachPossibleAliasAtStatement
import org.opentaint.dataflow.jvm.ap.ifds.taint.TaintRulesProvider
import org.opentaint.dataflow.jvm.ap.ifds.taint.resolveAp
Expand Down Expand Up @@ -58,6 +59,11 @@ class JIRMethodCallPrecondition(
preconditionForFact(aliasedFact)?.let { results += PreconditionFactsForInitialFact(aliasedFact, it) }
}

// todo: do we need to explore all accessors?
analysisContext.aliasAnalysis?.forEachAliasAtStatement(statement, fact) { aliasedFact ->
preconditionForFact(aliasedFact)?.let { results += PreconditionFactsForInitialFact(aliasedFact, it) }
}

return results
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package issues.i98;

public class User_i98_deep {
private class Caller {
void call(Depth2 r, String b) {
r.depth1.data = b;
}

void call(Depth3 r, String b) {
r.depth2.depth1.data = b;
}

void call(Depth4 r, String b) {
r.depth3.depth2.depth1.data = b;
}
}

private class Depth1 {
String data = "";
}

private class Depth2 {
Depth1 depth1 = new Depth1();
}

private class Depth3 {
Depth2 depth2 = new Depth2();
}

private class Depth4 {
Depth3 depth3 = new Depth3();
}

public String badUser(String badString) {
Depth2 d2 = new Depth2();
Depth1 d = d2.depth1;
Caller k = new Caller();
k.call(d2, badString);
return d.data;
}

public String badUserDepth4(String badString) {
Depth4 d4 = new Depth4();
Depth3 d3 = d4.depth3;
Caller k = new Caller();
k.call(d4, badString);
return d3.depth2.depth1.data;
}

public String badUserDepth3(String badString) {
Depth4 d4 = new Depth4();
Depth2 d2 = d4.depth3.depth2;
Caller k = new Caller();
k.call(d4, badString);
return d2.depth1.data;
}

public String badUserDepth2(String badString) {
Depth4 d4 = new Depth4();
Depth1 d1 = d4.depth3.depth2.depth1;
Caller k = new Caller();
k.call(d4, badString);
return d1.data;
}

public String badUserDepth4Call2(String badString) {
Depth4 d4 = new Depth4();
Depth3 d3 = d4.depth3;
Caller k = new Caller();
k.call(d4.depth3.depth2, badString);
return d3.depth2.depth1.data;
}

public String badUserDepth4Call3(String badString) {
Depth4 d4 = new Depth4();
Depth2 d2 = d4.depth3.depth2;
Caller k = new Caller();
k.call(d4.depth3, badString);
return d2.depth1.data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package issues;

import base.RuleSample;
import base.RuleSet;
import issues.i98.User_i98_deep;

@RuleSet("issues/issue98.yaml")
public abstract class issue98_deep implements RuleSample {
static String badString() {
return "42";
}

static void sink(String data) {
}

static class PositiveTaint extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUser(badString())); }
}

static class PositiveDepth4 extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUserDepth4(badString())); }
}

static class PositiveDepth3 extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUserDepth3(badString())); }
}

static class PositiveDepth2 extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUserDepth2(badString())); }
}

static class PositiveDepth4Call2 extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUserDepth4Call2(badString())); }
}

static class PositiveDepth4Call3 extends issue98_deep {
@Override
public void entrypoint() { sink((new User_i98_deep()).badUserDepth4Call3(badString())); }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
rules:
- id: i97
languages:
- java
severity: ERROR
message: badMethod
patterns:
- pattern: |
$A = badString();
...
sink($A);
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import issues.issue96
import issues.issue97
import issues.issueChain
import issues.issueChainSplitBuilder
import issues.issue98_deep
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.TestInstance
Expand Down Expand Up @@ -113,6 +114,9 @@ class IssuesTest : SampleBasedTest() {
@Test
fun `issue chain-pattern split builder`() = runTest<issueChainSplitBuilder>(EXPECT_STATE_VAR)

@Test
fun `issue 98 deep`() = runTest<issue98_deep>()

@AfterAll
fun close() {
closeRunner()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.opentaint.jvm.dataflow.approximations.stdlib;

import org.opentaint.ir.approximation.annotation.Approximate;

import java.util.Iterator;
import java.util.function.Consumer;

@Approximate(java.lang.Iterable.class)
public class Iterable {
public void forEach(Consumer action) {
java.lang.Iterable t = (java.lang.Iterable) (Object) this;
Iterator it = t.iterator();
if (it.hasNext()) {
action.accept(it.next());
}
}
}
Loading