@@ -169,3 +169,39 @@ private module Cached {
169169}
170170
171171import Cached
172+ import SpeculativeTaintFlow
173+
174+ private module SpeculativeTaintFlow {
175+ private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
176+ private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as Impl
177+
178+ private predicate hasTarget ( Call call ) {
179+ exists ( Impl:: Public:: SummarizedCallable sc | sc .getACall ( ) = call )
180+ or
181+ exists ( Impl:: Public:: NeutralSummaryCallable nc | nc .getACall ( ) = call )
182+ or
183+ call .getTarget ( ) .getUnboundDeclaration ( ) instanceof ExternalFlow:: SinkCallable
184+ or
185+ exists ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .getACall ( ) = call )
186+ }
187+
188+ predicate speculativeTaintStep ( DataFlow:: Node src , DataFlow:: Node sink ) {
189+ exists ( DataFlowCall call , Call srcCall , ArgumentPosition argpos |
190+ not exists ( viableCallable ( call ) ) and
191+ not hasTarget ( srcCall ) and
192+ call .( NonDelegateDataFlowCall ) .getDispatchCall ( ) .getCall ( ) = srcCall and
193+ ( srcCall instanceof ConstructorInitializer or srcCall instanceof MethodCall ) and
194+ src .( ArgumentNode ) .argumentOf ( call , argpos ) and
195+ not src instanceof PostUpdateNodes:: ObjectInitializerNode and
196+ not src instanceof MallocNode
197+ |
198+ not argpos .isQualifier ( ) and
199+ sink .( PostUpdateNode )
200+ .getPreUpdateNode ( )
201+ .( ArgumentNode )
202+ .argumentOf ( call , any ( ArgumentPosition qualpos | qualpos .isQualifier ( ) ) )
203+ or
204+ sink .( OutNode ) .getCall ( _) = call
205+ )
206+ }
207+ }
0 commit comments