|
4 | 4 | */
|
5 | 5 |
|
6 | 6 | private import codeql.util.Location
|
| 7 | +private import codeql.util.Unit |
7 | 8 |
|
8 | 9 | /** Provides the input specification of the SSA implementation. */
|
9 | 10 | signature module InputSig<LocationSig Location> {
|
@@ -1631,23 +1632,62 @@ module Make<LocationSig Location, InputSig<Location> Input> {
|
1631 | 1632 | )
|
1632 | 1633 | }
|
1633 | 1634 |
|
| 1635 | + bindingset[this] |
| 1636 | + signature class StateSig; |
| 1637 | + |
| 1638 | + private module WithState<StateSig State> { |
| 1639 | + /** |
| 1640 | + * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`, blocking |
| 1641 | + * flow in the given `state`. |
| 1642 | + * |
| 1643 | + * The expression `e` is expected to be a syntactic part of the guard `g`. |
| 1644 | + * For example, the guard `g` might be a call `isSafe(x)` and the expression `e` |
| 1645 | + * the argument `x`. |
| 1646 | + */ |
| 1647 | + signature predicate guardChecksSig( |
| 1648 | + DfInput::Guard g, DfInput::Expr e, boolean branch, State state |
| 1649 | + ); |
| 1650 | + } |
| 1651 | + |
1634 | 1652 | /**
|
1635 | 1653 | * Provides a set of barrier nodes for a guard that validates an expression.
|
1636 | 1654 | *
|
1637 | 1655 | * This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
1638 | 1656 | * in data flow and taint tracking.
|
1639 | 1657 | */
|
1640 | 1658 | module BarrierGuard<guardChecksSig/3 guardChecks> {
|
| 1659 | + private predicate guardChecksWithState( |
| 1660 | + DfInput::Guard g, DfInput::Expr e, boolean branch, Unit state |
| 1661 | + ) { |
| 1662 | + guardChecks(g, e, branch) and exists(state) |
| 1663 | + } |
| 1664 | + |
| 1665 | + private module StatefulBarrier = BarrierGuardWithState<Unit, guardChecksWithState/4>; |
| 1666 | + |
| 1667 | + /** Gets a node that is safely guarded by the given guard check. */ |
| 1668 | + pragma[nomagic] |
| 1669 | + Node getABarrierNode() { result = StatefulBarrier::getABarrierNode(_) } |
| 1670 | + } |
| 1671 | + |
| 1672 | + /** |
| 1673 | + * Provides a set of barrier nodes for a guard that validates an expression. |
| 1674 | + * |
| 1675 | + * This is expected to be used in `isBarrier`/`isSanitizer` definitions |
| 1676 | + * in data flow and taint tracking. |
| 1677 | + */ |
| 1678 | + module BarrierGuardWithState<StateSig State, WithState<State>::guardChecksSig/4 guardChecks> { |
1641 | 1679 | pragma[nomagic]
|
1642 |
| - private predicate guardChecksSsaDef(DfInput::Guard g, Definition def, boolean branch) { |
1643 |
| - guardChecks(g, DfInput::getARead(def), branch) |
| 1680 | + private predicate guardChecksSsaDef( |
| 1681 | + DfInput::Guard g, Definition def, boolean branch, State state |
| 1682 | + ) { |
| 1683 | + guardChecks(g, DfInput::getARead(def), branch, state) |
1644 | 1684 | }
|
1645 | 1685 |
|
1646 | 1686 | /** Gets a node that is safely guarded by the given guard check. */
|
1647 | 1687 | pragma[nomagic]
|
1648 |
| - Node getABarrierNode() { |
| 1688 | + Node getABarrierNode(State state) { |
1649 | 1689 | exists(DfInput::Guard g, boolean branch, Definition def, BasicBlock bb |
|
1650 |
| - guardChecksSsaDef(g, def, branch) |
| 1690 | + guardChecksSsaDef(g, def, branch, state) |
1651 | 1691 | |
|
1652 | 1692 | // guard controls a read
|
1653 | 1693 | exists(DfInput::Expr e |
|
|
0 commit comments