11private import codeql.dataflow.DataFlow as DF
22private import codeql.util.Location
33
4+ signature module DataFlowStackSig<
5+ LocationSig Location, DF:: InputSig< Location > Lang, DF:: Configs< Location , Lang > :: ConfigSig Config>
6+ {
7+ Lang:: Node getNode ( DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n ) ;
8+
9+ predicate isSource ( DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n ) ;
10+
11+ DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode getASuccessor (
12+ DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n
13+ ) ;
14+
15+ Lang:: DataFlowCallable getARuntimeTarget ( Lang:: DataFlowCall call ) ;
16+
17+ Lang:: Node getAnArgumentNode ( Lang:: DataFlowCall call ) ;
18+ }
19+
420module DataFlowStackMake< LocationSig Location, DF:: InputSig< Location > Lang> {
5- import DF:: DataFlowMake< Location , Lang > as DataFlow
21+ module DataFlow = DF:: DataFlowMake< Location , Lang > ;
22+
23+ module BiStackAnalysis<
24+ DF:: Configs< Location , Lang > :: ConfigSig ConfigA,
25+ DataFlowStackSig< Location , Lang , ConfigA > DataFlowStackA,
26+ DF:: Configs< Location , Lang > :: ConfigSig ConfigB,
27+ DataFlowStackSig< Location , Lang , ConfigB > DataFlowStackB>
28+ {
29+ module FlowA = DataFlow:: Global< ConfigA > ;
630
7- module BiStackAnalysis< DataFlow:: GlobalFlowSig FlowA, DataFlow:: GlobalFlowSig FlowB> {
8- module FlowStackA = FlowStack< FlowA > ;
31+ module FlowStackA = FlowStack< ConfigA , DataFlowStackA > ;
932
10- module FlowStackB = FlowStack< FlowB > ;
33+ module FlowB = DataFlow:: Global< ConfigB > ;
34+
35+ module FlowStackB = FlowStack< ConfigB , DataFlowStackB > ;
1136
1237 /**
1338 * Holds if either the Stack associated with `sourceNodeA` is a subset of the stack associated with `sourceNodeB`
@@ -25,9 +50,11 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
2550 flowStackA = FlowStackA:: createFlowStack ( sourceNodeA , sinkNodeA ) and
2651 flowStackB = FlowStackB:: createFlowStack ( sourceNodeB , sinkNodeB ) and
2752 (
28- BiStackAnalysisImpl< FlowA , FlowB > :: flowStackIsSubsetOf ( flowStackA , flowStackB )
53+ BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsSubsetOf ( flowStackA ,
54+ flowStackB )
2955 or
30- BiStackAnalysisImpl< FlowB , FlowA > :: flowStackIsSubsetOf ( flowStackB , flowStackA )
56+ BiStackAnalysisImpl< ConfigB , DataFlowStackB , ConfigA , DataFlowStackA > :: flowStackIsSubsetOf ( flowStackB ,
57+ flowStackA )
3158 )
3259 )
3360 }
@@ -51,10 +78,10 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
5178 flowStackA = FlowStackA:: createFlowStack ( sourceNodeA , sinkNodeA ) and
5279 flowStackB = FlowStackB:: createFlowStack ( sourceNodeB , sinkNodeB ) and
5380 (
54- BiStackAnalysisImpl< FlowA , FlowB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
81+ BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
5582 flowStackB )
5683 or
57- BiStackAnalysisImpl< FlowB , FlowA > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackB ,
84+ BiStackAnalysisImpl< ConfigB , DataFlowStackB , ConfigA , DataFlowStackA > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackB ,
5885 flowStackA )
5986 )
6087 )
@@ -67,7 +94,8 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
6794 * The top of stackA is in stackB and the bottom of stackA is then some successor further down stackB.
6895 */
6996 predicate flowStackIsSubsetOf ( FlowStackA:: FlowStack flowStackA , FlowStackB:: FlowStack flowStackB ) {
70- BiStackAnalysisImpl< FlowA , FlowB > :: flowStackIsSubsetOf ( flowStackA , flowStackB )
97+ BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsSubsetOf ( flowStackA ,
98+ flowStackB )
7199 }
72100
73101 /**
@@ -78,15 +106,20 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
78106 predicate flowStackIsConvergingTerminatingSubsetOf (
79107 FlowStackA:: FlowStack flowStackA , FlowStackB:: FlowStack flowStackB
80108 ) {
81- BiStackAnalysisImpl< FlowA , FlowB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
109+ BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
82110 flowStackB )
83111 }
84112 }
85113
86- private module BiStackAnalysisImpl< DataFlow:: GlobalFlowSig FlowA, DataFlow:: GlobalFlowSig FlowB> {
87- module FlowStackA = FlowStack< FlowA > ;
114+ private module BiStackAnalysisImpl<
115+ DF:: Configs< Location , Lang > :: ConfigSig ConfigA,
116+ DataFlowStackSig< Location , Lang , ConfigA > DataFlowStackA,
117+ DF:: Configs< Location , Lang > :: ConfigSig ConfigB,
118+ DataFlowStackSig< Location , Lang , ConfigB > DataFlowStackB>
119+ {
120+ module FlowStackA = FlowStack< ConfigA , DataFlowStackA > ;
88121
89- module FlowStackB = FlowStack< FlowB > ;
122+ module FlowStackB = FlowStack< ConfigB , DataFlowStackB > ;
90123
91124 /**
92125 * Holds if stackA is a subset of stackB,
@@ -130,25 +163,30 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
130163 }
131164 }
132165
133- module FlowStack< DataFlow:: GlobalFlowSig Flow> {
166+ module FlowStack<
167+ DF:: Configs< Location , Lang > :: ConfigSig Config,
168+ DataFlowStackSig< Location , Lang , Config > DataFlowStack>
169+ {
170+ private module Flow = DF:: DataFlowMake< Location , Lang > :: Global< Config > ;
171+
134172 /**
135173 * Determines whether or not the given PathNode is a source
136174 * TODO: Refactor to Flow::PathNode signature
137175 */
138- predicate isSource ( Flow:: PathNode node ) { node . isSource ( ) }
176+ predicate isSource ( Flow:: PathNode node ) { DataFlowStack :: isSource ( node ) }
139177
140178 /**
141179 * Determines whether or not the given PathNode is a sink
142180 * TODO: Refactor to Flow::PathNode signature
143181 */
144- predicate isSink ( Flow:: PathNode node ) { not exists ( node . getASuccessor ( ) ) }
182+ predicate isSink ( Flow:: PathNode node ) { not exists ( DataFlowStack :: getASuccessor ( node ) ) }
145183
146184 /** A FlowStack encapsulates flows between a source and a sink, and all the pathways inbetween (possibly multiple) */
147185 private newtype FlowStackType =
148186 TFlowStack ( Flow:: PathNode source , Flow:: PathNode sink ) {
149- source . isSource ( ) and
150- not exists ( sink . getASuccessor ( ) ) and
151- source . getASuccessor * ( ) = sink
187+ DataFlowStack :: isSource ( source ) and
188+ not exists ( DataFlowStack :: getASuccessor ( sink ) ) and
189+ DataFlowStack :: getASuccessor * ( source ) = sink
152190 }
153191
154192 class FlowStack extends FlowStackType , TFlowStack {
@@ -197,8 +235,8 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
197235 TFlowStackFrame ( FlowStack flowStack , CallFrame frame ) {
198236 exists ( Flow:: PathNode source , Flow:: PathNode sink |
199237 flowStack = TFlowStack ( source , sink ) and
200- frame .getPathNode ( ) = source . getASuccessor * ( ) and
201- frame .getPathNode ( ) . getASuccessor * ( ) = sink
238+ frame .getPathNode ( ) = DataFlowStack :: getASuccessor * ( source ) and
239+ DataFlowStack :: getASuccessor ( frame .getPathNode ( ) ) = sink
202240 )
203241 }
204242
@@ -241,7 +279,8 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
241279 FlowStackFrame getChildStackFrame ( ) {
242280 exists ( FlowStackFrame transitiveSuccessor |
243281 transitiveSuccessor = this .getASuccessor + ( ) and
244- this .getCall ( ) .getARuntimeTarget ( ) = transitiveSuccessor .getCall ( ) .getEnclosingCallable ( ) and
282+ DataFlowStack:: getARuntimeTarget ( this .getCall ( ) ) =
283+ transitiveSuccessor .getCall ( ) .getEnclosingCallable ( ) and
245284 result = transitiveSuccessor
246285 )
247286 }
@@ -272,7 +311,9 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
272311 */
273312 private newtype TCallFrameType =
274313 TCallFrame ( Flow:: PathNode node ) {
275- exists ( Lang:: DataFlowCall c | c .getAnArgumentNode ( ) = node .getNode ( ) )
314+ exists ( Lang:: DataFlowCall c |
315+ DataFlowStack:: getAnArgumentNode ( c ) = DataFlowStack:: getNode ( node )
316+ )
276317 }
277318
278319 /**
@@ -307,7 +348,7 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
307348 Lang:: DataFlowCall getCall ( ) {
308349 exists ( Lang:: DataFlowCall call , Flow:: PathNode node |
309350 this = TCallFrame ( node ) and
310- call . getAnArgumentNode ( ) = node . getNode ( ) and
351+ DataFlowStack :: getAnArgumentNode ( call ) = DataFlowStack :: getNode ( node ) and
311352 result = call
312353 )
313354 }
@@ -329,8 +370,11 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
329370 */
330371 private Flow:: PathNode getSuccessorCall ( Flow:: PathNode n ) {
331372 exists ( Flow:: PathNode succ |
332- succ = n .getASuccessor ( ) and
333- if exists ( Lang:: DataFlowCall c | c .getAnArgumentNode ( ) = succ .getNode ( ) )
373+ succ = DataFlowStack:: getASuccessor ( n ) and
374+ if
375+ exists ( Lang:: DataFlowCall c |
376+ DataFlowStack:: getAnArgumentNode ( c ) = DataFlowStack:: getNode ( succ )
377+ )
334378 then result = succ
335379 else result = getSuccessorCall ( succ )
336380 )
0 commit comments