Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5dbb4af

Browse files
committed
Python: Implement BarrierGuard
1 parent 31495b8 commit 5dbb4af

3 files changed

Lines changed: 54 additions & 16 deletions

File tree

python/ql/src/experimental/dataflow/internal/DataFlowPublic.qll

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,19 @@ class ParameterNode extends EssaNode {
148148
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
149149
}
150150

151+
/**
152+
* A node that controls whether other nodes are evaluated.
153+
*/
154+
class GuardNode extends ControlFlowNode {
155+
ConditionBlock conditionBlock;
156+
157+
GuardNode() { this = conditionBlock.getLastNode() }
158+
159+
predicate controlsNode(ControlFlowNode node, boolean testIsTrue) {
160+
conditionBlock.controls(node.getBasicBlock(), testIsTrue)
161+
}
162+
}
163+
151164
/**
152165
* A guard that validates some expression.
153166
*
@@ -157,16 +170,16 @@ class ParameterNode extends EssaNode {
157170
*
158171
* It is important that all extending classes in scope are disjoint.
159172
*/
160-
class BarrierGuard extends Expr {
161-
// /** Holds if this guard validates `e` upon evaluating to `v`. */
162-
// abstract predicate checks(Expr e, AbstractValue v);
173+
class BarrierGuard extends GuardNode {
174+
/** Holds if this guard validates `e` upon evaluating to `v`. */
175+
abstract predicate checks(ControlFlowNode node, boolean testIsTrue);
176+
163177
/** Gets a node guarded by this guard. */
164178
final ExprNode getAGuardedNode() {
165-
none()
166-
// exists(Expr e, AbstractValue v |
167-
// this.checks(e, v) and
168-
// this.controlsNode(result.getControlFlowNode(), e, v)
169-
// )
179+
exists(boolean testIsTrue |
180+
this.checks(result.asCfgNode(), testIsTrue) and
181+
this.controlsNode(result.asCfgNode(), testIsTrue)
182+
)
170183
}
171184
}
172185

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
test_taint
22
| test.py:22 | ok | test_custom_sanitizer | s |
3-
| test.py:36 | fail | test_custom_sanitizer_guard | s |
3+
| test.py:36 | ok | test_custom_sanitizer_guard | s |
44
| test.py:38 | ok | test_custom_sanitizer_guard | s |
55
| test.py:49 | ok | test_escape | s2 |
66
isSanitizer
77
| TestTaintTrackingConfiguration | test.py:21:39:21:39 | ControlFlowNode for s |
88
| TestTaintTrackingConfiguration | test.py:48:10:48:29 | ControlFlowNode for emulated_escaping() |
99
isSanitizerGuard
10+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() |
11+
sanitizerGuardControls
12+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:9:36:26 | ControlFlowNode for ensure_not_tainted | true |
13+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:9:36:29 | ControlFlowNode for ensure_not_tainted() | true |
14+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:36:28:36:28 | ControlFlowNode for s | true |
15+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:9:38:22 | ControlFlowNode for ensure_tainted | false |
16+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:9:38:25 | ControlFlowNode for ensure_tainted() | false |
17+
| TestTaintTrackingConfiguration | test.py:35:8:35:26 | ControlFlowNode for emulated_is_safe() | test.py:38:24:38:24 | ControlFlowNode for s | false |
Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
import experimental.dataflow.tainttracking.TestTaintLib
22

3+
class IsSafeCheck extends DataFlow::BarrierGuard {
4+
Variable v;
5+
6+
IsSafeCheck() {
7+
this.(CallNode).getNode().getFunc().(Name).getId() = "emulated_is_safe" and
8+
this.(CallNode).getAnArg().(NameNode).uses(v)
9+
}
10+
11+
override predicate checks(ControlFlowNode node, boolean testIsTrue) {
12+
node.(NameNode).uses(v) and
13+
testIsTrue = true
14+
}
15+
}
16+
317
class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
418
override predicate isSanitizer(DataFlow::Node node) {
519
exists(Call call |
@@ -10,13 +24,7 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
1024
node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping"
1125
}
1226

13-
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
14-
// TODO: Future work for when BarrierGuard is implemented properly
15-
// exists(Call call |
16-
// call.getFunc().(Name).getId() = "emulated_is_safe" and
17-
// )
18-
none()
19-
}
27+
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof IsSafeCheck }
2028
}
2129

2230
query predicate isSanitizer(TestTaintTrackingConfiguration conf, DataFlow::Node node) {
@@ -28,3 +36,12 @@ query predicate isSanitizerGuard(TestTaintTrackingConfiguration conf, DataFlow::
2836
exists(guard.getLocation().getFile().getRelativePath()) and
2937
conf.isSanitizerGuard(guard)
3038
}
39+
40+
query predicate sanitizerGuardControls(
41+
TestTaintTrackingConfiguration conf, DataFlow::BarrierGuard guard, ControlFlowNode node,
42+
boolean testIsTrue
43+
) {
44+
exists(guard.getLocation().getFile().getRelativePath()) and
45+
conf.isSanitizerGuard(guard) and
46+
guard.controlsNode(node, testIsTrue)
47+
}

0 commit comments

Comments
 (0)