Skip to content

Commit 3c110f2

Browse files
author
Alex Eyers-Taylor
committed
DataFlow: Add code for merging base with overlay.
1 parent c49e2ab commit 3c110f2

File tree

3 files changed

+295
-9
lines changed

3 files changed

+295
-9
lines changed

shared/dataflow/codeql/dataflow/DataFlow.qll

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ private module PathGraphSigMod {
657657
}
658658
}
659659

660-
module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
660+
module DataFlowMakeCore<LocationSig Location, InputSig<Location> Lang> {
661661
private import Lang
662662
private import internal.DataFlowImpl::MakeImpl<Location, Lang>
663663
private import internal.DataFlowImplStage1::MakeImplStage1<Location, Lang>
@@ -1099,6 +1099,13 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
10991099
// Re-export the PathGraph so the user can import a single module and get both PathNode and the query predicates
11001100
import PathGraph
11011101
}
1102+
}
1103+
1104+
module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
1105+
import DataFlowMakeCore<Location, Lang>
1106+
private import Lang
1107+
private import internal.DataFlowImpl::MakeImpl<Location, Lang>
1108+
private import internal.DataFlowImplStage1::MakeImplStage1<Location, Lang>
11021109

11031110
/**
11041111
* Constructs a global data flow computation.
@@ -1157,3 +1164,71 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
11571164
import Flow
11581165
}
11591166
}
1167+
1168+
module DataFlowMakeOverlay<LocationSig Location, InputSig<Location> Lang> {
1169+
import DataFlowMakeCore<Location, Lang>
1170+
private import Lang
1171+
private import internal.DataFlowImpl::MakeImpl<Location, Lang>
1172+
private import internal.DataFlowImplStage1::MakeImplStage1<Location, Lang>
1173+
1174+
/**
1175+
* Constructs a global data flow computation.
1176+
*/
1177+
module Global<ConfigSig Config> implements GlobalFlowSig {
1178+
private module C implements FullStateConfigSig {
1179+
import DefaultState<Config>
1180+
import Config
1181+
1182+
predicate accessPathLimit = Config::accessPathLimit/0;
1183+
1184+
predicate isAdditionalFlowStep(Node node1, Node node2, string model) {
1185+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
1186+
}
1187+
1188+
predicate observeOverlayInformedIncrementalMode() {
1189+
not Config::observeDiffInformedIncrementalMode()
1190+
}
1191+
}
1192+
1193+
private module Stage1 = ImplStage1<C>;
1194+
1195+
import Stage1::PartialFlow
1196+
1197+
private module Flow = OverlayImpl<C, Stage1::Stage1NoState>;
1198+
1199+
import Flow
1200+
}
1201+
1202+
/**
1203+
* Constructs a global data flow computation using flow state.
1204+
*/
1205+
module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig {
1206+
private module C implements FullStateConfigSig {
1207+
import Config
1208+
1209+
predicate accessPathLimit = Config::accessPathLimit/0;
1210+
1211+
predicate isAdditionalFlowStep(Node node1, Node node2, string model) {
1212+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
1213+
}
1214+
1215+
predicate isAdditionalFlowStep(
1216+
Node node1, FlowState state1, Node node2, FlowState state2, string model
1217+
) {
1218+
Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config"
1219+
}
1220+
1221+
predicate observeOverlayInformedIncrementalMode() {
1222+
not Config::observeDiffInformedIncrementalMode()
1223+
}
1224+
}
1225+
1226+
private module Stage1 = ImplStage1<C>;
1227+
1228+
import Stage1::PartialFlow
1229+
1230+
private module Flow = OverlayImpl<C, Stage1::Stage1WithState>;
1231+
1232+
import Flow
1233+
}
1234+
}

shared/dataflow/codeql/dataflow/TaintTracking.qll

