@@ -1019,6 +1019,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1019
1019
callEdgeReturn ( call , c , _, _, _, _, _)
1020
1020
}
1021
1021
1022
+ bindingset [ node1, node2]
1023
+ predicate storeReachesRead ( NodeEx node1 , NodeEx node2 ) {
1024
+ exists ( node1 ) and
1025
+ exists ( node2 )
1026
+ }
1027
+
1022
1028
additional predicate stats (
1023
1029
boolean fwd , int nodes , int fields , int conscand , int states , int tuples , int calledges
1024
1030
) {
@@ -1314,6 +1320,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1314
1320
predicate relevantCallEdgeIn ( DataFlowCall call , DataFlowCallable c ) ;
1315
1321
1316
1322
predicate relevantCallEdgeOut ( DataFlowCall call , DataFlowCallable c ) ;
1323
+
1324
+ bindingset [ node1, node2]
1325
+ predicate storeReachesRead ( NodeEx node1 , NodeEx node2 ) ;
1317
1326
}
1318
1327
1319
1328
private module MkStage< StageSig PrevStage> {
@@ -1512,9 +1521,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1512
1521
)
1513
1522
or
1514
1523
// read
1515
- exists ( Typ t0 , Ap ap0 , Content c |
1524
+ exists ( Typ t0 , Ap ap0 , Content c , NodeEx storeSource |
1516
1525
fwdFlowRead ( t0 , ap0 , c , _, node , state , cc , summaryCtx , argT , argAp ) and
1517
- fwdFlowConsCand ( t0 , ap0 , c , t , ap ) and
1526
+ fwdFlowConsCand ( storeSource , t0 , ap0 , c , t , ap ) and
1527
+ PrevStage:: storeReachesRead ( storeSource , node ) and
1518
1528
apa = getApprox ( ap )
1519
1529
)
1520
1530
or
@@ -1583,16 +1593,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1583
1593
/**
1584
1594
* Holds if forward flow with access path `tail` and type `t1` reaches a
1585
1595
* store of `c` on a container of type `t2` resulting in access path
1586
- * `cons`.
1596
+ * `cons`. `storeSource` is a node that may be stored into `c`.
1587
1597
*/
1588
1598
pragma [ nomagic]
1589
- private predicate fwdFlowConsCand ( Typ t2 , Ap cons , Content c , Typ t1 , Ap tail ) {
1590
- fwdFlowStore ( _, t1 , tail , c , t2 , _, _, _, _, _, _) and
1599
+ private predicate fwdFlowConsCand (
1600
+ NodeEx storeSource , Typ t2 , Ap cons , Content c , Typ t1 , Ap tail
1601
+ ) {
1602
+ fwdFlowStore ( storeSource , t1 , tail , c , t2 , _, _, _, _, _, _) and
1591
1603
cons = apCons ( c , t1 , tail )
1592
1604
or
1593
1605
exists ( Typ t0 |
1594
1606
typeStrengthen ( t0 , cons , t2 ) and
1595
- fwdFlowConsCand ( t0 , cons , c , t1 , tail )
1607
+ fwdFlowConsCand ( storeSource , t0 , cons , c , t1 , tail )
1596
1608
)
1597
1609
}
1598
1610
@@ -2041,9 +2053,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2041
2053
2042
2054
pragma [ nomagic]
2043
2055
private predicate readStepFwd ( NodeEx n1 , Ap ap1 , Content c , NodeEx n2 , Ap ap2 ) {
2044
- exists ( Typ t1 |
2056
+ exists ( Typ t1 , NodeEx storeSource |
2045
2057
fwdFlowRead ( t1 , ap1 , c , n1 , n2 , _, _, _, _, _) and
2046
- fwdFlowConsCand ( t1 , ap1 , c , _, ap2 )
2058
+ fwdFlowConsCand ( storeSource , t1 , ap1 , c , _, ap2 ) and
2059
+ PrevStage:: storeReachesRead ( storeSource , n2 )
2047
2060
)
2048
2061
}
2049
2062
@@ -2157,9 +2170,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2157
2170
returnAp = apNone ( )
2158
2171
or
2159
2172
// store
2160
- exists ( Ap ap0 , Content c |
2173
+ exists ( NodeEx readTarget , Ap ap0 , Content c |
2161
2174
revFlowStore ( ap0 , c , ap , _, node , state , _, returnCtx , returnAp ) and
2162
- revFlowConsCand ( ap0 , c , ap )
2175
+ revFlowConsCand ( readTarget , ap0 , c , ap ) and
2176
+ PrevStage:: storeReachesRead ( node , readTarget )
2163
2177
)
2164
2178
or
2165
2179
// read
@@ -2225,11 +2239,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2225
2239
* resulting in access path `cons`.
2226
2240
*/
2227
2241
pragma [ nomagic]
2228
- private predicate revFlowConsCand ( Ap cons , Content c , Ap tail ) {
2229
- exists ( NodeEx mid , Ap tail0 |
2230
- revFlow ( mid , _, _, _, tail ) and
2242
+ private predicate revFlowConsCand ( NodeEx readTarget , Ap cons , Content c , Ap tail ) {
2243
+ exists ( Ap tail0 |
2244
+ revFlow ( readTarget , _, _, _, tail ) and
2231
2245
tail = pragma [ only_bind_into ] ( tail0 ) and
2232
- readStepFwd ( _, cons , c , mid , tail0 )
2246
+ readStepFwd ( _, cons , c , readTarget , tail0 )
2233
2247
)
2234
2248
}
2235
2249
@@ -2357,7 +2371,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2357
2371
exists ( Ap ap2 |
2358
2372
PrevStage:: storeStepCand ( node1 , _, c , node2 , contentType , containerType ) and
2359
2373
revFlowStore ( ap2 , c , ap1 , _, node1 , _, node2 , _, _) and
2360
- revFlowConsCand ( ap2 , c , ap1 )
2374
+ revFlowConsCand ( _ , ap2 , c , ap1 )
2361
2375
)
2362
2376
}
2363
2377
@@ -2384,7 +2398,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2384
2398
private predicate revConsCand ( Content c , Typ t , Ap ap ) {
2385
2399
exists ( Ap ap2 |
2386
2400
revFlowStore ( ap2 , c , ap , t , _, _, _, _, _) and
2387
- revFlowConsCand ( ap2 , c , ap )
2401
+ revFlowConsCand ( _ , ap2 , c , ap )
2388
2402
)
2389
2403
}
2390
2404
@@ -2487,6 +2501,75 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2487
2501
callEdgeReturn ( call , c , _, _, _, _, _)
2488
2502
}
2489
2503
2504
+ private signature predicate storeReachesReadSig ( NodeEx node1 , NodeEx node2 ) ;
2505
+
2506
+ private module StoreReachesRead< storeReachesReadSig / 2 storeReachesReadIn> {
2507
+ pragma [ nomagic]
2508
+ private predicate step ( NodeEx node1 , NodeEx node2 ) {
2509
+ exists ( FlowState state , Ap ap , ApOption returnAp1 , ApOption returnAp2 |
2510
+ revFlow ( node1 , pragma [ only_bind_into ] ( state ) , _, returnAp1 , pragma [ only_bind_into ] ( ap ) ) and
2511
+ revFlow ( node2 , pragma [ only_bind_into ] ( state ) , _, returnAp2 , pragma [ only_bind_into ] ( ap ) )
2512
+ |
2513
+ localStep ( node1 , state , node2 , state , true , _, _) and
2514
+ returnAp1 = returnAp2
2515
+ or
2516
+ jumpStepEx ( node1 , node2 )
2517
+ or
2518
+ callEdgeArgParam ( _, _, node1 , node2 , _, _)
2519
+ or
2520
+ callEdgeReturn ( _, _, node1 , _, node2 , _, _)
2521
+ or
2522
+ storeReachesReadIn ( node1 , node2 )
2523
+ )
2524
+ }
2525
+
2526
+ private predicate isStoreTarget ( NodeEx node ) { storeStepCand ( _, _, _, node , _, _) }
2527
+
2528
+ private predicate isReadSource ( NodeEx node ) { readStepCand ( node , _, _) }
2529
+
2530
+ private predicate storeReachesReadTc ( NodeEx node1 , NodeEx node2 ) =
2531
+ doublyBoundedFastTC( step / 2 , isStoreTarget / 1 , isReadSource / 1 ) ( node1 , node2 )
2532
+
2533
+ bindingset [ node2, c]
2534
+ pragma [ inline_late]
2535
+ private predicate storeStepCand ( NodeEx node1 , Content c , NodeEx node2 ) {
2536
+ storeStepCand ( node1 , _, c , node2 , _, _)
2537
+ }
2538
+
2539
+ pragma [ nomagic]
2540
+ predicate storeReachesReadOut ( NodeEx node1 , NodeEx node2 ) {
2541
+ exists ( Content c , NodeEx storeTarget , NodeEx readSource |
2542
+ storeReachesReadTc ( storeTarget , readSource ) and
2543
+ storeStepCand ( node1 , c , storeTarget ) and
2544
+ readStepCand ( readSource , c , node2 )
2545
+ )
2546
+ or
2547
+ exists ( Content c , NodeEx storeTargetReadSource |
2548
+ storeStepCand ( node1 , c , storeTargetReadSource ) and
2549
+ readStepCand ( storeTargetReadSource , c , node2 )
2550
+ )
2551
+ }
2552
+ }
2553
+
2554
+ private predicate storeReachesRead0 ( NodeEx node1 , NodeEx node2 ) { none ( ) }
2555
+
2556
+ private predicate storeReachesRead1 =
2557
+ StoreReachesRead< storeReachesRead0 / 2 > :: storeReachesReadOut / 2 ;
2558
+
2559
+ private predicate storeReachesRead2 =
2560
+ StoreReachesRead< storeReachesRead1 / 2 > :: storeReachesReadOut / 2 ;
2561
+
2562
+ private predicate storeReachesRead3 =
2563
+ StoreReachesRead< storeReachesRead2 / 2 > :: storeReachesReadOut / 2 ;
2564
+
2565
+ private predicate storeReachesRead4 =
2566
+ StoreReachesRead< storeReachesRead3 / 2 > :: storeReachesReadOut / 2 ;
2567
+
2568
+ private predicate storeReachesRead5 =
2569
+ StoreReachesRead< storeReachesRead4 / 2 > :: storeReachesReadOut / 2 ;
2570
+
2571
+ predicate storeReachesRead = storeReachesRead5 / 2 ;
2572
+
2490
2573
additional predicate stats (
2491
2574
boolean fwd , int nodes , int fields , int conscand , int states , int tuples , int calledges ,
2492
2575
int tfnodes , int tftuples
0 commit comments