Skip to content

Rust: Update legacy MaD models 4 #19948

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extensions:
- addsTo:
pack: codeql/rust-all
extensible: sourceModelDeprecated
extensible: sourceModel
data:
- ["repo:https://github.com/async-rs/async-std:async-std", "<crate::net::tcp::stream::TcpStream>::connect", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "remote", "manual"]
- ["<async_std::net::tcp::stream::TcpStream>::connect", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "remote", "manual"]
30 changes: 15 additions & 15 deletions rust/ql/lib/codeql/rust/frameworks/futures.model.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
extensions:
- addsTo:
pack: codeql/rust-all
extensible: summaryModelDeprecated
extensible: summaryModel
data:
- ["repo:https://github.com/rust-lang/futures-rs:futures-executor", "crate::local_pool::block_on", "Argument[0]", "ReturnValue", "value", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "<crate::io::buf_reader::BufReader>::new", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_line", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_until", "Argument[self]", "Argument[1].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_until", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::fill_buf", "Argument[self]", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::lines", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::stream::stream::StreamExt::next", "Argument[self]", "ReturnValue.Future.Field[core::option::Option::Some(0)]", "taint", "manual"]
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "<crate::io::buf_reader::BufReader as crate::if_std::AsyncBufRead>::poll_fill_buf", "Argument[self].Reference", "ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["futures_executor::local_pool::block_on", "Argument[0]", "ReturnValue", "value", "manual"]
- ["<futures_util::io::buf_reader::BufReader>::new", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_line", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_until", "Argument[self]", "Argument[1].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_until", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::fill_buf", "Argument[self]", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::lines", "Argument[self]", "ReturnValue", "taint", "manual"]
Comment on lines +8 to +17
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be futures_util.

Suggested change
- ["futures-util::io::AsyncReadExt::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncReadExt::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_line", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_until", "Argument[self]", "Argument[1].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::read_until", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::fill_buf", "Argument[self]", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["futures-util::io::AsyncBufReadExt::lines", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["futures_util::io::AsyncReadExt::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncReadExt::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncReadExt::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncReadExt::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::read_line", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::read_until", "Argument[self]", "Argument[1].Reference", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::read_until", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::fill_buf", "Argument[self]", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "taint", "manual"]
- ["futures_util::io::AsyncBufReadExt::lines", "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.

Actually might need to be <_ as futures_util::io::AsyncReadExt>::read etc.

- ["<alloc::boxed::Box as core::iter::traits::iterator::Iterator>::next", "Argument[self]", "ReturnValue.Future.Field[core::option::Option::Some(0)]", "taint", "manual"]
- ["<futures-util::io::buf_reader::BufReader as futures_io::if_std::AsyncBufRead>::poll_fill_buf", "Argument[self].Reference", "ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]", "taint", "manual"]
19 changes: 12 additions & 7 deletions rust/ql/lib/codeql/rust/frameworks/libc.model.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
extensions:
- addsTo:
pack: codeql/rust-all
extensible: sourceModelDeprecated
extensible: sourceModel
data:
- ["repo:https://github.com/rust-lang/libc:libc", "::free", "Argument[0]", "pointer-invalidate", "manual"]
- ["libc::unix::free", "Argument[0]", "pointer-invalidate", "manual"]
- ["libc::windows::free", "Argument[0]", "pointer-invalidate", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sinkModelDeprecated
extensible: sinkModel
data:
- ["repo:https://github.com/rust-lang/libc:libc", "::malloc", "Argument[0]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::aligned_alloc", "Argument[1]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::calloc", "Argument[0,1]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::realloc", "Argument[1]", "alloc-size", "manual"]
- ["libc::unix::malloc", "Argument[0]", "alloc-size", "manual"]
- ["libc::windows::malloc", "Argument[0]", "alloc-size", "manual"]
- ["libc::unix::aligned_alloc", "Argument[1]", "alloc-size", "manual"]
- ["libc::windows::aligned_alloc", "Argument[1]", "alloc-size", "manual"]
- ["libc::unix::calloc", "Argument[0,1]", "alloc-size", "manual"]
- ["libc::windows::calloc", "Argument[0,1]", "alloc-size", "manual"]
- ["libc::unix::realloc", "Argument[1]", "alloc-size", "manual"]
- ["libc::windows::realloc", "Argument[1]", "alloc-size", "manual"]
4 changes: 2 additions & 2 deletions rust/ql/lib/codeql/rust/frameworks/stdlib/io.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ extensions:
- ["lang:std", "<crate::io::stdio::StdinLock as crate::io::Read>::read_to_string", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "<crate::fs::File as crate::io::Read>::read_to_string", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "crate::io::Read::read_to_string", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", ":<crate::io::stdio::Stdin as crate::io::Read>::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", ":<crate::io::stdio::StdinLock as crate::io::Read>::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "<crate::io::stdio::Stdin as crate::io::Read>::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "<crate::io::stdio::StdinLock as crate::io::Read>::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "<crate::fs::File as crate::io::Read>::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "crate::io::Read::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
- ["lang:std", "<crate::io::stdio::Stdin as crate::io::Read>::read_exact", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
models
| 1 | Summary: repo:https://github.com/rust-lang/futures-rs:futures-executor; crate::local_pool::block_on; Argument[0]; ReturnValue; value |
| 1 | Summary: futures_executor::local_pool::block_on; Argument[0]; ReturnValue; value |
edges
| main.rs:12:28:14:1 | { ... } | main.rs:17:13:17:23 | get_data(...) | provenance | |
| main.rs:13:5:13:13 | source(...) | main.rs:12:28:14:1 | { ... } | provenance | |
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/test/library-tests/dataflow/sources/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ fn test_io_stdin() -> std::io::Result<()> {
{
let mut buffer = Vec::<u8>::new();
let _bytes = std::io::stdin().read_to_end(&mut buffer)?; // $ Alert[rust/summary/taint-sources]
sink(&buffer); // $ hasTaintFlow -- @hvitved: works in CI, but not for me locally
sink(&buffer); // $ hasTaintFlow
}

{
Expand Down
12 changes: 6 additions & 6 deletions rust/ql/test/library-tests/dataflow/sources/test_futures_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn test_futures_rustls_futures_io() -> io::Result<()> {
// using the `AsyncReadExt::read` extension method (higher-level)
let mut buffer1 = [0u8; 64];
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader, &mut buffer1).await?;
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url
sink(&buffer1[..bytes_read1]); // $ MISSING: hasTaintFlow=url

let mut buffer2 = [0u8; 64];
let bytes_read2 = reader.read(&mut buffer2).await?; // we cannot resolve the `read` call, which comes from `impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}` in `async_read_ext.rs`
Expand All @@ -61,16 +61,16 @@ async fn test_futures_rustls_futures_io() -> io::Result<()> {
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
let buffer = pinned.poll_fill_buf(&mut cx);
if let Poll::Ready(Ok(buf)) = buffer {
sink(&buffer); // $ hasTaintFlow=url
sink(&buffer); // $ MISSING: hasTaintFlow=url
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently the computed canonical path for this function is <core::pin::Pin as tokio::io::async_buf_read::AsyncBufRead>::poll_fill_buf which makes very little sense. I guess we should implement some auto-unpinning or something @hvitved , what do you think?

Copy link
Contributor

@aibaars aibaars Jul 8, 2025

Choose a reason for hiding this comment

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

Hmm the impl<P> AsyncBufRead for Pin<P> actually exists in futures-io so that canonical path is perhaps fine. Although rust-analyzer resolves the call to impl<R: AsyncRead> AsyncBufRead for BufReader<R> from futures-util. Not sure which one is best. I guess if the Pin version is in scope then it would make sense, if not, then rust-analyzer is probably right and we should have auto-unpinned somehow.

sink(buf); // $ MISSING: hasTaintFlow=url
}

// using the `AsyncBufRead` trait (alternative syntax)
let buffer2 = Pin::new(&mut reader2).poll_fill_buf(&mut cx);
match (buffer2) {
Poll::Ready(Ok(buf)) => {
sink(&buffer2); // $ hasTaintFlow=url
sink(buf); // $ hasTaintFlow=url
sink(&buffer2); // $ MISSING: hasTaintFlow=url
sink(buf); // $ MISSING: hasTaintFlow=url
}
_ => {
// ...
Expand Down Expand Up @@ -101,7 +101,7 @@ async fn test_futures_rustls_futures_io() -> io::Result<()> {
// using the `AsyncReadExt::read` extension method (higher-level)
let mut buffer1 = [0u8; 64];
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader2, &mut buffer1).await?;
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url
sink(&buffer1[..bytes_read1]); // $ MISSING: hasTaintFlow=url

let mut buffer2 = [0u8; 64];
let bytes_read2 = reader2.read(&mut buffer2).await?; // we cannot resolve the `read` call, which comes from `impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}` in `async_read_ext.rs`
Expand All @@ -114,7 +114,7 @@ async fn test_futures_rustls_futures_io() -> io::Result<()> {
sink(&pinned); // $ hasTaintFlow=url
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
let buffer = pinned.poll_fill_buf(&mut cx);
sink(&buffer); // $ hasTaintFlow=url
sink(&buffer); // $ MISSING: hasTaintFlow=url
if let Poll::Ready(Ok(buf)) = buffer {
sink(buf); // $ MISSING: hasTaintFlow=url
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ models
| 23 | Sink: lang:std; <crate::alloc::System as crate::alloc::Allocator>::grow_zeroed; Argument[2]; alloc-layout |
| 24 | Sink: lang:std; <crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc; Argument[0]; alloc-layout |
| 25 | Sink: lang:std; <crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc_zeroed; Argument[0]; alloc-layout |
| 26 | Sink: repo:https://github.com/rust-lang/libc:libc; ::aligned_alloc; Argument[1]; alloc-size |
| 27 | Sink: repo:https://github.com/rust-lang/libc:libc; ::calloc; Argument[0,1]; alloc-size |
| 28 | Sink: repo:https://github.com/rust-lang/libc:libc; ::malloc; Argument[0]; alloc-size |
| 29 | Sink: repo:https://github.com/rust-lang/libc:libc; ::realloc; Argument[1]; alloc-size |
| 26 | Sink: libc::unix::aligned_alloc; Argument[1]; alloc-size |
| 27 | Sink: libc::unix::calloc; Argument[0,1]; alloc-size |
| 28 | Sink: libc::unix::malloc; Argument[0]; alloc-size |
| 29 | Sink: libc::unix::realloc; Argument[1]; alloc-size |
| 30 | Source: std::env::args; ReturnValue.Element; commandargs |
| 31 | Summary: <core::alloc::layout::Layout>::from_size_align_unchecked; Argument[0]; ReturnValue.Field[core::alloc::layout::Layout::size]; value |
| 32 | Summary: <core::alloc::layout::Layout>::size; Argument[self].Field[core::alloc::layout::Layout::size]; ReturnValue; value |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ models
| 7 | Source: lang:core; crate::ptr::dangling_mut; ReturnValue; pointer-invalidate |
| 8 | Source: lang:core; crate::ptr::drop_in_place; Argument[0]; pointer-invalidate |
| 9 | Source: lang:core; crate::ptr::null; ReturnValue; pointer-invalidate |
| 10 | Source: repo:https://github.com/rust-lang/libc:libc; ::free; Argument[0]; pointer-invalidate |
| 10 | Source: libc::unix::free; Argument[0]; pointer-invalidate |
nodes
| deallocation.rs:20:3:20:21 | ...::dealloc | semmle.label | ...::dealloc |
| deallocation.rs:20:23:20:24 | [post] m1 | semmle.label | [post] m1 |
Expand Down