Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
88 changes: 69 additions & 19 deletions rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll
Original file line number Diff line number Diff line change
Expand Up @@ -128,38 +128,35 @@
}

private predicate summaryModelRelevant(
Function f, string input, string output, string kind, Provenance provenance,
Function f, string input, string output, string kind, Provenance provenance, boolean isInherited,
QlBuiltins::ExtensionId madId
) {
exists(boolean isInherited |
summaryModel(f, input, output, kind, provenance, isInherited, madId)
|
// Only apply generated or inherited models to functions in library code and
// when no strictly better model exists
if provenance.isGenerated() or isInherited = true
then
not f.fromSource() and
not exists(Provenance other | summaryModel(f, _, _, _, other, false, _) |
provenance.isGenerated() and other.isManual()
or
provenance = other and isInherited = true
)
else any()
)
summaryModel(f, input, output, kind, provenance, isInherited, madId) and
// Only apply generated or inherited models to functions in library code and
// when no strictly better model exists
if provenance.isGenerated() or isInherited = true
then
not f.fromSource() and
not exists(Provenance other | summaryModel(f, _, _, _, other, false, _) |
provenance.isGenerated() and other.isManual()
or
provenance = other and isInherited = true
)
else any()
}

private class SummarizedCallableFromModel extends SummarizedCallable::Range {
SummarizedCallableFromModel() { summaryModelRelevant(this, _, _, _, _, _) }
SummarizedCallableFromModel() { summaryModelRelevant(this, _, _, _, _, _, _) }

override predicate hasProvenance(Provenance provenance) {
summaryModelRelevant(this, _, _, _, provenance, _)
summaryModelRelevant(this, _, _, _, provenance, _, _)
}

override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
exists(string kind, QlBuiltins::ExtensionId madId |
summaryModelRelevant(this, input, output, kind, _, madId) and
summaryModelRelevant(this, input, output, kind, _, _, madId) and
model = "MaD:" + madId.toString()
|
kind = "value" and
Expand Down Expand Up @@ -202,3 +199,56 @@
)
}
}

