Skip to content

Commit 63329b4

Browse files
authored
Merge pull request #21036 from paldepind/rust/prioritize-manual-summaries
Rust: Don't apply generated models for functions that have a manual model
2 parents d709343 + 8c4b81e commit 63329b4

File tree

7 files changed

+716
-677
lines changed

7 files changed

+716
-677
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,15 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
123123
summaryModel(path, _, _, _, provenance, _)
124124
}
125125

126+
private predicate hasManualModel() { summaryModel(path, _, _, _, "manual", _) }
127+
126128
override predicate propagatesFlow(
127129
string input, string output, boolean preservesValue, string model
128130
) {
129-
exists(string kind, QlBuiltins::ExtensionId madId |
130-
summaryModel(path, input, output, kind, _, madId) and
131-
model = "MaD:" + madId.toString()
131+
exists(string kind, string provenance, QlBuiltins::ExtensionId madId |
132+
summaryModel(path, input, output, kind, provenance, madId) and
133+
model = "MaD:" + madId.toString() and
134+
(provenance = "manual" or not this.hasManualModel())
132135
|
133136
kind = "value" and
134137
preservesValue = true

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ extensions:
9696
- ["<_ as core::iter::traits::iterator::Iterator>::take", "Argument[self]", "ReturnValue", "taint", "manual"]
9797
# Pin
9898
- ["<core::pin::Pin>::new", "Argument[0]", "ReturnValue.Field[core::pin::Pin::pointer]", "value", "manual"]
99+
# This model is not precise, but helps in cases where a `Pin` is implicitly dereferenced.
100+
- ["<core::pin::Pin>::new", "Argument[0].Reference", "ReturnValue", "value", "manual"]
99101
- ["<core::pin::Pin>::new_unchecked", "Argument[0]", "ReturnValue.Field[core::pin::Pin::pointer]", "value", "manual"]
100102
- ["<core::pin::Pin>::into_inner", "Argument[0].Field[core::pin::Pin::pointer]", "ReturnValue", "value", "manual"]
101103
- ["<core::pin::Pin>::into_inner_unchecked", "Argument[0].Field[core::pin::Pin::pointer]", "ReturnValue", "value", "manual"]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extensions:
5858
data:
5959
- ["std::fs::canonicalize", "Argument[0].OptionalStep[normalize-path]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
6060
- ["std::fs::canonicalize", "Argument[0].OptionalBarrier[normalize-path]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
61-
- ["<std::path::PathBuf>::as_path", "Argument[Self]", "ReturnValue.Reference", "value", "manual"]
61+
- ["<std::path::PathBuf>::as_path", "Argument[self].Reference", "ReturnValue.Reference", "value", "manual"]
6262
- ["<std::path::PathBuf>::as_mut_os_string", "Argument[Self].Reference", "ReturnValue.Reference", "value", "manual"]
6363
- ["<std::path::PathBuf>::into_os_string", "Argument[Self]", "ReturnValue", "value", "manual"]
6464
- ["<std::path::PathBuf>::into_boxed_path", "Argument[Self]", "ReturnValue.Reference", "value", "manual"]

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ enum MyPosEnum {
3131
B(i64),
3232
}
3333

34+
// has a manual flow model with flow from second argument to the return value
35+
// and a wrong generated model with flow from first argument to the return value
36+
fn snd(a: i64, b: i64) -> i64 {
37+
0
38+
}
39+
40+
fn test_snd() {
41+
let s1 = source(99);
42+
sink(snd(0, s1)); // $ hasValueFlow=99
43+
44+
let s2 = source(88);
45+
sink(snd(s2, 0));
46+
}
47+
3448
// has a flow model
3549
fn get_var_pos(e: MyPosEnum) -> i64 {
3650
0

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

Lines changed: 689 additions & 672 deletions
Large diffs are not rendered by default.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ extensions:
2020
extensible: summaryModel
2121
data:
2222
- ["main::coerce", "Argument[0]", "ReturnValue", "taint", "manual"]
23+
- ["main::snd", "Argument[1]", "ReturnValue", "value", "manual"]
24+
# Wrong generated model which should not take effect due to the manual model above
25+
- ["main::snd", "Argument[0]", "ReturnValue", "value", "dfc-generated"]
2326
- ["main::get_var_pos", "Argument[0].Field[main::MyPosEnum::A(0)]", "ReturnValue", "value", "manual"]
2427
- ["main::set_var_pos", "Argument[0]", "ReturnValue.Field[main::MyPosEnum::B(0)]", "value", "manual"]
2528
- ["main::get_var_field", "Argument[0].Field[main::MyFieldEnum::C::field_c]", "ReturnValue", "value", "manual"]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ models
3535
| 34 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self].Reference; Argument[0].Reference; taint |
3636
| 35 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
3737
| 36 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
38-
| 37 | Summary: <std::path::PathBuf>::as_path; Argument[self]; ReturnValue; value |
38+
| 37 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
3939
edges
4040
| test.rs:12:13:12:18 | buffer | test.rs:13:14:13:19 | buffer | provenance | |
4141
| test.rs:12:31:12:43 | ...::read | test.rs:12:31:12:55 | ...::read(...) [Ok] | provenance | Src:MaD:11 |

0 commit comments

Comments
 (0)