C++: Add a parameter-based version of 'getAnIndirectBarrierNode'.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-05-03 17:06:59 +01:00
parent 490b253dc8
commit 2d98fb7cf1

View File

@@ -1975,12 +1975,48 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If an non-indirect expression is tracked, use `getABarrierNode` instead.
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode() {
IndirectExprNode getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
/**
* Gets an indirect expression node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
*
* For example, given the following code:
* ```cpp
* int* p;
* // ...
* *p = source();
* if(is_safe_pointer(p)) {
* sink(*p);
* }
* ```
* and the following barrier guard check:
* ```ql
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
* exists(Call call |
* g.getUnconvertedResultExpression() = call and
* call.getTarget().hasName("is_safe_pointer") and
* e = call.getAnArgument() and
* branch = true
* )
* }
* ```
* implementing `isBarrier` as:
* ```ql
* predicate isBarrier(DataFlow::Node barrier) {
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
* }
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode(int indirectionIndex) {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
result.getConvertedExpr(_) = e and
result.getConvertedExpr(indirectionIndex) = e and
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
g.controls(result.getBasicBlock(), edge)
)