@@ -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
@@ -2487,6 +2500,77 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2487
2500
callEdgeReturn ( call , c , _, _, _, _, _)
2488
2501
}
2489
2502
2503
+ private signature predicate storeReachesReadSig ( NodeEx node1 , NodeEx node2 ) ;
2504
+
2505
+ private newtype TNodeAndAp = MkNodeAndAp ( TNodeEx node , Ap ap ) { revFlow ( node , _, _, _, ap ) }
2506
+
2507
+ private module StoreReachesRead< storeReachesReadSig / 2 storeReachesReadIn> {
2508
+ pragma [ nomagic]
2509
+ private predicate step ( TNodeAndAp n1 , TNodeAndAp n2 ) {
2510
+ exists ( NodeEx node1 , NodeEx node2 , Ap ap , FlowState state1 , FlowState state2 |
2511
+ revFlow ( node1 , state1 ) and
2512
+ revFlow ( node2 , state2 ) and
2513
+ n1 = MkNodeAndAp ( node1 , pragma [ only_bind_into ] ( ap ) ) and
2514
+ n2 = MkNodeAndAp ( node2 , pragma [ only_bind_into ] ( ap ) )
2515
+ |
2516
+ localStep ( node1 , state1 , node2 , state2 , true , _, _)
2517
+ or
2518
+ jumpStepEx ( node1 , node2 )
2519
+ or
2520
+ callEdgeArgParam ( _, _, node1 , node2 , _, _)
2521
+ or
2522
+ callEdgeReturn ( _, _, node1 , _, node2 , _, _)
2523
+ or
2524
+ storeReachesReadIn ( node1 , node2 )
2525
+ )
2526
+ }
2527
+
2528
+ private predicate isStoreTarget ( TNodeAndAp n ) {
2529
+ exists ( NodeEx node , Ap ap |
2530
+ n = MkNodeAndAp ( node , ap ) and
2531
+ storeStepCand ( _, _, _, node , _, _)
2532
+ )
2533
+ }
2534
+
2535
+ private predicate isReadSource ( TNodeAndAp n ) {
2536
+ exists ( NodeEx node , Ap ap |
2537
+ n = MkNodeAndAp ( node , ap ) and
2538
+ readStepCand ( node , _, _)
2539
+ )
2540
+ }
2541
+
2542
+ private predicate storeReachesReadTc ( TNodeAndAp node1 , TNodeAndAp node2 ) =
2543
+ doublyBoundedFastTC( step / 2 , isStoreTarget / 1 , isReadSource / 1 ) ( node1 , node2 )
2544
+
2545
+ pragma [ nomagic]
2546
+ predicate storeReachesReadOut ( NodeEx node1 , NodeEx node2 ) {
2547
+ exists ( Content c , NodeEx storeTarget , NodeEx readSource |
2548
+ storeReachesReadTc ( MkNodeAndAp ( storeTarget , _) , MkNodeAndAp ( readSource , _) ) and
2549
+ storeStepCand ( node1 , _, c , storeTarget , _, _) and
2550
+ readStepCand ( readSource , c , node2 )
2551
+ )
2552
+ }
2553
+ }
2554
+
2555
+ private predicate storeReachesRead0 ( NodeEx node1 , NodeEx node2 ) { none ( ) }
2556
+
2557
+ private predicate storeReachesRead1 =
2558
+ StoreReachesRead< storeReachesRead0 / 2 > :: storeReachesReadOut / 2 ;
2559
+
2560
+ private predicate storeReachesRead2 =
2561
+ StoreReachesRead< storeReachesRead1 / 2 > :: storeReachesReadOut / 2 ;
2562
+
2563
+ private predicate storeReachesRead3 =
2564
+ StoreReachesRead< storeReachesRead2 / 2 > :: storeReachesReadOut / 2 ;
2565
+
2566
+ private predicate storeReachesRead4 =
2567
+ StoreReachesRead< storeReachesRead3 / 2 > :: storeReachesReadOut / 2 ;
2568
+
2569
+ private predicate storeReachesRead5 =
2570
+ StoreReachesRead< storeReachesRead4 / 2 > :: storeReachesReadOut / 2 ;
2571
+
2572
+ predicate storeReachesRead = storeReachesRead5 / 2 ;
2573
+
2490
2574
additional predicate stats (
2491
2575
boolean fwd , int nodes , int fields , int conscand , int states , int tuples , int calledges ,
2492
2576
int tfnodes , int tftuples
0 commit comments