@@ -29,6 +29,12 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
29
29
*/
30
30
bindingset [ node]
31
31
predicate defaultImplicitTaintRead ( Lang:: Node node , Lang:: ContentSet c ) ;
32
+
33
+ /**
34
+ * Holds if the additional step from `src` to `sink` should be considered in
35
+ * speculative taint flow exploration.
36
+ */
37
+ predicate speculativeTaintStep ( Lang:: Node src , Lang:: Node sink ) ;
32
38
}
33
39
34
40
/**
@@ -130,4 +136,124 @@ module TaintFlowMake<
130
136
{
131
137
import GlobalWithState< Config >
132
138
}
139
+
140
+ signature int speculationLimitSig ( ) ;
141
+
142
+ private module AddSpeculativeTaintSteps<
143
+ DataFlowInternal:: FullStateConfigSig Config, speculationLimitSig / 0 speculationLimit> implements
144
+ DataFlowInternal:: FullStateConfigSig
145
+ {
146
+ import Config
147
+
148
+ private predicate relevantState ( Config:: FlowState state ) {
149
+ Config:: isSource ( _, state )
150
+ or
151
+ exists ( Config:: FlowState state0 |
152
+ relevantState ( state0 ) and Config:: isAdditionalFlowStep ( _, state0 , _, state , _)
153
+ )
154
+ }
155
+
156
+ private newtype TFlowState =
157
+ TMkFlowState ( Config:: FlowState state , int spec ) {
158
+ relevantState ( state ) and spec = [ 0 .. speculationLimit ( ) ]
159
+ }
160
+
161
+ class FlowState extends TFlowState {
162
+ private Config:: FlowState state ;
163
+ private int spec ;
164
+
165
+ FlowState ( ) { this = TMkFlowState ( state , spec ) }
166
+
167
+ string toString ( ) { result = "FlowState" }
168
+
169
+ Config:: FlowState getState ( ) { result = state }
170
+
171
+ int getSpec ( ) { result = spec }
172
+ }
173
+
174
+ predicate isSource ( DataFlowLang:: Node source , FlowState state ) {
175
+ Config:: isSource ( source , state .getState ( ) ) and state .getSpec ( ) = 0
176
+ }
177
+
178
+ predicate isSink ( DataFlowLang:: Node sink , FlowState state ) {
179
+ Config:: isSink ( sink , state .getState ( ) )
180
+ }
181
+
182
+ predicate isBarrier ( DataFlowLang:: Node node , FlowState state ) {
183
+ Config:: isBarrier ( node , state .getState ( ) )
184
+ }
185
+
186
+ predicate isBarrierIn ( DataFlowLang:: Node node , FlowState state ) {
187
+ Config:: isBarrierIn ( node , state .getState ( ) )
188
+ }
189
+
190
+ predicate isBarrierOut ( DataFlowLang:: Node node , FlowState state ) {
191
+ Config:: isBarrierOut ( node , state .getState ( ) )
192
+ }
193
+
194
+ predicate isAdditionalFlowStep (
195
+ DataFlowLang:: Node node1 , FlowState state1 , DataFlowLang:: Node node2 , FlowState state2 ,
196
+ string model
197
+ ) {
198
+ Config:: isAdditionalFlowStep ( node1 , state1 .getState ( ) , node2 , state2 .getState ( ) , model ) and
199
+ state1 .getSpec ( ) = state2 .getSpec ( )
200
+ or
201
+ speculativeTaintStep ( node1 , node2 ) and
202
+ not defaultAdditionalTaintStep ( node1 , node2 , _) and
203
+ not Config:: isAdditionalFlowStep ( node1 , _, node2 , _, _) and
204
+ not Config:: isAdditionalFlowStep ( node1 , node2 , _) and
205
+ model = "Speculative" and
206
+ state1 .getSpec ( ) + 1 = state2 .getSpec ( ) and
207
+ state1 .getState ( ) = state2 .getState ( )
208
+ }
209
+ }
210
+
211
+ module SpeculativeFlow< DataFlow:: ConfigSig Config, speculationLimitSig / 0 speculationLimit>
212
+ implements DataFlow:: GlobalFlowSig
213
+ {
214
+ private module Config0 implements DataFlowInternal:: FullStateConfigSig {
215
+ import DataFlowInternal:: DefaultState< Config >
216
+ import Config
217
+
218
+ predicate isAdditionalFlowStep (
219
+ DataFlowLang:: Node node1 , DataFlowLang:: Node node2 , string model
220
+ ) {
221
+ Config:: isAdditionalFlowStep ( node1 , node2 ) and model = "Config"
222
+ }
223
+ }
224
+
225
+ private module C implements DataFlowInternal:: FullStateConfigSig {
226
+ import AddTaintDefaults< AddSpeculativeTaintSteps< Config0 , speculationLimit / 0 > >
227
+ }
228
+
229
+ import DataFlowInternal:: Impl< C >
230
+ }
231
+
232
+ module SpeculativeFlowWithState<
233
+ DataFlow:: StateConfigSig Config, speculationLimitSig / 0 speculationLimit> implements
234
+ DataFlow:: GlobalFlowSig
235
+ {
236
+ private module Config0 implements DataFlowInternal:: FullStateConfigSig {
237
+ import Config
238
+
239
+ predicate isAdditionalFlowStep (
240
+ DataFlowLang:: Node node1 , DataFlowLang:: Node node2 , string model
241
+ ) {
242
+ Config:: isAdditionalFlowStep ( node1 , node2 ) and model = "Config"
243
+ }
244
+
245
+ predicate isAdditionalFlowStep (
246
+ DataFlowLang:: Node node1 , FlowState state1 , DataFlowLang:: Node node2 , FlowState state2 ,
247
+ string model
248
+ ) {
249
+ Config:: isAdditionalFlowStep ( node1 , state1 , node2 , state2 ) and model = "Config"
250
+ }
251
+ }
252
+
253
+ private module C implements DataFlowInternal:: FullStateConfigSig {
254
+ import AddTaintDefaults< AddSpeculativeTaintSteps< Config0 , speculationLimit / 0 > >
255
+ }
256
+
257
+ import DataFlowInternal:: Impl< C >
258
+ }
133
259
}
0 commit comments