mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Python: Implement BarrierGuard
This commit is contained in:
@@ -148,6 +148,19 @@ class ParameterNode extends EssaNode {
|
||||
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that controls whether other nodes are evaluated.
|
||||
*/
|
||||
class GuardNode extends ControlFlowNode {
|
||||
ConditionBlock conditionBlock;
|
||||
|
||||
GuardNode() { this = conditionBlock.getLastNode() }
|
||||
|
||||
predicate controlsNode(ControlFlowNode node, boolean testIsTrue) {
|
||||
conditionBlock.controls(node.getBasicBlock(), testIsTrue)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that validates some expression.
|
||||
*
|
||||
@@ -157,16 +170,16 @@ class ParameterNode extends EssaNode {
|
||||
*
|
||||
* It is important that all extending classes in scope are disjoint.
|
||||
*/
|
||||
class BarrierGuard extends Expr {
|
||||
// /** Holds if this guard validates `e` upon evaluating to `v`. */
|
||||
// abstract predicate checks(Expr e, AbstractValue v);
|
||||
class BarrierGuard extends GuardNode {
|
||||
/** Holds if this guard validates `e` upon evaluating to `v`. */
|
||||
abstract predicate checks(ControlFlowNode node, boolean testIsTrue);
|
||||
|
||||
/** Gets a node guarded by this guard. */
|
||||
final ExprNode getAGuardedNode() {
|
||||
none()
|
||||
// exists(Expr e, AbstractValue v |
|
||||
// this.checks(e, v) and
|
||||
// this.controlsNode(result.getControlFlowNode(), e, v)
|
||||
// )
|
||||
exists(boolean testIsTrue |
|
||||
this.checks(result.asCfgNode(), testIsTrue) and
|
||||
this.controlsNode(result.asCfgNode(), testIsTrue)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
test_taint
|
||||
| test.py:22 | ok | test_custom_sanitizer | s |
|
||||
| test.py:36 | fail | test_custom_sanitizer_guard | s |
|
||||
| test.py:36 | ok | test_custom_sanitizer_guard | s |
|
||||
| test.py:38 | ok | test_custom_sanitizer_guard | s |
|
||||
| test.py:49 | ok | test_escape | s2 |
|
||||
isSanitizer
|
||||
| TestTaintTrackingConfiguration | test.py:21:39:21:39 | ControlFlowNode for s |
|
||||
| TestTaintTrackingConfiguration | test.py:48:10:48:29 | ControlFlowNode for emulated_escaping() |
|
||||
isSanitizerGuard
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() |
|
||||
sanitizerGuardControls
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:9:36:26 | ControlFlowNode for ensure_not_tainted | true |
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:9:36:29 | ControlFlowNode for ensure_not_tainted() | true |
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:28:36:28 | ControlFlowNode for s | true |
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:9:38:22 | ControlFlowNode for ensure_tainted | false |
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:9:38:25 | ControlFlowNode for ensure_tainted() | false |
|
||||
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:24:38:24 | ControlFlowNode for s | false |
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
import experimental.dataflow.tainttracking.TestTaintLib
|
||||
|
||||
class IsSafeCheck extends DataFlow::BarrierGuard {
|
||||
Variable v;
|
||||
|
||||
IsSafeCheck() {
|
||||
this.(CallNode).getNode().getFunc().(Name).getId() = "emulated_is_safe" and
|
||||
this.(CallNode).getAnArg().(NameNode).uses(v)
|
||||
}
|
||||
|
||||
override predicate checks(ControlFlowNode node, boolean testIsTrue) {
|
||||
node.(NameNode).uses(v) and
|
||||
testIsTrue = true
|
||||
}
|
||||
}
|
||||
|
||||
class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
exists(Call call |
|
||||
@@ -10,13 +24,7 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
|
||||
node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping"
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
// TODO: Future work for when BarrierGuard is implemented properly
|
||||
// exists(Call call |
|
||||
// call.getFunc().(Name).getId() = "emulated_is_safe" and
|
||||
// )
|
||||
none()
|
||||
}
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof IsSafeCheck }
|
||||
}
|
||||
|
||||
query predicate isSanitizer(TestTaintTrackingConfiguration conf, DataFlow::Node node) {
|
||||
@@ -28,3 +36,12 @@ query predicate isSanitizerGuard(TestTaintTrackingConfiguration conf, DataFlow::
|
||||
exists(guard.getLocation().getFile().getRelativePath()) and
|
||||
conf.isSanitizerGuard(guard)
|
||||
}
|
||||
|
||||
query predicate sanitizerGuardControls(
|
||||
TestTaintTrackingConfiguration conf, DataFlow::BarrierGuard guard, ControlFlowNode node,
|
||||
boolean testIsTrue
|
||||
) {
|
||||
exists(guard.getLocation().getFile().getRelativePath()) and
|
||||
conf.isSanitizerGuard(guard) and
|
||||
guard.controlsNode(node, testIsTrue)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user