Skip to content

Commit cfed7e9

Browse files
committed
Shared: add in/out barriers with flow state
1 parent ab6e8b9 commit cfed7e9

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

shared/dataflow/codeql/dataflow/DataFlow.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,15 @@ module Configs<InputSig Lang> {
357357
/** Holds if data flow into `node` is prohibited. */
358358
default predicate isBarrierIn(Node node) { none() }
359359

360+
/** Holds if data flow into `node` is prohibited when the target flow state is `state`. */
361+
default predicate isBarrierIn(Node node, FlowState state) { none() }
362+
360363
/** Holds if data flow out of `node` is prohibited. */
361364
default predicate isBarrierOut(Node node) { none() }
362365

366+
/** Holds if data flow out of `node` is prohibited when the originating flow state is `state`. */
367+
default predicate isBarrierOut(Node node, FlowState state) { none() }
368+
363369
/**
364370
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
365371
*/

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,15 @@ module MakeImpl<InputSig Lang> {
5353
/** Holds if data flow into `node` is prohibited. */
5454
predicate isBarrierIn(Node node);
5555

56+
/** Holds if data flow into `node` is prohibited when the target flow state is `state`. */
57+
predicate isBarrierIn(Node node, FlowState state);
58+
5659
/** Holds if data flow out of `node` is prohibited. */
5760
predicate isBarrierOut(Node node);
5861

62+
/** Holds if data flow out of `node` is prohibited when the originating flow state is `state`. */
63+
predicate isBarrierOut(Node node, FlowState state);
64+
5965
/**
6066
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
6167
*/
@@ -133,6 +139,10 @@ module MakeImpl<InputSig Lang> {
133139

134140
predicate isBarrier(Node node, FlowState state) { none() }
135141

142+
predicate isBarrierIn(Node node, FlowState state) { none() }
143+
144+
predicate isBarrierOut(Node node, FlowState state) { none() }
145+
136146
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
137147
none()
138148
}
@@ -220,6 +230,14 @@ module MakeImpl<InputSig Lang> {
220230
)
221231
}
222232

233+
private predicate inBarrier(NodeEx node, FlowState state) {
234+
exists(Node n |
235+
node.asNode() = n and
236+
Config::isBarrierIn(n, state) and
237+
Config::isSource(n, state)
238+
)
239+
}
240+
223241
private predicate outBarrier(NodeEx node) {
224242
exists(Node n |
225243
node.asNode() = n and
@@ -231,6 +249,17 @@ module MakeImpl<InputSig Lang> {
231249
)
232250
}
233251

252+
private predicate outBarrier(NodeEx node, FlowState state) {
253+
exists(Node n |
254+
node.asNode() = n and
255+
Config::isBarrierOut(n, state)
256+
|
257+
Config::isSink(n, state)
258+
or
259+
Config::isSink(n)
260+
)
261+
}
262+
234263
pragma[nomagic]
235264
private predicate fullBarrier(NodeEx node) {
236265
exists(Node n | node.asNode() = n |
@@ -247,7 +276,16 @@ module MakeImpl<InputSig Lang> {
247276

248277
pragma[nomagic]
249278
private predicate stateBarrier(NodeEx node, FlowState state) {
250-
exists(Node n | node.asNode() = n | Config::isBarrier(n, state))
279+
exists(Node n | node.asNode() = n |
280+
Config::isBarrier(n, state)
281+
or
282+
Config::isBarrierIn(n, state) and
283+
not Config::isSource(n, state)
284+
or
285+
Config::isBarrierOut(n, state) and
286+
not Config::isSink(n, state) and
287+
not Config::isSink(n)
288+
)
251289
}
252290

253291
pragma[nomagic]
@@ -265,6 +303,7 @@ module MakeImpl<InputSig Lang> {
265303
}
266304

267305
/** Provides the relevant barriers for a step from `node1` to `node2`. */
306+
bindingset[node1, node2]
268307
pragma[inline]
269308
private predicate stepFilter(NodeEx node1, NodeEx node2) {
270309
not outBarrier(node1) and
@@ -273,6 +312,17 @@ module MakeImpl<InputSig Lang> {
273312
not fullBarrier(node2)
274313
}
275314

315+
/** Provides the relevant barriers for a step from `node1,state1` to `node2,state2`, including stateless barriers for `node1` to `node2`. */
316+
bindingset[node1, state1, node2, state2]
317+
pragma[inline]
318+
private predicate stateStepFilter(NodeEx node1, FlowState state1, NodeEx node2, FlowState state2) {
319+
stepFilter(node1, node2) and
320+
not outBarrier(node1, state1) and
321+
not inBarrier(node2, state2) and
322+
not stateBarrier(node1, state1) and
323+
not stateBarrier(node2, state2)
324+
}
325+
276326
pragma[nomagic]
277327
private predicate isUnreachableInCall1(NodeEx n, LocalCallContextSpecificCall cc) {
278328
isUnreachableInCallCached(n.asNode(), cc.getCall())
@@ -325,9 +375,7 @@ module MakeImpl<InputSig Lang> {
325375
node2.asNode() = n2 and
326376
Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
327377
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
328-
stepFilter(node1, node2) and
329-
not stateBarrier(node1, s1) and
330-
not stateBarrier(node2, s2)
378+
stateStepFilter(node1, s1, node2, s2)
331379
)
332380
}
333381

@@ -364,9 +412,7 @@ module MakeImpl<InputSig Lang> {
364412
node2.asNode() = n2 and
365413
Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
366414
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
367-
stepFilter(node1, node2) and
368-
not stateBarrier(node1, s1) and
369-
not stateBarrier(node2, s2) and
415+
stateStepFilter(node1, s1, node2, s2) and
370416
not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext
371417
)
372418
}

0 commit comments

Comments
 (0)