Skip to content

Commit 7d12329

Browse files
committed
Dataflow: Add speculative flow modules.
1 parent c80627a commit 7d12329

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

shared/dataflow/codeql/dataflow/TaintTracking.qll

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
2929
*/
3030
bindingset[node]
3131
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);
3238
}
3339

3440
/**
@@ -130,4 +136,124 @@ module TaintFlowMake<
130136
{
131137
import GlobalWithState<Config>
132138
}
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+
}
133259
}

0 commit comments

Comments
 (0)