pascal-lab / Tai-e

An easy-to-learn/use static analysis framework for Java
https://tai-e.pascal-lab.net/docs/index.html
GNU Lesser General Public License v3.0
1.4k stars 172 forks source link

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

Closed chengxinwei closed 1 year ago

chengxinwei commented 1 year ago

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

chengxinwei commented 1 year ago

image

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

zhangt2333 commented 1 year ago

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:

https://github.com/pascal-lab/Tai-e/blob/081bf63309745ae4b9406427bccb87818350c11c/src/main/java/pascal/taie/analysis/graph/callgraph/CallGraphs.java#L112-L113

                .setEdgeLabeler(e -> IRPrinter.toString(
-                        ((MethodEdge<Invoke, JMethod>) e).callSite()))
+                        ((MethodEdge<Invoke, JMethod>) e).callSite())
+                        .replace("\"", "\\\""))
chengxinwei commented 1 year ago

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?

chengxinwei commented 1 year ago

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

zhangt2333 commented 1 year ago

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 https://github.com/pascal-lab/Tai-e/blob/92adc485e319a5c108b7d711f557b9c7b69a9f43/src/main/java/pascal/taie/analysis/pta/core/solver/DefaultSolver.java#L527-L530

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.

chengxinwei commented 1 year ago

got it, it's working, thank you!