Skip to content

Commit f10ffa3

Browse files
committed
Rust: Add tests for taint flow
1 parent b7792d6 commit f10ffa3

File tree

6 files changed

+164
-45
lines changed

6 files changed

+164
-45
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ fn test_identify() {
1616
sink(identity(s)); // $ hasValueFlow=1
1717
}
1818

19+
// has a flow model
20+
fn coerce(_i: i64) -> i64 {
21+
0
22+
}
23+
24+
fn test_coerce() {
25+
let s = source(14);
26+
sink(coerce(s)); // $ MISSING: hasTaintFlow=14
27+
}
28+
1929
enum MyPosEnum {
2030
A(i64),
2131
B(i64),
Lines changed: 94 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,107 @@
11
models
22
edges
33
| main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | |
4+
| main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | |
5+
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
46
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
5-
| main.rs:30:13:30:21 | source(...) | main.rs:31:27:31:27 | s | provenance | |
6-
| main.rs:31:14:31:28 | ...::A(...) [A] | main.rs:32:22:32:23 | e1 [A] | provenance | |
7-
| main.rs:31:27:31:27 | s | main.rs:31:14:31:28 | ...::A(...) [A] | provenance | |
8-
| main.rs:32:22:32:23 | e1 [A] | main.rs:32:10:32:24 | get_var_pos(...) | provenance | |
9-
| main.rs:43:13:43:21 | source(...) | main.rs:44:26:44:26 | s | provenance | |
10-
| main.rs:44:14:44:27 | set_var_pos(...) [B] | main.rs:47:9:47:23 | ...::B(...) [B] | provenance | |
11-
| main.rs:44:26:44:26 | s | main.rs:44:14:44:27 | set_var_pos(...) [B] | provenance | |
12-
| main.rs:47:9:47:23 | ...::B(...) [B] | main.rs:47:22:47:22 | i | provenance | |
13-
| main.rs:47:22:47:22 | i | main.rs:47:33:47:33 | i | provenance | |
14-
| main.rs:62:13:62:21 | source(...) | main.rs:63:40:63:40 | s | provenance | |
15-
| main.rs:63:14:63:42 | ...::C {...} [C] | main.rs:64:24:64:25 | e1 [C] | provenance | |
16-
| main.rs:63:40:63:40 | s | main.rs:63:14:63:42 | ...::C {...} [C] | provenance | |
17-
| main.rs:64:24:64:25 | e1 [C] | main.rs:64:10:64:26 | get_var_field(...) | provenance | |
18-
| main.rs:75:13:75:21 | source(...) | main.rs:76:28:76:28 | s | provenance | |
19-
| main.rs:76:14:76:29 | set_var_field(...) [D] | main.rs:79:9:79:37 | ...::D {...} [D] | provenance | |
20-
| main.rs:76:28:76:28 | s | main.rs:76:14:76:29 | set_var_field(...) [D] | provenance | |
21-
| main.rs:79:9:79:37 | ...::D {...} [D] | main.rs:79:35:79:35 | i | provenance | |
22-
| main.rs:79:35:79:35 | i | main.rs:79:47:79:47 | i | provenance | |
7+
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
8+
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
9+
| main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | |
10+
| main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | |
11+
| main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | |
12+
| main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | |
13+
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | |
14+
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | |
15+
| main.rs:53:13:53:21 | source(...) | main.rs:54:26:54:26 | s | provenance | |
16+
| main.rs:53:13:53:21 | source(...) | main.rs:54:26:54:26 | s | provenance | |
17+
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
18+
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
19+
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | |
20+
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | |
21+
| main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | |
22+
| main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | |
23+
| main.rs:57:22:57:22 | i | main.rs:57:33:57:33 | i | provenance | |
24+
| main.rs:57:22:57:22 | i | main.rs:57:33:57:33 | i | provenance | |
25+
| main.rs:72:13:72:21 | source(...) | main.rs:73:40:73:40 | s | provenance | |
26+
| main.rs:72:13:72:21 | source(...) | main.rs:73:40:73:40 | s | provenance | |
27+
| main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:74:24:74:25 | e1 [C] | provenance | |
28+
| main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:74:24:74:25 | e1 [C] | provenance | |
29+
| main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | |
30+
| main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | |
31+
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | |
32+
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | |
33+
| main.rs:85:13:85:21 | source(...) | main.rs:86:28:86:28 | s | provenance | |
34+
| main.rs:85:13:85:21 | source(...) | main.rs:86:28:86:28 | s | provenance | |
35+
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
36+
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
37+
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | |
38+
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | |
39+
| main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | |
40+
| main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | |
41+
| main.rs:89:35:89:35 | i | main.rs:89:47:89:47 | i | provenance | |
42+
| main.rs:89:35:89:35 | i | main.rs:89:47:89:47 | i | provenance | |
2343
nodes
2444
| main.rs:15:13:15:21 | source(...) | semmle.label | source(...) |
45+
| main.rs:15:13:15:21 | source(...) | semmle.label | source(...) |
2546
| main.rs:16:10:16:20 | identity(...) | semmle.label | identity(...) |
47+
| main.rs:16:10:16:20 | identity(...) | semmle.label | identity(...) |
48+
| main.rs:16:19:16:19 | s | semmle.label | s |
2649
| main.rs:16:19:16:19 | s | semmle.label | s |
27-
| main.rs:30:13:30:21 | source(...) | semmle.label | source(...) |
28-
| main.rs:31:14:31:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
29-
| main.rs:31:27:31:27 | s | semmle.label | s |
30-
| main.rs:32:10:32:24 | get_var_pos(...) | semmle.label | get_var_pos(...) |
31-
| main.rs:32:22:32:23 | e1 [A] | semmle.label | e1 [A] |
32-
| main.rs:43:13:43:21 | source(...) | semmle.label | source(...) |
33-
| main.rs:44:14:44:27 | set_var_pos(...) [B] | semmle.label | set_var_pos(...) [B] |
34-
| main.rs:44:26:44:26 | s | semmle.label | s |
35-
| main.rs:47:9:47:23 | ...::B(...) [B] | semmle.label | ...::B(...) [B] |
36-
| main.rs:47:22:47:22 | i | semmle.label | i |
37-
| main.rs:47:33:47:33 | i | semmle.label | i |
38-
| main.rs:62:13:62:21 | source(...) | semmle.label | source(...) |
39-
| main.rs:63:14:63:42 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
40-
| main.rs:63:40:63:40 | s | semmle.label | s |
41-
| main.rs:64:10:64:26 | get_var_field(...) | semmle.label | get_var_field(...) |
42-
| main.rs:64:24:64:25 | e1 [C] | semmle.label | e1 [C] |
43-
| main.rs:75:13:75:21 | source(...) | semmle.label | source(...) |
44-
| main.rs:76:14:76:29 | set_var_field(...) [D] | semmle.label | set_var_field(...) [D] |
45-
| main.rs:76:28:76:28 | s | semmle.label | s |
46-
| main.rs:79:9:79:37 | ...::D {...} [D] | semmle.label | ...::D {...} [D] |
47-
| main.rs:79:35:79:35 | i | semmle.label | i |
48-
| main.rs:79:47:79:47 | i | semmle.label | i |
50+
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
51+
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
52+
| main.rs:41:14:41:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
53+
| main.rs:41:14:41:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
54+
| main.rs:41:27:41:27 | s | semmle.label | s |
55+
| main.rs:41:27:41:27 | s | semmle.label | s |
56+
| main.rs:42:10:42:24 | get_var_pos(...) | semmle.label | get_var_pos(...) |
57+
| main.rs:42:10:42:24 | get_var_pos(...) | semmle.label | get_var_pos(...) |
58+
| main.rs:42:22:42:23 | e1 [A] | semmle.label | e1 [A] |
59+
| main.rs:42:22:42:23 | e1 [A] | semmle.label | e1 [A] |
60+
| main.rs:53:13:53:21 | source(...) | semmle.label | source(...) |
61+
| main.rs:53:13:53:21 | source(...) | semmle.label | source(...) |
62+
| main.rs:54:14:54:27 | set_var_pos(...) [B] | semmle.label | set_var_pos(...) [B] |
63+
| main.rs:54:14:54:27 | set_var_pos(...) [B] | semmle.label | set_var_pos(...) [B] |
64+
| main.rs:54:26:54:26 | s | semmle.label | s |
65+
| main.rs:54:26:54:26 | s | semmle.label | s |
66+
| main.rs:57:9:57:23 | ...::B(...) [B] | semmle.label | ...::B(...) [B] |
67+
| main.rs:57:9:57:23 | ...::B(...) [B] | semmle.label | ...::B(...) [B] |
68+
| main.rs:57:22:57:22 | i | semmle.label | i |
69+
| main.rs:57:22:57:22 | i | semmle.label | i |
70+
| main.rs:57:33:57:33 | i | semmle.label | i |
71+
| main.rs:57:33:57:33 | i | semmle.label | i |
72+
| main.rs:72:13:72:21 | source(...) | semmle.label | source(...) |
73+
| main.rs:72:13:72:21 | source(...) | semmle.label | source(...) |
74+
| main.rs:73:14:73:42 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
75+
| main.rs:73:14:73:42 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
76+
| main.rs:73:40:73:40 | s | semmle.label | s |
77+
| main.rs:73:40:73:40 | s | semmle.label | s |
78+
| main.rs:74:10:74:26 | get_var_field(...) | semmle.label | get_var_field(...) |
79+
| main.rs:74:10:74:26 | get_var_field(...) | semmle.label | get_var_field(...) |
80+
| main.rs:74:24:74:25 | e1 [C] | semmle.label | e1 [C] |
81+
| main.rs:74:24:74:25 | e1 [C] | semmle.label | e1 [C] |
82+
| main.rs:85:13:85:21 | source(...) | semmle.label | source(...) |
83+
| main.rs:85:13:85:21 | source(...) | semmle.label | source(...) |
84+
| main.rs:86:14:86:29 | set_var_field(...) [D] | semmle.label | set_var_field(...) [D] |
85+
| main.rs:86:14:86:29 | set_var_field(...) [D] | semmle.label | set_var_field(...) [D] |
86+
| main.rs:86:28:86:28 | s | semmle.label | s |
87+
| main.rs:86:28:86:28 | s | semmle.label | s |
88+
| main.rs:89:9:89:37 | ...::D {...} [D] | semmle.label | ...::D {...} [D] |
89+
| main.rs:89:9:89:37 | ...::D {...} [D] | semmle.label | ...::D {...} [D] |
90+
| main.rs:89:35:89:35 | i | semmle.label | i |
91+
| main.rs:89:35:89:35 | i | semmle.label | i |
92+
| main.rs:89:47:89:47 | i | semmle.label | i |
93+
| main.rs:89:47:89:47 | i | semmle.label | i |
4994
subpaths
5095
testFailures
5196
invalidSpecComponent
5297
#select
5398
| 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(...) |
54-
| main.rs:32:10:32:24 | get_var_pos(...) | main.rs:30:13:30:21 | source(...) | main.rs:32:10:32:24 | get_var_pos(...) | $@ | main.rs:30:13:30:21 | source(...) | source(...) |
55-
| main.rs:47:33:47:33 | i | main.rs:43:13:43:21 | source(...) | main.rs:47:33:47:33 | i | $@ | main.rs:43:13:43:21 | source(...) | source(...) |
56-
| main.rs:64:10:64:26 | get_var_field(...) | main.rs:62:13:62:21 | source(...) | main.rs:64:10:64:26 | get_var_field(...) | $@ | main.rs:62:13:62:21 | source(...) | source(...) |
57-
| main.rs:79:47:79:47 | i | main.rs:75:13:75:21 | source(...) | main.rs:79:47:79:47 | i | $@ | main.rs:75:13:75:21 | source(...) | source(...) |
99+
| 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(...) |
100+
| 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(...) |
101+
| 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(...) |
102+
| 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(...) |
103+
| 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(...) |
104+
| main.rs:74:10:74:26 | get_var_field(...) | main.rs:72:13:72:21 | source(...) | main.rs:74:10:74:26 | get_var_field(...) | $@ | main.rs:72:13:72:21 | source(...) | source(...) |
105+
| main.rs:74:10:74:26 | get_var_field(...) | main.rs:72:13:72:21 | source(...) | main.rs:74:10:74:26 | get_var_field(...) | $@ | main.rs:72:13:72:21 | source(...) | source(...) |
106+
| main.rs:89:47:89:47 | i | main.rs:85:13:85:21 | source(...) | main.rs:89:47:89:47 | i | $@ | main.rs:85:13:85:21 | source(...) | source(...) |
107+
| main.rs:89:47:89:47 | i | main.rs:85:13:85:21 | source(...) | main.rs:89:47:89:47 | i | $@ | main.rs:85:13:85:21 | source(...) | source(...) |

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ private class SummarizedCallableIdentity extends SummarizedCallable::Range {
2525
}
2626
}
2727

