From 533aa7fc268a2ac7c51ed0d27d59b617e2945b7a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 May 2025 18:34:33 +0100 Subject: [PATCH 1/4] Rust: Add tests for std::Pin. --- .../dataflow/modeled/inline-flow.expected | 16 ++++++ .../library-tests/dataflow/modeled/main.rs | 55 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected index b7afe9dae35b..b8d2136fcc02 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected @@ -55,6 +55,12 @@ edges | main.rs:84:29:84:29 | [post] y [&ref] | main.rs:85:33:85:33 | y [&ref] | provenance | | | main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:7 | | main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:6 | +| main.rs:100:13:100:17 | mut i | main.rs:105:14:105:14 | i | provenance | | +| main.rs:100:21:100:30 | source(...) | main.rs:100:13:100:17 | mut i | provenance | | +| main.rs:114:13:114:18 | mut ms [MyStruct] | main.rs:119:14:119:15 | ms [MyStruct] | provenance | | +| main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | main.rs:114:13:114:18 | mut ms [MyStruct] | provenance | | +| main.rs:114:38:114:47 | source(...) | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | provenance | | +| main.rs:119:14:119:15 | ms [MyStruct] | main.rs:119:14:119:19 | ms.val | provenance | | nodes | main.rs:12:9:12:9 | a [Some] | semmle.label | a [Some] | | main.rs:12:13:12:28 | Some(...) [Some] | semmle.label | Some(...) [Some] | @@ -108,6 +114,14 @@ nodes | main.rs:84:32:84:41 | source(...) | semmle.label | source(...) | | main.rs:85:18:85:34 | ...::read(...) | semmle.label | ...::read(...) | | main.rs:85:33:85:33 | y [&ref] | semmle.label | y [&ref] | +| main.rs:100:13:100:17 | mut i | semmle.label | mut i | +| main.rs:100:21:100:30 | source(...) | semmle.label | source(...) | +| main.rs:105:14:105:14 | i | semmle.label | i | +| main.rs:114:13:114:18 | mut ms [MyStruct] | semmle.label | mut ms [MyStruct] | +| main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | semmle.label | MyStruct {...} [MyStruct] | +| main.rs:114:38:114:47 | source(...) | semmle.label | source(...) | +| main.rs:119:14:119:15 | ms [MyStruct] | semmle.label | ms [MyStruct] | +| main.rs:119:14:119:19 | ms.val | semmle.label | ms.val | subpaths testFailures #select @@ -121,3 +135,5 @@ testFailures | main.rs:47:38:47:38 | n | main.rs:41:30:41:39 | source(...) | main.rs:47:38:47:38 | n | $@ | main.rs:41:30:41:39 | source(...) | source(...) | | main.rs:63:22:63:22 | m | main.rs:58:22:58:31 | source(...) | main.rs:63:22:63:22 | m | $@ | main.rs:58:22:58:31 | source(...) | source(...) | | main.rs:85:18:85:34 | ...::read(...) | main.rs:84:32:84:41 | source(...) | main.rs:85:18:85:34 | ...::read(...) | $@ | main.rs:84:32:84:41 | source(...) | source(...) | +| main.rs:105:14:105:14 | i | main.rs:100:21:100:30 | source(...) | main.rs:105:14:105:14 | i | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:119:14:119:19 | ms.val | main.rs:114:38:114:47 | source(...) | main.rs:119:14:119:19 | ms.val | $@ | main.rs:114:38:114:47 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index cb955ce32bde..ec82951affc7 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -87,9 +87,64 @@ mod ptr { } } +use std::pin::Pin; +use std::pin::pin; + +#[derive(Clone)] +struct MyStruct { + val: i64, +} + +fn test_pin() { + { + let mut i = source(40); + let mut pin1 = Pin::new(&i); + let mut pin2 = Box::pin(i); + let mut pin3 = Box::into_pin(Box::new(i)); + let mut pin4 = pin!(i); + sink(i); // $ hasValueFlow=40 + sink(*pin1); // $ MISSING: hasValueFlow=40 + sink(*Pin::into_inner(pin1)); // $ MISSING: hasValueFlow=40 + sink(*pin2); // $ MISSING: hasValueFlow=40 + sink(*pin3); // $ MISSING: hasValueFlow=40 + sink(*pin4); // $ MISSING: hasValueFlow=40 + } + + { + let mut ms = MyStruct { val: source(41) }; + let mut pin1 = Pin::new(&ms); + let mut pin2 = Box::pin(ms.clone()); + let mut pin3 = Box::into_pin(Box::new(ms.clone())); + let mut pin4 = pin!(&ms); + sink(ms.val); // $ hasValueFlow=41 + sink(pin1.val); // $ MISSING: hasValueFlow=41 + sink(Pin::into_inner(pin1).val); // $ MISSING: hasValueFlow=41 + sink(pin2.val); // $ MISSING: hasValueFlow=41 + sink(pin3.val); // $ MISSING: hasValueFlow=41 + sink(pin4.val); // $ MISSING: hasValueFlow=41 + } + + unsafe { + let mut ms = MyStruct { val: source(42) }; + let mut pin5 = Pin::new_unchecked(&ms); + sink(pin5.val); // $ MISSING: hasValueFlow=42 + sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=40 + } + + { + let mut ms = MyStruct { val: source(43) }; + let mut ms2 = MyStruct { val: source(44) }; + let mut pin = Pin::new(&mut ms); + sink(pin.val); // $ MISSING: hasValueFlow=43 + pin.set(ms2); + sink(pin.val); // $ MISSING: hasValueFlow=44 + } +} + fn main() { option_clone(); result_clone(); i64_clone(); my_clone::wrapper_clone(); + test_pin(); } From ebd75a118b144c33c834f933e8932066e8f68f17 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 17:30:06 +0100 Subject: [PATCH 2/4] Rust: Add models for std::Pin. --- .../frameworks/stdlib/lang-alloc.model.yml | 4 + .../frameworks/stdlib/lang-core.model.yml | 8 ++ .../dataflow/modeled/inline-flow.expected | 81 +++++++++++++++---- .../library-tests/dataflow/modeled/main.rs | 12 +-- 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml index 8d177c4e8565..77c33b47b0c2 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml @@ -29,6 +29,10 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: + # Box + - ["lang:alloc", "::pin", "Argument[0]", "ReturnValue.Reference", "value", "manual"] + - ["lang:alloc", "::new", "Argument[0]", "ReturnValue.Reference", "value", "manual"] + - ["lang:alloc", "::into_pin", "Argument[0]", "ReturnValue", "value", "manual"] # Fmt - ["lang:alloc", "crate::fmt::format", "Argument[0]", "ReturnValue", "taint", "manual"] # String diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml index 3e37ed7797bd..69b2236e3ce8 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml @@ -32,6 +32,14 @@ extensions: - ["lang:core", "::align_to", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"] - ["lang:core", "::pad_to_align", "Argument[self]", "ReturnValue", "taint", "manual"] - ["lang:core", "::size", "Argument[self]", "ReturnValue", "taint", "manual"] + # Pin + - ["lang:core", "crate::pin::Pin", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::new", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::new_unchecked", "Argument[0].Reference", "ReturnValue", "value", "manual"] + - ["lang:core", "::into_inner", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::into_inner_unchecked", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::set", "Argument[0]", "Argument[self]", "value", "manual"] + - ["lang:core", "::into_inner", "Argument[0]", "ReturnValue", "value", "manual"] # Ptr - ["lang:core", "crate::ptr::read", "Argument[0].Reference", "ReturnValue", "value", "manual"] - ["lang:core", "crate::ptr::read_unaligned", "Argument[0].Reference", "ReturnValue", "value", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected index b8d2136fcc02..d1af296044e6 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected @@ -1,32 +1,37 @@ models -| 1 | Summary: lang:core; ::clone; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | -| 2 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 3 | Summary: lang:core; ::zip; Argument[0].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)].Field[1]; value | -| 4 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 5 | Summary: lang:core; ::clone; Argument[self].Reference; ReturnValue; value | -| 6 | Summary: lang:core; crate::ptr::read; Argument[0].Reference; ReturnValue; value | -| 7 | Summary: lang:core; crate::ptr::write; Argument[1]; Argument[0].Reference; value | +| 1 | Summary: lang:alloc; ::into_pin; Argument[0]; ReturnValue; value | +| 2 | Summary: lang:alloc; ::new; Argument[0]; ReturnValue.Reference; value | +| 3 | Summary: lang:alloc; ::pin; Argument[0]; ReturnValue.Reference; value | +| 4 | Summary: lang:core; ::clone; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 5 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 6 | Summary: lang:core; ::zip; Argument[0].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)].Field[1]; value | +| 7 | Summary: lang:core; ::into_inner; Argument[0]; ReturnValue; value | +| 8 | Summary: lang:core; ::new; Argument[0]; ReturnValue; value | +| 9 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | +| 10 | Summary: lang:core; ::clone; Argument[self].Reference; ReturnValue; value | +| 11 | Summary: lang:core; crate::ptr::read; Argument[0].Reference; ReturnValue; value | +| 12 | Summary: lang:core; crate::ptr::write; Argument[1]; Argument[0].Reference; value | edges -| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:2 | +| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:5 | | main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:13 | a [Some] | provenance | | -| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:1 | +| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:4 | | main.rs:12:13:12:28 | Some(...) [Some] | main.rs:12:9:12:9 | a [Some] | provenance | | | main.rs:12:18:12:27 | source(...) | main.rs:12:13:12:28 | Some(...) [Some] | provenance | | -| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:2 | +| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:5 | | main.rs:14:13:14:13 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | generated | | main.rs:14:13:14:21 | a.clone() [Some] | main.rs:14:9:14:9 | b [Some] | provenance | | -| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:4 | +| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:9 | | main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:13 | a [Ok] | provenance | | | main.rs:19:31:19:44 | Ok(...) [Ok] | main.rs:19:9:19:9 | a [Ok] | provenance | | | main.rs:19:34:19:43 | source(...) | main.rs:19:31:19:44 | Ok(...) [Ok] | provenance | | -| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:4 | +| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:9 | | main.rs:21:13:21:13 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated | | main.rs:21:13:21:21 | a.clone() [Ok] | main.rs:21:9:21:9 | b [Ok] | provenance | | | main.rs:26:9:26:9 | a | main.rs:27:10:27:10 | a | provenance | | | main.rs:26:9:26:9 | a | main.rs:28:13:28:13 | a | provenance | | | main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | a | provenance | | | main.rs:28:9:28:9 | b | main.rs:29:10:29:10 | b | provenance | | -| main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | MaD:5 | +| main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | MaD:10 | | main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | generated | | main.rs:28:13:28:21 | a.clone() | main.rs:28:9:28:9 | b | provenance | | | main.rs:41:13:41:13 | w [Wrapper] | main.rs:42:15:42:15 | w [Wrapper] | provenance | | @@ -47,16 +52,36 @@ edges | main.rs:58:22:58:31 | source(...) | main.rs:58:17:58:32 | Some(...) [Some] | provenance | | | main.rs:59:13:59:13 | z [Some, tuple.1] | main.rs:60:15:60:15 | z [Some, tuple.1] | provenance | | | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | main.rs:59:13:59:13 | z [Some, tuple.1] | provenance | | -| main.rs:59:23:59:23 | b [Some] | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | provenance | MaD:3 | +| main.rs:59:23:59:23 | b [Some] | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | provenance | MaD:6 | | main.rs:60:15:60:15 | z [Some, tuple.1] | main.rs:61:13:61:24 | Some(...) [Some, tuple.1] | provenance | | | main.rs:61:13:61:24 | Some(...) [Some, tuple.1] | main.rs:61:18:61:23 | TuplePat [tuple.1] | provenance | | | main.rs:61:18:61:23 | TuplePat [tuple.1] | main.rs:61:22:61:22 | m | provenance | | | main.rs:61:22:61:22 | m | main.rs:63:22:63:22 | m | provenance | | | main.rs:84:29:84:29 | [post] y [&ref] | main.rs:85:33:85:33 | y [&ref] | provenance | | -| main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:7 | -| main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:6 | +| main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:12 | +| main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:11 | +| main.rs:100:13:100:17 | mut i | main.rs:101:34:101:34 | i | provenance | | +| main.rs:100:13:100:17 | mut i | main.rs:102:33:102:33 | i | provenance | | +| main.rs:100:13:100:17 | mut i | main.rs:103:47:103:47 | i | provenance | | | main.rs:100:13:100:17 | mut i | main.rs:105:14:105:14 | i | provenance | | | main.rs:100:21:100:30 | source(...) | main.rs:100:13:100:17 | mut i | provenance | | +| main.rs:101:13:101:20 | mut pin1 [&ref] | main.rs:106:15:106:18 | pin1 [&ref] | provenance | | +| main.rs:101:13:101:20 | mut pin1 [&ref] | main.rs:107:31:107:34 | pin1 [&ref] | provenance | | +| main.rs:101:24:101:35 | ...::new(...) [&ref] | main.rs:101:13:101:20 | mut pin1 [&ref] | provenance | | +| main.rs:101:33:101:34 | &i [&ref] | main.rs:101:24:101:35 | ...::new(...) [&ref] | provenance | MaD:8 | +| main.rs:101:34:101:34 | i | main.rs:101:33:101:34 | &i [&ref] | provenance | | +| main.rs:102:13:102:20 | mut pin2 [&ref] | main.rs:108:15:108:18 | pin2 [&ref] | provenance | | +| main.rs:102:24:102:34 | ...::pin(...) [&ref] | main.rs:102:13:102:20 | mut pin2 [&ref] | provenance | | +| main.rs:102:33:102:33 | i | main.rs:102:24:102:34 | ...::pin(...) [&ref] | provenance | MaD:3 | +| main.rs:103:13:103:20 | mut pin3 [&ref] | main.rs:109:15:109:18 | pin3 [&ref] | provenance | | +| main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | main.rs:103:13:103:20 | mut pin3 [&ref] | provenance | | +| main.rs:103:38:103:48 | ...::new(...) [&ref] | main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | provenance | MaD:1 | +| main.rs:103:47:103:47 | i | main.rs:103:38:103:48 | ...::new(...) [&ref] | provenance | MaD:2 | +| main.rs:106:15:106:18 | pin1 [&ref] | main.rs:106:14:106:18 | * ... | provenance | | +| main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | main.rs:107:14:107:35 | * ... | provenance | | +| main.rs:107:31:107:34 | pin1 [&ref] | main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | provenance | MaD:7 | +| main.rs:108:15:108:18 | pin2 [&ref] | main.rs:108:14:108:18 | * ... | provenance | | +| main.rs:109:15:109:18 | pin3 [&ref] | main.rs:109:14:109:18 | * ... | provenance | | | main.rs:114:13:114:18 | mut ms [MyStruct] | main.rs:119:14:119:15 | ms [MyStruct] | provenance | | | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | main.rs:114:13:114:18 | mut ms [MyStruct] | provenance | | | main.rs:114:38:114:47 | source(...) | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | provenance | | @@ -116,7 +141,27 @@ nodes | main.rs:85:33:85:33 | y [&ref] | semmle.label | y [&ref] | | main.rs:100:13:100:17 | mut i | semmle.label | mut i | | main.rs:100:21:100:30 | source(...) | semmle.label | source(...) | +| main.rs:101:13:101:20 | mut pin1 [&ref] | semmle.label | mut pin1 [&ref] | +| main.rs:101:24:101:35 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:101:33:101:34 | &i [&ref] | semmle.label | &i [&ref] | +| main.rs:101:34:101:34 | i | semmle.label | i | +| main.rs:102:13:102:20 | mut pin2 [&ref] | semmle.label | mut pin2 [&ref] | +| main.rs:102:24:102:34 | ...::pin(...) [&ref] | semmle.label | ...::pin(...) [&ref] | +| main.rs:102:33:102:33 | i | semmle.label | i | +| main.rs:103:13:103:20 | mut pin3 [&ref] | semmle.label | mut pin3 [&ref] | +| main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | semmle.label | ...::into_pin(...) [&ref] | +| main.rs:103:38:103:48 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:103:47:103:47 | i | semmle.label | i | | main.rs:105:14:105:14 | i | semmle.label | i | +| main.rs:106:14:106:18 | * ... | semmle.label | * ... | +| main.rs:106:15:106:18 | pin1 [&ref] | semmle.label | pin1 [&ref] | +| main.rs:107:14:107:35 | * ... | semmle.label | * ... | +| main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | semmle.label | ...::into_inner(...) [&ref] | +| main.rs:107:31:107:34 | pin1 [&ref] | semmle.label | pin1 [&ref] | +| main.rs:108:14:108:18 | * ... | semmle.label | * ... | +| main.rs:108:15:108:18 | pin2 [&ref] | semmle.label | pin2 [&ref] | +| main.rs:109:14:109:18 | * ... | semmle.label | * ... | +| main.rs:109:15:109:18 | pin3 [&ref] | semmle.label | pin3 [&ref] | | main.rs:114:13:114:18 | mut ms [MyStruct] | semmle.label | mut ms [MyStruct] | | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | semmle.label | MyStruct {...} [MyStruct] | | main.rs:114:38:114:47 | source(...) | semmle.label | source(...) | @@ -136,4 +181,8 @@ testFailures | main.rs:63:22:63:22 | m | main.rs:58:22:58:31 | source(...) | main.rs:63:22:63:22 | m | $@ | main.rs:58:22:58:31 | source(...) | source(...) | | main.rs:85:18:85:34 | ...::read(...) | main.rs:84:32:84:41 | source(...) | main.rs:85:18:85:34 | ...::read(...) | $@ | main.rs:84:32:84:41 | source(...) | source(...) | | main.rs:105:14:105:14 | i | main.rs:100:21:100:30 | source(...) | main.rs:105:14:105:14 | i | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:106:14:106:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:106:14:106:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:107:14:107:35 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:107:14:107:35 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:108:14:108:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:108:14:108:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:109:14:109:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:109:14:109:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | | main.rs:119:14:119:19 | ms.val | main.rs:114:38:114:47 | source(...) | main.rs:119:14:119:19 | ms.val | $@ | main.rs:114:38:114:47 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index ec82951affc7..440f3bfd7eec 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -102,11 +102,11 @@ fn test_pin() { let mut pin2 = Box::pin(i); let mut pin3 = Box::into_pin(Box::new(i)); let mut pin4 = pin!(i); - sink(i); // $ hasValueFlow=40 - sink(*pin1); // $ MISSING: hasValueFlow=40 - sink(*Pin::into_inner(pin1)); // $ MISSING: hasValueFlow=40 - sink(*pin2); // $ MISSING: hasValueFlow=40 - sink(*pin3); // $ MISSING: hasValueFlow=40 + sink(i); // $ hasValueFlow=40 + sink(*pin1); // $ hasValueFlow=40 + sink(*Pin::into_inner(pin1)); // $ hasValueFlow=40 + sink(*pin2); // $ hasValueFlow=40 + sink(*pin3); // $ hasValueFlow=40 sink(*pin4); // $ MISSING: hasValueFlow=40 } @@ -116,7 +116,7 @@ fn test_pin() { let mut pin2 = Box::pin(ms.clone()); let mut pin3 = Box::into_pin(Box::new(ms.clone())); let mut pin4 = pin!(&ms); - sink(ms.val); // $ hasValueFlow=41 + sink(ms.val); // $ hasValueFlow=41 sink(pin1.val); // $ MISSING: hasValueFlow=41 sink(Pin::into_inner(pin1).val); // $ MISSING: hasValueFlow=41 sink(pin2.val); // $ MISSING: hasValueFlow=41 From 94b57ac9a984f22f2994451ce4a3ff216088ec35 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 21:49:02 +0100 Subject: [PATCH 3/4] Update rust/ql/test/library-tests/dataflow/modeled/main.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rust/ql/test/library-tests/dataflow/modeled/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index 440f3bfd7eec..b30443366690 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -128,7 +128,7 @@ fn test_pin() { let mut ms = MyStruct { val: source(42) }; let mut pin5 = Pin::new_unchecked(&ms); sink(pin5.val); // $ MISSING: hasValueFlow=42 - sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=40 + sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=42 } { From bfb15cd88f8f3cf463efbbc58ee6fc54fbfdb853 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 May 2025 11:07:06 +0100 Subject: [PATCH 4/4] Rust: Accept changes to other tests. --- .../dataflow/local/DataFlowStep.expected | 3 + .../dataflow/local/inline-flow.expected | 55 +++++++++++-------- .../test/library-tests/dataflow/local/main.rs | 2 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 98a2634346e7..95ec16852020 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1167,6 +1167,8 @@ storeStep | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::allocator | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::allocator | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_mut_ptr | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_mut_ptr | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_ptr | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_ptr | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::new | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::new | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::pin | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::pin | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::borrow | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::borrow | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::borrow_mut | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::borrow_mut | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_mut | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_mut | @@ -1367,6 +1369,7 @@ readStep | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or_else | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::unwrap_or_else | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::zip | Some | file://:0:0:0:0 | [summary] read: Argument[0].Field[crate::option::Option::Some(0)] in lang:core::_::::zip | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::zip_with | Some | file://:0:0:0:0 | [summary] read: Argument[0].Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::new_unchecked | &ref | file://:0:0:0:0 | [summary] read: Argument[0].Reference in lang:core::_::::new_unchecked | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::is_err_and | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::is_err_and | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::is_ok_and | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::is_ok_and | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::map | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::map | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 80469e0b3995..cf3fd262c65a 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,14 +1,15 @@ models -| 1 | Summary: lang:core; <_ as crate::convert::From>::from; Argument[0]; ReturnValue; value | -| 2 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 3 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value | -| 4 | Summary: lang:core; ::unwrap_or; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 5 | Summary: lang:core; ::unwrap_or_else; Argument[0].ReturnValue; ReturnValue; value | -| 6 | Summary: lang:core; ::unwrap_or_else; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 7 | Summary: lang:core; ::err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | -| 8 | Summary: lang:core; ::expect; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 9 | Summary: lang:core; ::expect_err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue; value | -| 10 | Summary: lang:core; ::ok; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 1 | Summary: lang:alloc; ::new; Argument[0]; ReturnValue.Reference; value | +| 2 | Summary: lang:core; <_ as crate::convert::From>::from; Argument[0]; ReturnValue; value | +| 3 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 4 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value | +| 5 | Summary: lang:core; ::unwrap_or; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 6 | Summary: lang:core; ::unwrap_or_else; Argument[0].ReturnValue; ReturnValue; value | +| 7 | Summary: lang:core; ::unwrap_or_else; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 8 | Summary: lang:core; ::err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 9 | Summary: lang:core; ::expect; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | +| 10 | Summary: lang:core; ::expect_err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue; value | +| 11 | Summary: lang:core; ::ok; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | edges | main.rs:22:9:22:9 | s | main.rs:23:10:23:10 | s | provenance | | | main.rs:22:13:22:21 | source(...) | main.rs:22:9:22:9 | s | provenance | | @@ -22,6 +23,10 @@ edges | main.rs:48:15:48:23 | source(...) | main.rs:47:9:47:9 | b | provenance | | | main.rs:56:5:56:5 | i | main.rs:57:10:57:10 | i | provenance | | | main.rs:56:9:56:17 | source(...) | main.rs:56:5:56:5 | i | provenance | | +| main.rs:89:9:89:9 | i [&ref] | main.rs:90:11:90:11 | i [&ref] | provenance | | +| main.rs:89:13:89:31 | ...::new(...) [&ref] | main.rs:89:9:89:9 | i [&ref] | provenance | | +| main.rs:89:22:89:30 | source(...) | main.rs:89:13:89:31 | ...::new(...) [&ref] | provenance | MaD:1 | +| main.rs:90:11:90:11 | i [&ref] | main.rs:90:10:90:11 | * ... | provenance | | | main.rs:97:9:97:9 | a [tuple.0] | main.rs:98:10:98:10 | a [tuple.0] | provenance | | | main.rs:97:13:97:26 | TupleExpr [tuple.0] | main.rs:97:9:97:9 | a [tuple.0] | provenance | | | main.rs:97:14:97:22 | source(...) | main.rs:97:13:97:26 | TupleExpr [tuple.0] | provenance | | @@ -95,32 +100,32 @@ edges | main.rs:229:11:229:12 | s1 [Some] | main.rs:230:9:230:15 | Some(...) [Some] | provenance | | | main.rs:230:9:230:15 | Some(...) [Some] | main.rs:230:14:230:14 | n | provenance | | | main.rs:230:14:230:14 | n | main.rs:230:25:230:25 | n | provenance | | -| main.rs:240:9:240:10 | s1 [Some] | main.rs:241:10:241:20 | s1.unwrap() | provenance | MaD:2 | +| main.rs:240:9:240:10 | s1 [Some] | main.rs:241:10:241:20 | s1.unwrap() | provenance | MaD:3 | | main.rs:240:14:240:29 | Some(...) [Some] | main.rs:240:9:240:10 | s1 [Some] | provenance | | | main.rs:240:19:240:28 | source(...) | main.rs:240:14:240:29 | Some(...) [Some] | provenance | | -| main.rs:245:9:245:10 | s1 [Some] | main.rs:246:10:246:24 | s1.unwrap_or(...) | provenance | MaD:4 | +| main.rs:245:9:245:10 | s1 [Some] | main.rs:246:10:246:24 | s1.unwrap_or(...) | provenance | MaD:5 | | main.rs:245:14:245:29 | Some(...) [Some] | main.rs:245:9:245:10 | s1 [Some] | provenance | | | main.rs:245:19:245:28 | source(...) | main.rs:245:14:245:29 | Some(...) [Some] | provenance | | -| main.rs:249:23:249:32 | source(...) | main.rs:249:10:249:33 | s2.unwrap_or(...) | provenance | MaD:3 | -| main.rs:253:9:253:10 | s1 [Some] | main.rs:254:10:254:32 | s1.unwrap_or_else(...) | provenance | MaD:6 | +| main.rs:249:23:249:32 | source(...) | main.rs:249:10:249:33 | s2.unwrap_or(...) | provenance | MaD:4 | +| main.rs:253:9:253:10 | s1 [Some] | main.rs:254:10:254:32 | s1.unwrap_or_else(...) | provenance | MaD:7 | | main.rs:253:14:253:29 | Some(...) [Some] | main.rs:253:9:253:10 | s1 [Some] | provenance | | | main.rs:253:19:253:28 | source(...) | main.rs:253:14:253:29 | Some(...) [Some] | provenance | | -| main.rs:257:31:257:40 | source(...) | main.rs:257:10:257:41 | s2.unwrap_or_else(...) | provenance | MaD:5 | +| main.rs:257:31:257:40 | source(...) | main.rs:257:10:257:41 | s2.unwrap_or_else(...) | provenance | MaD:6 | | main.rs:261:9:261:10 | s1 [Some] | main.rs:263:14:263:15 | s1 [Some] | provenance | | | main.rs:261:14:261:29 | Some(...) [Some] | main.rs:261:9:261:10 | s1 [Some] | provenance | | | main.rs:261:19:261:28 | source(...) | main.rs:261:14:261:29 | Some(...) [Some] | provenance | | | main.rs:263:9:263:10 | i1 | main.rs:264:10:264:11 | i1 | provenance | | | main.rs:263:14:263:15 | s1 [Some] | main.rs:263:14:263:16 | TryExpr | provenance | | | main.rs:263:14:263:16 | TryExpr | main.rs:263:9:263:10 | i1 | provenance | | -| main.rs:270:9:270:10 | r1 [Ok] | main.rs:271:29:271:35 | r1.ok() [Some] | provenance | MaD:10 | +| main.rs:270:9:270:10 | r1 [Ok] | main.rs:271:29:271:35 | r1.ok() [Some] | provenance | MaD:11 | | main.rs:270:33:270:46 | Ok(...) [Ok] | main.rs:270:9:270:10 | r1 [Ok] | provenance | | | main.rs:270:36:270:45 | source(...) | main.rs:270:33:270:46 | Ok(...) [Ok] | provenance | | -| main.rs:271:9:271:11 | o1a [Some] | main.rs:273:10:273:21 | o1a.unwrap() | provenance | MaD:2 | +| main.rs:271:9:271:11 | o1a [Some] | main.rs:273:10:273:21 | o1a.unwrap() | provenance | MaD:3 | | main.rs:271:29:271:35 | r1.ok() [Some] | main.rs:271:9:271:11 | o1a [Some] | provenance | | -| main.rs:276:9:276:10 | r2 [Err] | main.rs:278:29:278:36 | r2.err() [Some] | provenance | MaD:7 | +| main.rs:276:9:276:10 | r2 [Err] | main.rs:278:29:278:36 | r2.err() [Some] | provenance | MaD:8 | | main.rs:276:33:276:47 | Err(...) [Err] | main.rs:276:9:276:10 | r2 [Err] | provenance | | | main.rs:276:37:276:46 | source(...) | main.rs:276:33:276:47 | Err(...) [Err] | provenance | | -| main.rs:278:9:278:11 | o2b [Some] | main.rs:280:10:280:21 | o2b.unwrap() | provenance | MaD:2 | +| main.rs:278:9:278:11 | o2b [Some] | main.rs:280:10:280:21 | o2b.unwrap() | provenance | MaD:3 | | main.rs:278:29:278:36 | r2.err() [Some] | main.rs:278:9:278:11 | o2b [Some] | provenance | | | main.rs:284:9:284:10 | s1 [Ok] | main.rs:287:14:287:15 | s1 [Ok] | provenance | | | main.rs:284:32:284:45 | Ok(...) [Ok] | main.rs:284:9:284:10 | s1 [Ok] | provenance | | @@ -128,10 +133,10 @@ edges | main.rs:287:9:287:10 | i1 | main.rs:289:10:289:11 | i1 | provenance | | | main.rs:287:14:287:15 | s1 [Ok] | main.rs:287:14:287:16 | TryExpr | provenance | | | main.rs:287:14:287:16 | TryExpr | main.rs:287:9:287:10 | i1 | provenance | | -| main.rs:297:9:297:10 | s1 [Ok] | main.rs:298:10:298:22 | s1.expect(...) | provenance | MaD:8 | +| main.rs:297:9:297:10 | s1 [Ok] | main.rs:298:10:298:22 | s1.expect(...) | provenance | MaD:9 | | main.rs:297:32:297:45 | Ok(...) [Ok] | main.rs:297:9:297:10 | s1 [Ok] | provenance | | | main.rs:297:35:297:44 | source(...) | main.rs:297:32:297:45 | Ok(...) [Ok] | provenance | | -| main.rs:301:9:301:10 | s2 [Err] | main.rs:303:10:303:26 | s2.expect_err(...) | provenance | MaD:9 | +| main.rs:301:9:301:10 | s2 [Err] | main.rs:303:10:303:26 | s2.expect_err(...) | provenance | MaD:10 | | main.rs:301:32:301:46 | Err(...) [Err] | main.rs:301:9:301:10 | s2 [Err] | provenance | | | main.rs:301:36:301:45 | source(...) | main.rs:301:32:301:46 | Err(...) [Err] | provenance | | | main.rs:312:9:312:10 | s1 [A] | main.rs:314:11:314:12 | s1 [A] | provenance | | @@ -233,7 +238,7 @@ edges | main.rs:524:11:524:15 | c_ref [&ref] | main.rs:524:10:524:15 | * ... | provenance | | | main.rs:528:9:528:9 | a | main.rs:532:20:532:20 | a | provenance | | | main.rs:528:18:528:27 | source(...) | main.rs:528:9:528:9 | a | provenance | | -| main.rs:532:20:532:20 | a | main.rs:532:10:532:21 | ...::from(...) | provenance | MaD:1 | +| main.rs:532:20:532:20 | a | main.rs:532:10:532:21 | ...::from(...) | provenance | MaD:2 | nodes | main.rs:18:10:18:18 | source(...) | semmle.label | source(...) | | main.rs:22:9:22:9 | s | semmle.label | s | @@ -253,6 +258,11 @@ nodes | main.rs:56:5:56:5 | i | semmle.label | i | | main.rs:56:9:56:17 | source(...) | semmle.label | source(...) | | main.rs:57:10:57:10 | i | semmle.label | i | +| main.rs:89:9:89:9 | i [&ref] | semmle.label | i [&ref] | +| main.rs:89:13:89:31 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:89:22:89:30 | source(...) | semmle.label | source(...) | +| main.rs:90:10:90:11 | * ... | semmle.label | * ... | +| main.rs:90:11:90:11 | i [&ref] | semmle.label | i [&ref] | | main.rs:97:9:97:9 | a [tuple.0] | semmle.label | a [tuple.0] | | main.rs:97:13:97:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | | main.rs:97:14:97:22 | source(...) | semmle.label | source(...) | @@ -514,6 +524,7 @@ testFailures | main.rs:39:10:39:10 | b | main.rs:34:13:34:21 | source(...) | main.rs:39:10:39:10 | b | $@ | main.rs:34:13:34:21 | source(...) | source(...) | | main.rs:50:10:50:10 | b | main.rs:48:15:48:23 | source(...) | main.rs:50:10:50:10 | b | $@ | main.rs:48:15:48:23 | source(...) | source(...) | | main.rs:57:10:57:10 | i | main.rs:56:9:56:17 | source(...) | main.rs:57:10:57:10 | i | $@ | main.rs:56:9:56:17 | source(...) | source(...) | +| main.rs:90:10:90:11 | * ... | main.rs:89:22:89:30 | source(...) | main.rs:90:10:90:11 | * ... | $@ | main.rs:89:22:89:30 | source(...) | source(...) | | main.rs:98:10:98:12 | a.0 | main.rs:97:14:97:22 | source(...) | main.rs:98:10:98:12 | a.0 | $@ | main.rs:97:14:97:22 | source(...) | source(...) | | main.rs:106:10:106:11 | a1 | main.rs:103:17:103:26 | source(...) | main.rs:106:10:106:11 | a1 | $@ | main.rs:103:17:103:26 | source(...) | source(...) | | main.rs:113:10:113:12 | a.1 | main.rs:111:21:111:30 | source(...) | main.rs:113:10:113:12 | a.1 | $@ | main.rs:111:21:111:30 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 1d91135a31d5..4323f58c880b 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -87,7 +87,7 @@ fn block_expression3(b: bool) -> i64 { fn box_deref() { let i = Box::new(source(7)); - sink(*i); // $ MISSING: hasValueFlow=7 + sink(*i); // $ hasValueFlow=7 } // -----------------------------------------------------------------------------