From fc70024f521f4751d5597efc7bfad24cf7da9a2f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 11 Dec 2024 14:15:58 +0100 Subject: [PATCH] C#: Remove false-positive reflection calls in dataflow --- .../dataflow/internal/DataFlowDispatch.qll | 6 +++++- .../lib/semmle/code/csharp/dispatch/Dispatch.qll | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index c711096cfb5e..e17bff759159 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -424,7 +424,11 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall { Callable getATarget(boolean static) { result = dc.getADynamicTarget().getUnboundDeclaration() and static = false or - result = dc.getAStaticTarget().getUnboundDeclaration() and static = true + result = dc.getAStaticTarget().getUnboundDeclaration() and + static = true and + // In reflection calls, _all_ methods with matching names and arities are considered + // static targets, so we need to exclude them + not dc.isReflection() } override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn } diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll index 790f055ef56a..1b27871d1ef6 100644 --- a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll @@ -52,7 +52,21 @@ class DispatchCall extends Internal::TDispatchCall { } /** Holds if this call uses reflection. */ - predicate isReflection() { this instanceof Internal::TDispatchReflectionCall } + predicate isReflection() { + this instanceof Internal::TDispatchReflectionCall + or + this instanceof Internal::TDispatchDynamicElementAccess + or + this instanceof Internal::TDispatchDynamicMemberAccess + or + this instanceof Internal::TDispatchDynamicMethodCall + or + this instanceof Internal::TDispatchDynamicOperatorCall + or + this instanceof Internal::TDispatchDynamicEventAccess + or + this instanceof Internal::TDispatchDynamicObjectCreation + } } /** Internal implementation details. */