@@ -169,3 +169,39 @@ private module Cached {
169
169
}
170
170
171
171
import 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