Python: Implement BarrierGuard

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-09-11 11:55:51 +02:00
parent 31495b876e
commit 5dbb4af5b5
3 changed files with 54 additions and 16 deletions

View File

@@ -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)
)
}
}

View File

@@ -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 |

View File

@@ -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)
}