Skip to content

Commit 8a00ac7

Browse files
committed
Rust: Taint flow through operations using MaD
1 parent 594e8ac commit 8a00ac7

File tree

6 files changed

+93
-32
lines changed

6 files changed

+93
-32
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,12 @@ module LocalFlow {
255255
)
256256
or
257257
// An edge from a pattern/expression to its corresponding SSA definition.
258-
nodeFrom.(AstNodeNode).getAstNode() =
259-
nodeTo.(SsaNode).asDefinition().(Ssa::WriteDefinition).getWriteAccess()
258+
exists(AstNode n |
259+
n = nodeTo.(SsaNode).asDefinition().(Ssa::WriteDefinition).getWriteAccess() and
260+
if n = any(CompoundAssignmentExpr ca).getLhs()
261+
then n = nodeFrom.(PostUpdateNode).getPreUpdateNode().(AstNodeNode).getAstNode()
262+
else n = nodeFrom.(AstNodeNode).getAstNode()
263+
)
260264
or
261265
nodeFrom.(SourceParameterNode).getParameter().(Param).getPat() = nodeTo.asPat()
262266
or

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,6 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
2020
Stages::DataFlowStage::ref() and
2121
model = "" and
2222
(
23-
exists(BinaryExpr binary |
24-
binary.getOperatorName() = ["+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>"] and
25-
pred.asExpr() = [binary.getLhs(), binary.getRhs()] and
26-
succ.asExpr() = binary
27-
)
28-
or
29-
exists(PrefixExpr prefix |
30-
prefix.getOperatorName() = ["-", "!"] and
31-
pred.asExpr() = prefix.getExpr() and
32-
succ.asExpr() = prefix
33-
)
34-
or
3523
pred.asExpr() = succ.asExpr().(CastExpr).getExpr()
3624
or
3725
exists(IndexExpr index |

rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,70 @@ extensions:
99
# Index
1010
- ["<_ as core::ops::index::Index>::index", "Argument[self].Reference.Element", "ReturnValue.Reference", "value", "manual"]
1111
- ["<_ as core::ops::index::IndexMut>::index_mut", "Argument[self].Reference.Element", "ReturnValue.Reference", "value", "manual"]
12-
# Arithmetic
12+
# Unary operators
13+
- ["<_ as core::ops::arith::Neg>::neg", "Argument[self]", "ReturnValue", "taint", "manual"]
14+
- ["<_ as core::ops::bit::Not>::not", "Argument[self]", "ReturnValue", "taint", "manual"]
15+
# Arithmetic operators
1316
- ["<_ as core::ops::arith::Add>::add", "Argument[self]", "ReturnValue", "taint", "manual"]
1417
- ["<_ as core::ops::arith::Add>::add", "Argument[0]", "ReturnValue", "taint", "manual"]
1518
- ["<_ as core::ops::arith::Add>::add", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
19+
- ["<_ as core::ops::arith::Sub>::sub", "Argument[self]", "ReturnValue", "taint", "manual"]
20+
- ["<_ as core::ops::arith::Sub>::sub", "Argument[0]", "ReturnValue", "taint", "manual"]
21+
- ["<_ as core::ops::arith::Sub>::sub", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
22+
- ["<_ as core::ops::arith::Mul>::mul", "Argument[self]", "ReturnValue", "taint", "manual"]
23+
- ["<_ as core::ops::arith::Mul>::mul", "Argument[0]", "ReturnValue", "taint", "manual"]
24+
- ["<_ as core::ops::arith::Mul>::mul", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
25+
- ["<_ as core::ops::arith::Div>::div", "Argument[self]", "ReturnValue", "taint", "manual"]
26+
- ["<_ as core::ops::arith::Div>::div", "Argument[0]", "ReturnValue", "taint", "manual"]
27+
- ["<_ as core::ops::arith::Div>::div", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
28+
- ["<_ as core::ops::arith::Rem>::rem", "Argument[self]", "ReturnValue", "taint", "manual"]
29+
- ["<_ as core::ops::arith::Rem>::rem", "Argument[0]", "ReturnValue", "taint", "manual"]
30+
- ["<_ as core::ops::arith::Rem>::rem", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
31+
# Arithmetic assignment expressions
32+
- ["<_ as core::ops::arith::AddAssign>::add_assign", "Argument[self].Reference", "Argument[self].Reference", "taint", "manual"]
33+
- ["<_ as core::ops::arith::AddAssign>::add_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
34+
- ["<_ as core::ops::arith::AddAssign>::add_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
35+
- ["<_ as core::ops::arith::SubAssign>::sub_assign", "Argument[self].Reference", "Argument[self].Reference", "taint", "manual"]
36+
- ["<_ as core::ops::arith::SubAssign>::sub_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
37+
- ["<_ as core::ops::arith::SubAssign>::sub_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
38+
- ["<_ as core::ops::arith::MulAssign>::mul_assign", "Argument[self].Reference", "Argument[self].Reference", "taint", "manual"]
39+
- ["<_ as core::ops::arith::MulAssign>::mul_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
40+
- ["<_ as core::ops::arith::MulAssign>::mul_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
41+
- ["<_ as core::ops::arith::DivAssign>::div_assign", "Argument[self].Reference", "Argument[self].Reference", "taint", "manual"]
42+
- ["<_ as core::ops::arith::DivAssign>::div_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
43+
- ["<_ as core::ops::arith::DivAssign>::div_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
44+
- ["<_ as core::ops::arith::RemAssign>::rem_assign", "Argument[self].Reference", "Argument[self].Reference", "taint", "manual"]
45+
- ["<_ as core::ops::arith::RemAssign>::rem_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
46+
- ["<_ as core::ops::arith::RemAssign>::rem_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
47+
# Bitwise operators
48+
- ["<_ as core::ops::bit::BitAnd>::bitand", "Argument[self]", "ReturnValue", "taint", "manual"]
49+
- ["<_ as core::ops::bit::BitAnd>::bitand", "Argument[0]", "ReturnValue", "taint", "manual"]
50+
- ["<_ as core::ops::bit::BitAnd>::bitand", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
51+
- ["<_ as core::ops::bit::BitOr>::bitor", "Argument[self]", "ReturnValue", "taint", "manual"]
52+
- ["<_ as core::ops::bit::BitOr>::bitor", "Argument[0]", "ReturnValue", "taint", "manual"]
53+
- ["<_ as core::ops::bit::BitOr>::bitor", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
54+
- ["<_ as core::ops::bit::BitXor>::bitxor", "Argument[self]", "ReturnValue", "taint", "manual"]
55+
- ["<_ as core::ops::bit::BitXor>::bitxor", "Argument[0]", "ReturnValue", "taint", "manual"]
56+
- ["<_ as core::ops::bit::BitXor>::bitxor", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
57+
# Bitwise assignment operators
58+
- ["<_ as core::ops::bit::BitAndAssign>::bitand_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
59+
- ["<_ as core::ops::bit::BitAndAssign>::bitand_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
60+
- ["<_ as core::ops::bit::BitOrAssign>::bitor_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
61+
- ["<_ as core::ops::bit::BitOrAssign>::bitor_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
62+
- ["<_ as core::ops::bit::BitXorAssign>::bitxor_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
63+
- ["<_ as core::ops::bit::BitXorAssign>::bitxor_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
64+
# Shift operators
65+
- ["<_ as core::ops::bit::Shl>::shl", "Argument[self]", "ReturnValue", "taint", "manual"]
66+
- ["<_ as core::ops::bit::Shl>::shl", "Argument[0]", "ReturnValue", "taint", "manual"]
67+
- ["<_ as core::ops::bit::Shl>::shl", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
68+
- ["<_ as core::ops::bit::Shr>::shr", "Argument[self]", "ReturnValue", "taint", "manual"]
69+
- ["<_ as core::ops::bit::Shr>::shr", "Argument[0]", "ReturnValue", "taint", "manual"]
70+
- ["<_ as core::ops::bit::Shr>::shr", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
71+
# Shift assignment operators
72+
- ["<_ as core::ops::bit::ShlAssign>::shl_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
73+
- ["<_ as core::ops::bit::ShlAssign>::shl_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
74+
- ["<_ as core::ops::bit::ShrAssign>::shr_assign", "Argument[0]", "Argument[self].Reference", "taint", "manual"]
75+
- ["<_ as core::ops::bit::ShrAssign>::shr_assign", "Argument[0].Reference", "Argument[self].Reference", "taint", "manual"]
1676
# Clone
1777
- ["<_ as core::clone::Clone>::clone", "Argument[self].Reference", "ReturnValue", "value", "manual"]
1878
# Conversions

rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
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 | ... + ... |
31
| main.rs:8:20:8:20 | s | main.rs:8:14:8:20 | FormatArgsExpr |
4-
| main.rs:13:10:13:10 | a | main.rs:13:10:13:17 | ... + ... |
5-
| main.rs:13:14:13:17 | 1i64 | main.rs:13:10:13:17 | ... + ... |
62
| main.rs:16:5:16:5 | [post] b [borrowed] | main.rs:16:5:16:5 | [post] b |
73
| main.rs:20:5:20:5 | [post] c [borrowed] | main.rs:20:5:20:5 | [post] c |
8-
| main.rs:26:11:26:11 | a | main.rs:26:10:26:11 | - ... |
94
| main.rs:31:13:31:13 | a | main.rs:31:13:31:19 | a as u8 |
105
| main.rs:32:10:32:10 | b | main.rs:32:10:32:17 | b as i64 |
116
| main.rs:32:10:32:17 | [post] b as i64 | main.rs:32:10:32:10 | [post] b |

rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
models
22
| 1 | Summary: <_ as core::ops::arith::Add>::add; Argument[self]; ReturnValue; taint |
3-
| 2 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
4-
| 3 | Summary: <core::i64 as core::ops::arith::Add>::add; Argument[self]; ReturnValue; taint |
5-
| 4 | Summary: <core::i64 as core::ops::arith::Neg>::neg; Argument[self]; ReturnValue; taint |
3+
| 2 | Summary: <_ as core::ops::arith::AddAssign>::add_assign; Argument[0].Reference; Argument[self].Reference; taint |
4+
| 3 | Summary: <_ as core::ops::arith::AddAssign>::add_assign; Argument[0]; Argument[self].Reference; taint |
5+
| 4 | Summary: <_ as core::ops::arith::AddAssign>::add_assign; Argument[self].Reference; Argument[self].Reference; taint |
6+
| 5 | Summary: <_ as core::ops::arith::Neg>::neg; Argument[self]; ReturnValue; taint |
7+
| 6 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
8+
| 7 | Summary: <core::i64 as core::ops::arith::Add>::add; Argument[self]; ReturnValue; taint |
9+
| 8 | Summary: <core::i64 as core::ops::arith::Neg>::neg; Argument[self]; ReturnValue; taint |
610
edges
711
| main.rs:12:9:12:9 | a | main.rs:13:10:13:10 | a | provenance | |
8-
| main.rs:12:9:12:9 | a | main.rs:13:10:13:17 | ... + ... | provenance | |
912
| main.rs:12:13:12:22 | source(...) | main.rs:12:9:12:9 | a | provenance | |
1013
| main.rs:13:10:13:10 | a | main.rs:13:10:13:17 | ... + ... | provenance | MaD:1 |
11-
| main.rs:13:10:13:10 | a | main.rs:13:10:13:17 | ... + ... | provenance | MaD:3 |
12-
| main.rs:15:9:15:13 | mut b | main.rs:17:10:17:10 | b | provenance | |
14+
| main.rs:13:10:13:10 | a | main.rs:13:10:13:17 | ... + ... | provenance | MaD:7 |
15+
| main.rs:15:9:15:13 | mut b | main.rs:16:5:16:5 | b | provenance | |
1316
| main.rs:15:17:15:26 | source(...) | main.rs:15:9:15:13 | mut b | provenance | |
14-
| main.rs:25:9:25:9 | a | main.rs:26:10:26:11 | - ... | provenance | |
17+
| main.rs:16:5:16:5 | [post] b | main.rs:17:10:17:10 | b | provenance | |
18+
| main.rs:16:5:16:5 | b | main.rs:16:5:16:5 | [post] b | provenance | MaD:4 |
19+
| main.rs:20:5:20:5 | [post] c | main.rs:21:10:21:10 | c | provenance | |
20+
| main.rs:20:10:20:19 | source(...) | main.rs:20:5:20:5 | [post] c | provenance | MaD:2 |
21+
| main.rs:20:10:20:19 | source(...) | main.rs:20:5:20:5 | [post] c | provenance | MaD:3 |
1522
| main.rs:25:9:25:9 | a | main.rs:26:11:26:11 | a | provenance | |
1623
| main.rs:25:13:25:22 | source(...) | main.rs:25:9:25:9 | a | provenance | |
17-
| main.rs:26:11:26:11 | a | main.rs:26:10:26:11 | - ... | provenance | MaD:4 |
24+
| main.rs:26:11:26:11 | a | main.rs:26:10:26:11 | - ... | provenance | MaD:5 |
25+
| main.rs:26:11:26:11 | a | main.rs:26:10:26:11 | - ... | provenance | MaD:8 |
1826
| main.rs:30:9:30:9 | a | main.rs:31:9:31:9 | b | provenance | |
1927
| main.rs:30:13:30:22 | source(...) | main.rs:30:9:30:9 | a | provenance | |
2028
| main.rs:31:9:31:9 | b | main.rs:32:10:32:17 | b as i64 | provenance | |
@@ -23,11 +31,11 @@ edges
2331
| main.rs:45:17:45:26 | source(...) | main.rs:45:13:45:13 | s | provenance | |
2432
| main.rs:46:13:46:18 | sliced [&ref] | main.rs:47:14:47:19 | sliced | provenance | |
2533
| main.rs:46:22:46:29 | &... [&ref] | main.rs:46:13:46:18 | sliced [&ref] | provenance | |
26-
| main.rs:46:23:46:23 | s | main.rs:46:23:46:29 | s[...] | provenance | MaD:2 |
34+
| main.rs:46:23:46:23 | s | main.rs:46:23:46:29 | s[...] | provenance | MaD:6 |
2735
| main.rs:46:23:46:29 | s[...] | main.rs:46:22:46:29 | &... [&ref] | provenance | |
2836
| main.rs:61:13:61:15 | arr | main.rs:62:14:62:16 | arr | provenance | |
2937
| main.rs:61:19:61:28 | source(...) | main.rs:61:13:61:15 | arr | provenance | |
30-
| main.rs:62:14:62:16 | arr | main.rs:62:14:62:19 | arr[1] | provenance | MaD:2 |
38+
| main.rs:62:14:62:16 | arr | main.rs:62:14:62:19 | arr[1] | provenance | MaD:6 |
3139
| main.rs:77:9:77:12 | [post] arr2 [element] | main.rs:78:14:78:17 | arr2 | provenance | |
3240
| main.rs:77:19:77:28 | source(...) | main.rs:77:9:77:12 | [post] arr2 [element] | provenance | |
3341
nodes
@@ -37,7 +45,12 @@ nodes
3745
| main.rs:13:10:13:17 | ... + ... | semmle.label | ... + ... |
3846
| main.rs:15:9:15:13 | mut b | semmle.label | mut b |
3947
| main.rs:15:17:15:26 | source(...) | semmle.label | source(...) |
48+
| main.rs:16:5:16:5 | [post] b | semmle.label | [post] b |
49+
| main.rs:16:5:16:5 | b | semmle.label | b |
4050
| main.rs:17:10:17:10 | b | semmle.label | b |
51+
| main.rs:20:5:20:5 | [post] c | semmle.label | [post] c |
52+
| main.rs:20:10:20:19 | source(...) | semmle.label | source(...) |
53+
| main.rs:21:10:21:10 | c | semmle.label | c |
4154
| main.rs:25:9:25:9 | a | semmle.label | a |
4255
| main.rs:25:13:25:22 | source(...) | semmle.label | source(...) |
4356
| main.rs:26:10:26:11 | - ... | semmle.label | - ... |
@@ -65,6 +78,7 @@ testFailures
6578
#select
6679
| main.rs:13:10:13:17 | ... + ... | main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:17 | ... + ... | $@ | main.rs:12:13:12:22 | source(...) | source(...) |
6780
| main.rs:17:10:17:10 | b | main.rs:15:17:15:26 | source(...) | main.rs:17:10:17:10 | b | $@ | main.rs:15:17:15:26 | source(...) | source(...) |
81+
| main.rs:21:10:21:10 | c | main.rs:20:10:20:19 | source(...) | main.rs:21:10:21:10 | c | $@ | main.rs:20:10:20:19 | source(...) | source(...) |
6882
| main.rs:26:10:26:11 | - ... | main.rs:25:13:25:22 | source(...) | main.rs:26:10:26:11 | - ... | $@ | main.rs:25:13:25:22 | source(...) | source(...) |
6983
| main.rs:32:10:32:17 | b as i64 | main.rs:30:13:30:22 | source(...) | main.rs:32:10:32:17 | b as i64 | $@ | main.rs:30:13:30:22 | source(...) | source(...) |
7084
| main.rs:47:14:47:19 | sliced | main.rs:45:17:45:26 | source(...) | main.rs:47:14:47:19 | sliced | $@ | main.rs:45:17:45:26 | source(...) | source(...) |

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ fn addition() {
1414

1515
let mut b = source(58);
1616
b += 2i64;
17-
sink(b); // $ MISSING: hasTaintFlow=58 $ SPURIOUS: hasValueFlow=58
17+
sink(b); // $ hasTaintFlow=58
1818

1919
let mut c = 0i64; // for now, we cannot resolve `+=` when `0i64` is replaced with `0`
2020
c += source(99);
21-
sink(c); // $ MISSING: hasTaintFlow=99
21+
sink(c); // $ hasTaintFlow=99
2222
}
2323

2424
fn negation() {

0 commit comments

Comments
 (0)