Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data flow: Prune parameter-self flow in stage 1 #18333

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading