Skip to content

Commit c825ca8

Browse files
committed
Shared: Refactor DataFlowStack so that we don't depend on our own modifications to the shared dataflow library files.
1 parent 464ae8b commit c825ca8

File tree

2 files changed

+506
-26
lines changed

2 files changed

+506
-26
lines changed

shared/dataflowstack/codeql/dataflowstack/DataFlowStack.qll

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,38 @@
11
private import codeql.dataflow.DataFlow as DF
22
private 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+
420
module 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

Comments
 (0)