From b4e2188d2a23bd2360ffccd8d1ca1ee834c0857c Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Thu, 22 Oct 2026 10:26:58 +0200 Subject: [PATCH] Rust: Add neutral models for spurious Vec and VecDeque sink models --- .../2026-10-22-neutral-models-vec-vecdeque.md | 4 +++ .../rust/frameworks/stdlib/alloc.model.yml | 26 +++++++++++++++++++ .../security/CWE-312/test_logging.rs | 21 +++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 rust/ql/lib/change-notes/2026-10-22-neutral-models-vec-vecdeque.md diff --git a/rust/ql/lib/change-notes/2026-10-22-neutral-models-vec-vecdeque.md b/rust/ql/lib/change-notes/2026-10-22-neutral-models-vec-vecdeque.md new file mode 100644 index 000000000000..53ebd1cc4d3f --- /dev/null +++ b/rust/ql/lib/change-notes/2026-10-22-neutral-models-vec-vecdeque.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added neutral models to inhibit spurious generated sink models for `Vec` and `VecDeque` methods such as `insert`, `remove` and `push_back`. This fixes some false positive results from queries such as `rust/cleartext-logging`. diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml index 67edf4eadfaf..21909e7a428e 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml @@ -70,3 +70,29 @@ extensions: - ["::from", "sink", "manual"] - ["::split_off", "sink", "manual"] - ["::split_off", "sink", "manual"] + - ["::insert", "sink", "manual"] + - ["::insert_mut", "sink", "manual"] + - ["::remove", "sink", "manual"] + - ["::swap_remove", "sink", "manual"] + - ["::spec_extend", "sink", "manual"] + - ["::extend_one", "sink", "manual"] + - ["::extend_reserve", "sink", "manual"] + - ["::write_all_vectored", "sink", "manual"] + - ["::write_vectored", "sink", "manual"] + - ["::append", "sink", "manual"] + - ["::insert", "sink", "manual"] + - ["::insert_mut", "sink", "manual"] + - ["::make_contiguous", "sink", "manual"] + - ["::push_back", "sink", "manual"] + - ["::push_back_mut", "sink", "manual"] + - ["::push_front", "sink", "manual"] + - ["::push_front_mut", "sink", "manual"] + - ["::remove", "sink", "manual"] + - ["::reserve", "sink", "manual"] + - ["::reserve_exact", "sink", "manual"] + - ["::rotate_left", "sink", "manual"] + - ["::rotate_right", "sink", "manual"] + - ["::shrink_to", "sink", "manual"] + - ["::shrink_to_fit", "sink", "manual"] + - ["::try_reserve", "sink", "manual"] + - ["::try_reserve_exact", "sink", "manual"] diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs index d9dc9952086a..2936cb4f538b 100644 --- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs +++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs @@ -251,6 +251,26 @@ fn test_std(password: String, i: i32, opt_i: Option) { err.write(format!("message = {}\n", password).as_bytes()); // $ Alert[rust/cleartext-logging] } +fn test_collections(harmless: String) { + // collection operations are not logging + let mut passwords = Vec::new(); + passwords.insert(0, harmless.clone()); + passwords.insert(1, harmless.clone()); + _ = passwords.remove(1); + _ = passwords.swap_remove(0); + + let mut password_queue = std::collections::VecDeque::new(); + password_queue.push_back(harmless.clone()); + password_queue.push_front(harmless.clone()); + password_queue.insert(1, harmless.clone()); + password_queue.append(&mut std::collections::VecDeque::from([harmless])); + password_queue.reserve(1); + password_queue.rotate_left(1); + password_queue.shrink_to(1); + _ = password_queue.remove(1); + password_queue.make_contiguous(); +} + fn main() { simple_logger::SimpleLogger::new().init().unwrap(); @@ -260,4 +280,5 @@ fn main() { "[encrypted]".to_string(), ); test_std("123456".to_string(), 0, None); + test_collections("harmless".to_string()); }