@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
1135
1135
DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow
1136
1136
) ;
1137
1137
1138
- bindingset [ node, state, t , ap]
1139
- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) ;
1138
+ bindingset [ node, state, t0 , ap]
1139
+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) ;
1140
1140
1141
1141
bindingset [ typ, contentType]
1142
1142
predicate typecheckStore ( Typ typ , DataFlowType contentType ) ;
@@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> {
1199
1199
NodeEx node , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
1200
1200
ApOption argAp , Typ t , Ap ap , ApApprox apa
1201
1201
) {
1202
- fwdFlow0 ( node , state , cc , summaryCtx , argT , argAp , t , ap , apa ) and
1203
- PrevStage:: revFlow ( node , state , apa ) and
1204
- filter ( node , state , t , ap )
1202
+ fwdFlow1 ( node , state , cc , summaryCtx , argT , argAp , _, t , ap , apa )
1205
1203
}
1206
1204
1207
- pragma [ inline]
1208
- additional predicate fwdFlow (
1205
+ private predicate fwdFlow1 (
1209
1206
NodeEx node , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
1210
- ApOption argAp , Typ t , Ap ap
1207
+ ApOption argAp , Typ t0 , Typ t , Ap ap , ApApprox apa
1211
1208
) {
1212
- fwdFlow ( node , state , cc , summaryCtx , argT , argAp , t , ap , _)
1209
+ fwdFlow0 ( node , state , cc , summaryCtx , argT , argAp , t0 , ap , apa ) and
1210
+ PrevStage:: revFlow ( node , state , apa ) and
1211
+ filter ( node , state , t0 , ap , t )
1212
+ }
1213
+
1214
+ private predicate typeStrengthen ( Typ t0 , Ap ap , Typ t ) {
1215
+ fwdFlow1 ( _, _, _, _, _, _, t0 , t , ap , _) and t0 != t
1213
1216
}
1214
1217
1215
1218
pragma [ assume_small_delta]
@@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> {
1339
1342
private predicate fwdFlowConsCand ( Typ t2 , Ap cons , Content c , Typ t1 , Ap tail ) {
1340
1343
fwdFlowStore ( _, t1 , tail , c , t2 , _, _, _, _, _, _) and
1341
1344
cons = apCons ( c , t1 , tail )
1345
+ or
1346
+ exists ( Typ t0 |
1347
+ typeStrengthen ( t0 , cons , t2 ) and
1348
+ fwdFlowConsCand ( t0 , cons , c , t1 , tail )
1349
+ )
1342
1350
}
1343
1351
1344
1352
pragma [ nomagic]
@@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> {
1359
1367
ParamNodeOption summaryCtx , TypOption argT , ApOption argAp
1360
1368
) {
1361
1369
exists ( ApHeadContent apc |
1362
- fwdFlow ( node1 , state , cc , summaryCtx , argT , argAp , t , ap ) and
1370
+ fwdFlow ( node1 , state , cc , summaryCtx , argT , argAp , t , ap , _ ) and
1363
1371
apc = getHeadContent ( ap ) and
1364
1372
readStepCand0 ( node1 , apc , c , node2 )
1365
1373
)
@@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> {
1520
1528
NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap
1521
1529
) {
1522
1530
revFlow0 ( node , state , returnCtx , returnAp , ap ) and
1523
- fwdFlow ( node , state , _, _, _, _, _, ap )
1531
+ fwdFlow ( node , state , _, _, _, _, _, ap , _ )
1524
1532
}
1525
1533
1526
1534
pragma [ nomagic]
1527
1535
private predicate revFlow0 (
1528
1536
NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap
1529
1537
) {
1530
- fwdFlow ( node , state , _, _, _, _, _, ap ) and
1538
+ fwdFlow ( node , state , _, _, _, _, _, ap , _ ) and
1531
1539
sinkNode ( node , state ) and
1532
1540
(
1533
1541
if hasSinkCallCtx ( )
@@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> {
1780
1788
boolean fwd , int nodes , int fields , int conscand , int states , int tuples
1781
1789
) {
1782
1790
fwd = true and
1783
- nodes = count ( NodeEx node | fwdFlow ( node , _, _, _, _, _, _, _) ) and
1791
+ nodes = count ( NodeEx node | fwdFlow ( node , _, _, _, _, _, _, _, _ ) ) and
1784
1792
fields = count ( Content f0 | fwdConsCand ( f0 , _, _) ) and
1785
1793
conscand = count ( Content f0 , Typ t , Ap ap | fwdConsCand ( f0 , t , ap ) ) and
1786
- states = count ( FlowState state | fwdFlow ( _, state , _, _, _, _, _, _) ) and
1794
+ states = count ( FlowState state | fwdFlow ( _, state , _, _, _, _, _, _, _ ) ) and
1787
1795
tuples =
1788
1796
count ( NodeEx n , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
1789
- ApOption argAp , Typ t , Ap ap | fwdFlow ( n , state , cc , summaryCtx , argT , argAp , t , ap ) )
1797
+ ApOption argAp , Typ t , Ap ap | fwdFlow ( n , state , cc , summaryCtx , argT , argAp , t , ap , _ ) )
1790
1798
or
1791
1799
fwd = false and
1792
1800
nodes = count ( NodeEx node | revFlow ( node , _, _, _, _) ) and
@@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> {
1963
1971
)
1964
1972
}
1965
1973
1966
- bindingset [ node, state, t , ap]
1967
- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
1974
+ bindingset [ node, state, t0 , ap]
1975
+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
1968
1976
PrevStage:: revFlowState ( state ) and
1969
- exists ( t ) and
1977
+ t0 = t and
1970
1978
exists ( ap ) and
1971
1979
not stateBarrier ( node , state ) and
1972
1980
(
@@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> {
2197
2205
import BooleanCallContext
2198
2206
2199
2207
predicate localStep (
2200
- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2201
- DataFlowType t , LocalCc lcc
2208
+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2209
+ LocalCc lcc
2202
2210
) {
2203
2211
localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , _) and
2204
2212
exists ( lcc )
@@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> {
2218
2226
)
2219
2227
}
2220
2228
2221
- bindingset [ node, state, t , ap]
2222
- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2229
+ bindingset [ node, state, t0 , ap]
2230
+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
2223
2231
exists ( state ) and
2224
- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2232
+ // We can get away with not using type strengthening here, since we aren't
2233
+ // going to use the tracked types in the construction of Stage 4 access
2234
+ // paths. For Stage 4 and onwards, the tracked types must be consistent as
2235
+ // the cons candidates including types are used to construct subsequent
2236
+ // access path approximations.
2237
+ t0 = t and
2238
+ ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t0 ) else any ( ) ) and
2225
2239
(
2226
2240
notExpectsContent ( node )
2227
2241
or
@@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> {
2274
2288
2275
2289
pragma [ nomagic]
2276
2290
predicate localStep (
2277
- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2278
- DataFlowType t , LocalCc lcc
2291
+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2292
+ LocalCc lcc
2279
2293
) {
2280
2294
localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , _) and
2281
2295
PrevStage:: revFlow ( node1 , pragma [ only_bind_into ] ( state1 ) , _) and
@@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> {
2333
2347
)
2334
2348
}
2335
2349
2336
- bindingset [ node, state, t , ap]
2337
- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2350
+ bindingset [ node, state, t0 , ap]
2351
+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
2338
2352
exists ( state ) and
2339
2353
not clear ( node , ap ) and
2340
- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2354
+ (
2355
+ if castingNodeEx ( node )
2356
+ then
2357
+ exists ( Typ nt | nt = node .getDataFlowType ( ) |
2358
+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
2359
+ )
2360
+ else t = t0
2361
+ ) and
2341
2362
(
2342
2363
notExpectsContent ( node )
2343
2364
or
@@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> {
2365
2386
exists ( AccessPathFront apf |
2366
2387
Stage4:: revFlow ( node , state , TReturnCtxMaybeFlowThrough ( _) , _, apf ) and
2367
2388
Stage4:: fwdFlow ( node , state , any ( Stage4:: CcCall ccc ) , _, _, TAccessPathFrontSome ( argApf ) , _,
2368
- apf )
2389
+ apf , _ )
2369
2390
)
2370
2391
}
2371
2392
@@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> {
2579
2600
import LocalCallContext
2580
2601
2581
2602
predicate localStep (
2582
- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2583
- DataFlowType t , LocalCc lcc
2603
+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2604
+ LocalCc lcc
2584
2605
) {
2585
2606
localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , lcc ) and
2586
2607
PrevStage:: revFlow ( node1 , pragma [ only_bind_into ] ( state1 ) , _) and
@@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> {
2609
2630
)
2610
2631
}
2611
2632
2612
- bindingset [ node, state, t, ap]
2613
- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2614
- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2633
+ bindingset [ node, state, t0, ap]
2634
+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
2635
+ (
2636
+ if castingNodeEx ( node )
2637
+ then
2638
+ exists ( Typ nt | nt = node .getDataFlowType ( ) |
2639
+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
2640
+ )
2641
+ else t = t0
2642
+ ) and
2615
2643
exists ( state ) and
2616
2644
exists ( ap )
2617
2645
}
@@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> {
2632
2660
Stage5:: parameterMayFlowThrough ( p , _) and
2633
2661
Stage5:: revFlow ( n , state , TReturnCtxMaybeFlowThrough ( _) , _, apa0 ) and
2634
2662
Stage5:: fwdFlow ( n , state , any ( CallContextCall ccc ) , TParamNodeSome ( p .asNode ( ) ) , _,
2635
- TAccessPathApproxSome ( apa ) , _, apa0 )
2663
+ TAccessPathApproxSome ( apa ) , _, apa0 , _ )
2636
2664
)
2637
2665
}
2638
2666
@@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> {
2649
2677
TSummaryCtxSome ( ParamNodeEx p , FlowState state , DataFlowType t , AccessPath ap ) {
2650
2678
exists ( AccessPathApprox apa | ap .getApprox ( ) = apa |
2651
2679
Stage5:: parameterMayFlowThrough ( p , apa ) and
2652
- Stage5:: fwdFlow ( p , state , _, _, _, _, t , apa ) and
2680
+ Stage5:: fwdFlow ( p , state , _, _, _, _, t , apa , _ ) and
2653
2681
Stage5:: revFlow ( p , state , _)
2654
2682
)
2655
2683
}
@@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> {
2820
2848
ap = TAccessPathNil ( )
2821
2849
or
2822
2850
// ... or a step from an existing PathNode to another node.
2823
- pathStep ( _, node , state , cc , sc , t , ap ) and
2824
- Stage5:: revFlow ( node , state , ap .getApprox ( ) ) and
2825
- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) )
2851
+ pathStep ( _, node , state , cc , sc , t , ap )
2826
2852
} or
2827
2853
TPathNodeSink ( NodeEx node , FlowState state ) {
2828
2854
exists ( PathNodeMid sink |
@@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> {
3340
3366
ap = mid .getAp ( )
3341
3367
}
3342
3368
3369
+ private predicate pathStep (
3370
+ PathNodeMid mid , NodeEx node , FlowState state , CallContext cc , SummaryCtx sc , DataFlowType t ,
3371
+ AccessPath ap
3372
+ ) {
3373
+ exists ( DataFlowType t0 |
3374
+ pathStep0 ( mid , node , state , cc , sc , t0 , ap ) and
3375
+ Stage5:: revFlow ( node , state , ap .getApprox ( ) ) and
3376
+ (
3377
+ if castingNodeEx ( node )
3378
+ then
3379
+ exists ( DataFlowType nt | nt = node .getDataFlowType ( ) |
3380
+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
3381
+ )
3382
+ else t = t0
3383
+ )
3384
+ )
3385
+ }
3386
+
3343
3387
/**
3344
3388
* Holds if data may flow from `mid` to `node`. The last step in or out of
3345
3389
* a callable is recorded by `cc`.
3346
3390
*/
3347
3391
pragma [ assume_small_delta]
3348
3392
pragma [ nomagic]
3349
- private predicate pathStep (
3393
+ private predicate pathStep0 (
3350
3394
PathNodeMid mid , NodeEx node , FlowState state , CallContext cc , SummaryCtx sc , DataFlowType t ,
3351
3395
AccessPath ap
3352
3396
) {
0 commit comments