Skip to content

Commit 636bbe3

Browse files
authored
Merge pull request #21122 from hvitved/rust/summary-read-taint-step
Rust: Also lift read steps in summaries as taint steps
2 parents ac62a9f + 209ee92 commit 636bbe3

File tree

9 files changed

+202
-145
lines changed

9 files changed

+202
-145
lines changed

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

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,9 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
5252
// Read steps give rise to taint steps. This has the effect that if `foo`
5353
// is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
5454
// taint is propagated.
55-
exists(Content c |
56-
RustDataFlow::readContentStep(pred, c, succ) and
57-
not excludedTaintStepContent(c)
58-
)
59-
or
60-
// In addition to the above, for element and reference content we let
61-
// _all_ read steps (including those from flow summaries and those that
62-
// result in small primitive types) give rise to taint steps.
63-
exists(SingletonContentSet cs | RustDataFlow::readStep(pred, cs, succ) |
64-
cs.getContent() instanceof ElementContent
65-
or
66-
cs.getContent() instanceof ReferenceContent
55+
exists(ContentSet cs |
56+
RustDataFlow::readStep(pred, cs, succ) and
57+
not excludedTaintStepContent(cs.getAReadContent())
6758
)
6859
or
6960
exists(FormatArgsExpr format | succ.asExpr() = format |

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

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ models
1717
| 16 | Summary: <core::pin::Pin as core::ops::deref::Deref>::deref; Argument[self].Reference.Field[core::pin::Pin::pointer].Reference; ReturnValue.Reference; value |
1818
| 17 | Summary: <core::pin::Pin>::into_inner; Argument[0].Field[core::pin::Pin::pointer]; ReturnValue; value |
1919
| 18 | Summary: <core::pin::Pin>::into_inner_unchecked; Argument[0].Field[core::pin::Pin::pointer]; ReturnValue; value |
20-
| 19 | Summary: <core::pin::Pin>::new; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
21-
| 20 | Summary: <core::pin::Pin>::new_unchecked; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
22-
| 21 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
23-
| 22 | Summary: core::ptr::read; Argument[0].Reference; ReturnValue; value |
24-
| 23 | Summary: core::ptr::write; Argument[1]; Argument[0].Reference; value |
20+
| 19 | Summary: <core::pin::Pin>::new; Argument[0].Reference; ReturnValue; value |
21+
| 20 | Summary: <core::pin::Pin>::new; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
22+
| 21 | Summary: <core::pin::Pin>::new_unchecked; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
23+
| 22 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
24+
| 23 | Summary: core::ptr::read; Argument[0].Reference; ReturnValue; value |
25+
| 24 | Summary: core::ptr::write; Argument[1]; Argument[0].Reference; value |
2526
edges
2627
| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:10 | a [Some] | provenance | |
2728
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:13 | a [Some] | provenance | |
@@ -36,11 +37,11 @@ edges
3637
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:13 | a [Ok] | provenance | |
3738
| main.rs:19:31:19:44 | Ok(...) [Ok] | main.rs:19:9:19:9 | a [Ok] | provenance | |
3839
| main.rs:19:34:19:43 | source(...) | main.rs:19:31:19:44 | Ok(...) [Ok] | provenance | |
39-
| main.rs:20:10:20:10 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:21 |
40+
| main.rs:20:10:20:10 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:22 |
4041
| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:10 | b [Ok] | provenance | |
4142
| main.rs:21:13:21:13 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | MaD:2 |
4243
| main.rs:21:13:21:21 | a.clone() [Ok] | main.rs:21:9:21:9 | b [Ok] | provenance | |
43-
| main.rs:22:10:22:10 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:21 |
44+
| main.rs:22:10:22:10 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:22 |
4445
| main.rs:26:9:26:9 | a | main.rs:27:10:27:10 | a | provenance | |
4546
| main.rs:26:9:26:9 | a | main.rs:28:13:28:13 | a | provenance | |
4647
| main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | a | provenance | |
@@ -81,18 +82,22 @@ edges
8182
| main.rs:79:37:79:46 | source(...) | main.rs:79:33:79:46 | ... + ... | provenance | MaD:6 |
8283
| main.rs:79:37:79:46 | source(...) | main.rs:79:33:79:46 | ... + ... | provenance | MaD:7 |
8384
| main.rs:92:29:92:29 | [post] y [&ref] | main.rs:93:33:93:33 | y [&ref] | provenance | |
84-
| main.rs:92:32:92:41 | source(...) | main.rs:92:29:92:29 | [post] y [&ref] | provenance | MaD:23 |
85-
| main.rs:93:33:93:33 | y [&ref] | main.rs:93:18:93:34 | ...::read(...) | provenance | MaD:22 |
85+
| main.rs:92:32:92:41 | source(...) | main.rs:92:29:92:29 | [post] y [&ref] | provenance | MaD:24 |
86+
| main.rs:93:33:93:33 | y [&ref] | main.rs:93:18:93:34 | ...::read(...) | provenance | MaD:23 |
8687
| main.rs:108:13:108:17 | mut i | main.rs:109:34:109:34 | i | provenance | |
8788
| main.rs:108:13:108:17 | mut i | main.rs:110:33:110:33 | i | provenance | |
8889
| main.rs:108:13:108:17 | mut i | main.rs:111:47:111:47 | i | provenance | |
8990
| main.rs:108:13:108:17 | mut i | main.rs:112:24:112:27 | mut pinned | provenance | |
9091
| main.rs:108:13:108:17 | mut i | main.rs:113:14:113:14 | i | provenance | |
9192
| main.rs:108:21:108:30 | source(...) | main.rs:108:13:108:17 | mut i | provenance | |
93+
| main.rs:109:13:109:20 | mut pin1 | main.rs:114:15:114:18 | pin1 | provenance | |
94+
| main.rs:109:13:109:20 | mut pin1 | main.rs:115:31:115:34 | pin1 | provenance | |
9295
| main.rs:109:13:109:20 | mut pin1 [Pin, &ref] | main.rs:114:15:114:18 | pin1 [Pin, &ref] | provenance | |
9396
| main.rs:109:13:109:20 | mut pin1 [Pin, &ref] | main.rs:115:31:115:34 | pin1 [Pin, &ref] | provenance | |
97+
| main.rs:109:24:109:35 | ...::new(...) | main.rs:109:13:109:20 | mut pin1 | provenance | |
9498
| main.rs:109:24:109:35 | ...::new(...) [Pin, &ref] | main.rs:109:13:109:20 | mut pin1 [Pin, &ref] | provenance | |
95-
| main.rs:109:33:109:34 | &i [&ref] | main.rs:109:24:109:35 | ...::new(...) [Pin, &ref] | provenance | MaD:19 |
99+
| main.rs:109:33:109:34 | &i [&ref] | main.rs:109:24:109:35 | ...::new(...) | provenance | MaD:19 |
100+
| main.rs:109:33:109:34 | &i [&ref] | main.rs:109:24:109:35 | ...::new(...) [Pin, &ref] | provenance | MaD:20 |
96101
| main.rs:109:34:109:34 | i | main.rs:109:33:109:34 | &i [&ref] | provenance | |
97102
| main.rs:110:13:110:20 | mut pin2 [Pin, Box(0)] | main.rs:116:15:116:18 | pin2 [Pin, Box(0)] | provenance | |
98103
| main.rs:110:24:110:34 | ...::pin(...) [Pin, Box(0)] | main.rs:110:13:110:20 | mut pin2 [Pin, Box(0)] | provenance | |
@@ -102,12 +107,16 @@ edges
102107
| main.rs:111:38:111:48 | ...::new(...) [Box(0)] | main.rs:111:24:111:49 | ...::into_pin(...) [Pin, Box(0)] | provenance | MaD:8 |
103108
| main.rs:111:47:111:47 | i | main.rs:111:38:111:48 | ...::new(...) [Box(0)] | provenance | MaD:9 |
104109
| main.rs:112:13:112:20 | mut pin4 [Pin, &ref] | main.rs:118:15:118:18 | pin4 [Pin, &ref] | provenance | |
105-
| main.rs:112:24:112:27 | &mut pinned [&ref] | main.rs:112:24:112:27 | ...::new_unchecked(...) [Pin, &ref] | provenance | MaD:20 |
110+
| main.rs:112:24:112:27 | &mut pinned [&ref] | main.rs:112:24:112:27 | ...::new_unchecked(...) [Pin, &ref] | provenance | MaD:21 |
106111
| main.rs:112:24:112:27 | ...::new_unchecked(...) [Pin, &ref] | main.rs:112:13:112:20 | mut pin4 [Pin, &ref] | provenance | |
107112
| main.rs:112:24:112:27 | mut pinned | main.rs:112:24:112:27 | pinned | provenance | |
108113
| main.rs:112:24:112:27 | pinned | main.rs:112:24:112:27 | &mut pinned [&ref] | provenance | |
114+
| main.rs:114:15:114:18 | pin1 | main.rs:114:14:114:18 | * ... | provenance | MaD:15 |
115+
| main.rs:114:15:114:18 | pin1 | main.rs:114:14:114:18 | * ... | provenance | MaD:16 |
109116
| main.rs:114:15:114:18 | pin1 [Pin, &ref] | main.rs:114:14:114:18 | * ... | provenance | MaD:16 |
117+
| main.rs:115:15:115:35 | ...::into_inner(...) | main.rs:115:14:115:35 | * ... | provenance | MaD:1 |
110118
| main.rs:115:15:115:35 | ...::into_inner(...) [&ref] | main.rs:115:14:115:35 | * ... | provenance | MaD:1 |
119+
| main.rs:115:31:115:34 | pin1 | main.rs:115:15:115:35 | ...::into_inner(...) | provenance | MaD:17 |
111120
| main.rs:115:31:115:34 | pin1 [Pin, &ref] | main.rs:115:15:115:35 | ...::into_inner(...) [&ref] | provenance | MaD:17 |
112121
| main.rs:116:15:116:18 | pin2 [Pin, Box(0)] | main.rs:116:14:116:18 | * ... | provenance | MaD:15 |
113122
| main.rs:117:15:117:18 | pin3 [Pin, Box(0)] | main.rs:117:14:117:18 | * ... | provenance | MaD:15 |
@@ -118,7 +127,7 @@ edges
118127
| main.rs:122:38:122:47 | source(...) | main.rs:122:22:122:49 | MyStruct {...} [MyStruct] | provenance | |
119128
| main.rs:123:13:123:20 | mut pin1 [Pin, &ref, MyStruct] | main.rs:129:30:129:33 | pin1 [Pin, &ref, MyStruct] | provenance | |
120129
| main.rs:123:24:123:36 | ...::new(...) [Pin, &ref, MyStruct] | main.rs:123:13:123:20 | mut pin1 [Pin, &ref, MyStruct] | provenance | |
121-
| main.rs:123:33:123:35 | &ms [&ref, MyStruct] | main.rs:123:24:123:36 | ...::new(...) [Pin, &ref, MyStruct] | provenance | MaD:19 |
130+
| main.rs:123:33:123:35 | &ms [&ref, MyStruct] | main.rs:123:24:123:36 | ...::new(...) [Pin, &ref, MyStruct] | provenance | MaD:20 |
122131
| main.rs:123:34:123:35 | ms [MyStruct] | main.rs:123:33:123:35 | &ms [&ref, MyStruct] | provenance | |
123132
| main.rs:127:14:127:15 | ms [MyStruct] | main.rs:127:14:127:19 | ms.val | provenance | |
124133
| main.rs:129:14:129:34 | ...::into_inner(...) [&ref, MyStruct] | main.rs:129:14:129:38 | ... .val | provenance | |
@@ -128,7 +137,7 @@ edges
128137
| main.rs:136:38:136:47 | source(...) | main.rs:136:22:136:49 | MyStruct {...} [MyStruct] | provenance | |
129138
| main.rs:137:13:137:20 | mut pin5 [Pin, &ref, MyStruct] | main.rs:139:40:139:43 | pin5 [Pin, &ref, MyStruct] | provenance | |
130139
| main.rs:137:24:137:46 | ...::new_unchecked(...) [Pin, &ref, MyStruct] | main.rs:137:13:137:20 | mut pin5 [Pin, &ref, MyStruct] | provenance | |
131-
| main.rs:137:43:137:45 | &ms [&ref, MyStruct] | main.rs:137:24:137:46 | ...::new_unchecked(...) [Pin, &ref, MyStruct] | provenance | MaD:20 |
140+
| main.rs:137:43:137:45 | &ms [&ref, MyStruct] | main.rs:137:24:137:46 | ...::new_unchecked(...) [Pin, &ref, MyStruct] | provenance | MaD:21 |
132141
| main.rs:137:44:137:45 | ms [MyStruct] | main.rs:137:43:137:45 | &ms [&ref, MyStruct] | provenance | |
133142
| main.rs:139:14:139:44 | ...::into_inner_unchecked(...) [&ref, MyStruct] | main.rs:139:14:139:48 | ... .val | provenance | |
134143
| main.rs:139:40:139:43 | pin5 [Pin, &ref, MyStruct] | main.rs:139:14:139:44 | ...::into_inner_unchecked(...) [&ref, MyStruct] | provenance | MaD:18 |
@@ -227,7 +236,9 @@ nodes
227236
| main.rs:93:33:93:33 | y [&ref] | semmle.label | y [&ref] |
228237
| main.rs:108:13:108:17 | mut i | semmle.label | mut i |
229238
| main.rs:108:21:108:30 | source(...) | semmle.label | source(...) |
239+
| main.rs:109:13:109:20 | mut pin1 | semmle.label | mut pin1 |
230240
| main.rs:109:13:109:20 | mut pin1 [Pin, &ref] | semmle.label | mut pin1 [Pin, &ref] |
241+
| main.rs:109:24:109:35 | ...::new(...) | semmle.label | ...::new(...) |
231242
| main.rs:109:24:109:35 | ...::new(...) [Pin, &ref] | semmle.label | ...::new(...) [Pin, &ref] |
232243
| main.rs:109:33:109:34 | &i [&ref] | semmle.label | &i [&ref] |
233244
| main.rs:109:34:109:34 | i | semmle.label | i |
@@ -245,9 +256,12 @@ nodes
245256
| main.rs:112:24:112:27 | pinned | semmle.label | pinned |
246257
| main.rs:113:14:113:14 | i | semmle.label | i |
247258
| main.rs:114:14:114:18 | * ... | semmle.label | * ... |
259+
| main.rs:114:15:114:18 | pin1 | semmle.label | pin1 |
248260
| main.rs:114:15:114:18 | pin1 [Pin, &ref] | semmle.label | pin1 [Pin, &ref] |
249261
| main.rs:115:14:115:35 | * ... | semmle.label | * ... |
262+
| main.rs:115:15:115:35 | ...::into_inner(...) | semmle.label | ...::into_inner(...) |
250263
| main.rs:115:15:115:35 | ...::into_inner(...) [&ref] | semmle.label | ...::into_inner(...) [&ref] |
264+
| main.rs:115:31:115:34 | pin1 | semmle.label | pin1 |
251265
| main.rs:115:31:115:34 | pin1 [Pin, &ref] | semmle.label | pin1 [Pin, &ref] |
252266
| main.rs:116:14:116:18 | * ... | semmle.label | * ... |
253267
| main.rs:116:15:116:18 | pin2 [Pin, Box(0)] | semmle.label | pin2 [Pin, Box(0)] |

rust/ql/test/library-tests/dataflow/sources/file/InlineFlow.expected

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ models
3636
| 35 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self].Reference; Argument[0].Reference; taint |
3737
| 36 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
3838
| 37 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
39-
| 38 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
39+
| 38 | Summary: <std::ffi::os_str::OsString>::into_string; Argument[self].Field[std::ffi::os_str::OsString::inner].Field[std::sys::os_str::bytes::Buf::inner]; ReturnValue.Field[core::result::Result::Ok(0)].Field[alloc::string::String::vec]; value |
40+
| 39 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
4041
edges
4142
| test.rs:12:13:12:18 | buffer | test.rs:13:14:13:19 | buffer | provenance | |
4243
| test.rs:12:31:12:43 | ...::read | test.rs:12:31:12:55 | ...::read(...) [Ok] | provenance | Src:MaD:11 |
@@ -58,14 +59,18 @@ edges
5859
| test.rs:29:22:29:25 | path | test.rs:29:20:29:27 | e.path() | provenance | Src:MaD:4 MaD:4 |
5960
| test.rs:30:14:30:17 | path | test.rs:30:14:30:25 | path.clone() | provenance | MaD:18 |
6061
| test.rs:31:14:31:17 | path | test.rs:31:14:31:25 | path.clone() | provenance | MaD:18 |
61-
| test.rs:31:14:31:25 | path.clone() | test.rs:31:14:31:35 | ... .as_path() | provenance | MaD:38 |
62+
| test.rs:31:14:31:25 | path.clone() | test.rs:31:14:31:35 | ... .as_path() | provenance | MaD:39 |
6263
| test.rs:40:14:40:17 | path | test.rs:40:14:40:32 | path.canonicalize() [Ok] | provenance | MaD:19 |
6364
| test.rs:40:14:40:32 | path.canonicalize() [Ok] | test.rs:40:14:40:41 | ... .unwrap() | provenance | MaD:37 |
6465
| test.rs:43:13:43:21 | file_name | test.rs:44:14:44:22 | file_name | provenance | |
66+
| test.rs:43:13:43:21 | file_name | test.rs:45:14:45:22 | file_name | provenance | |
6567
| test.rs:43:13:43:21 | file_name | test.rs:49:14:49:22 | file_name | provenance | |
6668
| test.rs:43:25:43:37 | e.file_name() | test.rs:43:13:43:21 | file_name | provenance | |
6769
| test.rs:43:27:43:35 | file_name | test.rs:43:25:43:37 | e.file_name() | provenance | Src:MaD:3 MaD:3 |
6870
| test.rs:44:14:44:22 | file_name | test.rs:44:14:44:30 | file_name.clone() | provenance | MaD:18 |
71+
| test.rs:45:14:45:22 | file_name | test.rs:45:14:45:30 | file_name.clone() | provenance | MaD:18 |
72+
| test.rs:45:14:45:30 | file_name.clone() | test.rs:45:14:45:44 | ... .into_string() [Ok, String] | provenance | MaD:38 |
73+
| test.rs:45:14:45:44 | ... .into_string() [Ok, String] | test.rs:45:14:45:53 | ... .unwrap() | provenance | MaD:37 |
6974
| test.rs:65:13:65:18 | target | test.rs:66:14:66:19 | target | provenance | |
7075
| test.rs:65:22:65:34 | ...::read_link | test.rs:65:22:65:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:12 |
7176
| test.rs:65:22:65:49 | ...::read_link(...) [Ok] | test.rs:65:22:65:50 | TryExpr | provenance | |
@@ -286,6 +291,10 @@ nodes
286291
| test.rs:43:27:43:35 | file_name | semmle.label | file_name |
287292
| test.rs:44:14:44:22 | file_name | semmle.label | file_name |
288293
| test.rs:44:14:44:30 | file_name.clone() | semmle.label | file_name.clone() |
294+
| test.rs:45:14:45:22 | file_name | semmle.label | file_name |
295+
| test.rs:45:14:45:30 | file_name.clone() | semmle.label | file_name.clone() |
296+
| test.rs:45:14:45:44 | ... .into_string() [Ok, String] | semmle.label | ... .into_string() [Ok, String] |
297+
| test.rs:45:14:45:53 | ... .unwrap() | semmle.label | ... .unwrap() |
289298
| test.rs:49:14:49:22 | file_name | semmle.label | file_name |
290299
| test.rs:65:13:65:18 | target | semmle.label | target |
291300
| test.rs:65:22:65:34 | ...::read_link | semmle.label | ...::read_link |
@@ -502,6 +511,7 @@ testFailures
502511
| test.rs:40:14:40:41 | ... .unwrap() | test.rs:29:22:29:25 | path | test.rs:40:14:40:41 | ... .unwrap() | $@ | test.rs:29:22:29:25 | path | path |
503512
| test.rs:41:14:41:17 | path | test.rs:29:22:29:25 | path | test.rs:41:14:41:17 | path | $@ | test.rs:29:22:29:25 | path | path |
504513
| test.rs:44:14:44:30 | file_name.clone() | test.rs:43:27:43:35 | file_name | test.rs:44:14:44:30 | file_name.clone() | $@ | test.rs:43:27:43:35 | file_name | file_name |
514+
| test.rs:45:14:45:53 | ... .unwrap() | test.rs:43:27:43:35 | file_name | test.rs:45:14:45:53 | ... .unwrap() | $@ | test.rs:43:27:43:35 | file_name | file_name |
505515
| test.rs:49:14:49:22 | file_name | test.rs:43:27:43:35 | file_name | test.rs:49:14:49:22 | file_name | $@ | test.rs:43:27:43:35 | file_name | file_name |
506516
| test.rs:66:14:66:19 | target | test.rs:65:22:65:34 | ...::read_link | test.rs:66:14:66:19 | target | $@ | test.rs:65:22:65:34 | ...::read_link | ...::read_link |
507517
| test.rs:75:14:75:19 | buffer | test.rs:74:31:74:45 | ...::read | test.rs:75:14:75:19 | buffer | $@ | test.rs:74:31:74:45 | ...::read | ...::read |

rust/ql/test/library-tests/dataflow/sources/file/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
4242

4343
let file_name = e.file_name(); // $ Alert[rust/summary/taint-sources]
4444
sink(file_name.clone()); // $ hasTaintFlow
45-
sink(file_name.clone().into_string().unwrap()); // $ MISSING: hasTaintFlow
45+
sink(file_name.clone().into_string().unwrap()); // $ hasTaintFlow
4646
sink(file_name.to_str().unwrap()); // $ MISSING: hasTaintFlow
4747
sink(file_name.to_string_lossy().to_mut()); // $ MISSING: hasTaintFlow
4848
sink(file_name.clone().as_encoded_bytes()); // $ MISSING: hasTaintFlow

0 commit comments

Comments
 (0)