From cf1b19f7c4446b796d48d498a547f25eb7634f44 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 25 Mar 2025 08:52:48 +0100 Subject: [PATCH 1/3] Rust: Add test for MaD argument source --- rust/ql/test/library-tests/dataflow/models/main.rs | 10 ++++++++++ .../test/library-tests/dataflow/models/models.ext.yml | 1 + 2 files changed, 11 insertions(+) diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 62e79c804482..38a4940cccb9 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -279,6 +279,15 @@ fn test_simple_sink() { simple_sink(s); // $ hasValueFlow=17 } +// has a source model +fn arg_source(i: i64) {} + +fn test_arg_source() { + let i = 19; + arg_source(i); + sink(i) // $ MISSING: hasValueFlow=i +} + #[tokio::main] async fn main() { test_identify(); @@ -299,5 +308,6 @@ async fn main() { test_simple_source(); test_simple_sink(); test_get_async_number().await; + test_arg_source(); let dummy = Some(0); // ensure that the the `lang:core` crate is extracted } diff --git a/rust/ql/test/library-tests/dataflow/models/models.ext.yml b/rust/ql/test/library-tests/dataflow/models/models.ext.yml index 3ad18be99fc1..9a9fa9e96ac4 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.ext.yml +++ b/rust/ql/test/library-tests/dataflow/models/models.ext.yml @@ -6,6 +6,7 @@ extensions: - ["repo::test", "crate::simple_source", "ReturnValue", "test-source", "manual"] - ["repo::test", "crate::enum_source", "ReturnValue.Field[crate::MyFieldEnum::D::field_d]", "test-source", "manual"] - ["repo::test", "::source", "ReturnValue.Field[crate::MyFieldEnum::C::field_c]", "test-source", "manual"] + - ["repo::test", "crate::arg_source", "Argument[0]", "test-source", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel From d6d3028e5a075ff984f413fc256c7767b7a69dae Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 25 Mar 2025 08:54:51 +0100 Subject: [PATCH 2/3] Rust: Support `Argument[x]` MaD source definitions --- .../dataflow/internal/FlowSummaryImpl.qll | 20 ++- .../library-tests/dataflow/models/main.rs | 2 +- .../dataflow/models/models.expected | 119 ++++++++++-------- 3 files changed, 82 insertions(+), 59 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 0c6a9e52e015..28a184116348 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -143,20 +143,30 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.asCallBaseExprCfgNode().getCallExprBase() = sc.(LibraryCallable).getACall() } + private Expr getArg(CallExprBase call, ParameterPosition pos) { + result = call.getArgList().getArg(pos.getPosition()) + or + result = call.(MethodCallExpr).getReceiver() and pos.isSelf() + } + RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { sc = Impl::Private::SummaryComponent::return(_) and result.asExpr().getExpr() = source.getCall() + or + exists(CallExprBase call, Expr arg, ParameterPosition pos | + result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() = arg and + sc = Impl::Private::SummaryComponent::argument(pos) and + call = source.getCall() and + arg = getArg(call, pos) + ) } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { exists(CallExprBase call, Expr arg, ParameterPosition pos | result.asExpr().getExpr() = arg and sc = Impl::Private::SummaryComponent::argument(pos) and - call = sink.getCall() - | - arg = call.getArgList().getArg(pos.getPosition()) - or - arg = call.(MethodCallExpr).getReceiver() and pos.isSelf() + call = sink.getCall() and + arg = getArg(call, pos) ) } } diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 38a4940cccb9..54337a1f0214 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -285,7 +285,7 @@ fn arg_source(i: i64) {} fn test_arg_source() { let i = 19; arg_source(i); - sink(i) // $ MISSING: hasValueFlow=i + sink(i) // $ hasValueFlow=i } #[tokio::main] diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index c434d3f13703..03db13a96dbc 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -3,22 +3,23 @@ models | 2 | Sink: repo::test; crate::enum_sink; test-sink; Argument[0].Field[crate::MyFieldEnum::C::field_c] | | 3 | Sink: repo::test; crate::simple_sink; test-sink; Argument[0] | | 4 | Source: repo::test; ::source; test-source; ReturnValue.Field[crate::MyFieldEnum::C::field_c] | -| 5 | Source: repo::test; crate::enum_source; test-source; ReturnValue.Field[crate::MyFieldEnum::D::field_d] | -| 6 | Source: repo::test; crate::simple_source; test-source; ReturnValue | -| 7 | Summary: repo::test; crate::apply; Argument[0]; Argument[1].Parameter[0]; value | -| 8 | Summary: repo::test; crate::apply; Argument[1].ReturnValue; ReturnValue; value | -| 9 | Summary: repo::test; crate::coerce; Argument[0]; ReturnValue; taint | -| 10 | Summary: repo::test; crate::get_array_element; Argument[0].Element; ReturnValue; value | -| 11 | Summary: repo::test; crate::get_async_number; Argument[0]; ReturnValue.Future; value | -| 12 | Summary: repo::test; crate::get_struct_field; Argument[0].Field[crate::MyStruct::field1]; ReturnValue; value | -| 13 | Summary: repo::test; crate::get_tuple_element; Argument[0].Field[0]; ReturnValue; value | -| 14 | Summary: repo::test; crate::get_var_field; Argument[0].Field[crate::MyFieldEnum::C::field_c]; ReturnValue; value | -| 15 | Summary: repo::test; crate::get_var_pos; Argument[0].Field[crate::MyPosEnum::A(0)]; ReturnValue; value | -| 16 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.Element; value | -| 17 | Summary: repo::test; crate::set_struct_field; Argument[0]; ReturnValue.Field[crate::MyStruct::field2]; value | -| 18 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value | -| 19 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Field[crate::MyFieldEnum::D::field_d]; value | -| 20 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Field[crate::MyPosEnum::B(0)]; value | +| 5 | Source: repo::test; crate::arg_source; test-source; Argument[0] | +| 6 | Source: repo::test; crate::enum_source; test-source; ReturnValue.Field[crate::MyFieldEnum::D::field_d] | +| 7 | Source: repo::test; crate::simple_source; test-source; ReturnValue | +| 8 | Summary: repo::test; crate::apply; Argument[0]; Argument[1].Parameter[0]; value | +| 9 | Summary: repo::test; crate::apply; Argument[1].ReturnValue; ReturnValue; value | +| 10 | Summary: repo::test; crate::coerce; Argument[0]; ReturnValue; taint | +| 11 | Summary: repo::test; crate::get_array_element; Argument[0].Element; ReturnValue; value | +| 12 | Summary: repo::test; crate::get_async_number; Argument[0]; ReturnValue.Future; value | +| 13 | Summary: repo::test; crate::get_struct_field; Argument[0].Field[crate::MyStruct::field1]; ReturnValue; value | +| 14 | Summary: repo::test; crate::get_tuple_element; Argument[0].Field[0]; ReturnValue; value | +| 15 | Summary: repo::test; crate::get_var_field; Argument[0].Field[crate::MyFieldEnum::C::field_c]; ReturnValue; value | +| 16 | Summary: repo::test; crate::get_var_pos; Argument[0].Field[crate::MyPosEnum::A(0)]; ReturnValue; value | +| 17 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.Element; value | +| 18 | Summary: repo::test; crate::set_struct_field; Argument[0]; ReturnValue.Field[crate::MyStruct::field2]; value | +| 19 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value | +| 20 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Field[crate::MyFieldEnum::D::field_d]; value | +| 21 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Field[crate::MyPosEnum::B(0)]; value | edges | main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | | | main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | | @@ -28,7 +29,7 @@ edges | main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | QL | | main.rs:25:9:25:9 | s | main.rs:26:17:26:17 | s | provenance | | | main.rs:25:13:25:22 | source(...) | main.rs:25:9:25:9 | s | provenance | | -| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | MaD:9 | +| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | MaD:10 | | main.rs:40:9:40:9 | s | main.rs:41:27:41:27 | s | provenance | | | main.rs:40:9:40:9 | s | main.rs:41:27:41:27 | s | provenance | | | main.rs:40:13:40:21 | source(...) | main.rs:40:9:40:9 | s | provenance | | @@ -39,8 +40,8 @@ edges | main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:41:9:41:10 | e1 [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:15 | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:15 | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:16 | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:16 | | main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | | | main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | | | main.rs:53:13:53:21 | source(...) | main.rs:53:9:53:9 | s | provenance | | @@ -49,8 +50,8 @@ edges | main.rs:54:9:54:10 | e1 [B] | main.rs:55:11:55:12 | e1 [B] | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:20 | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:20 | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:21 | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:21 | | main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | | main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | | main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | | @@ -67,8 +68,8 @@ edges | main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:73:9:73:10 | e1 [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:14 | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:14 | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:15 | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:15 | | main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | | | main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | | | main.rs:85:13:85:21 | source(...) | main.rs:85:9:85:9 | s | provenance | | @@ -77,8 +78,8 @@ edges | main.rs:86:9:86:10 | e1 [D] | main.rs:87:11:87:12 | e1 [D] | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:19 | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:19 | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:20 | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:20 | | main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | | main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | | main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | | @@ -95,8 +96,8 @@ edges | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | main.rs:105:9:105:17 | my_struct [MyStruct.field1] | provenance | | | main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | | main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | -| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 | -| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:13 | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:13 | | main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | | | main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | | | main.rs:126:13:126:21 | source(...) | main.rs:126:9:126:9 | s | provenance | | @@ -105,16 +106,16 @@ edges | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | provenance | | | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | | | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | | -| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:17 | -| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:17 | +| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:18 | +| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:18 | | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | | | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | | | main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | | | main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | | | main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | | | main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | | -| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:10 | -| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:10 | +| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:11 | +| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:11 | | main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [element] | provenance | | | main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [element] | provenance | | | main.rs:148:9:148:9 | s | main.rs:149:33:149:33 | s | provenance | | @@ -125,8 +126,8 @@ edges | main.rs:149:9:149:11 | arr [element] | main.rs:150:10:150:12 | arr [element] | provenance | | | main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | | | main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | | -| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:16 | -| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:16 | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:17 | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:17 | | main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | | | main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | | | main.rs:159:9:159:9 | s | main.rs:160:14:160:14 | s | provenance | | @@ -139,8 +140,8 @@ edges | main.rs:160:13:160:18 | TupleExpr [tuple.0] | main.rs:160:9:160:9 | t [tuple.0] | provenance | | | main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | | main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | -| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:13 | -| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:13 | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:14 | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:14 | | main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | | | main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | | | main.rs:172:13:172:22 | source(...) | main.rs:172:9:172:9 | s | provenance | | @@ -149,8 +150,8 @@ edges | main.rs:173:9:173:9 | t [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | | | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | | | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | | -| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:18 | -| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:18 | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:19 | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:19 | | main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | | main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | | main.rs:184:9:184:9 | s | main.rs:189:11:189:11 | s | provenance | | @@ -159,8 +160,8 @@ edges | main.rs:184:13:184:22 | source(...) | main.rs:184:9:184:9 | s | provenance | | | main.rs:185:14:185:14 | ... | main.rs:186:14:186:14 | n | provenance | | | main.rs:185:14:185:14 | ... | main.rs:186:14:186:14 | n | provenance | | -| main.rs:189:11:189:11 | s | main.rs:185:14:185:14 | ... | provenance | MaD:7 | -| main.rs:189:11:189:11 | s | main.rs:185:14:185:14 | ... | provenance | MaD:7 | +| main.rs:189:11:189:11 | s | main.rs:185:14:185:14 | ... | provenance | MaD:8 | +| main.rs:189:11:189:11 | s | main.rs:185:14:185:14 | ... | provenance | MaD:8 | | main.rs:193:13:193:22 | source(...) | main.rs:195:23:195:23 | f [captured s] | provenance | | | main.rs:193:13:193:22 | source(...) | main.rs:195:23:195:23 | f [captured s] | provenance | | | main.rs:194:40:194:40 | s | main.rs:194:17:194:42 | if ... {...} else {...} | provenance | | @@ -169,14 +170,14 @@ edges | main.rs:195:9:195:9 | t | main.rs:196:10:196:10 | t | provenance | | | main.rs:195:13:195:24 | apply(...) | main.rs:195:9:195:9 | t | provenance | | | main.rs:195:13:195:24 | apply(...) | main.rs:195:9:195:9 | t | provenance | | -| main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:7 | -| main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:7 | | main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:8 | | main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:8 | -| main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:7 | -| main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:7 | +| main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:9 | +| main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | provenance | MaD:9 | | main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:8 | | main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:8 | +| main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:9 | +| main.rs:195:23:195:23 | f [captured s] | main.rs:195:13:195:24 | apply(...) | provenance | MaD:9 | | main.rs:200:9:200:9 | s | main.rs:202:19:202:19 | s | provenance | | | main.rs:200:9:200:9 | s | main.rs:202:19:202:19 | s | provenance | | | main.rs:200:13:200:22 | source(...) | main.rs:200:9:200:9 | s | provenance | | @@ -187,10 +188,10 @@ edges | main.rs:202:9:202:9 | t | main.rs:203:10:203:10 | t | provenance | | | main.rs:202:13:202:23 | apply(...) | main.rs:202:9:202:9 | t | provenance | | | main.rs:202:13:202:23 | apply(...) | main.rs:202:9:202:9 | t | provenance | | -| main.rs:202:19:202:19 | s | main.rs:201:14:201:14 | ... | provenance | MaD:7 | -| main.rs:202:19:202:19 | s | main.rs:201:14:201:14 | ... | provenance | MaD:7 | -| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:7 | -| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:7 | +| main.rs:202:19:202:19 | s | main.rs:201:14:201:14 | ... | provenance | MaD:8 | +| main.rs:202:19:202:19 | s | main.rs:201:14:201:14 | ... | provenance | MaD:8 | +| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:8 | +| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:8 | | main.rs:212:9:212:9 | s | main.rs:213:30:213:30 | s | provenance | | | main.rs:212:9:212:9 | s | main.rs:213:30:213:30 | s | provenance | | | main.rs:212:13:212:22 | source(...) | main.rs:212:9:212:9 | s | provenance | | @@ -201,12 +202,12 @@ edges | main.rs:213:13:213:31 | get_async_number(...) [future] | main.rs:213:13:213:37 | await ... | provenance | | | main.rs:213:13:213:37 | await ... | main.rs:213:9:213:9 | t | provenance | | | main.rs:213:13:213:37 | await ... | main.rs:213:9:213:9 | t | provenance | | -| main.rs:213:30:213:30 | s | main.rs:213:13:213:31 | get_async_number(...) [future] | provenance | MaD:11 | -| main.rs:213:30:213:30 | s | main.rs:213:13:213:31 | get_async_number(...) [future] | provenance | MaD:11 | +| main.rs:213:30:213:30 | s | main.rs:213:13:213:31 | get_async_number(...) [future] | provenance | MaD:12 | +| main.rs:213:30:213:30 | s | main.rs:213:13:213:31 | get_async_number(...) [future] | provenance | MaD:12 | | main.rs:233:9:233:9 | s [D] | main.rs:234:11:234:11 | s [D] | provenance | | | main.rs:233:9:233:9 | s [D] | main.rs:234:11:234:11 | s [D] | provenance | | -| main.rs:233:13:233:23 | enum_source | main.rs:233:13:233:27 | enum_source(...) [D] | provenance | Src:MaD:5 | -| main.rs:233:13:233:23 | enum_source | main.rs:233:13:233:27 | enum_source(...) [D] | provenance | Src:MaD:5 | +| main.rs:233:13:233:23 | enum_source | main.rs:233:13:233:27 | enum_source(...) [D] | provenance | Src:MaD:6 | +| main.rs:233:13:233:23 | enum_source | main.rs:233:13:233:27 | enum_source(...) [D] | provenance | Src:MaD:6 | | main.rs:233:13:233:27 | enum_source(...) [D] | main.rs:233:9:233:9 | s [D] | provenance | | | main.rs:233:13:233:27 | enum_source(...) [D] | main.rs:233:9:233:9 | s [D] | provenance | | | main.rs:234:11:234:11 | s [D] | main.rs:236:9:236:37 | ...::D {...} [D] | provenance | | @@ -249,8 +250,8 @@ edges | main.rs:261:5:261:5 | e [D] | main.rs:261:7:261:10 | sink | provenance | MaD:1 Sink:MaD:1 | | main.rs:270:9:270:9 | s | main.rs:271:10:271:10 | s | provenance | | | main.rs:270:9:270:9 | s | main.rs:271:10:271:10 | s | provenance | | -| main.rs:270:13:270:25 | simple_source | main.rs:270:13:270:29 | simple_source(...) | provenance | Src:MaD:6 MaD:6 | -| main.rs:270:13:270:25 | simple_source | main.rs:270:13:270:29 | simple_source(...) | provenance | Src:MaD:6 MaD:6 | +| main.rs:270:13:270:25 | simple_source | main.rs:270:13:270:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | +| main.rs:270:13:270:25 | simple_source | main.rs:270:13:270:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | | main.rs:270:13:270:29 | simple_source(...) | main.rs:270:9:270:9 | s | provenance | | | main.rs:270:13:270:29 | simple_source(...) | main.rs:270:9:270:9 | s | provenance | | | main.rs:278:9:278:9 | s | main.rs:279:17:279:17 | s | provenance | | @@ -259,6 +260,10 @@ edges | main.rs:278:13:278:22 | source(...) | main.rs:278:9:278:9 | s | provenance | | | main.rs:279:17:279:17 | s | main.rs:279:5:279:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | | main.rs:279:17:279:17 | s | main.rs:279:5:279:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | +| main.rs:287:5:287:14 | arg_source | main.rs:287:16:287:16 | [post] i | provenance | Src:MaD:5 MaD:5 | +| main.rs:287:5:287:14 | arg_source | main.rs:287:16:287:16 | [post] i | provenance | Src:MaD:5 MaD:5 | +| main.rs:287:16:287:16 | [post] i | main.rs:288:10:288:10 | i | provenance | | +| main.rs:287:16:287:16 | [post] i | main.rs:288:10:288:10 | i | provenance | | nodes | main.rs:15:9:15:9 | s | semmle.label | s | | main.rs:15:9:15:9 | s | semmle.label | s | @@ -538,6 +543,12 @@ nodes | main.rs:279:5:279:15 | simple_sink | semmle.label | simple_sink | | main.rs:279:17:279:17 | s | semmle.label | s | | main.rs:279:17:279:17 | s | semmle.label | s | +| main.rs:287:5:287:14 | arg_source | semmle.label | arg_source | +| main.rs:287:5:287:14 | arg_source | semmle.label | arg_source | +| main.rs:287:16:287:16 | [post] i | semmle.label | [post] i | +| main.rs:287:16:287:16 | [post] i | semmle.label | [post] i | +| main.rs:288:10:288:10 | i | semmle.label | i | +| main.rs:288:10:288:10 | i | semmle.label | i | subpaths | main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | main.rs:194:17:194:42 | if ... {...} else {...} | main.rs:195:13:195:24 | apply(...) | | main.rs:195:23:195:23 | f [captured s] | main.rs:194:40:194:40 | s | main.rs:194:17:194:42 | if ... {...} else {...} | main.rs:195:13:195:24 | apply(...) | @@ -589,3 +600,5 @@ invalidSpecComponent | main.rs:271:10:271:10 | s | main.rs:270:13:270:25 | simple_source | main.rs:271:10:271:10 | s | $@ | main.rs:270:13:270:25 | simple_source | simple_source | | main.rs:279:5:279:15 | simple_sink | main.rs:278:13:278:22 | source(...) | main.rs:279:5:279:15 | simple_sink | $@ | main.rs:278:13:278:22 | source(...) | source(...) | | main.rs:279:5:279:15 | simple_sink | main.rs:278:13:278:22 | source(...) | main.rs:279:5:279:15 | simple_sink | $@ | main.rs:278:13:278:22 | source(...) | source(...) | +| main.rs:288:10:288:10 | i | main.rs:287:5:287:14 | arg_source | main.rs:288:10:288:10 | i | $@ | main.rs:287:5:287:14 | arg_source | arg_source | +| main.rs:288:10:288:10 | i | main.rs:287:5:287:14 | arg_source | main.rs:288:10:288:10 | i | $@ | main.rs:287:5:287:14 | arg_source | arg_source | From b4926475d3862d14536709a8abade618be40b303 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 26 Mar 2025 08:44:03 +0100 Subject: [PATCH 3/3] Address review comment --- .../rust/dataflow/internal/DataFlowImpl.qll | 26 ++++++++++++++++--- .../dataflow/internal/FlowSummaryImpl.qll | 18 +++++-------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 2ae5ccf359f8..0dc31a7966e9 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -90,10 +90,10 @@ final class DataFlowCall extends TDataFlowCall { } /** - * The position of a parameter or an argument in a function or call. + * The position of a parameter in a function. * - * As there is a 1-to-1 correspondence between parameter positions and - * arguments positions in Rust we use the same type for both. + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. */ final class ParameterPosition extends TParameterPosition { /** Gets the underlying integer position, if any. */ @@ -126,6 +126,22 @@ final class ParameterPosition extends TParameterPosition { } } +/** + * The position of an argument in a call. + * + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. + */ +final class ArgumentPosition extends ParameterPosition { + /** Gets the argument of `call` at this position, if any. */ + Expr getArgument(CallExprBase call) { + result = call.getArgList().getArg(this.getPosition()) + or + this.isSelf() and + result = call.(MethodCallExpr).getReceiver() + } +} + /** Holds if `call` invokes a qualified path that resolves to a method. */ private predicate callToMethod(CallExpr call) { exists(Path path | @@ -432,6 +448,8 @@ private module Aliases { class ParameterPositionAlias = ParameterPosition; + class ArgumentPositionAlias = ArgumentPosition; + class ContentAlias = Content; class ContentSetAlias = ContentSet; @@ -550,7 +568,7 @@ module RustDataFlow implements InputSig { class ParameterPosition = ParameterPositionAlias; - class ArgumentPosition = ParameterPosition; + class ArgumentPosition = ArgumentPositionAlias; /** * Holds if the parameter position `ppos` matches the argument position diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 28a184116348..3f2d7b8c5451 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -58,7 +58,9 @@ module Input implements InputSig { string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() } - predicate encodeArgumentPosition = encodeParameterPosition/1; + string encodeArgumentPosition(RustDataFlow::ArgumentPosition pos) { + result = encodeParameterPosition(pos) + } string encodeContent(ContentSet cs, string arg) { exists(Content c | cs = TSingletonContentSet(c) | @@ -143,30 +145,24 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.asCallBaseExprCfgNode().getCallExprBase() = sc.(LibraryCallable).getACall() } - private Expr getArg(CallExprBase call, ParameterPosition pos) { - result = call.getArgList().getArg(pos.getPosition()) - or - result = call.(MethodCallExpr).getReceiver() and pos.isSelf() - } - RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { sc = Impl::Private::SummaryComponent::return(_) and result.asExpr().getExpr() = source.getCall() or - exists(CallExprBase call, Expr arg, ParameterPosition pos | + exists(CallExprBase call, Expr arg, ArgumentPosition pos | result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() = arg and sc = Impl::Private::SummaryComponent::argument(pos) and call = source.getCall() and - arg = getArg(call, pos) + arg = pos.getArgument(call) ) } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { - exists(CallExprBase call, Expr arg, ParameterPosition pos | + exists(CallExprBase call, Expr arg, ArgumentPosition pos | result.asExpr().getExpr() = arg and sc = Impl::Private::SummaryComponent::argument(pos) and call = sink.getCall() and - arg = getArg(call, pos) + arg = pos.getArgument(call) ) } }