@@ -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 = ""
@@ -3021,6 +3106,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
3021
3106
( isRelevantSink ( n ) or isRelevantSink ( n , _) ) and
3022
3107
result .asNode ( ) = n
3023
3108
)
3109
+ or
3110
+ exists ( Node n |
3111
+ node .asNodeReverse ( _) = n and
3112
+ ( isRelevantSinkReverse ( n ) or isRelevantSinkReverse ( n , _) ) and
3113
+ result = node
3114
+ )
3024
3115
}
3025
3116
3026
3117
override PathNodeImpl getASuccessorImpl ( string label ) {
@@ -3520,6 +3611,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
3520
3611
/** Gets the underlying `Node`. */
3521
3612
final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
3522
3613
3614
+ /** Gets the underlying `Node`, but only when it represents a reverse-flow node. */
3615
+ final Node getNodeReverse ( ) { super .getNodeEx ( ) .asNodeReverse ( _) = result }
3616
+
3523
3617
/** Gets the parameter node through which data is returned, if any. */
3524
3618
final ParameterNode asParameterReturnNode ( ) {
3525
3619
result = super .getNodeEx ( ) .asNodeReverse ( _)
@@ -4869,7 +4963,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4869
4963
private predicate interestingCallableSink ( DataFlowCallable c ) {
4870
4964
exists ( Node n | c = getNodeEnclosingCallable ( n ) |
4871
4965
isRelevantSink ( n , _) or
4872
- isRelevantSink ( n )
4966
+ isRelevantSink ( n ) or
4967
+ isRelevantSinkReverse ( n , _) or
4968
+ isRelevantSinkReverse ( n )
4873
4969
)
4874
4970
or
4875
4971
exists ( DataFlowCallable mid | interestingCallableSink ( mid ) and callableStep ( c , mid ) )
@@ -4905,7 +5001,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4905
5001
ce1 = TCallable ( getNodeEnclosingCallable ( n ) )
4906
5002
|
4907
5003
isRelevantSink ( n , _) or
4908
- isRelevantSink ( n )
5004
+ isRelevantSink ( n ) or
5005
+ isRelevantSinkReverse ( n , _) or
5006
+ isRelevantSinkReverse ( n )
4909
5007
)
4910
5008
}
4911
5009
@@ -4973,6 +5071,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4973
5071
relevantState ( state ) and
4974
5072
not fullBarrier ( node ) and
4975
5073
not stateBarrier ( node , state )
5074
+ or
5075
+ isRelevantSinkReverse ( node .asNodeReverse ( _) ) and
5076
+ relevantState ( state ) and
5077
+ not fullBarrier ( node ) and
5078
+ not stateBarrier ( node , state )
4976
5079
}
4977
5080
4978
5081
private newtype TSummaryCtx1 =
0 commit comments