Skip to content

Commit 9794269

Browse files
authored
Merge pull request #16952 from hvitved/ssa/barrier-guards-param-mod
SSA: Make barrier guards a parameterized module
2 parents f41d2a8 + 16b142d commit 9794269

File tree

1 file changed

+71
-49
lines changed

1 file changed

+71
-49
lines changed

shared/ssa/codeql/ssa/Ssa.qll

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,19 +1322,31 @@ module Make<LocationSig Location, InputSig<Location> Input> {
13221322
}
13231323
}
13241324

1325-
cached
1326-
private newtype TNode =
1327-
TParamNode(DfInput::Parameter p) { DfInput::ssaDefInitializesParam(_, p) } or
1328-
TExprNode(DfInput::Expr e, Boolean isPost) {
1329-
e = DfInput::getARead(_)
1330-
or
1331-
DfInput::ssaDefAssigns(_, e) and
1332-
isPost = false
1333-
} or
1334-
TSsaDefinitionNode(DefinitionExt def) or
1335-
TSsaInputNode(SsaInputDefinitionExt def, BasicBlock input) {
1336-
def.hasInputFromBlock(_, _, _, _, input)
1325+
private module Cached {
1326+
cached
1327+
newtype TNode =
1328+
TParamNode(DfInput::Parameter p) { DfInput::ssaDefInitializesParam(_, p) } or
1329+
TExprNode(DfInput::Expr e, Boolean isPost) {
1330+
e = DfInput::getARead(_)
1331+
or
1332+
DfInput::ssaDefAssigns(_, e) and
1333+
isPost = false
1334+
} or
1335+
TSsaDefinitionNode(DefinitionExt def) or
1336+
TSsaInputNode(SsaInputDefinitionExt def, BasicBlock input) {
1337+
def.hasInputFromBlock(_, _, _, _, input)
1338+
}
1339+
1340+
cached
1341+
Definition getAPhiInputDef(SsaInputNode n) {
1342+
exists(SsaInputDefinitionExt phi, BasicBlock bb |
1343+
phi.hasInputFromBlock(result, _, _, _, bb) and
1344+
n.isInputInto(phi, bb)
1345+
)
13371346
}
1347+
}
1348+
1349+
private import Cached
13381350

13391351
/**
13401352
* A data flow node that we need to reference in the value step relation.
@@ -1606,46 +1618,56 @@ module Make<LocationSig Location, InputSig<Location> Input> {
16061618
nodeTo.(ExprNode).getExpr() = DfInput::getARead(def)
16071619
}
16081620

1609-
pragma[nomagic]
1610-
private predicate guardControlsSsaRead(
1611-
DfInput::Guard g, boolean branch, Definition def, ExprNode n
1612-
) {
1613-
exists(BasicBlock bb, DfInput::Expr e |
1614-
e = n.getExpr() and
1615-
DfInput::getARead(def) = e and
1616-
DfInput::guardControlsBlock(g, bb, branch) and
1617-
e.hasCfgNode(bb, _)
1618-
)
1619-
}
1620-
1621-
pragma[nomagic]
1622-
private predicate guardControlsPhiInput(
1623-
DfInput::Guard g, boolean branch, Definition def, BasicBlock input, SsaInputDefinitionExt phi
1624-
) {
1625-
phi.hasInputFromBlock(def, _, _, _, input) and
1626-
(
1627-
DfInput::guardControlsBlock(g, input, branch)
1628-
or
1629-
exists(int last |
1630-
last = input.length() - 1 and
1631-
g.hasCfgNode(input, last) and
1632-
DfInput::getAConditionalBasicBlockSuccessor(input, branch) = phi.getBasicBlock()
1633-
)
1634-
)
1635-
}
1621+
/**
1622+
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
1623+
*
1624+
* The expression `e` is expected to be a syntactic part of the guard `g`.
1625+
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
1626+
* the argument `x`.
1627+
*/
1628+
signature predicate guardChecksSig(DfInput::Guard g, DfInput::Expr e, boolean branch);
16361629

16371630
/**
1638-
* Gets a node that reads SSA defininition `def`, and which is guarded by
1639-
* `g` evaluating to `branch`.
1631+
* Provides a set of barrier nodes for a guard that validates an expression.
1632+
*
1633+
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
1634+
* in data flow and taint tracking.
16401635
*/
1641-
pragma[nomagic]
1642-
Node getABarrierNode(DfInput::Guard g, Definition def, boolean branch) {
1643-
guardControlsSsaRead(g, branch, def, result)
1644-
or
1645-
exists(BasicBlock input, SsaInputDefinitionExt phi |
1646-
guardControlsPhiInput(g, branch, def, input, phi) and
1647-
result.(SsaInputNode).isInputInto(phi, input)
1648-
)
1636+
module BarrierGuard<guardChecksSig/3 guardChecks> {
1637+
pragma[nomagic]
1638+
private predicate guardChecksSsaDef(DfInput::Guard g, Definition def, boolean branch) {
1639+
guardChecks(g, DfInput::getARead(def), branch)
1640+
}
1641+
1642+
/** Gets a node that is safely guarded by the given guard check. */
1643+
pragma[nomagic]
1644+
Node getABarrierNode() {
1645+
exists(DfInput::Guard g, boolean branch, Definition def, BasicBlock bb |
1646+
guardChecksSsaDef(g, def, branch)
1647+
|
1648+
// guard controls a read
1649+
exists(DfInput::Expr e |
1650+
e = DfInput::getARead(def) and
1651+
e.hasCfgNode(bb, _) and
1652+
DfInput::guardControlsBlock(g, bb, branch) and
1653+
result.(ExprNode).getExpr() = e
1654+
)
1655+
or
1656+
// guard controls input block to a phi node
1657+
exists(SsaInputDefinitionExt phi |
1658+
def = getAPhiInputDef(result) and
1659+
result.(SsaInputNode).isInputInto(phi, bb)
1660+
|
1661+
DfInput::guardControlsBlock(g, bb, branch)
1662+
or
1663+
exists(int last |
1664+
last = bb.length() - 1 and
1665+
g.hasCfgNode(bb, last) and
1666+
DfInput::getAConditionalBasicBlockSuccessor(bb, branch) = phi.getBasicBlock()
1667+
)
1668+
)
1669+
)
1670+
}
16491671
}
16501672
}
16511673
}

0 commit comments

Comments
 (0)