Data flow: Prune parameter-self flow in stage 1

This commit is contained in:
Tom Hvitved
2024-12-19 20:19:35 +01:00
parent b0062fc727
commit 06ba814929
2 changed files with 61 additions and 28 deletions

View File

@@ -557,17 +557,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) )
or or
// flow into a callable // flow into a callable
fwdFlowIn(_, _, _, node) and fwdFlowInParam(_, node, _) and
cc = true cc = true
or or
// flow out of a callable // flow out of a callable
fwdFlowOut(_, node, false) and fwdFlowOut(_, _, node, false) and
cc = false cc = false
or or
// flow through a callable // flow through a callable
exists(DataFlowCall call | exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
fwdFlowOutFromArg(call, node) and fwdFlowOutFromArg(call, kind, node) and
fwdFlowIsEntered(call, cc) fwdFlowIsEntered(call, disallowReturnKind, cc) and
kind != disallowReturnKind
) )
} }
@@ -593,11 +594,30 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) )
} }
pragma[nomagic]
private predicate fwdFlowInParam(DataFlowCall call, ParamNodeEx p, Cc cc) {
fwdFlowIn(call, _, cc, p)
}
pragma[nomagic]
private ReturnKindExtOption getDisallowedReturnKind(ParamNodeEx p) {
if allowParameterReturnInSelfEx(p)
then result.isNone()
else p.isParameterOf(_, result.asSome().(ParamUpdateReturnKind).getPosition())
}
/** /**
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`. * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
*/ */
pragma[nomagic] pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc) { fwdFlowIn(call, _, cc, _) } private predicate fwdFlowIsEntered(
DataFlowCall call, ReturnKindExtOption disallowReturnKind, Cc cc
) {
exists(ParamNodeEx p |
fwdFlowInParam(call, p, cc) and
disallowReturnKind = getDisallowedReturnKind(p)
)
}
pragma[nomagic] pragma[nomagic]
private predicate fwdFlowInReducedViableImplInSomeCallContext( private predicate fwdFlowInReducedViableImplInSomeCallContext(
@@ -618,7 +638,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic] pragma[nomagic]
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) { private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) {
exists(DataFlowCall ctx | exists(DataFlowCall ctx |
fwdFlowIsEntered(ctx, _) and fwdFlowIsEntered(ctx, _, _) and
result = viableImplInCallContextExt(call, ctx) result = viableImplInCallContextExt(call, ctx)
) )
} }
@@ -666,17 +686,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
// inline to reduce the number of iterations // inline to reduce the number of iterations
pragma[inline] pragma[inline]
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc) { private predicate fwdFlowOut(DataFlowCall call, ReturnKindExt kind, NodeEx out, Cc cc) {
exists(ReturnPosition pos | exists(ReturnPosition pos |
fwdFlowReturnPosition(pos, cc) and fwdFlowReturnPosition(pos, cc) and
viableReturnPosOutEx(call, pos, out) and viableReturnPosOutEx(call, pos, out) and
not fullBarrier(out) not fullBarrier(out) and
kind = pos.getKind()
) )
} }
pragma[nomagic] pragma[nomagic]
private predicate fwdFlowOutFromArg(DataFlowCall call, NodeEx out) { private predicate fwdFlowOutFromArg(DataFlowCall call, ReturnKindExtOption kind, NodeEx out) {
fwdFlowOut(call, out, true) fwdFlowOut(call, kind.asSome(), out, true)
} }
private predicate stateStepFwd(FlowState state1, FlowState state2) { private predicate stateStepFwd(FlowState state1, FlowState state2) {
@@ -750,7 +771,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) )
or or
// flow into a callable // flow into a callable
revFlowIn(_, node, false) and revFlowIn(_, _, node, false) and
toReturn = false toReturn = false
or or
// flow out of a callable // flow out of a callable
@@ -761,9 +782,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) )
or or
// flow through a callable // flow through a callable
exists(DataFlowCall call | exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
revFlowInToReturn(call, node) and revFlowIsReturned(call, kind, toReturn) and
revFlowIsReturned(call, toReturn) revFlowInToReturn(call, disallowReturnKind, node) and
kind != disallowReturnKind
) )
} }
@@ -824,16 +846,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
// inline to reduce the number of iterations // inline to reduce the number of iterations
pragma[inline] pragma[inline]
private predicate revFlowIn(DataFlowCall call, ArgNodeEx arg, boolean toReturn) { private predicate revFlowIn(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, boolean toReturn) {
exists(ParamNodeEx p | revFlow(p, toReturn) and
revFlow(p, toReturn) and viableParamArgNodeCandFwd1(call, p, arg)
viableParamArgNodeCandFwd1(call, p, arg)
)
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgNodeEx arg) { private predicate revFlowInToReturn(
revFlowIn(call, arg, true) DataFlowCall call, ReturnKindExtOption disallowReturnKind, ArgNodeEx arg
) {
exists(ParamNodeEx p |
revFlowIn(call, p, arg, true) and
disallowReturnKind = getDisallowedReturnKind(p)
)
} }
/** /**
@@ -842,10 +867,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
* reaching an argument of `call`. * reaching an argument of `call`.
*/ */
pragma[nomagic] pragma[nomagic]
private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn) { private predicate revFlowIsReturned(
DataFlowCall call, ReturnKindExtOption kind, boolean toReturn
) {
exists(NodeEx out | exists(NodeEx out |
revFlow(out, toReturn) and revFlow(out, toReturn) and
fwdFlowOutFromArg(call, out) fwdFlowOutFromArg(call, kind, out)
) )
} }
@@ -947,10 +974,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic] pragma[nomagic]
predicate callMayFlowThroughRev(DataFlowCall call) { predicate callMayFlowThroughRev(DataFlowCall call) {
exists(ArgNodeEx arg, boolean toReturn | exists(
revFlow(arg, toReturn) and ArgNodeEx arg, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind,
revFlowInToReturn(call, arg) and boolean toReturn
revFlowIsReturned(call, toReturn) |
revFlow(arg, pragma[only_bind_into](toReturn)) and
revFlowIsReturned(call, kind, pragma[only_bind_into](toReturn)) and
revFlowInToReturn(call, disallowReturnKind, arg) and
kind != disallowReturnKind
) )
} }

View File

@@ -2417,6 +2417,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
override string toString() { result = "param update " + pos } override string toString() { result = "param update " + pos }
} }
class ReturnKindExtOption = Option<ReturnKindExt>::Option;
/** A callable tagged with a relevant return kind. */ /** A callable tagged with a relevant return kind. */
class ReturnPosition extends TReturnPosition0 { class ReturnPosition extends TReturnPosition0 {
private DataFlowCallable c; private DataFlowCallable c;