@@ -1198,6 +1198,21 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1198
1198
* previous definitions or reads.
1199
1199
*/
1200
1200
default predicate allowFlowIntoUncertainDef ( UncertainWriteDefinition def ) { none ( ) }
1201
+
1202
+ /** A (potential) guard. */
1203
+ class Guard {
1204
+ /** Gets a textual representation of this guard. */
1205
+ string toString ( ) ;
1206
+
1207
+ /** Holds if the `i`th node of basic block `bb` evaluates this guard. */
1208
+ predicate hasCfgNode ( BasicBlock bb , int i ) ;
1209
+ }
1210
+
1211
+ /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
1212
+ predicate guardControlsBlock ( Guard guard , BasicBlock bb , boolean branch ) ;
1213
+
1214
+ /** Gets an immediate conditional successor of basic block `bb`, if any. */
1215
+ BasicBlock getAConditionalBasicBlockSuccessor ( BasicBlock bb , boolean branch ) ;
1201
1216
}
1202
1217
1203
1218
/**
@@ -1294,6 +1309,11 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1294
1309
}
1295
1310
}
1296
1311
1312
+ cached
1313
+ private predicate ssaInputNode ( SsaInputDefinitionExt def , BasicBlock input ) {
1314
+ def .hasInputFromBlock ( _, _, _, _, input )
1315
+ }
1316
+
1297
1317
private newtype TNode =
1298
1318
TParamNode ( DfInput:: Parameter p ) or
1299
1319
TExprNode ( DfInput:: Expr e , Boolean isPost ) {
@@ -1305,9 +1325,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1305
1325
isPost = false
1306
1326
} or
1307
1327
TSsaDefinitionNode ( DefinitionExt def ) or
1308
- TSsaInputNode ( SsaInputDefinitionExt def , BasicBlock input ) {
1309
- def .hasInputFromBlock ( _, _, _, _, input )
1310
- }
1328
+ TSsaInputNode ( SsaInputDefinitionExt def , BasicBlock input ) { ssaInputNode ( def , input ) }
1311
1329
1312
1330
/**
1313
1331
* A data flow node that we need to reference in the value step relation.
@@ -1577,94 +1595,46 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1577
1595
nodeTo .( ExprNode ) .getExpr ( ) = getARead ( def )
1578
1596
}
1579
1597
1580
- /** Provides the input to `BarrierGuards`. */
1581
- signature module BarrierGuardsInputSig {
1582
- /** A (potential) guard. */
1583
- class Guard {
1584
- /** Gets a textual representation of this guard. */
1585
- string toString ( ) ;
1598
+ pragma [ nomagic]
1599
+ private predicate guardControlsSsaRead (
1600
+ DfInput:: Guard g , boolean branch , Definition def , ExprNode n
1601
+ ) {
1602
+ exists ( BasicBlock bb , DfInput:: Expr e |
1603
+ e = n .getExpr ( ) and
1604
+ getARead ( def ) = e and
1605
+ DfInput:: guardControlsBlock ( g , bb , branch ) and
1606
+ e .hasCfgNode ( bb , _)
1607
+ )
1608
+ }
1586
1609
1587
- /** Holds if the `i`th node of basic block `bb` evaluates this guard. */
1588
- predicate hasCfgNode ( BasicBlock bb , int i ) ;
1589
- }
1610
+ pragma [ nomagic]
1611
+ private predicate guardControlsPhiInput (
1612
+ DfInput:: Guard g , boolean branch , Definition def , BasicBlock input , SsaInputDefinitionExt phi
1613
+ ) {
1614
+ phi .hasInputFromBlock ( def , _, _, _, input ) and
1615
+ (
1616
+ DfInput:: guardControlsBlock ( g , input , branch )
1617
+ or
1618
+ exists ( int last |
1619
+ last = input .length ( ) - 1 and
1620
+ g .hasCfgNode ( input , last ) and
1621
+ DfInput:: getAConditionalBasicBlockSuccessor ( input , branch ) = phi .getBasicBlock ( )
1622
+ )
1623
+ )
1624
+ }
1590
1625
1591
- /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
1592
- predicate guardControlsBlock ( Guard guard , BasicBlock bb , boolean branch ) ;
1593
-
1594
- /** Gets an immediate conditional successor of basic block `bb`, if any. */
1595
- BasicBlock getAConditionalBasicBlockSuccessor ( BasicBlock bb , boolean branch ) ;
1596
- }
1597
-
1598
- /** Provides an implementatino of the `BarrierGuard` module. */
1599
- module BarrierGuards< BarrierGuardsInputSig BgInput> {
1600
- /**
1601
- * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
1602
- *
1603
- * The expression `e` is expected to be a syntactic part of the guard `g`.
1604
- * For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
1605
- * the argument `x`.
1606
- */
1607
- signature predicate guardChecksSig ( BgInput:: Guard g , DfInput:: Expr e , boolean branch ) ;
1608
-
1609
- /**
1610
- * Provides a set of barrier nodes for a guard that validates an expression.
1611
- *
1612
- * This is expected to be used in `isBarrier`/`isSanitizer` definitions
1613
- * in data flow and taint tracking.
1614
- */
1615
- module BarrierGuard< guardChecksSig / 3 guardChecks> {
1616
- pragma [ nomagic]
1617
- private predicate guardChecksSsaDef ( BgInput:: Guard g , boolean branch , Definition def ) {
1618
- guardChecks ( g , getARead ( def ) , branch )
1619
- }
1620
-
1621
- pragma [ nomagic]
1622
- private predicate guardControlsSsaRead (
1623
- BgInput:: Guard g , boolean branch , Definition def , ExprNode n
1624
- ) {
1625
- exists ( BasicBlock bb , DfInput:: Expr e |
1626
- e = n .getExpr ( ) and
1627
- getARead ( def ) = e and
1628
- BgInput:: guardControlsBlock ( g , bb , branch ) and
1629
- e .hasCfgNode ( bb , _)
1630
- )
1631
- }
1632
-
1633
- pragma [ nomagic]
1634
- private predicate guardControlsPhiInput (
1635
- BgInput:: Guard g , boolean branch , Definition def , BasicBlock input ,
1636
- SsaInputDefinitionExt phi
1637
- ) {
1638
- phi .hasInputFromBlock ( def , _, _, _, input ) and
1639
- (
1640
- BgInput:: guardControlsBlock ( g , input , branch )
1641
- or
1642
- exists ( int last |
1643
- last = input .length ( ) - 1 and
1644
- g .hasCfgNode ( input , last ) and
1645
- BgInput:: getAConditionalBasicBlockSuccessor ( input , branch ) = phi .getBasicBlock ( )
1646
- )
1647
- )
1648
- }
1649
-
1650
- /** Gets a node that is safely guarded by the given guard check. */
1651
- pragma [ nomagic]
1652
- Node getABarrierNode ( ) {
1653
- exists ( BgInput:: Guard g , boolean branch , Definition def |
1654
- guardChecksSsaDef ( g , branch , def ) and
1655
- guardControlsSsaRead ( g , branch , def , result )
1656
- )
1657
- or
1658
- exists (
1659
- BgInput:: Guard g , boolean branch , Definition def , BasicBlock input ,
1660
- SsaInputDefinitionExt phi
1661
- |
1662
- guardChecksSsaDef ( g , branch , def ) and
1663
- guardControlsPhiInput ( g , branch , def , input , phi ) and
1664
- result .( SsaInputNode ) .isInputInto ( phi , input )
1665
- )
1666
- }
1667
- }
1626
+ /**
1627
+ * Gets a node that reads SSA defininition `def`, and which is guarded by
1628
+ * `g` evaluating to `branch`.
1629
+ */
1630
+ pragma [ nomagic]
1631
+ Node getABarrierNode ( DfInput:: Guard g , Definition def , boolean branch ) {
1632
+ guardControlsSsaRead ( g , branch , def , result )
1633
+ or
1634
+ exists ( BasicBlock input , SsaInputDefinitionExt phi |
1635
+ guardControlsPhiInput ( g , branch , def , input , phi ) and
1636
+ result .( SsaInputNode ) .isInputInto ( phi , input )
1637
+ )
1668
1638
}
1669
1639
}
1670
1640
}
0 commit comments