1+ package it .unipr .checker ;
2+
3+ import it .unipr .analysis .AbstractStack ;
4+ import it .unipr .analysis .EVMAbstractState ;
5+ import it .unipr .analysis .taint .TaintAbstractDomain ;
6+ import it .unipr .cfg .Calldataload ;
7+ import it .unipr .cfg .EVMCFG ;
8+ import it .unipr .cfg .ProgramCounterLocation ;
9+ import it .unipr .utils .MyCache ;
10+ import it .unive .lisa .analysis .AnalysisState ;
11+ import it .unive .lisa .analysis .AnalyzedCFG ;
12+ import it .unive .lisa .analysis .SemanticException ;
13+ import it .unive .lisa .analysis .SimpleAbstractState ;
14+ import it .unive .lisa .analysis .heap .MonolithicHeap ;
15+ import it .unive .lisa .analysis .nonrelational .value .TypeEnvironment ;
16+ import it .unive .lisa .analysis .types .InferredTypes ;
17+ import it .unive .lisa .checks .semantic .CheckToolWithAnalysisResults ;
18+ import it .unive .lisa .checks .semantic .SemanticCheck ;
19+ import it .unive .lisa .program .cfg .CFG ;
20+ import it .unive .lisa .program .cfg .statement .Statement ;
21+ import java .util .Set ;
22+ import org .apache .logging .log4j .LogManager ;
23+ import org .apache .logging .log4j .Logger ;
24+
25+ public class CallDataLoadChecker implements
26+ SemanticCheck <SimpleAbstractState <MonolithicHeap , EVMAbstractState , TypeEnvironment <InferredTypes >>> {
27+
28+ private static final Logger log = LogManager .getLogger (CallDataLoadChecker .class );
29+
30+ @ Override
31+ public boolean visit (
32+ CheckToolWithAnalysisResults <
33+ SimpleAbstractState <MonolithicHeap , EVMAbstractState , TypeEnvironment <InferredTypes >>> tool ,
34+ CFG graph , Statement node ) {
35+
36+ if (node instanceof Calldataload ) {
37+ EVMCFG cfg = ((EVMCFG ) graph );
38+ Statement callDataLoad = node ;
39+
40+ for (AnalyzedCFG <SimpleAbstractState <MonolithicHeap , EVMAbstractState ,
41+ TypeEnvironment <InferredTypes >>> result : tool .getResultOf (cfg )) {
42+ AnalysisState <SimpleAbstractState <MonolithicHeap , EVMAbstractState ,
43+ TypeEnvironment <InferredTypes >>> analysisResult = null ;
44+
45+ try {
46+ analysisResult = result .getAnalysisStateBefore (callDataLoad );
47+ } catch (SemanticException e1 ) {
48+ log .error ("(CallDataLoadChecker): {}" , e1 .getMessage ());
49+ }
50+
51+ // Retrieve the symbolic stack from the analysis result
52+ EVMAbstractState valueState = analysisResult .getState ().getValueState ();
53+
54+ // If the value state is bottom, the jump is definitely
55+ // unreachable
56+ if (valueState .isBottom ())
57+ // Nothing to do
58+ continue ;
59+ else if (valueState .isTop ())
60+ continue ;
61+ else {
62+ for (AbstractStack stack : valueState .getStacks ()) {
63+ log .debug (stack );
64+ }
65+ }
66+ }
67+ }
68+
69+ return true ;
70+ }
71+
72+ private void checkForUncheckedStateUpdate (Statement sstore , CheckToolWithAnalysisResults <
73+ SimpleAbstractState <MonolithicHeap , TaintAbstractDomain , TypeEnvironment <InferredTypes >>> tool ,
74+ EVMCFG cfg ) {
75+
76+ Set <Statement > jumps = cfg .getAllJumpI ();
77+ Set <Statement > calls = cfg .getAllCall ();
78+
79+ for (Statement call : calls ) {
80+ if (cfg .reachableFrom (call , sstore )) {
81+ if (!cfg .reachableFromCrossing (call , sstore , jumps )) {
82+
83+ ProgramCounterLocation sstoreLocation = (ProgramCounterLocation ) sstore .getLocation ();
84+
85+ log .warn ("Unchecked State Update vulnerability at {} at line no. {} coming from line {}" ,
86+ sstoreLocation .getPc (),
87+ sstoreLocation .getSourceCodeLine (),
88+ ((ProgramCounterLocation ) call .getLocation ()).getSourceCodeLine ());
89+
90+ String warn = "Unchecked State Update vulnerability at "
91+ + ((ProgramCounterLocation ) call .getLocation ()).getSourceCodeLine ();
92+ tool .warn (warn );
93+ MyCache .getInstance ().addUncheckedStateUpdateWarning (cfg .hashCode (), warn );
94+ }
95+ }
96+ }
97+ }
98+ }
0 commit comments