Skip to content

Commit f0ffcd0

Browse files
committed
DataFlowStack updated
1 parent 635b32d commit f0ffcd0

File tree

3 files changed

+94
-69
lines changed

3 files changed

+94
-69
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/DataFlowStack.qll

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import csharp
22
private import codeql.dataflow.DataFlow
33
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
44
private import codeql.dataflowstack.DataFlowStack as DFS
5-
private import DFS::DataFlowStackMake<Location, CsharpDataFlow> as DataFlowStackFactory
65

7-
private module DataFlowStackInput<DataFlowStackFactory::DataFlow::ConfigSig Config> implements
8-
DFS::DataFlowStackSig<Location, CsharpDataFlow, Config>
6+
module LanguageDataFlowStack = DFS::LanguageDataFlow<Location, CsharpDataFlow>;
7+
8+
private module FlowStackInput<DataFlow::ConfigSig Config>
9+
implements LanguageDataFlowStack::DataFlowGroup<Config>::DataFlowStackSig<DataFlow::Global<Config>>
910
{
1011
private module Flow = DataFlow::Global<Config>;
1112

@@ -24,13 +25,13 @@ private module DataFlowStackInput<DataFlowStackFactory::DataFlow::ConfigSig Conf
2425
}
2526
}
2627

27-
module DataFlowStackMake<DataFlowStackFactory::DataFlow::ConfigSig Config> {
28-
import DataFlowStackFactory::FlowStack<Config, DataFlowStackInput<Config>>
28+
module DataFlowStackMake<DataFlow::ConfigSig Config> {
29+
import LanguageDataFlowStack::FlowStack<DataFlow::Global<Config>, Config, FlowStackInput<Config>>
2930
}
3031

3132
module BiStackAnalysisMake<
32-
DataFlowStackFactory::DataFlow::ConfigSig ConfigA,
33-
DataFlowStackFactory::DataFlow::ConfigSig ConfigB>
34-
{
35-
import DataFlowStackFactory::BiStackAnalysis<ConfigA, DataFlowStackInput<ConfigA>, ConfigB, DataFlowStackInput<ConfigB>>
36-
}
33+
DataFlow::ConfigSig ConfigA,
34+
DataFlow::ConfigSig ConfigB
35+
>{
36+
import LanguageDataFlowStack::BiStackAnalysis<ConfigA, DataFlow::Global<ConfigA>, FlowStackInput<ConfigA>, ConfigB, DataFlow::Global<ConfigB>, FlowStackInput<ConfigB>>
37+
}

java/ql/lib/semmle/code/java/dataflow/DataFlowStack.qll

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import java
55
private import semmle.code.java.dataflow.DataFlow
66
private import semmle.code.java.dataflow.internal.DataFlowImplSpecific
77
private import codeql.dataflowstack.DataFlowStack as DFS
8-
private import DFS::DataFlowStackMake<Location, JavaDataFlow> as DataFlowStackFactory
98

10-
private module DataFlowStackInput<DataFlowStackFactory::DataFlow::ConfigSig Config> implements
11-
DFS::DataFlowStackSig<Location, JavaDataFlow, Config>
9+
module LanguageDataFlowStack = DFS::LanguageDataFlow<Location, JavaDataFlow>;
10+
11+
private module FlowStackInput<DataFlow::ConfigSig Config>
12+
implements LanguageDataFlowStack::DataFlowGroup<Config>::DataFlowStackSig<DataFlow::Global<Config>>
1213
{
1314
private module Flow = DataFlow::Global<Config>;
1415

@@ -27,13 +28,13 @@ private module DataFlowStackInput<DataFlowStackFactory::DataFlow::ConfigSig Conf
2728
}
2829
}
2930

30-
module DataFlowStackMake<DataFlowStackFactory::DataFlow::ConfigSig Config> {
31-
import DataFlowStackFactory::FlowStack<Config, DataFlowStackInput<Config>>
31+
module DataFlowStackMake<DataFlow::ConfigSig Config> {
32+
import LanguageDataFlowStack::FlowStack<DataFlow::Global<Config>, Config, FlowStackInput<Config>>
3233
}
3334

3435
module BiStackAnalysisMake<
35-
DataFlowStackFactory::DataFlow::ConfigSig ConfigA,
36-
DataFlowStackFactory::DataFlow::ConfigSig ConfigB>
37-
{
38-
import DataFlowStackFactory::BiStackAnalysis<ConfigA, DataFlowStackInput<ConfigA>, ConfigB, DataFlowStackInput<ConfigB>>
39-
}
36+
DataFlow::ConfigSig ConfigA,
37+
DataFlow::ConfigSig ConfigB
38+
>{
39+
import LanguageDataFlowStack::BiStackAnalysis<ConfigA, DataFlow::Global<ConfigA>, FlowStackInput<ConfigA>, ConfigB, DataFlow::Global<ConfigB>, FlowStackInput<ConfigB>>
40+
}

shared/dataflowstack/codeql/dataflowstack/DataFlowStack.qll

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,57 @@ module;
44
private import codeql.dataflow.DataFlow as DF
55
private 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

Comments
 (0)