Skip to content

Commit 4020491

Browse files
committed
C#: Only allow source propgatation upwards in the call stack if the call path consists of unique call targets (to avoid unwanted virtual dispatch). This severely tightens the generation of extrapolated sources.
1 parent 1c3ceac commit 4020491

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ string captureSource(DataFlowTargetApi api) {
249249
PropagateFromSource::flow(source, sink) and
250250
ExternalFlow::sourceNode(source, kind) and
251251
api = sink.getEnclosingCallable() and
252+
not irrelevantSourceSinkApi(source.getEnclosingCallable(), api) and
252253
result = ModelPrinting::asSourceModel(api, sink.getOutput(), kind)
253254
)
254255
}

csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,29 @@ predicate apiSource(DataFlow::Node source) {
257257
)
258258
}
259259

260+
private predicate uniquelyCalls(DataFlowCallable dc1, DataFlowCallable dc2) {
261+
exists(DataFlowCall call |
262+
dc1 = call.getEnclosingCallable() and
263+
dc2 = unique(DataFlowCallable dc0 | dc0 = viableCallable(call) | dc0)
264+
)
265+
}
266+
267+
bindingset[dc1, dc2]
268+
private predicate uniquelyCallsPlus(DataFlowCallable dc1, DataFlowCallable dc2) =
269+
fastTC(uniquelyCalls/2)(dc1, dc2)
270+
271+
/**
272+
* Holds if it is not relevant to generate a source model for `api`, even
273+
* if flow is detected from a node within `source` to a sink within `api`.
274+
*/
275+
bindingset[sourceEnclosing, api]
276+
predicate irrelevantSourceSinkApi(Callable sourceEnclosing, TargetApiSpecific api) {
277+
not exists(DataFlowCallable dc1, DataFlowCallable dc2 | uniquelyCallsPlus(dc1, dc2) or dc1 = dc2 |
278+
dc1.getUnderlyingCallable() = api and
279+
dc2.getUnderlyingCallable() = sourceEnclosing
280+
)
281+
}
282+
260283
/**
261284
* Gets the MaD input string representation of `source`.
262285
*/

0 commit comments

Comments
 (0)