Lines changed: 168 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
4747
/**
4848
* Construct the modules for taint-tracking analyses.
4949
*/
50-
module TaintFlowMake<
50+
private module TaintFlowMakeCore<
5151
LocationSig Location, DF::InputSig<Location> DataFlowLang,
5252
InputSig<Location, DataFlowLang> TaintTrackingLang>
5353
{
54-
private import TaintTrackingLang
55-
private import DF::DataFlowMake<Location, DataFlowLang> as DataFlow
56-
private import MakeImpl<Location, DataFlowLang> as DataFlowInternal
57-
private import MakeImplStage1<Location, DataFlowLang> as DataFlowInternalStage1
54+
import TaintTrackingLang
55+
import DF::DataFlowMakeCore<Location, DataFlowLang> as DataFlow
56+
import MakeImpl<Location, DataFlowLang> as DataFlowInternal
57+
import MakeImplStage1<Location, DataFlowLang> as DataFlowInternalStage1
5858

59-
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
59+
module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
6060
DataFlowInternal::FullStateConfigSig
6161
{
6262
import Config
@@ -85,7 +85,7 @@ module TaintFlowMake<
8585

8686
signature int speculationLimitSig();
8787

88-
private module AddSpeculativeTaintSteps<
88+
module AddSpeculativeTaintSteps<
8989
DataFlowInternal::FullStateConfigSig Config, speculationLimitSig/0 speculationLimit> implements
9090
DataFlowInternal::FullStateConfigSig
9191
{
@@ -153,6 +153,13 @@ module TaintFlowMake<
153153
state1.getState() = state2.getState()
154154
}
155155
}
156+
}
157+
158+
module TaintFlowMake<
159+
LocationSig Location, DF::InputSig<Location> DataFlowLang,
160+
InputSig<Location, DataFlowLang> TaintTrackingLang>
161+
{
162+
private import TaintFlowMakeCore<Location, DataFlowLang, TaintTrackingLang>
156163

157164
/**
158165
* Constructs a global taint tracking computation.
@@ -288,8 +295,162 @@ module TaintFlowMake<
288295

289296
import Stage1::PartialFlow
290297

298+
private module Flow = DataFlowInternal::OverlayImpl<C, Stage1::Stage1WithState>;
299+
300+
import Flow
301+
}
302+
}
303+
304+
module TaintFlowMakeOverlay<
305+
LocationSig Location, DF::InputSig<Location> DataFlowLang,
306+
InputSig<Location, DataFlowLang> TaintTrackingLang>
307+
{
308+
private import TaintFlowMakeCore<Location, DataFlowLang, TaintTrackingLang>
309+
310+
/**
311+
* Constructs a global taint tracking computation.
312+
*/
313+
module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
314+
private module Config0 implements DataFlowInternal::FullStateConfigSig {
315+
import DataFlowInternal::DefaultState<Config>
316+
import Config
317+
318+
predicate isAdditionalFlowStep(
319+
DataFlowLang::Node node1, DataFlowLang::Node node2, string model
320+
) {
321+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
322+
}
323+
324+
predicate observeOverlayInformedIncrementalMode() {
325+
not Config::observeDiffInformedIncrementalMode()
326+
}
327+
}
328+
329+
private module C implements DataFlowInternal::FullStateConfigSig {
330+
import AddTaintDefaults<Config0>
331+
}
332+
333+
private module Stage1 = DataFlowInternalStage1::ImplStage1<C>;
334+
335+
import Stage1::PartialFlow
336+
337+
private module Flow = DataFlowInternal::OverlayImpl<C, Stage1::Stage1NoState>;
338+
339+
import Flow
340+
}
341+
342+
/**
343+
* Constructs a global taint tracking computation using flow state.
344+
*/
345+
module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
346+
private module Config0 implements DataFlowInternal::FullStateConfigSig {
347+
import Config
348+
349+
predicate isAdditionalFlowStep(
350+
DataFlowLang::Node node1, DataFlowLang::Node node2, string model
351+
) {
352+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
353+
}
354+
355+
predicate isAdditionalFlowStep(
356+
DataFlowLang::Node node1, FlowState state1, DataFlowLang::Node node2, FlowState state2,
357+
string model
358+
) {
359+
Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config"
360+
}
361+
362+
predicate observeOverlayInformedIncrementalMode() {
363+
not Config::observeDiffInformedIncrementalMode()
364+
}
365+
}
366+
367+
private module C implements DataFlowInternal::FullStateConfigSig {
368+
import AddTaintDefaults<Config0>
369+
}
370+
371+
private module Stage1 = DataFlowInternalStage1::ImplStage1<C>;
372+
373+
import Stage1::PartialFlow
374+
375+
private module Flow = DataFlowInternal::OverlayImpl<C, Stage1::Stage1WithState>;
376+
377+
import Flow
378+
}
379+
380+
/**
381+
* Constructs a global taint tracking computation that also allows a given
382+
* maximum number of speculative taint steps.
383+
*/
384+
module SpeculativeGlobal<DataFlow::ConfigSig Config, speculationLimitSig/0 speculationLimit>
385+
implements DataFlow::GlobalFlowSig
386+
{
387+
private module Config0 implements DataFlowInternal::FullStateConfigSig {
388+
import DataFlowInternal::DefaultState<Config>
389+
import Config
390+
391+
predicate isAdditionalFlowStep(
392+
DataFlowLang::Node node1, DataFlowLang::Node node2, string model
393+
) {
394+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
395+
}
396+
397+
predicate observeOverlayInformedIncrementalMode() {
398+
not Config::observeDiffInformedIncrementalMode()
399+
}
400+
}
401+
402+
private module C implements DataFlowInternal::FullStateConfigSig {
403+
import AddTaintDefaults<AddSpeculativeTaintSteps<Config0, speculationLimit/0>>
404+
}
405+
406+
private module Stage1 = DataFlowInternalStage1::ImplStage1<C>;
407+
408+
import Stage1::PartialFlow
409+
291410
private module Flow = DataFlowInternal::Impl<C, Stage1::Stage1WithState>;
292411

293412
import Flow
294413
}
414+
415+
/**
416+
* Constructs a global taint tracking computation using flow state that also
417+
* allows a given maximum number of speculative taint steps.
418+
*/
419+
module SpeculativeGlobalWithState<
420+
DataFlow::StateConfigSig Config, speculationLimitSig/0 speculationLimit> implements
421+
DataFlow::GlobalFlowSig
422+
{
423+
private module Config0 implements DataFlowInternal::FullStateConfigSig {
424+
import Config
425+
426+
predicate isAdditionalFlowStep(
427+
DataFlowLang::Node node1, DataFlowLang::Node node2, string model
428+
) {
429+
Config::isAdditionalFlowStep(node1, node2) and model = "Config"
430+
}
431+
432+
predicate isAdditionalFlowStep(
433+
DataFlowLang::Node node1, FlowState state1, DataFlowLang::Node node2, FlowState state2,
434+
string model
435+
) {
436+
Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config"
437+
}
438+
439+
predicate observeOverlayInformedIncrementalMode() {
440+
not Config::observeDiffInformedIncrementalMode()
441+
}
442+
}
443+
444+
private module C implements DataFlowInternal::FullStateConfigSig {
445+
import AddTaintDefaults<AddSpeculativeTaintSteps<Config0, speculationLimit/0>>
446+
}
447+
448+
private module Stage1 = DataFlowInternalStage1::ImplStage1<C>;
449+
450+
import Stage1::PartialFlow
451+
452+
private module Flow = DataFlowInternal::OverlayImpl<C, Stage1::Stage1WithState>;
453+
454+
import Flow
455+
}
295456
}

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ private import DataFlowImplStage1
1515

