@@ -4,38 +4,57 @@ module;
44private import codeql.dataflow.DataFlow as DF
55private import codeql.util.Location
66
7- signature module DataFlowStackSig<
8- LocationSig Location, DF:: InputSig< Location > Lang, DF:: Configs< Location , Lang > :: ConfigSig Config>
9- {
10- Lang:: Node getNode ( DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n ) ;
7+ /**
8+ * A Language-initialized grouping of DataFlow types and primitives.
9+ */
10+ module LanguageDataFlow< LocationSig Location, DF:: InputSig< Location > Lang> {
11+ module AbstractDF = DF:: Configs< Location , Lang > ;
12+ module AbstractDataFlow = DF:: DataFlowMake< Location , Lang > ;
13+ module AbstractDataFlowOverlay = DF:: DataFlowMakeOverlay< Location , Lang > ;
14+
15+ /**
16+ * A collection of modules that are scoped to a specific DataFlow config implementation
17+ */
18+ module DataFlowGroup< AbstractDF:: ConfigSig Config> {
19+
20+ module MyConfig = Config;
21+ module DataFlowGlobal = AbstractDataFlow:: Global< Config > ;
22+ module DataFlowOverlayGlobal = AbstractDataFlowOverlay:: Global< Config > ;
1123
12- predicate isSource ( DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n ) ;
24+ /**
25+ * A Taint tracking implementation, paramaterized over a DataFlow type
26+ */
27+ signature module DataFlowStackSig< AbstractDataFlow:: GlobalFlowSig GlobalFlow> {
28+
29+ Lang:: Node getNode ( GlobalFlow:: PathNode n ) ;
1330
14- DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode getASuccessor (
15- DF:: DataFlowMake< Location , Lang > :: Global< Config > :: PathNode n
16- ) ;
31+ predicate isSource ( GlobalFlow:: PathNode n ) ;
1732
18- Lang:: DataFlowCallable getARuntimeTarget ( Lang:: DataFlowCall call ) ;
33+ GlobalFlow:: PathNode getASuccessor (
34+ GlobalFlow:: PathNode n
35+ ) ;
1936
20- Lang:: Node getAnArgumentNode ( Lang:: DataFlowCall call ) ;
21- }
37+ Lang:: DataFlowCallable getARuntimeTarget ( Lang:: DataFlowCall call ) ;
2238
23- module DataFlowStackMake< LocationSig Location, DF:: InputSig< Location > Lang> {
24- module DataFlow = DF:: DataFlowMake< Location , Lang > ;
39+ Lang:: Node getAnArgumentNode ( Lang:: DataFlowCall call ) ;
40+ }
41+ }
2542
2643 module BiStackAnalysis<
27- DF:: Configs< Location , Lang > :: ConfigSig ConfigA,
28- DataFlowStackSig< Location , Lang , ConfigA > DataFlowStackA,
29- DF:: Configs< Location , Lang > :: ConfigSig ConfigB,
30- DataFlowStackSig< Location , Lang , ConfigB > DataFlowStackB>
44+ AbstractDF:: ConfigSig ConfigA,
45+ AbstractDataFlow:: GlobalFlowSig GlobalFlowA,
46+ DataFlowGroup< ConfigA > :: DataFlowStackSig< GlobalFlowA > TaintTrackingStackA,
47+ AbstractDF:: ConfigSig ConfigB,
48+ AbstractDataFlow:: GlobalFlowSig GlobalFlowB,
49+ DataFlowGroup< ConfigB > :: DataFlowStackSig< GlobalFlowB > TaintTrackingStackB>
3150 {
32- module FlowA = DataFlow :: Global < ConfigA > ;
51+ module FlowA = GlobalFlowA ;
3352
34- module FlowStackA = FlowStack< ConfigA , DataFlowStackA > ;
53+ module FlowStackA = FlowStack< GlobalFlowA , ConfigA , TaintTrackingStackA > ;
3554
36- module FlowB = DataFlow :: Global < ConfigB > ;
55+ module FlowB = GlobalFlowB ;
3756
38- module FlowStackB = FlowStack< ConfigB , DataFlowStackB > ;
57+ module FlowStackB = FlowStack< GlobalFlowB , ConfigB , TaintTrackingStackB > ;
3958
4059 /**
4160 * Holds if either the Stack associated with `sourceNodeA` is a subset of the stack associated with `sourceNodeB`
@@ -53,10 +72,10 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
5372 flowStackA = FlowStackA:: createFlowStack ( sourceNodeA , sinkNodeA ) and
5473 flowStackB = FlowStackB:: createFlowStack ( sourceNodeB , sinkNodeB ) and
5574 (
56- BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsSubsetOf ( flowStackA ,
75+ BiStackAnalysisImpl< GlobalFlowA , ConfigA , TaintTrackingStackA , GlobalFlowB , ConfigB , TaintTrackingStackB > :: flowStackIsSubsetOf ( flowStackA ,
5776 flowStackB )
5877 or
59- BiStackAnalysisImpl< ConfigB , DataFlowStackB , ConfigA , DataFlowStackA > :: flowStackIsSubsetOf ( flowStackB ,
78+ BiStackAnalysisImpl< GlobalFlowB , ConfigB , TaintTrackingStackB , GlobalFlowA , ConfigA , TaintTrackingStackA > :: flowStackIsSubsetOf ( flowStackB ,
6079 flowStackA )
6180 )
6281 )
@@ -81,10 +100,10 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
81100 flowStackA = FlowStackA:: createFlowStack ( sourceNodeA , sinkNodeA ) and
82101 flowStackB = FlowStackB:: createFlowStack ( sourceNodeB , sinkNodeB ) and
83102 (
84- BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
103+ BiStackAnalysisImpl< GlobalFlowA , ConfigA , TaintTrackingStackA , GlobalFlowB , ConfigB , TaintTrackingStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
85104 flowStackB )
86105 or
87- BiStackAnalysisImpl< ConfigB , DataFlowStackB , ConfigA , DataFlowStackA > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackB ,
106+ BiStackAnalysisImpl< GlobalFlowB , ConfigB , TaintTrackingStackB , GlobalFlowA , ConfigA , TaintTrackingStackA > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackB ,
88107 flowStackA )
89108 )
90109 )
@@ -97,7 +116,7 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
97116 * The top of stackA is in stackB and the bottom of stackA is then some successor further down stackB.
98117 */
99118 predicate flowStackIsSubsetOf ( FlowStackA:: FlowStack flowStackA , FlowStackB:: FlowStack flowStackB ) {
100- BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsSubsetOf ( flowStackA ,
119+ BiStackAnalysisImpl< GlobalFlowA , ConfigA , TaintTrackingStackA , GlobalFlowB , ConfigB , TaintTrackingStackB > :: flowStackIsSubsetOf ( flowStackA ,
101120 flowStackB )
102121 }
103122
@@ -109,20 +128,23 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
109128 predicate flowStackIsConvergingTerminatingSubsetOf (
110129 FlowStackA:: FlowStack flowStackA , FlowStackB:: FlowStack flowStackB
111130 ) {
112- BiStackAnalysisImpl< ConfigA , DataFlowStackA , ConfigB , DataFlowStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
131+ BiStackAnalysisImpl< GlobalFlowA , ConfigA , TaintTrackingStackA , GlobalFlowB , ConfigB , TaintTrackingStackB > :: flowStackIsConvergingTerminatingSubsetOf ( flowStackA ,
113132 flowStackB )
114133 }
115134 }
116135
117136 private module BiStackAnalysisImpl<
118- DF:: Configs< Location , Lang > :: ConfigSig ConfigA,
119- DataFlowStackSig< Location , Lang , ConfigA > DataFlowStackA,
120- DF:: Configs< Location , Lang > :: ConfigSig ConfigB,
121- DataFlowStackSig< Location , Lang , ConfigB > DataFlowStackB>
137+ AbstractDataFlow:: GlobalFlowSig GlobalFlowA,
138+ AbstractDF:: ConfigSig ConfigA,
139+ DataFlowGroup< ConfigA > :: DataFlowStackSig< GlobalFlowA > DataFlowStackA,
140+ AbstractDataFlow:: GlobalFlowSig GlobalFlowB,
141+ AbstractDF:: ConfigSig ConfigB,
142+ DataFlowGroup< ConfigB > :: DataFlowStackSig< GlobalFlowB > DataFlowStackB>
122143 {
123- module FlowStackA = FlowStack< ConfigA , DataFlowStackA > ;
124144
125- module FlowStackB = FlowStack< ConfigB , DataFlowStackB > ;
145+ module FlowStackA = FlowStack< GlobalFlowA , ConfigA , DataFlowStackA > ;
146+
147+ module FlowStackB = FlowStack< GlobalFlowB , ConfigB , DataFlowStackB > ;
126148
127149 /**
128150 * Holds if stackA is a subset of stackB,
@@ -167,29 +189,30 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
167189 }
168190
169191 module FlowStack<
170- DF:: Configs< Location , Lang > :: ConfigSig Config,
171- DataFlowStackSig< Location , Lang , Config > DataFlowStack>
192+ AbstractDataFlow:: GlobalFlowSig GlobalFlow,
193+ AbstractDF:: ConfigSig Config,
194+ DataFlowGroup< Config > :: DataFlowStackSig< GlobalFlow > TaintTrackingStack>
172195 {
173- private module Flow = DF :: DataFlowMake < Location , Lang > :: Global < Config > ;
196+ private module Flow = GlobalFlow ;
174197
175198 /**
176199 * Determines whether or not the given PathNode is a source
177200 * TODO: Refactor to Flow::PathNode signature
178201 */
179- predicate isSource ( Flow:: PathNode node ) { DataFlowStack :: isSource ( node ) }
202+ predicate isSource ( Flow:: PathNode node ) { TaintTrackingStack :: isSource ( node ) }
180203
181204 /**
182205 * Determines whether or not the given PathNode is a sink
183206 * TODO: Refactor to Flow::PathNode signature
184207 */
185- predicate isSink ( Flow:: PathNode node ) { not exists ( DataFlowStack :: getASuccessor ( node ) ) }
208+ predicate isSink ( Flow:: PathNode node ) { not exists ( TaintTrackingStack :: getASuccessor ( node ) ) }
186209
187210 /** A FlowStack encapsulates flows between a source and a sink, and all the pathways inbetween (possibly multiple) */
188211 private newtype FlowStackType =
189212 TFlowStack ( Flow:: PathNode source , Flow:: PathNode sink ) {
190- DataFlowStack :: isSource ( source ) and
191- not exists ( DataFlowStack :: getASuccessor ( sink ) ) and
192- DataFlowStack :: getASuccessor * ( source ) = sink
213+ TaintTrackingStack :: isSource ( source ) and
214+ not exists ( TaintTrackingStack :: getASuccessor ( sink ) ) and
215+ TaintTrackingStack :: getASuccessor * ( source ) = sink
193216 }
194217
195218 class FlowStack extends FlowStackType , TFlowStack {
@@ -238,8 +261,8 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
238261 TFlowStackFrame ( FlowStack flowStack , CallFrame frame ) {
239262 exists ( Flow:: PathNode source , Flow:: PathNode sink |
240263 flowStack = TFlowStack ( source , sink ) and
241- frame .getPathNode ( ) = DataFlowStack :: getASuccessor * ( source ) and
242- DataFlowStack :: getASuccessor * ( frame .getPathNode ( ) ) = sink
264+ frame .getPathNode ( ) = TaintTrackingStack :: getASuccessor * ( source ) and
265+ TaintTrackingStack :: getASuccessor * ( frame .getPathNode ( ) ) = sink
243266 )
244267 }
245268
@@ -282,7 +305,7 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
282305 FlowStackFrame getChildStackFrame ( ) {
283306 exists ( FlowStackFrame transitiveSuccessor |
284307 transitiveSuccessor = this .getASuccessor + ( ) and
285- DataFlowStack :: getARuntimeTarget ( this .getCall ( ) ) =
308+ TaintTrackingStack :: getARuntimeTarget ( this .getCall ( ) ) =
286309 transitiveSuccessor .getCall ( ) .getEnclosingCallable ( ) and
287310 result = transitiveSuccessor
288311 )
@@ -315,7 +338,7 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
315338 private newtype TCallFrameType =
316339 TCallFrame ( Flow:: PathNode node ) {
317340 exists ( Lang:: DataFlowCall c |
318- DataFlowStack :: getAnArgumentNode ( c ) = DataFlowStack :: getNode ( node )
341+ TaintTrackingStack :: getAnArgumentNode ( c ) = TaintTrackingStack :: getNode ( node )
319342 )
320343 }
321344
@@ -351,7 +374,7 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
351374 Lang:: DataFlowCall getCall ( ) {
352375 exists ( Lang:: DataFlowCall call , Flow:: PathNode node |
353376 this = TCallFrame ( node ) and
354- DataFlowStack :: getAnArgumentNode ( call ) = DataFlowStack :: getNode ( node ) and
377+ TaintTrackingStack :: getAnArgumentNode ( call ) = TaintTrackingStack :: getNode ( node ) and
355378 result = call
356379 )
357380 }
@@ -373,10 +396,10 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
373396 */
374397 private Flow:: PathNode getSuccessorCall ( Flow:: PathNode n ) {
375398 exists ( Flow:: PathNode succ |
376- succ = DataFlowStack :: getASuccessor ( n ) and
399+ succ = TaintTrackingStack :: getASuccessor ( n ) and
377400 if
378401 exists ( Lang:: DataFlowCall c |
379- DataFlowStack :: getAnArgumentNode ( c ) = DataFlowStack :: getNode ( succ )
402+ TaintTrackingStack :: getAnArgumentNode ( c ) = TaintTrackingStack :: getNode ( succ )
380403 )
381404 then result = succ
382405 else result = getSuccessorCall ( succ )
@@ -430,4 +453,4 @@ module DataFlowStackMake<LocationSig Location, DF::InputSig<Location> Lang> {
430453 }
431454 }
432455 }
433- }
456+ }
0 commit comments