Skip to content

Commit

Permalink
Data flow: Prune parameter-self flow in stage 1
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Dec 20, 2024
1 parent b392391 commit 5cef673
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 32 deletions.
95 changes: 63 additions & 32 deletions shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -557,17 +557,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
)
or
// flow into a callable
fwdFlowIn(_, _, _, node) and
fwdFlowInParam(_, node, _) and
cc = true
or
// flow out of a callable
fwdFlowOut(_, node, false) and
fwdFlowOut(_, _, node, false) and
cc = false
or
// flow through a callable
exists(DataFlowCall call |
fwdFlowOutFromArg(call, node) and
fwdFlowIsEntered(call, cc)
exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
fwdFlowOutFromArg(call, kind, node) and
fwdFlowIsEntered(call, disallowReturnKind, cc) and
kind != disallowReturnKind
)
}

Expand All @@ -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`.
*/
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]
private predicate fwdFlowInReducedViableImplInSomeCallContext(
Expand All @@ -618,7 +638,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic]
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) {
exists(DataFlowCall ctx |
fwdFlowIsEntered(ctx, _) and
fwdFlowIsEntered(ctx, _, _) and
result = viableImplInCallContextExt(call, ctx)
)
}
Expand Down Expand Up @@ -666,17 +686,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

// inline to reduce the number of iterations
pragma[inline]
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc) {
exists(ReturnPosition pos |
fwdFlowReturnPosition(pos, cc) and
viableReturnPosOutEx(call, pos, out) and
not fullBarrier(out)
)
private predicate fwdFlowOut(DataFlowCall call, ReturnPosition pos, NodeEx out, Cc cc) {
fwdFlowReturnPosition(pos, cc) and
viableReturnPosOutEx(call, pos, out) and
not fullBarrier(out)
}

pragma[nomagic]
private predicate fwdFlowOutFromArg(DataFlowCall call, NodeEx out) {
fwdFlowOut(call, out, true)
private predicate fwdFlowOutFromArg(DataFlowCall call, ReturnKindExtOption kind, NodeEx out) {
exists(ReturnPosition pos |
fwdFlowOut(call, pos, out, true) and
kind.asSome() = pos.getKind()
)
}

private predicate stateStepFwd(FlowState state1, FlowState state2) {
Expand Down Expand Up @@ -750,7 +771,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
)
or
// flow into a callable
revFlowIn(_, node, false) and
revFlowIn(_, _, node, false) and
toReturn = false
or
// flow out of a callable
Expand All @@ -761,9 +782,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
)
or
// flow through a callable
exists(DataFlowCall call |
revFlowInToReturn(call, node) and
revFlowIsReturned(call, toReturn)
exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
revFlowIsReturned(call, kind, toReturn) and
revFlowInToReturn(call, disallowReturnKind, node) and
kind != disallowReturnKind
)
}

Expand Down Expand Up @@ -824,16 +846,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

// inline to reduce the number of iterations
pragma[inline]
private predicate revFlowIn(DataFlowCall call, ArgNodeEx arg, boolean toReturn) {
exists(ParamNodeEx p |
revFlow(p, toReturn) and
viableParamArgNodeCandFwd1(call, p, arg)
)
private predicate revFlowIn(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, boolean toReturn) {
revFlow(p, toReturn) and
viableParamArgNodeCandFwd1(call, p, arg)
}

pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgNodeEx arg) {
revFlowIn(call, arg, true)
private predicate revFlowInToReturn(
DataFlowCall call, ReturnKindExtOption disallowReturnKind, ArgNodeEx arg
) {
exists(ParamNodeEx p |
revFlowIn(call, p, arg, true) and
disallowReturnKind = getDisallowedReturnKind(p)
)
}

/**
Expand All @@ -842,10 +867,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
* reaching an argument of `call`.
*/
pragma[nomagic]
private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn) {
private predicate revFlowIsReturned(
DataFlowCall call, ReturnKindExtOption kind, boolean toReturn
) {
exists(NodeEx out |
revFlow(out, toReturn) and
fwdFlowOutFromArg(call, out)
fwdFlowOutFromArg(call, kind, out)
)
}

Expand Down Expand Up @@ -947,10 +974,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

pragma[nomagic]
predicate callMayFlowThroughRev(DataFlowCall call) {
exists(ArgNodeEx arg, boolean toReturn |
revFlow(arg, toReturn) and
revFlowInToReturn(call, arg) and
revFlowIsReturned(call, toReturn)
exists(
ArgNodeEx arg, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind,
boolean 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
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2417,6 +2417,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
override string toString() { result = "param update " + pos }
}

module ReturnKindExtOption = Option<ReturnKindExt>;

class ReturnKindExtOption = ReturnKindExtOption::Option;

/** A callable tagged with a relevant return kind. */
class ReturnPosition extends TReturnPosition0 {
private DataFlowCallable c;
Expand Down

0 comments on commit 5cef673

Please sign in to comment.