Data flow: Track return position instead of return kind

Reverts bdb205a318.
This commit is contained in:
Tom Hvitved
2022-12-14 11:41:54 +01:00
parent 1820bb4b0b
commit d34901ac8c

View File

@@ -1508,26 +1508,28 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate fwdFlowRetFromArg( private predicate fwdFlowRetFromArg(
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config Ap ap, ApApprox apa, Configuration config
) { ) {
fwdFlow(pragma[only_bind_into](ret), state, ccc, exists(ReturnKindExt kind |
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), fwdFlow(pragma[only_bind_into](ret), state, ccc,
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
pragma[only_bind_into](config)) and pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
kind = ret.getKind() and pragma[only_bind_into](config)) and
parameterFlowThroughAllowed(summaryCtx, kind) and kind = ret.getKind() and
argApa = getApprox(argAp) and parameterFlowThroughAllowed(summaryCtx, kind) and
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) argApa = getApprox(argAp) and
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
)
} }
pragma[inline] pragma[inline]
private predicate fwdFlowThrough0( private predicate fwdFlowThrough0(
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ReturnKindExt kind, ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config Ap innerArgAp, ApApprox innerArgApa, Configuration config
) { ) {
fwdFlowRetFromArg(pragma[only_bind_into](ret), kind, state, pragma[only_bind_into](ccc), fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
innerSummaryCtx, innerArgAp, innerArgApa, ap, pragma[only_bind_into](apa), innerSummaryCtx, innerArgAp, innerArgApa, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and pragma[only_bind_into](config)) and
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp,
@@ -1540,7 +1542,7 @@ private module MkStage<StageSig PrevStage> {
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
) { ) {
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, _, innerArgApa, fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
config) config)
} }
@@ -1580,21 +1582,21 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate returnFlowsThrough0( private predicate returnFlowsThrough0(
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
ReturnKindExt kind, ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
Configuration config
) { ) {
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, kind, innerSummaryCtx, innerArgAp, fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
innerArgApa, config) innerArgApa, config)
} }
pragma[nomagic] pragma[nomagic]
private predicate returnFlowsThrough( private predicate returnFlowsThrough(
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
Ap ap, Configuration config Ap ap, Configuration config
) { ) {
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
returnFlowsThrough0(call, state, ccc, ap, apa, ret, kind, p, argAp, innerArgApa, config) and returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
pos = ret.getReturnPosition() and
if allowsFieldFlow = false then ap instanceof ApNil else any() if allowsFieldFlow = false then ap instanceof ApNil else any()
) )
} }
@@ -1628,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate flowOutOfCallAp( private predicate flowOutOfCallAp(
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
Ap ap, Configuration config Ap ap, Configuration config
) { ) {
exists(ApApprox apa | exists(ApApprox apa |
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
fwdFlow(ret, _, _, _, _, ap, apa, config) fwdFlow(ret, _, _, _, _, ap, apa, config) and
pos = ret.getReturnPosition()
) )
} }
@@ -1728,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
) )
or or
// flow through a callable // flow through a callable
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | exists(DataFlowCall call, ReturnPosition pos, Ap returnAp0 |
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and revFlowInToReturn(call, node, state, pos, returnAp0, ap, config) and
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) revFlowIsReturned(call, returnCtx, returnAp, pos, returnAp0, config)
) )
or or
// flow out of a callable // flow out of a callable
exists(ReturnKindExt kind | exists(ReturnPosition pos |
revFlowOut(_, node, kind, state, _, _, ap, config) and revFlowOut(_, node, pos, state, _, _, ap, config) and
if returnFlowsThrough(node, kind, state, _, _, _, ap, config) if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
then ( then (
returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnCtx = TReturnCtxMaybeFlowThrough(pos) and
returnAp = apSome(ap) returnAp = apSome(ap)
) else ( ) else (
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
@@ -1771,12 +1774,12 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate revFlowOut( private predicate revFlowOut(
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
ApOption returnAp, Ap ap, Configuration config ApOption returnAp, Ap ap, Configuration config
) { ) {
exists(NodeEx out, boolean allowsFieldFlow | exists(NodeEx out, boolean allowsFieldFlow |
revFlow(out, state, returnCtx, returnAp, ap, config) and revFlow(out, state, returnCtx, returnAp, ap, config) and
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
if allowsFieldFlow = false then ap instanceof ApNil else any() if allowsFieldFlow = false then ap instanceof ApNil else any()
) )
} }
@@ -1797,19 +1800,19 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate revFlowParamToReturn( private predicate revFlowParamToReturn(
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
) { ) {
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and revFlow(p, state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
parameterFlowThroughAllowed(p, kind) parameterFlowThroughAllowed(p, pos.getKind())
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlowInToReturn( private predicate revFlowInToReturn(
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap,
Configuration config Configuration config
) { ) {
exists(ParamNodeEx p, boolean allowsFieldFlow | exists(ParamNodeEx p, boolean allowsFieldFlow |
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and revFlowParamToReturn(p, state, pos, returnAp, ap, config) and
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config) revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
) )
} }
@@ -1821,12 +1824,12 @@ private module MkStage<StageSig PrevStage> {
*/ */
pragma[nomagic] pragma[nomagic]
private predicate revFlowIsReturned( private predicate revFlowIsReturned(
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
Configuration config Configuration config
) { ) {
exists(RetNodeEx ret, FlowState state, CcCall ccc | exists(RetNodeEx ret, FlowState state, CcCall ccc |
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
matchesCall(ccc, call) matchesCall(ccc, call)
) )
} }
@@ -1904,17 +1907,17 @@ private module MkStage<StageSig PrevStage> {
pragma[nomagic] pragma[nomagic]
private predicate parameterFlowsThroughRev( private predicate parameterFlowsThroughRev(
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
) { ) {
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
parameterFlowThroughAllowed(p, kind) parameterFlowThroughAllowed(p, pos.getKind())
} }
pragma[nomagic] pragma[nomagic]
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
exists(RetNodeEx ret, ReturnKindExt kind | exists(RetNodeEx ret, ReturnPosition pos |
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
parameterFlowsThroughRev(p, ap, kind, _, config) parameterFlowsThroughRev(p, ap, pos, _, config)
) )
} }
@@ -1922,9 +1925,10 @@ private module MkStage<StageSig PrevStage> {
predicate returnMayFlowThrough( predicate returnMayFlowThrough(
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
) { ) {
exists(ParamNodeEx p | exists(ParamNodeEx p, ReturnPosition pos |
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
parameterFlowsThroughRev(p, argAp, kind, ap, config) parameterFlowsThroughRev(p, argAp, pos, ap, config) and
kind = pos.getKind()
) )
} }
@@ -1933,9 +1937,9 @@ private module MkStage<StageSig PrevStage> {
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
Ap ap, Configuration config Ap ap, Configuration config
) { ) {
exists(ReturnKindExt returnKind0, Ap returnAp0 | exists(ReturnPosition pos, Ap returnAp0 |
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and revFlowInToReturn(call, arg, state, pos, returnAp0, ap, config) and
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) revFlowIsReturned(call, returnCtx, returnAp, pos, returnAp0, config)
) )
} }