Skip to content

Commit 3b8234e

Browse files
committed
SSA: Update data flow integration and BarrierGuard interface to use GuardValue.
1 parent 37b508b commit 3b8234e

File tree

11 files changed

+121
-71
lines changed

11 files changed

+121
-71
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,19 +1982,23 @@ module IteratorFlow {
19821982

19831983
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
19841984

1985+
class GuardValue = Void;
1986+
19851987
class Guard extends Void {
1986-
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
1988+
predicate hasValueBranchEdge(
1989+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
1990+
) {
19871991
none()
19881992
}
19891993

1990-
predicate controlsBranchEdge(
1991-
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
1994+
predicate valueControlsBranchEdge(
1995+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
19921996
) {
19931997
none()
19941998
}
19951999
}
19962000

1997-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
2001+
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
19982002
none()
19992003
}
20002004

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,8 @@ class GlobalDef extends Definition {
961961
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
962962

963963
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
964+
private import codeql.util.Boolean
965+
964966
class Expr extends Instruction {
965967
Expr() {
966968
exists(IRBlock bb, int i |
@@ -992,23 +994,29 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
992994
result instanceof FalseEdge
993995
}
994996

997+
class GuardValue = Boolean;
998+
995999
class Guard instanceof IRGuards::IRGuardCondition {
9961000
string toString() { result = super.toString() }
9971001

998-
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
1002+
predicate hasValueBranchEdge(
1003+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
1004+
) {
9991005
exists(EdgeKind kind |
10001006
super.getBlock() = bb1 and
10011007
kind = getConditionalEdge(branch) and
10021008
bb1.getSuccessor(kind) = bb2
10031009
)
10041010
}
10051011

1006-
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
1007-
this.hasBranchEdge(bb1, bb2, branch)
1012+
predicate valueControlsBranchEdge(
1013+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
1014+
) {
1015+
this.hasValueBranchEdge(bb1, bb2, branch)
10081016
}
10091017
}
10101018

1011-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
1019+
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
10121020
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
10131021
}
10141022

@@ -1037,7 +1045,8 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
10371045
}
10381046

10391047
private predicate guardChecks(
1040-
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex
1048+
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def,
1049+
DataFlowIntegrationInput::GuardValue branch, int indirectionIndex
10411050
) {
10421051
exists(UseImpl use |
10431052
guardChecksNode(g, use.getNode(), branch, indirectionIndex) and

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,8 @@ private module Cached {
975975
cached // nothing is actually cached
976976
module BarrierGuard<guardChecksSig/3 guardChecks> {
977977
private predicate guardChecksAdjTypes(
978-
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
978+
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
979+
DataFlowIntegrationInput::GuardValue branch
979980
) {
980981
exists(Guards::AbstractValues::BooleanValue v |
981982
guardChecks(g, e.getAstNode(), v) and
@@ -1016,6 +1017,7 @@ string getToStringPrefix(Definition def) {
10161017
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
10171018
private import csharp as Cs
10181019
private import semmle.code.csharp.controlflow.BasicBlocks
1020+
private import codeql.util.Boolean
10191021

10201022
class Expr extends ControlFlow::Node {
10211023
predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -1042,12 +1044,14 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
10421044
)
10431045
}
10441046

1047+
class GuardValue = Boolean;
1048+
10451049
class Guard extends Guards::Guard {
10461050
/**
10471051
* Holds if the evaluation of this guard to `branch` corresponds to the edge
10481052
* from `bb1` to `bb2`.
10491053
*/
1050-
predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
1054+
predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
10511055
exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s |
10521056
this.getAControlFlowNode() = bb1.getLastNode() and
10531057
bb2 = bb1.getASuccessorByType(s) and
@@ -1060,13 +1064,13 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
10601064
* branch edge from `bb1` to `bb2`. That is, following the edge from
10611065
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
10621066
*/
1063-
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
1064-
this.hasBranchEdge(bb1, bb2, branch)
1067+
predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) {
1068+
this.hasValueBranchEdge(bb1, bb2, branch)
10651069
}
10661070
}
10671071

10681072
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
1069-
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
1073+
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, GuardValue branch) {
10701074
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
10711075
guard.getAControlFlowNode() = conditionBlock.getLastNode() and
10721076
s.getValue() = branch and

java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,9 @@ private module Cached {
563563
cached // nothing is actually cached
564564
module BarrierGuard<guardChecksSig/3 guardChecks> {
565565
private predicate guardChecksAdjTypes(
566-
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
566+
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, Guards::GuardValue val
567567
) {
568-
guardChecks(g, e, branch)
568+
guardChecks(g, e, val.asBooleanValue())
569569
}
570570

571571
private Node getABarrierNodeImpl() {
@@ -657,16 +657,18 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
657657
def instanceof SsaUncertainImplicitUpdate
658658
}
659659

660+
class GuardValue = Guards::GuardValue;
661+
660662
class Guard = Guards::Guard;
661663

662-
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
663-
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
664-
guard.directlyControls(bb, branch)
664+
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `val`. */
665+
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
666+
guard.directlyValueControls(bb, val)
665667
}
666668

667-
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
668-
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
669-
guard.controls(bb, branch)
669+
/** Holds if the guard `guard` controls block `bb` upon evaluating to `val`. */
670+
predicate guardControlsBlock(Guard guard, BasicBlock bb, GuardValue val) {
671+
guard.valueControls(bb, val)
670672
}
671673

672674
predicate includeWriteDefsInFlowStep() { none() }

javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ private module ConditionGuardDominators {
193193
module MakeStateBarrierGuard<
194194
FlowStateSig FlowState, WithFlowState<FlowState>::BarrierGuardSig BaseGuard>
195195
{
196+
private import codeql.util.Boolean
197+
196198
final private class FinalNode = DataFlow::Node;
197199

198200
abstract private class BarrierGuard extends FinalNode {
@@ -295,7 +297,7 @@ module MakeStateBarrierGuard<
295297
}
296298

297299
private predicate ssa2GuardChecks(
298-
Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, boolean branch,
300+
Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, Boolean branch,
299301
FlowState state
300302
) {
301303
exists(BarrierGuard g |

javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as
66
private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate
77
private import semmle.javascript.dataflow.internal.BarrierGuards
88
private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2
9+
private import codeql.util.Boolean
910

1011
cached
1112
predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
@@ -37,7 +38,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2,
3738
}
3839

3940
private predicate guardChecksFalsy(
40-
Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, boolean outcome
41+
Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, Boolean outcome
4142
) {
4243
exists(ConditionGuardNode guard |
4344
guard.getTest() = g and

javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ module SsaConfig implements InputSig<js::DbLocation> {
5050
import Make<js::DbLocation, SsaConfig>
5151

5252
module SsaDataflowInput implements DataFlowIntegrationInputSig {
53+
private import codeql.util.Boolean
54+
5355
class Expr extends js::ControlFlowNode {
5456
Expr() { this = any(SsaConfig::SourceVariable v).getAUse() }
5557

@@ -71,14 +73,16 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
7173
)
7274
}
7375

76+
class GuardValue = Boolean;
77+
7478
class Guard extends js::ControlFlowNode {
7579
Guard() { this = any(js::ConditionGuardNode g).getTest() }
7680

7781
/**
7882
* Holds if the evaluation of this guard to `branch` corresponds to the edge
7983
* from `bb1` to `bb2`.
8084
*/
81-
predicate hasBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
85+
predicate hasValueBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) {
8286
exists(js::ConditionGuardNode g |
8387
g.getTest() = this and
8488
bb1 = this.getBasicBlock() and
@@ -92,13 +96,13 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
9296
* branch edge from `bb1` to `bb2`. That is, following the edge from
9397
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
9498
*/
95-
predicate controlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
96-
this.hasBranchEdge(bb1, bb2, branch)
99+
predicate valueControlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) {
100+
this.hasValueBranchEdge(bb1, bb2, branch)
97101
}
98102
}
99103

100104
pragma[inline]
101-
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
105+
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, GuardValue branch) {
102106
exists(js::ConditionGuardNode g |
103107
g.getTest() = guard and
104108
g.dominates(bb) and

ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ private module Cached {
400400
cached // nothing is actually cached
401401
module BarrierGuard<guardChecksSig/3 guardChecks> {
402402
private predicate guardChecksAdjTypes(
403-
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
403+
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
404+
DataFlowIntegrationInput::GuardValue branch
404405
) {
405406
guardChecks(g, e, branch)
406407
}
@@ -475,6 +476,7 @@ class ParameterExt extends TParameterExt {
475476

476477
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
477478
private import codeql.ruby.controlflow.internal.Guards as Guards
479+
private import codeql.util.Boolean
478480

479481
class Expr extends Cfg::CfgNodes::ExprCfgNode {
480482
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -486,12 +488,16 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
486488
any(ParameterExt p).isInitializedBy(def) or def.(Ssa::WriteDefinition).assigns(_)
487489
}
488490

491+
class GuardValue = Boolean;
492+
489493
class Guard extends Cfg::CfgNodes::AstCfgNode {
490494
/**
491495
* Holds if the evaluation of this guard to `branch` corresponds to the edge
492496
* from `bb1` to `bb2`.
493497
*/
494-
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
498+
predicate hasValueBranchEdge(
499+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
500+
) {
495501
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
496502
this.getBasicBlock() = bb1 and
497503
bb2 = bb1.getASuccessor(s) and
@@ -504,13 +510,15 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
504510
* branch edge from `bb1` to `bb2`. That is, following the edge from
505511
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
506512
*/
507-
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
508-
this.hasBranchEdge(bb1, bb2, branch)
513+
predicate valueControlsBranchEdge(
514+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
515+
) {
516+
this.hasValueBranchEdge(bb1, bb2, branch)
509517
}
510518
}
511519

512520
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
513-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
521+
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
514522
Guards::guardControlsBlock(guard, bb, branch)
515523
}
516524
}

rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ private module Cached {
301301
cached // nothing is actually cached
302302
module BarrierGuard<guardChecksSig/3 guardChecks> {
303303
private predicate guardChecksAdjTypes(
304-
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
304+
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
305+
DataFlowIntegrationInput::GuardValue branch
305306
) {
306307
guardChecks(g, e, branch)
307308
}
@@ -320,6 +321,7 @@ private import codeql.rust.dataflow.Ssa
320321

321322
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
322323
private import codeql.rust.dataflow.internal.DataFlowImpl as DataFlowImpl
324+
private import codeql.util.Boolean
323325

324326
class Expr extends CfgNodes::AstCfgNode {
325327
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -348,12 +350,16 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
348350
)
349351
}
350352

353+
class GuardValue = Boolean;
354+
351355
class Guard extends CfgNodes::AstCfgNode {
352356
/**
353357
* Holds if the evaluation of this guard to `branch` corresponds to the edge
354358
* from `bb1` to `bb2`.
355359
*/
356-
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
360+
predicate hasValueBranchEdge(
361+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
362+
) {
357363
exists(Cfg::ConditionalSuccessor s |
358364
this = bb1.getANode() and
359365
bb2 = bb1.getASuccessor(s) and
@@ -366,13 +372,15 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
366372
* branch edge from `bb1` to `bb2`. That is, following the edge from
367373
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
368374
*/
369-
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
370-
this.hasBranchEdge(bb1, bb2, branch)
375+
predicate valueControlsBranchEdge(
376+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
377+
) {
378+
this.hasValueBranchEdge(bb1, bb2, branch)
371379
}
372380
}
373381

374382
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
375-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
383+
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
376384
exists(ConditionBasicBlock conditionBlock, ConditionalSuccessor s |
377385
guard = conditionBlock.getLastNode() and
378386
s.getValue() = branch and

shared/dataflow/codeql/dataflow/VariableCapture.qll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,13 +733,15 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
733733
predicate hasCfgNode(BasicBlock bb, int i) { bb.getNode(i) = this }
734734
}
735735

736+
class GuardValue = Void;
737+
736738
class Guard extends Void {
737-
predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) { none() }
739+
predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue val) { none() }
738740

739-
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) { none() }
741+
predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue val) { none() }
740742
}
741743

742-
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) { none() }
744+
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { none() }
743745

744746
predicate includeWriteDefsInFlowStep() { none() }
745747

0 commit comments

Comments
 (0)