Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust: Data flow improvements to unlock flow in sqlx test #18291

Merged
merged 9 commits into from
Dec 18, 2024
6 changes: 6 additions & 0 deletions rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/rust-all
extensible: summaryModel
data:
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::response::Response>::text", "Argument[self]", "ReturnValue", "taint", "manual"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it should be ReturnValue.Variant[crate::result::Result::Ok(0)].

13 changes: 13 additions & 0 deletions rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,17 @@ extensions:
pack: codeql/rust-all
extensible: summaryModel
data:
# Option
- ["lang:core", "<crate::option::Option>::unwrap", "Argument[self].Variant[crate::option::Option::Some(0)]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::option::Option>::unwrap", "Argument[self]", "ReturnValue", "taint", "manual"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these taint models should not be needed after altering the summary above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved one of them. But some of our sources specify taint on the entire Result, so I think I'd be fine to keep the others until that is no longer the case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather that we remove these lines, and not have flow for now, we should soon be able to have it once #18298 lands. Otherwise I fear we forget to remove these lines.

- ["lang:core", "<crate::option::Option>::unwrap_or", "Argument[self].Variant[crate::option::Option::Some(0)]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::option::Option>::unwrap_or", "Argument[0]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::option::Option>::unwrap_or", "Argument[self]", "ReturnValue", "taint", "manual"]
# Result
- ["lang:core", "<crate::result::Result>::unwrap", "Argument[self].Variant[crate::result::Result::Ok(0)]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::result::Result>::unwrap", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["lang:core", "<crate::result::Result>::unwrap_or", "Argument[self].Variant[crate::result::Result::Ok(0)]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::result::Result>::unwrap_or", "Argument[0]", "ReturnValue", "value", "manual"]
- ["lang:core", "<crate::result::Result>::unwrap_or", "Argument[self]", "ReturnValue", "taint", "manual"]
# String
- ["lang:alloc", "<crate::string::String>::as_str", "Argument[self]", "ReturnValue", "taint", "manual"]
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,11 @@ localStep
| main.rs:229:9:229:10 | [SSA] s1 | main.rs:230:10:230:11 | s1 |
| main.rs:229:9:229:10 | s1 | main.rs:229:9:229:10 | [SSA] s1 |
| main.rs:229:14:229:29 | Some(...) | main.rs:229:9:229:10 | s1 |
| main.rs:230:23:230:23 | 0 | main.rs:230:10:230:24 | s1.unwrap_or(...) |
| main.rs:232:9:232:10 | [SSA] s2 | main.rs:233:10:233:11 | s2 |
| main.rs:232:9:232:10 | s2 | main.rs:232:9:232:10 | [SSA] s2 |
| main.rs:232:14:232:20 | Some(...) | main.rs:232:9:232:10 | s2 |
| main.rs:233:23:233:32 | source(...) | main.rs:233:10:233:33 | s2.unwrap_or(...) |
| main.rs:237:9:237:10 | [SSA] s1 | main.rs:239:14:239:15 | s1 |
| main.rs:237:9:237:10 | s1 | main.rs:237:9:237:10 | [SSA] s1 |
| main.rs:237:14:237:29 | Some(...) | main.rs:237:9:237:10 | s1 |
Expand Down Expand Up @@ -529,6 +531,9 @@ storeStep
| main.rs:407:27:407:27 | 0 | Some | main.rs:407:22:407:28 | Some(...) |
readStep
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap_or | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap_or |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::result::Result>::unwrap | Ok | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::result::Result>::unwrap_or | Ok | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap_or |
| main.rs:33:9:33:15 | Some(...) | Some | main.rs:33:14:33:14 | _ |
| main.rs:87:11:87:11 | i | &ref | main.rs:87:10:87:11 | * ... |
| main.rs:95:10:95:10 | a | tuple.0 | main.rs:95:10:95:12 | a.0 |
Expand Down
14 changes: 14 additions & 0 deletions rust/ql/test/library-tests/dataflow/local/inline-flow.expected
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
models
| 1 | Summary: lang:core; <crate::option::Option>::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
| 2 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[0]; ReturnValue; value |
| 3 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
edges
| main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | provenance | |
| main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | provenance | |
Expand Down Expand Up @@ -37,6 +39,10 @@ edges
| main.rs:224:14:224:29 | Some(...) [Some] | main.rs:225:10:225:11 | s1 [Some] | provenance | |
| main.rs:224:19:224:28 | source(...) | main.rs:224:14:224:29 | Some(...) [Some] | provenance | |
| main.rs:225:10:225:11 | s1 [Some] | main.rs:225:10:225:20 | s1.unwrap(...) | provenance | MaD:1 |
| main.rs:229:14:229:29 | Some(...) [Some] | main.rs:230:10:230:11 | s1 [Some] | provenance | |
| main.rs:229:19:229:28 | source(...) | main.rs:229:14:229:29 | Some(...) [Some] | provenance | |
| main.rs:230:10:230:11 | s1 [Some] | main.rs:230:10:230:24 | s1.unwrap_or(...) | provenance | MaD:3 |
| main.rs:233:23:233:32 | source(...) | main.rs:233:10:233:33 | s2.unwrap_or(...) | provenance | MaD:2 |
| main.rs:237:14:237:29 | Some(...) [Some] | main.rs:239:14:239:15 | s1 [Some] | provenance | |
| main.rs:237:19:237:28 | source(...) | main.rs:237:14:237:29 | Some(...) [Some] | provenance | |
| main.rs:239:14:239:15 | s1 [Some] | main.rs:239:14:239:16 | TryExpr | provenance | |
Expand Down Expand Up @@ -150,6 +156,12 @@ nodes
| main.rs:224:19:224:28 | source(...) | semmle.label | source(...) |
| main.rs:225:10:225:11 | s1 [Some] | semmle.label | s1 [Some] |
| main.rs:225:10:225:20 | s1.unwrap(...) | semmle.label | s1.unwrap(...) |
| main.rs:229:14:229:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:229:19:229:28 | source(...) | semmle.label | source(...) |
| main.rs:230:10:230:11 | s1 [Some] | semmle.label | s1 [Some] |
| main.rs:230:10:230:24 | s1.unwrap_or(...) | semmle.label | s1.unwrap_or(...) |
| main.rs:233:10:233:33 | s2.unwrap_or(...) | semmle.label | s2.unwrap_or(...) |
| main.rs:233:23:233:32 | source(...) | semmle.label | source(...) |
| main.rs:237:14:237:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:237:19:237:28 | source(...) | semmle.label | source(...) |
| main.rs:239:14:239:15 | s1 [Some] | semmle.label | s1 [Some] |
Expand Down Expand Up @@ -240,6 +252,8 @@ testFailures
| main.rs:201:33:201:33 | n | main.rs:198:27:198:36 | source(...) | main.rs:201:33:201:33 | n | $@ | main.rs:198:27:198:36 | source(...) | source(...) |
| main.rs:214:25:214:25 | n | main.rs:211:19:211:28 | source(...) | main.rs:214:25:214:25 | n | $@ | main.rs:211:19:211:28 | source(...) | source(...) |
| main.rs:225:10:225:20 | s1.unwrap(...) | main.rs:224:19:224:28 | source(...) | main.rs:225:10:225:20 | s1.unwrap(...) | $@ | main.rs:224:19:224:28 | source(...) | source(...) |
| main.rs:230:10:230:24 | s1.unwrap_or(...) | main.rs:229:19:229:28 | source(...) | main.rs:230:10:230:24 | s1.unwrap_or(...) | $@ | main.rs:229:19:229:28 | source(...) | source(...) |
| main.rs:233:10:233:33 | s2.unwrap_or(...) | main.rs:233:23:233:32 | source(...) | main.rs:233:10:233:33 | s2.unwrap_or(...) | $@ | main.rs:233:23:233:32 | source(...) | source(...) |
| main.rs:240:10:240:11 | i1 | main.rs:237:19:237:28 | source(...) | main.rs:240:10:240:11 | i1 | $@ | main.rs:237:19:237:28 | source(...) | source(...) |
| main.rs:251:10:251:11 | i1 | main.rs:246:35:246:44 | source(...) | main.rs:251:10:251:11 | i1 | $@ | main.rs:246:35:246:44 | source(...) | source(...) |
| main.rs:267:35:267:35 | n | main.rs:264:29:264:38 | source(...) | main.rs:267:35:267:35 | n | $@ | main.rs:264:29:264:38 | source(...) | source(...) |
Expand Down
4 changes: 2 additions & 2 deletions rust/ql/test/library-tests/dataflow/local/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ fn option_unwrap() {

fn option_unwrap_or() {
let s1 = Some(source(46));
sink(s1.unwrap_or(0)); // $ MISSING: hasValueFlow=46
sink(s1.unwrap_or(0)); // $ hasValueFlow=46

let s2 = Some(0);
sink(s2.unwrap_or(source(47))); // $ MISSING: hasValueFlow=47
sink(s2.unwrap_or(source(47))); // $ hasValueFlow=47
}

fn option_questionmark() -> Option<i64> {
Expand Down
4 changes: 2 additions & 2 deletions rust/ql/test/library-tests/dataflow/sources/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn test_env_vars() {
let var2 = std::env::var_os("PATH").unwrap(); // $ Alert[rust/summary/taint-sources]

sink(var1); // $ MISSING: hasTaintFlow
sink(var2); // $ MISSING: hasTaintFlow
sink(var2); // $ hasTaintFlow

for (key, value) in std::env::vars() { // $ Alert[rust/summary/taint-sources]
sink(key); // $ MISSING: hasTaintFlow
Expand Down Expand Up @@ -61,7 +61,7 @@ async fn test_reqwest() -> Result<(), reqwest::Error> {
sink(remote_string1); // $ MISSING: hasTaintFlow

let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(remote_string2); // $ MISSING: hasTaintFlow
sink(remote_string2); // $ hasTaintFlow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic!


let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources]
sink(remote_string3); // $ MISSING: hasTaintFlow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
models
| 1 | Summary: lang:alloc; <crate::string::String>::as_str; Argument[self]; ReturnValue; taint |
edges
| main.rs:20:13:20:22 | source(...) | main.rs:21:19:21:25 | s[...] | provenance | |
| main.rs:20:13:20:22 | source(...) | main.rs:22:16:22:21 | sliced | provenance | |
| main.rs:21:18:21:25 | &... [&ref] | main.rs:22:16:22:21 | sliced | provenance | |
| main.rs:21:19:21:25 | s[...] | main.rs:21:18:21:25 | &... [&ref] | provenance | |
| main.rs:26:14:26:23 | source(...) | main.rs:32:10:32:11 | s4 | provenance | |
| main.rs:37:14:37:23 | source(...) | main.rs:40:10:40:35 | ... + ... | provenance | |
| main.rs:57:13:57:22 | source(...) | main.rs:58:16:58:16 | s | provenance | |
| main.rs:58:16:58:16 | s | main.rs:58:16:58:25 | s.as_str(...) | provenance | MaD:1 |
nodes
| main.rs:20:13:20:22 | source(...) | semmle.label | source(...) |
| main.rs:21:18:21:25 | &... [&ref] | semmle.label | &... [&ref] |
Expand All @@ -15,9 +18,13 @@ nodes
| main.rs:32:10:32:11 | s4 | semmle.label | s4 |
| main.rs:37:14:37:23 | source(...) | semmle.label | source(...) |
| main.rs:40:10:40:35 | ... + ... | semmle.label | ... + ... |
| main.rs:57:13:57:22 | source(...) | semmle.label | source(...) |
| main.rs:58:16:58:16 | s | semmle.label | s |
| main.rs:58:16:58:25 | s.as_str(...) | semmle.label | s.as_str(...) |
subpaths
testFailures
#select
| main.rs:22:16:22:21 | sliced | main.rs:20:13:20:22 | source(...) | main.rs:22:16:22:21 | sliced | $@ | main.rs:20:13:20:22 | source(...) | source(...) |
| main.rs:32:10:32:11 | s4 | main.rs:26:14:26:23 | source(...) | main.rs:32:10:32:11 | s4 | $@ | main.rs:26:14:26:23 | source(...) | source(...) |
| main.rs:40:10:40:35 | ... + ... | main.rs:37:14:37:23 | source(...) | main.rs:40:10:40:35 | ... + ... | $@ | main.rs:37:14:37:23 | source(...) | source(...) |
| main.rs:58:16:58:25 | s.as_str(...) | main.rs:57:13:57:22 | source(...) | main.rs:58:16:58:25 | s.as_str(...) | $@ | main.rs:57:13:57:22 | source(...) | source(...) |
2 changes: 1 addition & 1 deletion rust/ql/test/library-tests/dataflow/strings/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Taint tests for strings

fn source(i: i64) -> String {

Check notice

Code scanning / CodeQL

Unused variable Note test

Variable 'i' is not used.
format!("{}", i)
}

Expand All @@ -8,11 +8,11 @@
"source"
}

fn sink_slice(s: &str) {

Check notice

Code scanning / CodeQL

Unused variable Note test

Variable 's' is not used.
println!("{}", s);
}

fn sink(s: String) {

Check notice

Code scanning / CodeQL

Unused variable Note test

Variable 's' is not used.
println!("{}", s);
}

Expand Down Expand Up @@ -55,7 +55,7 @@

fn as_str() {
let s = source(67);
sink_slice(s.as_str()); // $ MISSING: hasTaintFlow=67
sink_slice(s.as_str()); // $ hasTaintFlow=67
}

fn string_format() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
| file://:0:0:0:0 | [summary param] self in lang:alloc::_::<crate::string::String>::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::string::String>::as_str | MaD:11 |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap | MaD:2 |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap_or | MaD:5 |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::result::Result>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::unwrap | MaD:7 |
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::result::Result>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::unwrap_or | MaD:10 |
| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | MaD:0 |
| main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | |
| main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | |
| main.rs:13:10:13:10 | a | main.rs:13:10:13:14 | ... + ... | |
Expand Down
Loading
Loading