private module Debug {
private import FlowSummaryImpl
private import Private
private import Content
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.internal.TypeMention
private import codeql.rust.internal.Type

private predicate relevantManualModel(SummarizedCallableImpl sc, string can) {

Check warning

Code scanning / CodeQL

Dead code Warning

This code is never used, and it's not publicly exported.
exists(Provenance manual |
can = sc.getCanonicalPath() and
summaryModelRelevant(sc, _, _, _, manual, false, _) and
manual.isManual()
)
}

predicate manualModelMissingParameterReference(
SummarizedCallableImpl sc, string can, SummaryComponentStack input, ParamBase p
) {
exists(RustDataFlow::ParameterPosition pos, TypeMention tm |
relevantManualModel(sc, can) and
sc.propagatesFlow(input, _, _, _) and
input.head() = SummaryComponent::argument(pos) and
p = pos.getParameterIn(sc.getParamList()) and
tm.resolveType() instanceof RefType and
not input.tail().head() = SummaryComponent::content(TSingletonContentSet(TReferenceContent()))
|
tm = p.getTypeRepr()
or
tm = getSelfParamTypeMention(p)
)
}

predicate manualModelMissingReturnReference(

Check warning

Code scanning / CodeQL

Dead code Warning

This code is never used, and it's not publicly exported.
SummarizedCallableImpl sc, string can, SummaryComponentStack output
) {
exists(TypeMention tm |
relevantManualModel(sc, can) and
sc.propagatesFlow(_, output, _, _) and
tm.resolveType() instanceof RefType and
output.head() = SummaryComponent::return(_) and
not output.tail().head() =
SummaryComponent::content(TSingletonContentSet(TReferenceContent())) and
tm = getReturnTypeMention(sc) and
not can =
[
"<& as core::ops::deref::Deref>::deref",
"<&mut as core::ops::deref::Deref>::deref"
]
)
}
}
1 change: 0 additions & 1 deletion rust/ql/lib/codeql/rust/frameworks/futures.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ extensions:
data:
- ["futures_executor::local_pool::block_on", "Argument[0]", "ReturnValue", "value", "manual"]
- ["<futures_util::io::buf_reader::BufReader>::new", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["<_ as futures_util::io::AsyncReadExt>::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["<_ as futures_util::io::AsyncReadExt>::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["<_ as futures_util::io::AsyncReadExt>::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["<_ as futures_util::io::AsyncBufReadExt>::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
Expand Down
6 changes: 3 additions & 3 deletions rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ extensions:
- ["<core::alloc::layout::Layout>::pad_to_align", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
- ["<core::alloc::layout::Layout>::size", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
# String
- ["<alloc::string::String>::as_str", "Argument[self]", "ReturnValue", "value", "manual"]
- ["<alloc::string::String>::as_bytes", "Argument[self]", "ReturnValue", "value", "manual"]
- ["<alloc::string::String>::as_str", "Argument[self].Reference", "ReturnValue.Reference", "taint", "manual"]
- ["<alloc::string::String>::as_bytes", "Argument[self].Reference", "ReturnValue.Reference.Element", "taint", "manual"]
- ["<_ as alloc::string::ToString>::to_string", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
# Overwrite generated model
- ["<alloc::string::String as core::ops::arith::Add>::add", "Argument[self,0]", "ReturnValue", "taint", "manual"]
- ["<alloc::string::String as core::ops::arith::Add>::add", "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 thought there was some kind of edge case behind the overlapping .Reference and non-.Reference models here. Something to do with appending &str strings perhaps, I can't remember exactly. Still, as this stuff is well tested and I see no regressions in the tests, I'm happy.

Alternative possible explanation: the incorrect models were only required for compatibility with other incorrect models elsewhere, which you've already updated.

- ["<alloc::string::String as core::ops::arith::Add>::add", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
# Vec
- ["alloc::vec::from_elem", "Argument[0]", "ReturnValue.Element", "value", "manual"]
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ extensions:
- ["<core::pin::Pin as core::ops::deref::Deref>::deref", "Argument[self].Reference.Field[core::pin::Pin::pointer].Reference", "ReturnValue.Reference", "value", "manual"]
- ["<core::pin::Pin as core::ops::deref::Deref>::deref", "Argument[self].Reference.Field[core::pin::Pin::pointer].Field[alloc::boxed::Box(0)]", "ReturnValue.Reference", "value", "manual"]
# Str
- ["<core::str>::as_str", "Argument[self]", "ReturnValue", "value", "manual"]
- ["<core::str>::as_str", "Argument[self].Reference", "ReturnValue.Reference", "taint", "manual"]
- ["<core::str>::as_bytes", "Argument[self].Reference", "ReturnValue.Reference", "taint", "manual"]
- ["<core::str>::parse", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["<core::str>::trim", "Argument[self].Reference", "ReturnValue.Reference", "taint", "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 @@ -61,7 +61,7 @@ extensions:
- ["<std::path::PathBuf>::as_path", "Argument[self].Reference", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::PathBuf>::into_boxed_path", "Argument[self]", "ReturnValue.Field[alloc::boxed::Box(0)]", "taint", "manual"]
- ["<std::path::Path>::new", "Argument[0].Reference", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::Path>::join", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["<std::path::Path>::join", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
- ["<std::path::Path>::join", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["<std::path::Path>::as_os_str", "Argument[self].Reference.Field[std::path::Path::inner]", "ReturnValue.Reference", "value", "manual"]
- ["<std::path::Path>::as_mut_os_str", "Argument[self].Reference.Field[std::path::Path::inner]", "ReturnValue.Reference", "value", "manual"]
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/frameworks/stdlib/net.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ extensions:
pack: codeql/rust-all
extensible: summaryModel
data:
- ["<std::net::tcp::TcpStream>::try_clone", "Argument[self]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["<std::net::tcp::TcpStream>::try_clone", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
Loading
Loading