mirror of
https://github.com/github/codeql.git
synced 2025-12-22 19:56:32 +01:00
C/C++: Deprecate BarrierGuard class.
This commit is contained in:
@@ -850,6 +850,34 @@ class ContentSet instanceof Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||||
|
*
|
||||||
|
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||||
|
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||||
|
* the argument `x`.
|
||||||
|
*/
|
||||||
|
signature predicate guardChecksSig(GuardCondition g, Expr e, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(GuardCondition g, SsaDefinition def, Variable v, boolean branch |
|
||||||
|
result.getExpr() = def.getAUse(v) and
|
||||||
|
guardChecks(g, def.getAUse(v), branch) and
|
||||||
|
g.controls(result.getExpr().getBasicBlock(), branch)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* A guard that validates some expression.
|
* A guard that validates some expression.
|
||||||
*
|
*
|
||||||
* To use this in a configuration, extend the class and provide a
|
* To use this in a configuration, extend the class and provide a
|
||||||
@@ -858,7 +886,7 @@ class ContentSet instanceof Content {
|
|||||||
*
|
*
|
||||||
* It is important that all extending classes in scope are disjoint.
|
* It is important that all extending classes in scope are disjoint.
|
||||||
*/
|
*/
|
||||||
class BarrierGuard extends GuardCondition {
|
deprecated class BarrierGuard extends GuardCondition {
|
||||||
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
|
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
|
||||||
abstract predicate checks(Expr e, boolean b);
|
abstract predicate checks(Expr e, boolean b);
|
||||||
|
|
||||||
|
|||||||
@@ -47,12 +47,6 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
|
|
||||||
* but not in local taint.
|
|
||||||
*/
|
|
||||||
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
||||||
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
||||||
|
|||||||
@@ -1092,6 +1092,56 @@ class ContentSet instanceof Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||||
|
*
|
||||||
|
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||||
|
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||||
|
* the argument `x`.
|
||||||
|
*/
|
||||||
|
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||||
|
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
|
||||||
|
result.asInstruction() = value.getAnInstruction() and
|
||||||
|
g.controls(result.asInstruction().getBlock(), edge)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||||
|
*/
|
||||||
|
signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction instr, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an instruction.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||||
|
instructionGuardChecks(g, value.getAnInstruction(), edge) and
|
||||||
|
result.asInstruction() = value.getAnInstruction() and
|
||||||
|
g.controls(result.asInstruction().getBlock(), edge)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* A guard that validates some instruction.
|
* A guard that validates some instruction.
|
||||||
*
|
*
|
||||||
* To use this in a configuration, extend the class and provide a
|
* To use this in a configuration, extend the class and provide a
|
||||||
@@ -1100,7 +1150,7 @@ class ContentSet instanceof Content {
|
|||||||
*
|
*
|
||||||
* It is important that all extending classes in scope are disjoint.
|
* It is important that all extending classes in scope are disjoint.
|
||||||
*/
|
*/
|
||||||
class BarrierGuard extends IRGuardCondition {
|
deprecated class BarrierGuard extends IRGuardCondition {
|
||||||
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
|
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
|
||||||
predicate checksInstr(Instruction instr, boolean b) { none() }
|
predicate checksInstr(Instruction instr, boolean b) { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -94,12 +94,6 @@ private string getNodeProperty(DataFlow::Node node, string key) {
|
|||||||
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
|
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
|
||||||
or
|
or
|
||||||
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
||||||
or
|
|
||||||
exists(DataFlow::BarrierGuard guard |
|
|
||||||
any(DataFlow::Configuration cfg).isBarrierGuard(guard) and
|
|
||||||
node = guard.getAGuardedNode() and
|
|
||||||
kind = "guard(" + guard.getResultId() + ")"
|
|
||||||
)
|
|
||||||
|
|
|
|
||||||
kind, ", "
|
kind, ", "
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -163,12 +163,6 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
|
|
||||||
* but not in local taint.
|
|
||||||
*/
|
|
||||||
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
|
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
|
||||||
* modeled function.
|
* modeled function.
|
||||||
|
|||||||
@@ -2,19 +2,17 @@ import TestUtilities.dataflow.FlowTestCommon
|
|||||||
|
|
||||||
module AstTest {
|
module AstTest {
|
||||||
private import semmle.code.cpp.dataflow.DataFlow
|
private import semmle.code.cpp.dataflow.DataFlow
|
||||||
|
private import semmle.code.cpp.controlflow.Guards
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||||
* S in `if (guarded(x)) S`.
|
* S in `if (guarded(x)) S`.
|
||||||
*/
|
*/
|
||||||
// This is tested in `BarrierGuard.cpp`.
|
// This is tested in `BarrierGuard.cpp`.
|
||||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
|
||||||
TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
|
g.(FunctionCall).getTarget().getName() = "guarded" and
|
||||||
|
checked = g.(FunctionCall).getArgument(0) and
|
||||||
override predicate checks(Expr checked, boolean isTrue) {
|
isTrue = true
|
||||||
checked = this.(FunctionCall).getArgument(0) and
|
|
||||||
isTrue = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common data flow configuration to be used by tests. */
|
/** Common data flow configuration to be used by tests. */
|
||||||
@@ -40,29 +38,26 @@ module AstTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrier(DataFlow::Node barrier) {
|
override predicate isBarrier(DataFlow::Node barrier) {
|
||||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||||
|
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module IRTest {
|
module IRTest {
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
private import semmle.code.cpp.ir.IR
|
private import semmle.code.cpp.ir.IR
|
||||||
|
private import semmle.code.cpp.controlflow.IRGuards
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||||
* S in `if (guarded(x)) S`.
|
* S in `if (guarded(x)) S`.
|
||||||
*/
|
*/
|
||||||
// This is tested in `BarrierGuard.cpp`.
|
// This is tested in `BarrierGuard.cpp`.
|
||||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
predicate testBarrierGuard(IRGuardCondition g, Instruction checked, boolean isTrue) {
|
||||||
TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
|
g.(CallInstruction).getStaticCallTarget().getName() = "guarded" and
|
||||||
|
checked = g.(CallInstruction).getPositionalArgument(0) and
|
||||||
override predicate checksInstr(Instruction checked, boolean isTrue) {
|
isTrue = true
|
||||||
checked = this.(CallInstruction).getPositionalArgument(0) and
|
|
||||||
isTrue = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common data flow configuration to be used by tests. */
|
/** Common data flow configuration to be used by tests. */
|
||||||
@@ -93,10 +88,9 @@ module IRTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrier(DataFlow::Node barrier) {
|
override predicate isBarrier(DataFlow::Node barrier) {
|
||||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||||
|
barrier = DataFlow::InstructionBarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate readsVariable(LoadInstruction load, Variable var) {
|
private predicate readsVariable(LoadInstruction load, Variable var) {
|
||||||
|
|||||||
Reference in New Issue
Block a user