pascal-lab/Tai-e

`List::foreach` cannot be analyzed in `only-app:true`

chengxinwei opened this issue · 6 comments

Describe the bug

Hi

I'm trying to use Tai-e framework to analysis my java program, I may found a issue which Tai-e can't analysis lamda foreach statement.

the code be analysised

import java.util.ArrayList;
import java.util.List;

class InterTaintTransfer {

    public static void main(String[] args) {
        SourceSink sourceSink = new SourceSink();
        List<String> list = new ArrayList<>();
        list.stream().forEach( e -> {sink(sourceSink);});
    }
    static void sink(SourceSink s){
        doSink(s);
    }

    static void doSink(SourceSink s){

    }

}

the arguments I start Tai-e
-pp -m InterTaintTransfer -cp src/test/resources/pta/taint/ -a pta=cs:2-type;dump-ci:true;dump:true;only-app:true;implicit-entries:false;taint-config:src/test/resources/pta/taint/taint-config.yml;handle-invokedynamic:true -a cg=dump:true

the call-graph.dot result

digraph G {
  node [color=".3 .2 1.0",shape=box,style=filled];
  edge [];
  "0" [label="<java.util.Collection: java.util.stream.Stream stream()>",];
  "1" [label="<java.lang.Object: void <init>()>",];
  "2" [label="<java.lang.invoke.LambdaMetafactory: java.lang.invoke.CallSite metafactory(java.lang.invoke.MethodHandles$Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.invoke.MethodType,java.lang.invoke.MethodHandle,java.lang.invoke.MethodType)>",];
  "3" [label="<SourceSink: void <init>()>",];
  "4" [label="<InterTaintTransfer: void main(java.lang.String[])>",];
  "5" [label="<java.util.ArrayList: void <init>()>",];
  "3" -> "1" [label="[0@L1] invokespecial %this.<java.lang.Object: void <init>()>();",];
  "4" -> "5" [label="[3@L8] invokespecial $r1.<java.util.ArrayList: void <init>()>();",];
  "4" -> "0" [label="[4@L9] $r2 = invokeinterface $r1.<java.util.List: java.util.stream.Stream stream()>();",];
  "4" -> "3" [label="[1@L7] invokespecial $r0.<SourceSink: void <init>()>();",];
  "4" -> "2" [label="[5@L9] $r3 = invokedynamic <java.lang.invoke.LambdaMetafactory: java.lang.invoke.CallSite metafactory(java.lang.invoke.MethodHandles$Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.invoke.MethodType,java.lang.invoke.MethodHandle,java.lang.invoke.MethodType)> "accept" <MethodType: java.util.function.Consumer (SourceSink)>[MethodType: void (java.lang.Object), MethodHandle[REF_invokeStatic]: <InterTaintTransfer: void lambda$main$0(SourceSink,java.lang.String)>, MethodType: void (java.lang.String)]($r0);",];
}

issue 1:
the call graph of static void sink(SourceSink s) is missing.

issue 2:
the call-graph.dot looks like has some syntax error, it throw exception when I use dotviz to convert .dot to .pdf.
the command I executed
dot -Tpdf call-graph.dot -o cg_result.pdf

and the result and exception I got.
Error: call-graph.dot: syntax error in line 14 near '"'

Tai-e arguments

-pp -m InterTaintTransfer -cp src/test/resources/pta/taint/ -a pta=cs:2-type;dump-ci:true;dump:true;only-app:true;implicit-entries:false;taint-config:src/test/resources/pta/taint/taint-config.yml;handle-invokedynamic:true -a cg=dump:true

Runtime environment infomation

No response

image

BTW, I'm confirmed the LambdaAnalysis plugin and InvokeDynamicAnalysis plugin have been added during the analysis.

issue 1:
the call graph of static void sink(SourceSink s) is missing.

The lambda function of list.stream().forEach(e -> {sink(sourceSink);}) will be invoked within the JDK, and it is not part of the APP. So you need to change only-app:true; to only-app:false;

issue 2:
the call-graph.dot looks like has some syntax error

image

Yes, I will fix it later.

Before this, if you need it urgently, you can make the following modifications in your cloned Tai-e:

.setEdgeLabeler(e -> IRPrinter.toString(
((MethodEdge<Invoke, JMethod>) e).callSite()))

                .setEdgeLabeler(e -> IRPrinter.toString(
-                        ((MethodEdge<Invoke, JMethod>) e).callSite()))
+                        ((MethodEdge<Invoke, JMethod>) e).callSite())
+                        .replace("\"", "\\\""))

i've changed the running arguments to
-pp -m InterTaintTransfer -cp src/test/resources/pta/taint/ -a pta=cs:2-type;dump-ci:true;dump:true;only-app:false;implicit-entries:false;handle-invokedynamic:true -a cg=dump:true

the analysis program is running for 15mins, still running......

may I ask how long it will take?

is there anyway to support lamda while using only-app:true ?

i've changed the running arguments to -pp -m InterTaintTransfer -cp src/test/resources/pta/taint/ -a pta=cs:2-type;dump-ci:true;dump:true;only-app:false;implicit-entries:false;handle-invokedynamic:true -a cg=dump:true

the analysis program is running for 15mins, still running......

may I ask how long it will take?

I run with -pp -m InterTaintTransfer -cp src/test/resources/pta/taint/ -a pta=cs:2-type;only-app:false;implicit-entries:false;handle-invokedynamic:true -a cg=dump:true, and it took less than 5 mins on my machine.

is there anyway to support lamda while using only-app:true ?

Sure, but note that the analysis results may not sound.

Modify

private boolean isIgnored(JMethod method) {
return ignoredMethods.contains(method) ||
onlyApp && !method.isApplication();
}

to make collection-related (CollectionMethods can be useful) and lambda-related (maybe you can use check if the class name starts with java.util.function, java.util.stream and so on) methods non-ignored.

got it, it's working, thank you!