Skip to content

Commit 2a9f751

Browse files
committed
Data flow: Use stage path graph in store/load matching
1 parent 1211318 commit 2a9f751

File tree

2 files changed

+331
-141
lines changed

2 files changed

+331
-141
lines changed

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

Lines changed: 104 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,7 +1719,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
17191719
Typ t1, Ap ap1, Typ t2, Ap ap2, Content c, NodeEx node1, NodeEx node2, FlowState state,
17201720
Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp
17211721
) {
1722-
fwdFlowRead0(t1, ap1, c, node1, node2, state, cc, summaryCtx, argT, argAp) and
1722+
fwdFlowRead0(pragma[only_bind_into](t1), pragma[only_bind_into](ap1),
1723+
pragma[only_bind_into](c), node1, node2, state, cc, summaryCtx, argT, argAp) and
17231724
(
17241725
exists(NodeEx storeSource |
17251726
fwdFlowConsCandStoreReadMatchingEnabled(storeSource, t1, ap1, c, t2, ap2) and
@@ -2646,7 +2647,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26462647
abstract Location getLocation();
26472648

26482649
/** Gets the corresponding `Node`, if any. */
2649-
Node getNode() { none() }
2650+
NodeEx getNodeEx() { none() }
2651+
2652+
/** Gets the summary context. */
2653+
ParamNodeOption getSummaryCtx() { none() }
2654+
2655+
/** Gets the access path. */
2656+
Ap getAp() { none() }
2657+
2658+
/** Gets the corresponding `Node`, if any. */
2659+
final Node getNode() { result = this.getNodeEx().asNode() }
26502660

26512661
predicate isSource() { none() }
26522662

@@ -2690,7 +2700,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26902700

26912701
override Location getLocation() { result = node.getLocation() }
26922702

2693-
override Node getNode() { result = node.asNode() }
2703+
override NodeEx getNodeEx() { result = node }
2704+
2705+
override ParamNodeOption getSummaryCtx() { result = summaryCtx }
2706+
2707+
override Ap getAp() { result = ap }
26942708

26952709
override predicate isSource() {
26962710
sourceNode(node, state) and
@@ -2728,8 +2742,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27282742
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap,
27292743
boolean allowsFlowThrough
27302744
) {
2731-
exists(ApApprox apa, boolean allowsFlowThrough0 |
2732-
FwdFlowIn<FwdFlowInNoRestriction>::fwdFlowIn(_, arg, _, p, state, outercc, innercc,
2745+
exists(DataFlowCall call, ApApprox apa, boolean allowsFlowThrough0 |
2746+
callEdgeArgParam(call, _, arg, p, _, ap) and
2747+
FwdFlowIn<FwdFlowInNoRestriction>::fwdFlowIn(call, arg, _, p, state, outercc, innercc,
27332748
summaryCtx, argT, argAp, t, ap, apa, _, allowsFlowThrough0) and
27342749
if PrevStage::parameterMayFlowThrough(p, apa)
27352750
then allowsFlowThrough = allowsFlowThrough0
@@ -2744,6 +2759,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27442759
RetNodeEx ret, ParamNodeEx innerSummaryCtx, Typ innerArgT, Ap innerArgAp,
27452760
ApApprox innerArgApa
27462761
) {
2762+
callEdgeReturn(call, _, ret, _, _, _, ap) and
2763+
callMayFlowThroughRev(call) and
2764+
returnMayFlowThrough(ret, _, _, _) and
2765+
matchesCall(ccc, call) and
27472766
fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret,
27482767
innerSummaryCtx, innerArgT, innerArgAp, innerArgApa)
27492768
}
@@ -2797,6 +2816,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27972816
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow,
27982817
ApApprox innerArgApa, ApApprox apa
27992818
|
2819+
callEdgeReturn(call, _, ret, _, node, allowsFieldFlow, ap) and
28002820
fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, argT, argAp, t,
28012821
ap, apa, ret, innerArgApa) and
28022822
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and
@@ -2818,31 +2838,70 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28182838
localStep(mid, state0, node, state, false, t, localCc, label) and
28192839
ap instanceof ApNil
28202840
)
2821-
or
2822-
// store
2823-
exists(NodeEx mid, Content c, Typ t0, Ap ap0 |
2841+
}
2842+
2843+
private predicate storeStep(
2844+
StagePathNode pn1, Content c, NodeEx node, FlowState state, Cc cc,
2845+
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label
2846+
) {
2847+
exists(NodeEx mid, Typ t0, Ap ap0 |
28242848
pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and
28252849
fwdFlowStore(mid, t0, ap0, c, t, node, state, cc, summaryCtx, argT, argAp) and
2850+
storeStepCand(mid, ap0, c, node, _,
2851+
any(DataFlowType containerType | t = getTyp(containerType))) and
28262852
ap = apCons(c, t0, ap0) and
28272853
label = ""
28282854
)
2829-
or
2830-
// read
2855+
}
2856+
2857+
private predicate readStep(
2858+
StagePathNode pn1, Content c, NodeEx node, FlowState state, Cc cc,
2859+
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label
2860+
) {
28312861
exists(NodeEx mid, Typ t0, Ap ap0 |
28322862
pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and
2833-
fwdFlowRead(t0, ap0, t, ap, _, mid, node, state, cc, summaryCtx, argT, argAp) and
2863+
fwdFlowRead(t0, ap0, t, ap, c, mid, node, state, cc, summaryCtx, argT, argAp) and
2864+
readStepCand(mid, c, node) and
28342865
label = ""
28352866
)
28362867
}
28372868

2838-
private predicate localStep(StagePathNode pn1, StagePathNode pn2, string label) {
2869+
predicate localStep(StagePathNode pn1, StagePathNode pn2, string label) {
28392870
exists(
28402871
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
28412872
ApOption argAp, Typ t0, Ap ap
28422873
|
28432874
localStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and
28442875
pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap)
28452876
)
2877+
}
2878+
2879+
predicate storeStep(StagePathNode pn1, Content c, StagePathNode pn2, string label) {
2880+
exists(
2881+
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
2882+
ApOption argAp, Typ t0, Ap ap
2883+
|
2884+
storeStep(pn1, c, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and
2885+
pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap)
2886+
)
2887+
}
2888+
2889+
predicate readStep(StagePathNode pn1, Content c, StagePathNode pn2, string label) {
2890+
exists(
2891+
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
2892+
ApOption argAp, Typ t0, Ap ap
2893+
|
2894+
readStep(pn1, c, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and
2895+
pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap)
2896+
)
2897+
}
2898+
2899+
private predicate localScopeStep(StagePathNode pn1, StagePathNode pn2, string label) {
2900+
localStep(pn1, pn2, label)
2901+
or
2902+
storeStep(pn1, _, pn2, label)
2903+
or
2904+
readStep(pn1, _, pn2, label)
28462905
or
28472906
summaryStep(pn1, pn2, label)
28482907
}
@@ -2854,7 +2913,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28542913
or
28552914
exists(StagePathNode mid, string l1, string l2 |
28562915
summaryLabel(pn1, mid, l1) and
2857-
localStep(mid, pn2, l2) and
2916+
localScopeStep(mid, pn2, l2) and
28582917
summaryLabel = mergeLabels(l1, l2)
28592918
)
28602919
}
@@ -2917,16 +2976,20 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29172976
)
29182977
or
29192978
// flow out of a callable
2920-
exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow, ApApprox apa |
2979+
exists(
2980+
DataFlowCall call, RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow,
2981+
ApApprox apa
2982+
|
29212983
pn1 = TStagePathNodeMid(ret, state, innercc, summaryCtx, argT, argAp, t, ap) and
29222984
fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and
29232985
fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, apa, allowsFieldFlow) and
2986+
callEdgeReturn(call, _, ret, _, node, allowsFieldFlow, ap) and
29242987
label = "" and
29252988
if allowsFieldFlow = false then ap instanceof ApNil else any()
29262989
)
29272990
}
29282991

