Skip to content

Commit 6e69b63

Browse files
committed
Data flow: More lambda flow changes
1 parent 8154500 commit 6e69b63

File tree

2 files changed

+95
-26
lines changed

2 files changed

+95
-26
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,7 +2662,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26622662
or
26632663
node instanceof ParamNodeEx
26642664
or
2665-
node.asNode() instanceof OutNodeExt
2665+
node instanceof OutNodeEx
26662666
or
26672667
storeStepCand(_, _, _, node, _, _)
26682668
or
@@ -5441,7 +5441,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
54415441
exists(ReturnKindExt kind, DataFlowCall call |
54425442
partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap)
54435443
|
5444-
out.asNode() = kind.getAnOutNode(call)
5444+
out = kind.getAnOutNodeEx(call)
54455445
)
54465446
}
54475447

@@ -5526,7 +5526,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
55265526
) {
55275527
exists(DataFlowCall call, ReturnKindExt kind |
55285528
partialPathThroughCallable0(call, mid, kind, state, cc, t, ap) and
5529-
out.asNode() = kind.getAnOutNode(call)
5529+
out = kind.getAnOutNodeEx(call)
55305530
)
55315531
}
55325532

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

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,18 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
187187
)
188188
}
189189

190+
/**
191+
* Holds if `arg` is an argument of `call` with an argument position that matches
192+
* parameter position `ppos`.
193+
*/
194+
pragma[noinline]
195+
private predicate argumentPositionMatchEx(DataFlowCall call, ArgNodeEx arg, ParameterPosition ppos) {
196+
exists(ArgumentPosition apos |
197+
arg.argumentOf(call, apos) and
198+
parameterMatch(ppos, apos)
199+
)
200+
}
201+
190202
pragma[nomagic]
191203
private predicate hasSimpleReturnKindIn(ReturnNode ret, ReturnKind kind, DataFlowCallable c) {
192204
c = getNodeEnclosingCallable(ret) and
@@ -219,7 +231,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
219231

220232
pragma[noinline]
221233
private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
222-
p.isParameterOf(viableCallable(call), ppos)
234+
p.isParameterOf(viableCallableCached(call), ppos)
223235
}
224236

225237
pragma[noinline]
@@ -259,7 +271,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
259271

260272
pragma[nomagic]
261273
private TReturnPositionSimple viableReturnPosNonLambda(DataFlowCall call, ReturnKind kind) {
262-
result = TReturnPositionSimple0(viableCallable(call), kind)
274+
result = TReturnPositionSimple0(viableCallableCached(call), kind)
263275
}
264276

265277
pragma[nomagic]
@@ -881,9 +893,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
881893
or
882894
result = this.asLambdaInstancePostUpdateNode().toString() + " [LambdaPostUpdate]"
883895
or
884-
exists (DataFlowCall synthcall, ArgumentPosition apos, boolean isPost |
885-
this.isLambdaArgNode(synthcall, apos, isPost) |
886-
result = synthcall.toString() + "-" + apos.toString() + "-" + isPost.toString() + " [LambdaArg]"
896+
exists(DataFlowCall synthcall, ArgumentPosition apos, boolean isPost |
897+
this.isLambdaArgNode(synthcall, apos, isPost)
898+
|
899+
result =
900+
synthcall.toString() + "-" + apos.toString() + "-" + isPost.toString() + " [LambdaArg]"
887901
)
888902
}
889903

@@ -962,9 +976,29 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
962976
}
963977

964978
final class ArgNodeEx extends NodeEx {
965-
ArgNodeEx() { this.asNode() instanceof ArgNode }
979+
private DataFlowCall call_;
980+
private ArgumentPosition pos_;
981+
982+
ArgNodeEx() {
983+
this.asNode().(ArgNode).argumentOf(call_, pos_)
984+
or
985+
this.isLambdaArgNode(call_, pos_, false)
986+
or
987+
exists(Node lambda, DataFlowCallable c, ParameterNode p, ParameterPosition ppos |
988+
lambda = this.asLambdaMallocNode() and
989+
lambdaCreation(lambda, _, c, call_) and
990+
isParameterNode(p, c, ppos) and
991+
isLambdaInstanceParameter(p) and
992+
parameterMatch(ppos, pos_)
993+
)
994+
}
995+
996+
final DataFlowCall getCall() { this.argumentOf(result, _) }
966997

967-
DataFlowCall getCall() { this.asNode().(ArgNode).argumentOf(result, _) }
998+
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
999+
call = call_ and
1000+
pos = pos_
1001+
}
9681002
}
9691003

9701004
final class ParamNodeEx extends NodeEx {
@@ -991,6 +1025,14 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
9911025
ReturnKindExt getKind() { result = pos.getKind() }
9921026
}
9931027