28+
private class SummarizedCallableCoerce extends SummarizedCallable::Range {
29+
SummarizedCallableCoerce() { this = "repo::test::_::crate::coerce" }
30+
31+
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
32+
input = "Argument[0]" and
33+
output = "ReturnValue" and
34+
preservesValue = false
35+
}
36+
}
37+
2838
private class SummarizedCallableGetVarPos extends SummarizedCallable::Range {
2939
SummarizedCallableGetVarPos() { this = "repo::test::_::crate::get_var_pos" }
3040

@@ -71,7 +81,7 @@ module CustomConfig implements DataFlow::ConfigSig {
7181
predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) }
7282
}
7383

74-
import ValueFlowTest<CustomConfig>
84+
import FlowTest<CustomConfig, CustomConfig>
7585

7686
from PathNode source, PathNode sink
7787
where flowPath(source, sink)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
models
2+
edges
3+
nodes
4+
subpaths
5+
testFailures
6+
#select
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
5+
import rust
6+
import utils.InlineFlowTest
7+
import DefaultFlowTest
8+
import TaintFlow::PathGraph
9+
10+
from TaintFlow::PathNode source, TaintFlow::PathNode sink
11+
where TaintFlow::flowPath(source, sink)
12+
select sink, source, sink, "$@", source, source.toString()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Tests for taint flow.
2+
3+
fn source(i: i64) -> i64 {
4+
1000 + i
5+
}
6+
7+
fn sink(s: i64) {
8+
println!("{}", s);
9+
}
10+
11+
fn addition() {
12+
let a = source(42);
13+
sink(a + 1); // $ MISSING: hasTaintFlow=42
14+
}
15+
16+
fn negation() {
17+
let a = source(17);
18+
sink(-a); // $ MISSING: hasTaintFlow=17
19+
}
20+
21+
fn cast() {
22+
let a = source(77);
23+
let b = a as u8;
24+
sink(b as i64); // $ MISSING: hasTaintFlow=77
25+
}
26+
27+
fn main() {
28+
addition();
29+
negation();
30+
cast();
31+
}

0 commit comments

Comments
 (0)