@@ -40,6 +40,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
40
40
*/
41
41
predicate isSink ( Node sink ) ;
42
42
43
+ /**
44
+ * Holds if `sink` is a relevant data flow sink accepting `state`.
45
+ */
46
+ predicate isSinkReverse ( Node sink , FlowState state ) ;
47
+
48
+ /**
49
+ * Holds if `sink` is a relevant data flow sink for any state.
50
+ */
51
+ predicate isSinkReverse ( Node sink ) ;
52
+
43
53
/**
44
54
* Holds if data flow through `node` is prohibited. This completely removes
45
55
* `node` from the data flow graph.
@@ -149,6 +159,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
149
159
150
160
predicate isSink ( Node sink , FlowState state ) { Config:: isSink ( sink ) and exists ( state ) }
151
161
162
+ predicate isSinkReverse ( Node sink , FlowState state ) {
163
+ Config:: isSinkReverse ( sink ) and exists ( state )
164
+ }
165
+
152
166
predicate isBarrier ( Node node , FlowState state ) { none ( ) }
153
167
154
168
predicate isBarrierIn ( Node node , FlowState state ) { none ( ) }
@@ -192,18 +206,32 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
192
206
else any ( )
193
207
}
194
208
209
+ pragma [ nomagic]
210
+ private predicate isFilteredSinkReverse ( Node sink ) {
211
+ (
212
+ Config:: isSinkReverse ( sink , _) or
213
+ Config:: isSinkReverse ( sink )
214
+ ) and
215
+ if Config:: observeDiffInformedIncrementalMode ( )
216
+ then AlertFiltering:: filterByLocation ( sink .getLocation ( ) )
217
+ else any ( )
218
+ }
219
+
195
220
private predicate hasFilteredSource ( ) { isFilteredSource ( _) }
196
221
197
222
private predicate hasFilteredSink ( ) { isFilteredSink ( _) }
198
223
224
+ private predicate hasFilteredSinkReverse ( ) { isFilteredSinkReverse ( _) }
225
+
199
226
predicate isRelevantSource ( Node source , FlowState state ) {
200
227
// If there are filtered sinks, we need to pass through all sources to preserve all alerts
201
228
// with filtered sinks. Otherwise the only alerts of interest are those with filtered
202
229
// sources, so we can perform the source filtering right here.
203
230
Config:: isSource ( source , state ) and
204
231
(
205
232
isFilteredSource ( source ) or
206
- hasFilteredSink ( )
233
+ hasFilteredSink ( ) or
234
+ hasFilteredSinkReverse ( )
207
235
)
208
236
}
209
237
@@ -218,6 +246,17 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
218
246
)
219
247
}
220
248
249
+ predicate isRelevantSinkReverse ( Node sink , FlowState state ) {
250
+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
251
+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
252
+ // sinks, so we can perform the sink filtering right here.
253
+ Config:: isSinkReverse ( sink , state ) and
254
+ (
255
+ isFilteredSinkReverse ( sink ) or
256
+ hasFilteredSource ( )
257
+ )
258
+ }
259
+
221
260
predicate isRelevantSink ( Node sink ) {
222
261
// If there are filtered sources, we need to pass through all sinks to preserve all alerts
223
262
// with filtered sources. Otherwise the only alerts of interest are those with filtered
@@ -229,12 +268,30 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
229
268
)
230
269
}
231
270
271
+ predicate isRelevantSinkReverse ( Node sink ) {
272
+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
273
+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
274
+ // sinks, so we can perform the sink filtering right here.
275
+ Config:: isSinkReverse ( sink ) and
276
+ (
277
+ isFilteredSinkReverse ( sink ) or
278
+ hasFilteredSource ( )
279
+ )
280
+ }
281
+
232
282
bindingset [ source, sink]
233
283
pragma [ inline_late]
234
284
predicate isRelevantSourceSinkPair ( Node source , Node sink ) {
235
285
isFilteredSource ( source ) or
236
286
isFilteredSink ( sink )
237
287
}
288
+
289
+ bindingset [ source, sink]
290
+ pragma [ inline_late]
291
+ predicate isRelevantSourceSinkPairReverse ( Node source , Node sink ) {
292
+ isFilteredSource ( source ) or
293
+ isFilteredSinkReverse ( sink )
294
+ }
238
295
}
239
296
240
297
private import SourceSinkFiltering
@@ -258,19 +315,28 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
258
315
259
316
private predicate outBarrier ( NodeEx node ) {
260
317
exists ( Node n |
261
- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
318
+ node .asNodeOrImplicitRead ( ) = n and
262
319
Config:: isBarrierOut ( n )
263
320
|
264
321
isRelevantSink ( n , _)
265
322
or
266
323
isRelevantSink ( n )
267
324
)
325
+ or
326
+ exists ( Node n |
327
+ node .asNodeReverse ( _) = n and
328
+ Config:: isBarrierOut ( n )
329
+ |
330
+ isRelevantSinkReverse ( n , _)
331
+ or
332
+ isRelevantSinkReverse ( n )
333
+ )
268
334
}
269
335
270
336
pragma [ nomagic]
271
337
private predicate outBarrier ( NodeEx node , FlowState state ) {
272
338
exists ( Node n |
273
- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
339
+ node .asNodeOrImplicitRead ( ) = n and
274
340
Config:: isBarrierOut ( n , state )
275
341
|
276
342
isRelevantSink ( n , state )
@@ -321,6 +387,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
321
387
not stateBarrier ( node , state )
322
388
}
323
389
390
+ pragma [ nomagic]
391
+ private predicate sinkNodeWithStateReverse ( NodeEx node , FlowState state ) {
392
+ isRelevantSinkReverse ( node .asNodeReverse ( _) , state ) and
393
+ not fullBarrier ( node ) and
394
+ not stateBarrier ( node , state )
395
+ }
396
+
324
397
/** Provides the relevant barriers for a step from `node1` to `node2`. */
325
398
bindingset [ node1, node2]
326
399
private predicate stepFilter ( NodeEx node1 , NodeEx node2 ) {
@@ -707,6 +780,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
707
780
fwdFlow ( node ) and
708
781
fwdFlowState ( state ) and
709
782
sinkNodeWithState ( node , state )
783
+ or
784
+ fwdFlow ( pragma [ only_bind_into ] ( node ) ) and
785
+ fwdFlowState ( state ) and
786
+ isRelevantSinkReverse ( node .asNodeReverse ( _) )
787
+ or
788
+ fwdFlow ( node ) and
789
+ fwdFlowState ( state ) and
790
+ sinkNodeWithState ( node , state )
791
+ or
792
+ fwdFlow ( node ) and
793
+ fwdFlowState ( state ) and
794
+ sinkNodeWithStateReverse ( node , state )
710
795
}
711
796
712
797
/**
@@ -1025,7 +1110,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1025
1110
1026
1111
private predicate sinkModel ( NodeEx node , string model ) {
1027
1112
sinkNode ( node , _) and
1028
- exists ( Node n | n = node .asNodeOrImplicitRead ( ) |
1113
+ exists ( Node n | n = [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] |
1029
1114
knownSinkModel ( n , model )
1030
1115
or
1031
1116
not knownSinkModel ( n , _) and model = ""
@@ -2996,6 +3081,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2996
3081
( isRelevantSink ( n ) or isRelevantSink ( n , _) ) and
2997
3082
result .asNode ( ) = n
2998
3083
)
3084
+ or
3085
+ exists ( Node n |
3086
+ node .asNodeReverse ( _) = n and
3087
+ ( isRelevantSinkReverse ( n ) or isRelevantSinkReverse ( n , _) ) and
3088
+ result = node
3089
+ )
2999
3090
}
3000
3091
3001
3092
override PathNodeImpl getASuccessorImpl ( string label ) {
@@ -3492,6 +3583,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
3492
3583
/** Gets the underlying `Node`. */
3493
3584
final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
3494
3585
3586
+ /** Gets the underlying `Node`, but only when it represents a reverse-flow node. */
3587
+ final Node getNodeReverse ( ) { super .getNodeEx ( ) .asNodeReverse ( _) = result }
3588
+
3495
3589
/** Gets the parameter node through which data is returned, if any. */
3496
3590
final ParameterNode asParameterReturnNode ( ) {
3497
3591
result = super .getNodeEx ( ) .asNodeReverse ( _)
@@ -4841,7 +4935,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4841
4935
private predicate interestingCallableSink ( DataFlowCallable c ) {
4842
4936
exists ( Node n | c = getNodeEnclosingCallable ( n ) |
4843
4937
isRelevantSink ( n , _) or
4844
- isRelevantSink ( n )
4938
+ isRelevantSink ( n ) or
4939
+ isRelevantSinkReverse ( n , _) or
4940
+ isRelevantSinkReverse ( n )
4845
4941
)
4846
4942
or
4847
4943
exists ( DataFlowCallable mid | interestingCallableSink ( mid ) and callableStep ( c , mid ) )
@@ -4877,7 +4973,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4877
4973
ce1 = TCallable ( getNodeEnclosingCallable ( n ) )
4878
4974
|
4879
4975
isRelevantSink ( n , _) or
4880
- isRelevantSink ( n )
4976
+ isRelevantSink ( n ) or
4977
+ isRelevantSinkReverse ( n , _) or
4978
+ isRelevantSinkReverse ( n )
4881
4979
)
4882
4980
}
4883
4981
@@ -4945,6 +5043,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4945
5043
relevantState ( state ) and
4946
5044
not fullBarrier ( node ) and
4947
5045
not stateBarrier ( node , state )
5046
+ or
5047
+ isRelevantSinkReverse ( node .asNodeReverse ( _) ) and
5048
+ relevantState ( state ) and
5049
+ not fullBarrier ( node ) and
5050
+ not stateBarrier ( node , state )
4948
5051
}
4949
5052
4950
5053
private newtype TSummaryCtx1 =
0 commit comments