Skip to content

Commit 3004639

Browse files
committed
Rust: Add default taint flow steps
1 parent 70a296b commit 3004639

File tree

6 files changed

+62
-6
lines changed

6 files changed

+62
-6
lines changed

rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,45 @@
11
private import rust
22
private import codeql.dataflow.TaintTracking
3+
private import codeql.rust.controlflow.CfgNodes
4+
private import DataFlowImpl
5+
private import codeql.rust.dataflow.FlowSummary
6+
private import FlowSummaryImpl as FlowSummaryImpl
37
private import DataFlowImpl
48

59
module RustTaintTracking implements InputSig<Location, RustDataFlow> {
610
predicate defaultTaintSanitizer(Node::Node node) { none() }
711

812
/**
9-
* Holds if the additional step from `src` to `sink` should be included in all
13+
* Holds if the additional step from `pred` to `succ` should be included in all
1014
* global taint flow configurations.
1115
*/
12-
predicate defaultAdditionalTaintStep(Node::Node src, Node::Node sink, string model) { none() }
16+
predicate defaultAdditionalTaintStep(Node::Node pred, Node::Node succ, string model) {
17+
model = "" and
18+
(
19+
exists(BinaryExprCfgNode binary |
20+
binary.getOperatorName() = ["+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>"] and
21+
pred.asExpr() = [binary.getLhs(), binary.getRhs()] and
22+
succ.asExpr() = binary
23+
)
24+
or
25+
exists(PrefixExprCfgNode prefix |
26+
prefix.getOperatorName() = ["-", "!"] and
27+
pred.asExpr() = prefix.getExpr() and
28+
succ.asExpr() = prefix
29+
)
30+
or
31+
pred.asExpr() = succ.asExpr().(CastExprCfgNode).getExpr()
32+
or
33+
exists(IndexExprCfgNode index |
34+
index.getIndex() instanceof RangeExprCfgNode and
35+
pred.asExpr() = index.getBase() and
36+
succ.asExpr() = index
37+
)
38+
)
39+
or
40+
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(Node::FlowSummaryNode).getSummaryNode(),
41+
succ.(Node::FlowSummaryNode).getSummaryNode(), false, model)
42+
}
1343

