@@ -2338,6 +2338,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2338
2338
signature module StoreReadMatchingInputSig {
2339
2339
class NodeEx {
2340
2340
string toString ( ) ;
2341
+
2342
+ DataFlowType getDataFlowType ( ) ;
2341
2343
}
2342
2344
2343
2345
predicate nodeRange ( NodeEx node , boolean fromArg , DataFlowCallOption callCtx ) ;
@@ -2370,13 +2372,6 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2370
2372
* The implementation is based on `doublyBoundedFastTC`, and in order to avoid poor
2371
2373
* performance through recursion, we unroll the recursion manually 4 times, in order to
2372
2374
* be able to handle access paths of maximum length 5.
2373
- *
2374
- * Additionally, in order to speed up the join with `doublyBoundedFastTC`, we first
2375
- * compute three pruning steps:
2376
- *
2377
- * 1. Which _contents_ may have matching read-store pairs (called `contentIsReadAndStored` below).
2378
- * 2. Which store targets may have _a_ matching read (called `storeMayReachARead` below).
2379
- * 3. Which reads may have _a_ matching store (called `aStoreMayReachRead` below).
2380
2375
*/
2381
2376
module StoreReadMatching< StoreReadMatchingInputSig Input> {
2382
2377
private import codeql.util.Boolean
@@ -2396,36 +2391,24 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2396
2391
) ;
2397
2392
}
2398
2393
2399
- private newtype TNodeOrContent =
2400
- TNodeOrContentNode (
2401
- NodeEx n , Boolean usesPrevDelta , boolean fromArg , DataFlowCallOption callCtx
2402
- ) {
2394
+ private newtype TNodeExt =
2395
+ MkNodeExt ( NodeEx n , Boolean usesPrevDelta , boolean fromArg , DataFlowCallOption callCtx ) {
2403
2396
nodeRange ( n , fromArg , callCtx )
2404
- } or
2405
- TNodeOrContentStoreContent ( Content c ) { storeContentStep ( _, c , _) } or
2406
- TNodeOrContentReadContent ( Content c ) { readContentStep ( _, c , _) }
2397
+ }
2407
2398
2408
- private class NodeOrContent extends TNodeOrContent {
2399
+ private class NodeExt extends MkNodeExt {
2409
2400
NodeEx asNodeEx ( boolean usesPrevDelta , boolean fromArg , DataFlowCallOption callCtx ) {
2410
- this = TNodeOrContentNode ( result , usesPrevDelta , fromArg , callCtx )
2401
+ this = MkNodeExt ( result , usesPrevDelta , fromArg , callCtx )
2411
2402
}
2412
2403
2413
- Content asStoreContent ( ) { this = TNodeOrContentStoreContent ( result ) }
2414
-
2415
- Content asReadContent ( ) { this = TNodeOrContentReadContent ( result ) }
2404
+ DataFlowType getType ( ) { result = this .asNodeEx ( _, _, _) .getDataFlowType ( ) }
2416
2405
2417
- string toString ( ) {
2418
- result = this .asStoreContent ( ) .toString ( )
2419
- or
2420
- result = this .asReadContent ( ) .toString ( )
2421
- or
2422
- result = this .asNodeEx ( _, _, _) .toString ( )
2423
- }
2406
+ string toString ( ) { result = this .asNodeEx ( _, _, _) .toString ( ) }
2424
2407
}
2425
2408
2426
2409
pragma [ nomagic]
2427
2410
private predicate stepNodeCommon (
2428
- NodeOrContent node1 , NodeEx n2 , boolean usesPrevDelta2 , Boolean fromArg2 ,
2411
+ NodeExt node1 , NodeEx n2 , boolean usesPrevDelta2 , Boolean fromArg2 ,
2429
2412
DataFlowCallOption callCtx2
2430
2413
) {
2431
2414
exists ( NodeEx n1 , boolean fromArg1 , DataFlowCallOption callCtx1 |
@@ -2467,7 +2450,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2467
2450
2468
2451
pragma [ nomagic]
2469
2452
private predicate stepNode (
2470
- NodeOrContent node1 , NodeEx n2 , boolean usesPrevDelta2 , Boolean fromArg2 ,
2453
+ NodeExt node1 , NodeEx n2 , boolean usesPrevDelta2 , Boolean fromArg2 ,
2471
2454
DataFlowCallOption callCtx2
2472
2455
) {
2473
2456
enabled ( ) and
@@ -2487,135 +2470,51 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2487
2470
}
2488
2471
2489
2472
pragma [ nomagic]
2490
- private predicate step ( NodeOrContent node1 , NodeOrContent node2 ) {
2473
+ private predicate step ( NodeExt node1 , NodeExt node2 ) {
2491
2474
exists ( NodeEx n2 , boolean usesPrevDelta2 , boolean fromArg2 , DataFlowCallOption callCtx2 |
2492
2475
n2 = node2 .asNodeEx ( usesPrevDelta2 , fromArg2 , callCtx2 ) and
2493
2476
stepNode ( node1 , n2 , usesPrevDelta2 , fromArg2 , callCtx2 )
2494
2477
)
2495
- or
2496
- enabled ( ) and
2497
- (
2498
- exists ( NodeEx n2 , Content c , boolean usesPrevDelta2 |
2499
- n2 = node2 .asNodeEx ( usesPrevDelta2 , _, _) and
2500
- c = node1 .asStoreContent ( ) and
2501
- storeContentStep ( _, c , n2 ) and
2502
- usesPrevDelta2 = false
2503
- )
2504
- or
2505
- exists ( NodeEx n1 , Content c , boolean usesPrevDelta1 |
2506
- n1 = node1 .asNodeEx ( usesPrevDelta1 , _, _) and
2507
- c = node2 .asReadContent ( ) and
2508
- readContentStep ( n1 , c , _) and
2509
- usesPrevDelta ( usesPrevDelta1 )
2510
- )
2511
- )
2512
2478
}
2513
2479
2514
- private predicate isStoreContent ( NodeOrContent c ) {
2515
- enabled ( ) and
2516
- exists ( c .asStoreContent ( ) )
2517
- }
2518
-
2519
- private predicate isReadContent ( NodeOrContent c ) {
2520
- enabled ( ) and
2521
- exists ( c .asReadContent ( ) )
2522
- }
2523
-
2524
- private predicate contentReachesReadTc ( NodeOrContent node1 , NodeOrContent node2 ) =
2525
- doublyBoundedFastTC( step / 2 , isStoreContent / 1 , isReadContent / 1 ) ( node1 , node2 )
2526
-
2527
2480
pragma [ nomagic]
2528
- private predicate contentIsReadAndStoredJoin ( NodeOrContent c1 , NodeOrContent c2 , Content c ) {
2529
- enabled ( ) and
2530
- c1 .asStoreContent ( ) = c and
2531
- c2 .asReadContent ( ) = c
2532
- }
2533
-
2534
- additional predicate contentIsReadAndStored ( Content c ) {
2535
- exists ( NodeOrContent n1 , NodeOrContent n2 |
2536
- contentReachesReadTc ( n1 , n2 ) and
2537
- contentIsReadAndStoredJoin ( n1 , n2 , c )
2538
- )
2539
- }
2540
-
2541
- pragma [ nomagic]
2542
- private predicate isStoreTarget0 ( NodeOrContent node , Content c ) {
2481
+ private predicate isStoreTarget0 ( NodeExt node , Content c ) {
2543
2482
exists ( boolean usesPrevDelta |
2544
- contentIsReadAndStored ( c ) and
2545
2483
storeContentStep ( _, c , node .asNodeEx ( usesPrevDelta , _, _) ) and
2546
2484
usesPrevDelta = false
2547
2485
)
2548
2486
}
2549
2487
2550
- private predicate isStoreTarget ( NodeOrContent node ) { isStoreTarget0 ( node , _) }
2488
+ private predicate isStoreTarget ( NodeExt node ) { isStoreTarget0 ( node , _) }
2551
2489
2552
2490
pragma [ nomagic]
2553
- private predicate isReadSource0 ( NodeOrContent node , Content c ) {
2491
+ private predicate isReadSource0 ( NodeExt node , Content c ) {
2554
2492
exists ( boolean usesPrevDelta |
2555
- contentIsReadAndStored ( c ) and
2556
2493
readContentStep ( node .asNodeEx ( usesPrevDelta , _, _) , c , _) and
2557
2494
usesPrevDelta ( usesPrevDelta )
2558
2495
)
2559
2496
}
2560
2497
2561
- private predicate isReadSource ( NodeOrContent node ) { isReadSource0 ( node , _) }
2562
-
2563
- private predicate storeMayReachAReadTc ( NodeOrContent node1 , NodeOrContent node2 ) =
2564
- doublyBoundedFastTC( step / 2 , isStoreTarget / 1 , isReadContent / 1 ) ( node1 , node2 )
2565
-
2566
- pragma [ nomagic]
2567
- private predicate storeMayReachAReadJoin ( NodeOrContent n1 , NodeOrContent n2 , Content c ) {
2568
- isStoreTarget0 ( n1 , c ) and
2569
- n2 .asReadContent ( ) = c
2570
- }
2571
-
2572
- private predicate storeMayReachARead ( NodeOrContent node1 , Content c ) {
2573
- exists ( NodeOrContent node2 |
2574
- storeMayReachAReadTc ( node1 , node2 ) and
2575
- storeMayReachAReadJoin ( node1 , node2 , c )
2576
- )
2577
- }
2578
-
2579
- private predicate aStoreMayReachReadTc ( NodeOrContent node1 , NodeOrContent node2 ) =
2580
- doublyBoundedFastTC( step / 2 , isStoreContent / 1 , isReadSource / 1 ) ( node1 , node2 )
2581
-
2582
- pragma [ nomagic]
2583
- private predicate aStoreMayReachReadJoin ( NodeOrContent n1 , NodeOrContent n2 , Content c ) {
2584
- n1 .asStoreContent ( ) = c and
2585
- isReadSource0 ( n2 , c )
2586
- }
2587
-
2588
- additional predicate aStoreMayReachRead ( NodeOrContent node2 , Content c ) {
2589
- exists ( NodeOrContent node1 |
2590
- aStoreMayReachReadTc ( node1 , node2 ) and
2591
- aStoreMayReachReadJoin ( node1 , node2 , c )
2592
- )
2593
- }
2594
-
2595
- private predicate isStoreTargetPruned ( NodeOrContent node ) { storeMayReachARead ( node , _) }
2596
-
2597
- private predicate isReadSourcePruned ( NodeOrContent node ) { aStoreMayReachRead ( node , _) }
2498
+ private predicate isReadSource ( NodeExt node ) { isReadSource0 ( node , _) }
2598
2499
2599
- private predicate storeMayReachReadTc ( NodeOrContent node1 , NodeOrContent node2 ) =
2600
- doublyBoundedFastTC( step / 2 , isStoreTargetPruned / 1 , isReadSourcePruned / 1 ) ( node1 , node2 )
2500
+ private predicate storeMayReachReadTc ( NodeExt node1 , NodeExt node2 ) =
2501
+ doublyBoundedFastTC( step / 2 , isStoreTarget / 1 , isReadSource / 1 ) ( node1 , node2 )
2601
2502
2602
2503
pragma [ nomagic]
2603
2504
private predicate storeMayReachReadDeltaJoinLeft (
2604
- NodeEx node1 , Content c , NodeOrContent node2 , boolean fromArg2 , DataFlowCallOption callCtx2
2505
+ NodeEx node1 , Content c , NodeExt node2 , boolean fromArg2 , DataFlowCallOption callCtx2
2605
2506
) {
2606
2507
exists ( boolean usesPrevDelta |
2607
- storeMayReachARead ( pragma [ only_bind_into ] ( node2 ) , pragma [ only_bind_into ] ( c ) ) and
2608
2508
storeContentStep ( node1 , c , node2 .asNodeEx ( usesPrevDelta , fromArg2 , callCtx2 ) ) and
2609
2509
usesPrevDelta = false
2610
2510
)
2611
2511
}
2612
2512
2613
2513
pragma [ nomagic]
2614
2514
private predicate storeMayReachReadDeltaJoinRight (
2615
- NodeOrContent node1 , Content c , NodeEx node2 , boolean fromArg1 , DataFlowCallOption callCtx1
2515
+ NodeExt node1 , Content c , NodeEx node2 , boolean fromArg1 , DataFlowCallOption callCtx1
2616
2516
) {
2617
2517
exists ( boolean usesPrevDelta |
2618
- aStoreMayReachRead ( pragma [ only_bind_into ] ( node1 ) , pragma [ only_bind_into ] ( c ) ) and
2619
2518
readContentStep ( node1 .asNodeEx ( usesPrevDelta , fromArg1 , callCtx1 ) , c , node2 ) and
2620
2519
usesPrevDelta ( usesPrevDelta )
2621
2520
)
@@ -2626,10 +2525,20 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2626
2525
NodeEx storeSource , Content c , NodeEx readTarget , boolean fromArg1 , boolean fromArg2 ,
2627
2526
DataFlowCallOption callCtx1 , DataFlowCallOption callCtx2
2628
2527
) {
2629
- exists ( NodeOrContent storeTarget , NodeOrContent readSource |
2528
+ exists ( NodeExt storeTarget , NodeExt readSource |
2630
2529
storeMayReachReadTc ( storeTarget , readSource ) and
2631
2530
storeMayReachReadDeltaJoinLeft ( storeSource , c , storeTarget , fromArg1 , callCtx1 ) and
2632
- storeMayReachReadDeltaJoinRight ( readSource , c , readTarget , fromArg2 , callCtx2 )
2531
+ storeMayReachReadDeltaJoinRight ( readSource , c , readTarget , fromArg2 , callCtx2 ) and
2532
+ (
2533
+ compatibleTypesFilter ( storeTarget .getType ( ) , readSource .getType ( ) )
2534
+ or
2535
+ not exists ( readSource .getType ( ) )
2536
+ ) and
2537
+ (
2538
+ compatibleTypesFilter ( storeSource .getDataFlowType ( ) , readTarget .getDataFlowType ( ) )
2539
+ or
2540
+ not exists ( readTarget .getDataFlowType ( ) )
2541
+ )
2633
2542
) and
2634
2543
not Prev:: storeMayReachReadPrev ( storeSource , c , readTarget , fromArg1 , fromArg2 , callCtx1 ,
2635
2544
callCtx2 )
@@ -2679,7 +2588,6 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2679
2588
or
2680
2589
// special case only needed for the first iteration: a store immediately followed by a read
2681
2590
exists ( NodeEx storeTargetReadSource |
2682
- StoreReachesRead1:: contentIsReadAndStored ( c ) and
2683
2591
storeContentStep ( storeSource , c , storeTargetReadSource ) and
2684
2592
readContentStep ( storeTargetReadSource , c , readTarget )
2685
2593
) and
0 commit comments