Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
summaryModel(path, _, _, _, provenance, _)
}

private predicate hasManualModel() { summaryModel(path, _, _, _, "manual", _) }

override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
exists(string kind, QlBuiltins::ExtensionId madId |
summaryModel(path, input, output, kind, _, madId) and
model = "MaD:" + madId.toString()
exists(string kind, string provenance, QlBuiltins::ExtensionId madId |
summaryModel(path, input, output, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
(provenance = "manual" or not this.hasManualModel())
|
kind = "value" and
preservesValue = true
Expand Down
2 changes: 2 additions & 0 deletions rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ extensions:
- ["<_ as core::iter::traits::iterator::Iterator>::take", "Argument[self]", "ReturnValue", "taint", "manual"]
# Pin
- ["<core::pin::Pin>::new", "Argument[0]", "ReturnValue.Field[core::pin::Pin::pointer]", "value", "manual"]
# This model is not precise, but helps in cases the a `Pin` is implicitly dereferenced.
- ["<core::pin::Pin>::new", "Argument[0].Reference", "ReturnValue", "value", "manual"]
- ["<core::pin::Pin>::new_unchecked", "Argument[0]", "ReturnValue.Field[core::pin::Pin::pointer]", "value", "manual"]
- ["<core::pin::Pin>::into_inner", "Argument[0].Field[core::pin::Pin::pointer]", "ReturnValue", "value", "manual"]
- ["<core::pin::Pin>::into_inner_unchecked", "Argument[0].Field[core::pin::Pin::pointer]", "ReturnValue", "value", "manual"]
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ extensions:
data:
- ["std::fs::canonicalize", "Argument[0].OptionalStep[normalize-path]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["std::fs::canonicalize", "Argument[0].OptionalBarrier[normalize-path]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["<std::path::PathBuf>::as_path", "Argument[Self]", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::PathBuf>::as_path", "Argument[self].Reference", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::PathBuf>::as_mut_os_string", "Argument[Self].Reference", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::PathBuf>::into_os_string", "Argument[Self]", "ReturnValue", "value", "manual"]
- ["<std::path::PathBuf>::into_boxed_path", "Argument[Self]", "ReturnValue.Reference", "value", "manual"]
Expand Down
14 changes: 14 additions & 0 deletions rust/ql/test/library-tests/dataflow/models/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ enum MyPosEnum {
B(i64),
}

// has a manual flow model with flow from second argument to the return value
// and a wrong generated model with flow from first argument to the return value
fn snd(a: i64, b: i64) -> i64 {
0
}

fn test_snd() {
let s1 = source(99);
sink(snd(0, s1)); // $ hasValueFlow=99

let s2 = source(88);
sink(snd(s2, 0));
}

// has a flow model
fn get_var_pos(e: MyPosEnum) -> i64 {
0
Expand Down
1,361 changes: 689 additions & 672 deletions rust/ql/test/library-tests/dataflow/models/models.expected

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions rust/ql/test/library-tests/dataflow/models/models.ext.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ extensions:
extensible: summaryModel
data:
- ["main::coerce", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["main::snd", "Argument[1]", "ReturnValue", "value", "manual"]
# Wrong generated model which should not take effect due to the manual model above
- ["main::snd", "Argument[0]", "ReturnValue", "value", "dfc-generated"]
- ["main::get_var_pos", "Argument[0].Field[main::MyPosEnum::A(0)]", "ReturnValue", "value", "manual"]
- ["main::set_var_pos", "Argument[0]", "ReturnValue.Field[main::MyPosEnum::B(0)]", "value", "manual"]
- ["main::get_var_field", "Argument[0].Field[main::MyFieldEnum::C::field_c]", "ReturnValue", "value", "manual"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ models
| 34 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self].Reference; Argument[0].Reference; taint |
| 35 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 36 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
| 37 | Summary: <std::path::PathBuf>::as_path; Argument[self]; ReturnValue; value |
| 37 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
edges
| test.rs:12:13:12:18 | buffer | test.rs:13:14:13:19 | buffer | provenance | |
| test.rs:12:31:12:43 | ...::read | test.rs:12:31:12:55 | ...::read(...) [Ok] | provenance | Src:MaD:11 |
Expand Down