1444
/**
1545
* Holds if taint flow configurations should allow implicit reads of `c` at sinks

rust/ql/test/library-tests/dataflow/models/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn coerce(_i: i64) -> i64 {
2323

2424
fn test_coerce() {
2525
let s = source(14);
26-
sink(coerce(s)); // $ MISSING: hasTaintFlow=14
26+
sink(coerce(s)); // $ hasTaintFlow=14
2727
}
2828

2929
enum MyPosEnum {

rust/ql/test/library-tests/dataflow/models/models.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ edges
44
| main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | |
55
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
66
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
7+
| main.rs:25:13:25:22 | source(...) | main.rs:26:17:26:17 | s | provenance | |
8+
| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | |
79
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
810
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
911
| main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | |
@@ -47,6 +49,9 @@ nodes
4749
| main.rs:16:10:16:20 | identity(...) | semmle.label | identity(...) |
4850
| main.rs:16:19:16:19 | s | semmle.label | s |
4951
| main.rs:16:19:16:19 | s | semmle.label | s |
52+
| main.rs:25:13:25:22 | source(...) | semmle.label | source(...) |
53+
| main.rs:26:10:26:18 | coerce(...) | semmle.label | coerce(...) |
54+
| main.rs:26:17:26:17 | s | semmle.label | s |
5055
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
5156
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
5257
| main.rs:41:14:41:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
@@ -97,6 +102,7 @@ invalidSpecComponent
97102
#select
98103
| main.rs:16:10:16:20 | identity(...) | main.rs:15:13:15:21 | source(...) | main.rs:16:10:16:20 | identity(...) | $@ | main.rs:15:13:15:21 | source(...) | source(...) |
99104
| main.rs:16:10:16:20 | identity(...) | main.rs:15:13:15:21 | source(...) | main.rs:16:10:16:20 | identity(...) | $@ | main.rs:15:13:15:21 | source(...) | source(...) |
105+
| main.rs:26:10:26:18 | coerce(...) | main.rs:25:13:25:22 | source(...) | main.rs:26:10:26:18 | coerce(...) | $@ | main.rs:25:13:25:22 | source(...) | source(...) |
100106
| main.rs:42:10:42:24 | get_var_pos(...) | main.rs:40:13:40:21 | source(...) | main.rs:42:10:42:24 | get_var_pos(...) | $@ | main.rs:40:13:40:21 | source(...) | source(...) |
101107
| main.rs:42:10:42:24 | get_var_pos(...) | main.rs:40:13:40:21 | source(...) | main.rs:42:10:42:24 | get_var_pos(...) | $@ | main.rs:40:13:40:21 | source(...) | source(...) |
102108
| main.rs:57:33:57:33 | i | main.rs:53:13:53:21 | source(...) | main.rs:57:33:57:33 | i | $@ | main.rs:53:13:53:21 | source(...) | source(...) |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | |
2+
| main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | |
3+
| main.rs:13:10:13:10 | a | main.rs:13:10:13:14 | ... + ... | |
4+
| main.rs:13:14:13:14 | 1 | main.rs:13:10:13:14 | ... + ... | |
5+
| main.rs:18:11:18:11 | a | main.rs:18:10:18:11 | - ... | |
6+
| main.rs:23:13:23:13 | a | main.rs:23:13:23:19 | a as u8 | |
7+
| main.rs:24:10:24:10 | b | main.rs:24:10:24:17 | b as i64 | |
8+
| main.rs:38:23:38:23 | s | main.rs:38:23:38:29 | s[...] | |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
models
22
edges
3+
| main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | provenance | |
4+
| main.rs:17:13:17:22 | source(...) | main.rs:18:10:18:11 | - ... | provenance | |
5+
| main.rs:22:13:22:22 | source(...) | main.rs:24:10:24:17 | b as i64 | provenance | |
36
nodes
7+
| main.rs:12:13:12:22 | source(...) | semmle.label | source(...) |
8+
| main.rs:13:10:13:14 | ... + ... | semmle.label | ... + ... |
9+
| main.rs:17:13:17:22 | source(...) | semmle.label | source(...) |
10+
| main.rs:18:10:18:11 | - ... | semmle.label | - ... |
11+
| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) |
12+
| main.rs:24:10:24:17 | b as i64 | semmle.label | b as i64 |
413
subpaths
514
testFailures
615
#select
16+
| main.rs:13:10:13:14 | ... + ... | main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | $@ | main.rs:12:13:12:22 | source(...) | source(...) |
17+
| main.rs:18:10:18:11 | - ... | main.rs:17:13:17:22 | source(...) | main.rs:18:10:18:11 | - ... | $@ | main.rs:17:13:17:22 | source(...) | source(...) |
18+
| main.rs:24:10:24:17 | b as i64 | main.rs:22:13:22:22 | source(...) | main.rs:24:10:24:17 | b as i64 | $@ | main.rs:22:13:22:22 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/taint/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ fn sink(s: i64) {
1010

1111
fn addition() {
1212
let a = source(42);
13-
sink(a + 1); // $ MISSING: hasTaintFlow=42
13+
sink(a + 1); // $ hasTaintFlow=42
1414
}
1515

1616
fn negation() {
1717
let a = source(17);
18-
sink(-a); // $ MISSING: hasTaintFlow=17
18+
sink(-a); // $ hasTaintFlow=17
1919
}
2020

2121
fn cast() {
2222
let a = source(77);
2323
let b = a as u8;
24-
sink(b as i64); // $ MISSING: hasTaintFlow=77
24+
sink(b as i64); // $ hasTaintFlow=77
2525
}
2626

2727
mod string {

0 commit comments

Comments
 (0)