1028+
final class OutNodeEx extends NodeEx {
1029+
OutNodeEx() {
1030+
this.asNode() instanceof OutNodeExt
1031+
or
1032+
this.(PostUpdateNodeEx).getPreUpdateNode() instanceof ArgNodeEx
1033+
}
1034+
}
1035+
9941036
class PostUpdateNodeEx extends NodeEx {
9951037
private NodeEx pre;
9961038

@@ -1075,7 +1117,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
10751117
}
10761118

10771119
cached
1078-
predicate hiddenNode(Node n) { nodeIsHidden(n) }
1120+
predicate hiddenNode(Node n) {
1121+
// todo: add all lambda nodes here after end debugging
1122+
nodeIsHidden(n)
1123+
}
10791124

10801125
cached
10811126
OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) {
@@ -1087,6 +1132,16 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
10871132
)
10881133
}
10891134

1135+
cached
1136+
OutNodeEx getAnOutNodeEx(DataFlowCall call, ReturnKindExt k) {
1137+
result.asNode() = getAnOutNodeExt(call, k)
1138+
or
1139+
exists(ArgNodeEx arg |
1140+
result.(PostUpdateNodeEx).getPreUpdateNode() = arg and
1141+
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
1142+
)
1143+
}
1144+
10901145
pragma[nomagic]
10911146
private predicate paramReturnNode(
10921147
PostUpdateNodeEx n, ParamNode p, SndLevelScopeOption scope, ReturnKindExt k
@@ -1145,7 +1200,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
11451200
}
11461201

11471202
cached
1148-
DataFlowCallable viableCallableCached(DataFlowCall call) { result = viableCallable(call) }
1203+
DataFlowCallable viableCallableCached(DataFlowCall call) {
1204+
result = viableCallable(call)
1205+
or
1206+
lambdaCreation(_, _, result, call)
1207+
}
11491208

11501209
/*
11511210
* foo(x => sink(x), notaint)
@@ -1260,7 +1319,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
12601319
cached
12611320
DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
12621321
result = viableImplInCallContext(call, ctx) and
1263-
result = viableCallable(call)
1322+
result = viableCallableCached(call)
12641323
or
12651324
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
12661325
or
@@ -1407,23 +1466,29 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
14071466
cached
14081467
predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, NodeEx out) {
14091468
viableReturnPosOut(call, pos, out.asNode())
1469+
or
1470+
exists(ReturnKindExt kind |
1471+
pos = viableReturnPos(call, kind) and
1472+
out = kind.getAnOutNodeEx(call)
1473+
)
14101474
}
14111475

1412-
cached
1413-
predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) {
1414-
viableParamArg(call, p.asNode(), arg.asNode())
1476+
bindingset[call, p, arg]
1477+
private predicate golangSpecificParamArgFilterEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) {
1478+
golangSpecificParamArgFilter(call, p.asNode(), arg.asNode())
14151479
or
1416-
exists(ArgumentPosition apos, DataFlowCallable c, ParameterPosition ppos |
1417-
arg.isLambdaArgNode(call, apos, false) and
1418-
lambdaCreation(_, _, c, call) and
1419-
p.isParameterOf(c, ppos) and
1420-
parameterMatch(ppos, apos)
1421-
)
1480+
not p.asNode() instanceof ParamNode
14221481
or
1423-
exists(DataFlowCallable c |
1424-
isLambdaInstanceParameter(p.asNode()) and
1425-
lambdaCreation(arg.asLambdaMallocNode(), _, c, call) and
1426-
p.isParameterOf(c, _)
1482+
not arg.asNode() instanceof ArgNode
1483+
}
1484+
1485+
cached
1486+
predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) {
1487+
exists(ParameterPosition ppos |
1488+
viableParam(call, ppos, p.asNode()) and
1489+
argumentPositionMatchEx(call, arg, ppos) and
1490+
compatibleTypesFilter(arg.getDataFlowType(), p.getDataFlowType()) and
1491+
golangSpecificParamArgFilterEx(call, p, arg)
14271492
)
14281493
}
14291494

@@ -1969,6 +2034,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
19692034
exists(DataFlowCallable c, ParameterNode p, ParameterPosition ppos |
19702035
lambdaCreation(_, _, c, synthcall) and
19712036
isParameterNode(p, c, ppos) and
2037+
not isLambdaInstanceParameter(p) and
19722038
parameterMatch(ppos, apos) and
19732039
exists(ispost)
19742040
)
@@ -2549,6 +2615,9 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25492615

25502616
/** Gets a node corresponding to data flow out of `call`. */
25512617
final OutNodeExt getAnOutNode(DataFlowCall call) { result = getAnOutNodeExt(call, this) }
2618+
2619+
/** Gets a node corresponding to data flow out of `call`. */
2620+
final OutNodeEx getAnOutNodeEx(DataFlowCall call) { result = getAnOutNodeEx(call, this) }
25522621
}
25532622

25542623
class ValueReturnKind extends ReturnKindExt, TValueReturn {

0 commit comments

Comments
 (0)