1616
module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1717
private import Lang
18-
private import DataFlowMake<Location, Lang>
18+
private import DataFlowMakeCore<Location, Lang>
1919
private import MakeImplStage1<Location, Lang>
2020
private import DataFlowImplCommon::MakeImplCommon<Location, Lang>
2121
private import DataFlowImplCommonPublic
@@ -179,6 +179,56 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
179179
}
180180
}
181181

182+
/**
183+
* Constructs a data flow computation given a full input configuration, and
184+
* an initial stage 1 pruning with merging of overlay and base results.
185+
*/
186+
module OverlayImpl<FullStateConfigSig Config, Stage1Output<Config::FlowState> Stage1> {
187+
module Base = Impl<Config, Stage1>;
188+
189+
import Base
190+
191+
/**
192+
* Holds if data can flow from `source` to `sink`.
193+
*
194+
* This is a local predicate that only has results local to the overlay/base database.
195+
*/
196+
predicate flowLocal(Node source, Node sink) = forceLocal(Base::flow/2)(source, sink)
197+
198+
/**
199+
* Holds if data can flow from `source` to `sink`.
200+
*/
201+
predicate flow(Node source, Node sink) {
202+
Base::flow(source, sink)
203+
or
204+
// If we are overlay informed (i.e. we are not diff-informed), we
205+
// merge in the local results which includes the base database results.
206+
flowLocal(source, sink) and Config::observeOverlayInformedIncrementalMode()
207+
}
208+
209+
/**
210+
* Holds if data can flow from some source to `sink`.
211+
* This predicate that only has results local to the overlay/base database.
212+
*/
213+
predicate flowToLocal(Node sink) = forceLocal(Base::flowTo/1)(sink)
214+
215+
/**
216+
* Holds if data can flow from some source to `sink`.
217+
*/
218+
predicate flowTo(Node sink) {
219+
Base::flowTo(sink)
220+
or
221+
// If we are overlay informed (i.e. we are not diff-informed), we
222+
// merge in the local results which includes the base database results.
223+
flowToLocal(sink) and Config::observeOverlayInformedIncrementalMode()
224+
}
225+
226+
/**
227+
* Holds if data can flow from some source to `sink`.
228+
*/
229+
predicate flowToExpr(Lang::DataFlowExpr sink) { flowTo(exprNode(sink)) }
230+
}
231+
182232
/**
183233
* Constructs a data flow computation given a full input configuration, and
184234
* an initial stage 1 pruning.

0 commit comments

Comments
 (0)