2929-
private predicate nonLocalStep(StagePathNode pn1, StagePathNode pn2, string label) {
2992+
predicate nonLocalStep(StagePathNode pn1, StagePathNode pn2, string label) {
29302993
exists(
29312994
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
29322995
ApOption argAp, Typ t0, Ap ap
@@ -2951,7 +3014,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29513014
query predicate edges(StagePathNode pn1, StagePathNode pn2, string key, string val) {
29523015
key = "provenance" and
29533016
(
2954-
localStep(pn1, pn2, val)
3017+
localScopeStep(pn1, pn2, val)
29553018
or
29563019
nonLocalStep(pn1, pn2, val)
29573020
or
@@ -3417,73 +3480,49 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
34173480

34183481
predicate enableStoreReadMatching() { any() }
34193482

3420-
private class NodeExAlias = NodeEx;
3483+
final private class NodeExAlias = NodeEx;
3484+
3485+
final private class ArgNodeExAlias = ArgNodeEx;
3486+
3487+
final private class ParamNodeExAlias = ParamNodeEx;
34213488

34223489
private module StoreReadMatchingInput implements StoreReadMatchingInputSig {
34233490
class NodeEx = NodeExAlias;
34243491

3425-
predicate nodeRange(NodeEx node, boolean fromArg) {
3426-
exists(PrevStage::Ap ap |
3427-
PrevStage::revFlowAp(node, ap) and
3428-
(
3429-
ap = true
3430-
or
3431-
PrevStage::storeStepCand(node, ap, _, _, _, _)
3432-
or
3433-
PrevStage::readStepCand(_, _, node)
3434-
)
3435-
|
3436-
exists(PrevStage::Cc cc | PrevStage::fwdFlow(node, _, cc, _, _, _, _, ap, _) |
3437-
PrevStage::instanceofCcCall(cc) and
3438-
fromArg = true
3439-
or
3440-
PrevStage::instanceofCcNoCall(cc) and
3441-
fromArg = false
3442-
)
3443-
)
3444-
}
3492+
class ArgNodeEx = ArgNodeExAlias;
34453493

3446-
predicate localValueStep(NodeEx node1, NodeEx node2) {
3447-
exists(FlowState state, PrevStage::ApOption returnAp |
3448-
PrevStage::revFlow(node1, pragma[only_bind_into](state), _,
3449-
pragma[only_bind_into](returnAp), true) and
3450-
PrevStage::revFlow(node2, pragma[only_bind_into](state), _,
3451-
pragma[only_bind_into](returnAp), true) and
3452-
Stage2Param::localStep(node1, state, node2, state, true, _, _, _)
3453-
)
3454-
}
3494+
class ParamNodeEx = ParamNodeExAlias;
34553495

3456-
predicate jumpValueStep = jumpStepEx/2;
3496+
class PathNode = PrevStage::Graph::StagePathNode;
34573497

3458-
pragma[nomagic]
3459-
private predicate flowThroughOutOfCall(RetNodeEx ret, NodeEx out) {
3460-
exists(DataFlowCall call, CcCall ccc, ReturnKindExt kind |
3461-
PrevStage::callEdgeReturn(call, _, ret, kind, out, true, true) and
3462-
PrevStage::callMayFlowThroughRev(call) and
3463-
PrevStage::returnMayFlowThrough(ret, _, true, kind) and
3464-
matchesCall(ccc, call)
3465-
)
3498+
predicate localStep(PathNode node1, PathNode node2) {
3499+
PrevStage::Graph::localStep(node1, node2, _)
34663500
}
34673501

3468-
predicate callEdgeArgParam(NodeEx arg, NodeEx param) {
3469-
PrevStage::callEdgeArgParam(_, _, arg, param, true, true)
3502+
predicate nonLocalStep(PathNode node1, PathNode node2) {
3503+
PrevStage::Graph::nonLocalStep(node1, node2, _)
34703504
}
34713505

3472-
predicate callEdgeReturn(NodeEx ret, NodeEx out, boolean mayFlowThrough) {
3473-
PrevStage::callEdgeReturn(_, _, ret, _, out, true, true) and
3474-
if flowThroughOutOfCall(ret, out) then mayFlowThrough = true else mayFlowThrough = false
3475-
}
3506+
predicate subpaths = PrevStage::Graph::subpaths/4;
34763507

3477-
predicate readContentStep = PrevStage::readStepCand/3;
3508+
predicate readContentStep(PathNode node1, Content c, PathNode node2) {
3509+
PrevStage::Graph::readStep(node1, c, node2, _)
3510+
}
34783511

3479-
predicate storeContentStep(NodeEx node1, Content c, NodeEx node2) {
3480-
PrevStage::storeStepCand(node1, _, c, node2, _, _)
3512+
predicate storeContentStep(PathNode node1, Content c, PathNode node2) {
3513+
PrevStage::Graph::storeStep(node1, c, node2, _)
34813514
}
34823515

34833516
predicate accessPathConfigLimit = Config::accessPathLimit/0;
34843517
}
34853518

3486-
predicate storeMayReachRead = StoreReadMatching<StoreReadMatchingInput>::storeMayReachRead/3;
3519+
predicate storeMayReachRead(NodeEx storeSource, Content c, NodeEx readTarget) {
3520+
exists(StoreReadMatchingInput::PathNode pn1, StoreReadMatchingInput::PathNode pn2 |
3521+
StoreReadMatching<StoreReadMatchingInput>::storeMayReachRead(pn1, c, pn2) and
3522+
storeSource = pn1.getNodeEx() and
3523+
readTarget = pn2.getNodeEx()
3524+
)
3525+
}
34873526
}
34883527

34893528
private module Stage3 = MkStage<Stage2>::Stage<Stage3Param>;

0 commit comments

Comments
 (0)