Skip to content

Commit 87d9802

Browse files
committed
Data flow: Experiment
1 parent a756f86 commit 87d9802

File tree

1 file changed

+99
-16
lines changed

1 file changed

+99
-16
lines changed

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
10191019
callEdgeReturn(call, c, _, _, _, _, _)
10201020
}
10211021

1022+
bindingset[node1, node2]
1023+
predicate storeReachesRead(NodeEx node1, NodeEx node2) {
1024+
exists(node1) and
1025+
exists(node2)
1026+
}
1027+
10221028
additional predicate stats(
10231029
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges
10241030
) {
@@ -1314,6 +1320,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
13141320
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c);
13151321

13161322
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c);
1323+
1324+
bindingset[node1, node2]
1325+
predicate storeReachesRead(NodeEx node1, NodeEx node2);
13171326
}
13181327

13191328
private module MkStage<StageSig PrevStage> {
@@ -1512,9 +1521,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
15121521
)
15131522
or
15141523
// read
1515-
exists(Typ t0, Ap ap0, Content c |
1524+
exists(Typ t0, Ap ap0, Content c, NodeEx storeSource |
15161525
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
15181528
apa = getApprox(ap)
15191529
)
15201530
or
@@ -1583,16 +1593,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
15831593
/**
15841594
* Holds if forward flow with access path `tail` and type `t1` reaches a
15851595
* 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`.
15871597
*/
15881598
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
15911603
cons = apCons(c, t1, tail)
15921604
or
15931605
exists(Typ t0 |
15941606
typeStrengthen(t0, cons, t2) and
1595-
fwdFlowConsCand(t0, cons, c, t1, tail)
1607+
fwdFlowConsCand(storeSource, t0, cons, c, t1, tail)
15961608
)
15971609
}
15981610

@@ -2041,9 +2053,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
20412053

20422054
pragma[nomagic]
20432055
private predicate readStepFwd(NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2) {
2044-
exists(Typ t1 |
2056+
exists(Typ t1, NodeEx storeSource |
20452057
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)
20472060
)
20482061
}
20492062

@@ -2157,9 +2170,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
21572170
returnAp = apNone()
21582171
or
21592172
// store
2160-
exists(Ap ap0, Content c |
2173+
exists(NodeEx readTarget, Ap ap0, Content c |
21612174
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)
21632177
)
21642178
or
21652179
// read
@@ -2225,11 +2239,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
22252239
* resulting in access path `cons`.
22262240
*/
22272241
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
22312245
tail = pragma[only_bind_into](tail0) and
2232-
readStepFwd(_, cons, c, mid, tail0)
2246+
readStepFwd(_, cons, c, readTarget, tail0)
22332247
)
22342248
}
22352249

@@ -2357,7 +2371,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
23572371
exists(Ap ap2 |
23582372
PrevStage::storeStepCand(node1, _, c, node2, contentType, containerType) and
23592373
revFlowStore(ap2, c, ap1, _, node1, _, node2, _, _) and
2360-
revFlowConsCand(ap2, c, ap1)
2374+
revFlowConsCand(_, ap2, c, ap1)
23612375
)
23622376
}
23632377

@@ -2384,7 +2398,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
23842398
private predicate revConsCand(Content c, Typ t, Ap ap) {
23852399
exists(Ap ap2 |
23862400
revFlowStore(ap2, c, ap, t, _, _, _, _, _) and
2387-
revFlowConsCand(ap2, c, ap)
2401+
revFlowConsCand(_, ap2, c, ap)
23882402
)
23892403
}
23902404

@@ -2487,6 +2501,75 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
24872501
callEdgeReturn(call, c, _, _, _, _, _)
24882502
}
24892503

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+
24902573
additional predicate stats(
24912574
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges,
24922575
int tfnodes, int tftuples

0 commit comments

Comments
 (0)