Skip to content

Commit 5cef673

Browse files
committed
Data flow: Prune parameter-self flow in stage 1
1 parent b392391 commit 5cef673

File tree

2 files changed

+67
-32
lines changed

2 files changed

+67
-32
lines changed

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

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -557,17 +557,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
557557
)
558558
or
559559
// flow into a callable
560-
fwdFlowIn(_, _, _, node) and
560+
fwdFlowInParam(_, node, _) and
561561
cc = true
562562
or
563563
// flow out of a callable
564-
fwdFlowOut(_, node, false) and
564+
fwdFlowOut(_, _, node, false) and
565565
cc = false
566566
or
567567
// flow through a callable
568-
exists(DataFlowCall call |
569-
fwdFlowOutFromArg(call, node) and
570-
fwdFlowIsEntered(call, cc)
568+
exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
569+
fwdFlowOutFromArg(call, kind, node) and
570+
fwdFlowIsEntered(call, disallowReturnKind, cc) and
571+
kind != disallowReturnKind
571572
)
572573
}
573574

@@ -593,11 +594,30 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
593594
)
594595
}
595596

597+
pragma[nomagic]
598+
private predicate fwdFlowInParam(DataFlowCall call, ParamNodeEx p, Cc cc) {
599+
fwdFlowIn(call, _, cc, p)
600+
}
601+
602+
pragma[nomagic]
603+
private ReturnKindExtOption getDisallowedReturnKind(ParamNodeEx p) {
604+
if allowParameterReturnInSelfEx(p)
605+
then result.isNone()
606+
else p.isParameterOf(_, result.asSome().(ParamUpdateReturnKind).getPosition())
607+
}
608+
596609
/**
597610
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
598611
*/
599612
pragma[nomagic]
600-
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc) { fwdFlowIn(call, _, cc, _) }
613+
private predicate fwdFlowIsEntered(
614+
DataFlowCall call, ReturnKindExtOption disallowReturnKind, Cc cc
615+
) {
616+
exists(ParamNodeEx p |
617+
fwdFlowInParam(call, p, cc) and
618+
disallowReturnKind = getDisallowedReturnKind(p)
619+
)
620+
}
601621

602622
pragma[nomagic]
603623
private predicate fwdFlowInReducedViableImplInSomeCallContext(
@@ -618,7 +638,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
618638
pragma[nomagic]
619639
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) {
620640
exists(DataFlowCall ctx |
621-
fwdFlowIsEntered(ctx, _) and
641+
fwdFlowIsEntered(ctx, _, _) and
622642
result = viableImplInCallContextExt(call, ctx)
623643
)
624644
}
@@ -666,17 +686,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
666686

667687
// inline to reduce the number of iterations
668688
pragma[inline]
669-
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc) {
670-
exists(ReturnPosition pos |
671-
fwdFlowReturnPosition(pos, cc) and
672-
viableReturnPosOutEx(call, pos, out) and
673-
not fullBarrier(out)
674-
)
689+
private predicate fwdFlowOut(DataFlowCall call, ReturnPosition pos, NodeEx out, Cc cc) {
690+
fwdFlowReturnPosition(pos, cc) and
691+
viableReturnPosOutEx(call, pos, out) and
692+
not fullBarrier(out)
675693
}
676694

677695
pragma[nomagic]
678-
private predicate fwdFlowOutFromArg(DataFlowCall call, NodeEx out) {
679-
fwdFlowOut(call, out, true)
696+
private predicate fwdFlowOutFromArg(DataFlowCall call, ReturnKindExtOption kind, NodeEx out) {
697+
exists(ReturnPosition pos |
698+
fwdFlowOut(call, pos, out, true) and
699+
kind.asSome() = pos.getKind()
700+
)
680701
}
681702

682703
private predicate stateStepFwd(FlowState state1, FlowState state2) {
@@ -750,7 +771,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
750771
)
751772
or
752773
// flow into a callable
753-
revFlowIn(_, node, false) and
774+
revFlowIn(_, _, node, false) and
754775
toReturn = false
755776
or
756777
// flow out of a callable
@@ -761,9 +782,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
761782
)
762783
or
763784
// flow through a callable
764-
exists(DataFlowCall call |
765-
revFlowInToReturn(call, node) and
766-
revFlowIsReturned(call, toReturn)
785+
exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind |
786+
revFlowIsReturned(call, kind, toReturn) and
787+
revFlowInToReturn(call, disallowReturnKind, node) and
788+
kind != disallowReturnKind
767789
)
768790
}
769791

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

825847
// inline to reduce the number of iterations
826848
pragma[inline]
827-
private predicate revFlowIn(DataFlowCall call, ArgNodeEx arg, boolean toReturn) {
828-
exists(ParamNodeEx p |
829-
revFlow(p, toReturn) and
830-
viableParamArgNodeCandFwd1(call, p, arg)
831-
)
849+
private predicate revFlowIn(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, boolean toReturn) {
850+
revFlow(p, toReturn) and
851+
viableParamArgNodeCandFwd1(call, p, arg)
832852
}
833853

834854
pragma[nomagic]
835-
private predicate revFlowInToReturn(DataFlowCall call, ArgNodeEx arg) {
836-
revFlowIn(call, arg, true)
855+
private predicate revFlowInToReturn(
856+
DataFlowCall call, ReturnKindExtOption disallowReturnKind, ArgNodeEx arg
857+
) {
858+
exists(ParamNodeEx p |
859+
revFlowIn(call, p, arg, true) and
860+
disallowReturnKind = getDisallowedReturnKind(p)
861+
)
837862
}
838863

839864
/**
@@ -842,10 +867,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
842867
* reaching an argument of `call`.
843868
*/
844869
pragma[nomagic]
845-
private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn) {
870+
private predicate revFlowIsReturned(
871+
DataFlowCall call, ReturnKindExtOption kind, boolean toReturn
872+
) {
846873
exists(NodeEx out |
847874
revFlow(out, toReturn) and
848-
fwdFlowOutFromArg(call, out)
875+
fwdFlowOutFromArg(call, kind, out)
849876
)
850877
}
851878

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

948975
pragma[nomagic]
949976
predicate callMayFlowThroughRev(DataFlowCall call) {
950-
exists(ArgNodeEx arg, boolean toReturn |
951-
revFlow(arg, toReturn) and
952-
revFlowInToReturn(call, arg) and
953-
revFlowIsReturned(call, toReturn)
977+
exists(
978+
ArgNodeEx arg, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind,
979+
boolean toReturn
980+
|
981+
revFlow(arg, pragma[only_bind_into](toReturn)) and
982+
revFlowIsReturned(call, kind, pragma[only_bind_into](toReturn)) and
983+
revFlowInToReturn(call, disallowReturnKind, arg) and
984+
kind != disallowReturnKind
954985
)
955986
}
956987

shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
24172417
override string toString() { result = "param update " + pos }
24182418
}
24192419

2420+
module ReturnKindExtOption = Option<ReturnKindExt>;
2421+
2422+
class ReturnKindExtOption = ReturnKindExtOption::Option;
2423+
24202424
/** A callable tagged with a relevant return kind. */
24212425
class ReturnPosition extends TReturnPosition0 {
24222426
private DataFlowCallable c;

0 commit comments

Comments
 (0)