From 6e2702c3afb0802d9cd4a4d7f0a2521bac62f1ff Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 28 Nov 2025 11:42:06 +0000 Subject: [PATCH 1/2] Rust: Add some taint tests involving tuples. --- .../dataflow/taint/TaintFlowStep.expected | 24 +++++++++ .../dataflow/taint/inline-taint-flow.expected | 52 +++++++++++++++++++ .../test/library-tests/dataflow/taint/main.rs | 40 ++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected index 9799d66b124a..40c48c9bbf99 100644 --- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected @@ -17,3 +17,27 @@ | main.rs:72:24:72:27 | s[1] [pre-dereferenced] | main.rs:72:24:72:27 | s[1] | | main.rs:77:9:77:12 | [post] arr2 [borrowed] | main.rs:77:9:77:12 | [post] arr2 | | main.rs:77:9:77:15 | arr2[1] [pre-dereferenced] | main.rs:77:9:77:15 | arr2[1] | +| main.rs:98:14:98:47 | TupleExpr | main.rs:98:14:98:49 | ... .0 | +| main.rs:99:14:99:47 | TupleExpr | main.rs:99:14:99:49 | ... .1 | +| main.rs:102:14:102:28 | source_tuple(...) | main.rs:102:14:102:30 | ... .0 | +| main.rs:103:14:103:28 | source_tuple(...) | main.rs:103:14:103:30 | ... .1 | +| main.rs:106:14:106:83 | TupleExpr | main.rs:106:14:106:85 | ... .0 | +| main.rs:107:14:107:83 | TupleExpr | main.rs:107:14:107:85 | ... .0 | +| main.rs:107:14:107:85 | ... .0 | main.rs:107:14:107:87 | ... .0 | +| main.rs:108:14:108:83 | TupleExpr | main.rs:108:14:108:85 | ... .0 | +| main.rs:108:14:108:85 | ... .0 | main.rs:108:14:108:87 | ... .1 | +| main.rs:109:14:109:83 | TupleExpr | main.rs:109:14:109:85 | ... .1 | +| main.rs:110:14:110:83 | TupleExpr | main.rs:110:14:110:85 | ... .1 | +| main.rs:110:14:110:85 | ... .1 | main.rs:110:14:110:87 | ... .0 | +| main.rs:111:14:111:83 | TupleExpr | main.rs:111:14:111:85 | ... .1 | +| main.rs:111:14:111:85 | ... .1 | main.rs:111:14:111:87 | ... .1 | +| main.rs:114:14:114:64 | TupleExpr | main.rs:114:14:114:66 | ... .0 | +| main.rs:115:14:115:64 | TupleExpr | main.rs:115:14:115:66 | ... .0 | +| main.rs:115:14:115:66 | ... .0 | main.rs:115:14:115:68 | ... .0 | +| main.rs:116:14:116:64 | TupleExpr | main.rs:116:14:116:66 | ... .0 | +| main.rs:116:14:116:66 | ... .0 | main.rs:116:14:116:68 | ... .1 | +| main.rs:117:14:117:64 | TupleExpr | main.rs:117:14:117:66 | ... .1 | +| main.rs:118:14:118:64 | TupleExpr | main.rs:118:14:118:66 | ... .1 | +| main.rs:118:14:118:66 | ... .1 | main.rs:118:14:118:68 | ... .0 | +| main.rs:119:14:119:64 | TupleExpr | main.rs:119:14:119:66 | ... .1 | +| main.rs:119:14:119:66 | ... .1 | main.rs:119:14:119:68 | ... .1 | diff --git a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected index c43938341123..95e4764277c8 100644 --- a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected @@ -34,6 +34,22 @@ edges | main.rs:62:14:62:16 | arr | main.rs:62:14:62:19 | arr[1] | provenance | MaD:6 | | main.rs:77:9:77:12 | [post] arr2 [element] | main.rs:78:14:78:17 | arr2 | provenance | | | main.rs:77:19:77:28 | source(...) | main.rs:77:9:77:12 | [post] arr2 [element] | provenance | | +| main.rs:98:14:98:47 | TupleExpr [tuple.0] | main.rs:98:14:98:49 | ... .0 | provenance | | +| main.rs:98:15:98:30 | source_string(...) | main.rs:98:14:98:47 | TupleExpr [tuple.0] | provenance | | +| main.rs:102:14:102:28 | source_tuple(...) | main.rs:102:14:102:30 | ... .0 | provenance | | +| main.rs:103:14:103:28 | source_tuple(...) | main.rs:103:14:103:30 | ... .1 | provenance | | +| main.rs:108:14:108:83 | TupleExpr [tuple.0, tuple.1] | main.rs:108:14:108:85 | ... .0 [tuple.1] | provenance | | +| main.rs:108:14:108:85 | ... .0 [tuple.1] | main.rs:108:14:108:87 | ... .1 | provenance | | +| main.rs:108:15:108:48 | TupleExpr [tuple.1] | main.rs:108:14:108:83 | TupleExpr [tuple.0, tuple.1] | provenance | | +| main.rs:108:32:108:47 | source_string(...) | main.rs:108:15:108:48 | TupleExpr [tuple.1] | provenance | | +| main.rs:114:14:114:64 | TupleExpr [tuple.0] | main.rs:114:14:114:66 | ... .0 | provenance | | +| main.rs:114:15:114:29 | source_tuple(...) | main.rs:114:14:114:64 | TupleExpr [tuple.0] | provenance | | +| main.rs:115:14:115:64 | TupleExpr [tuple.0] | main.rs:115:14:115:66 | ... .0 | provenance | | +| main.rs:115:14:115:66 | ... .0 | main.rs:115:14:115:68 | ... .0 | provenance | | +| main.rs:115:15:115:29 | source_tuple(...) | main.rs:115:14:115:64 | TupleExpr [tuple.0] | provenance | | +| main.rs:116:14:116:64 | TupleExpr [tuple.0] | main.rs:116:14:116:66 | ... .0 | provenance | | +| main.rs:116:14:116:66 | ... .0 | main.rs:116:14:116:68 | ... .1 | provenance | | +| main.rs:116:15:116:29 | source_tuple(...) | main.rs:116:14:116:64 | TupleExpr [tuple.0] | provenance | | nodes | main.rs:12:9:12:9 | a | semmle.label | a | | main.rs:12:13:12:22 | source(...) | semmle.label | source(...) | @@ -67,8 +83,36 @@ nodes | main.rs:77:9:77:12 | [post] arr2 [element] | semmle.label | [post] arr2 [element] | | main.rs:77:19:77:28 | source(...) | semmle.label | source(...) | | main.rs:78:14:78:17 | arr2 | semmle.label | arr2 | +| main.rs:98:14:98:47 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:98:14:98:49 | ... .0 | semmle.label | ... .0 | +| main.rs:98:15:98:30 | source_string(...) | semmle.label | source_string(...) | +| main.rs:101:14:101:28 | source_tuple(...) | semmle.label | source_tuple(...) | +| main.rs:102:14:102:28 | source_tuple(...) | semmle.label | source_tuple(...) | +| main.rs:102:14:102:30 | ... .0 | semmle.label | ... .0 | +| main.rs:103:14:103:28 | source_tuple(...) | semmle.label | source_tuple(...) | +| main.rs:103:14:103:30 | ... .1 | semmle.label | ... .1 | +| main.rs:108:14:108:83 | TupleExpr [tuple.0, tuple.1] | semmle.label | TupleExpr [tuple.0, tuple.1] | +| main.rs:108:14:108:85 | ... .0 [tuple.1] | semmle.label | ... .0 [tuple.1] | +| main.rs:108:14:108:87 | ... .1 | semmle.label | ... .1 | +| main.rs:108:15:108:48 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:108:32:108:47 | source_string(...) | semmle.label | source_string(...) | +| main.rs:114:14:114:64 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:114:14:114:66 | ... .0 | semmle.label | ... .0 | +| main.rs:114:15:114:29 | source_tuple(...) | semmle.label | source_tuple(...) | +| main.rs:115:14:115:64 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:115:14:115:66 | ... .0 | semmle.label | ... .0 | +| main.rs:115:14:115:68 | ... .0 | semmle.label | ... .0 | +| main.rs:115:15:115:29 | source_tuple(...) | semmle.label | source_tuple(...) | +| main.rs:116:14:116:64 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:116:14:116:66 | ... .0 | semmle.label | ... .0 | +| main.rs:116:14:116:68 | ... .1 | semmle.label | ... .1 | +| main.rs:116:15:116:29 | source_tuple(...) | semmle.label | source_tuple(...) | subpaths testFailures +| main.rs:102:14:102:30 | ... .0 | Fixed missing result: hasTaintFlow=2 | +| main.rs:103:14:103:30 | ... .1 | Fixed missing result: hasTaintFlow=2 | +| main.rs:115:14:115:68 | ... .0 | Fixed missing result: hasTaintFlow=4 | +| main.rs:116:14:116:68 | ... .1 | Fixed missing result: hasTaintFlow=4 | #select | main.rs:13:10:13:14 | ... + ... | main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | $@ | main.rs:12:13:12:22 | source(...) | source(...) | | main.rs:17:10:17:10 | b | main.rs:15:17:15:26 | source(...) | main.rs:17:10:17:10 | b | $@ | main.rs:15:17:15:26 | source(...) | source(...) | @@ -78,3 +122,11 @@ testFailures | main.rs:47:14:47:19 | sliced | main.rs:45:17:45:26 | source(...) | main.rs:47:14:47:19 | sliced | $@ | main.rs:45:17:45:26 | source(...) | source(...) | | main.rs:62:14:62:19 | arr[1] | main.rs:61:19:61:28 | source(...) | main.rs:62:14:62:19 | arr[1] | $@ | main.rs:61:19:61:28 | source(...) | source(...) | | main.rs:78:14:78:17 | arr2 | main.rs:77:19:77:28 | source(...) | main.rs:78:14:78:17 | arr2 | $@ | main.rs:77:19:77:28 | source(...) | source(...) | +| main.rs:98:14:98:49 | ... .0 | main.rs:98:15:98:30 | source_string(...) | main.rs:98:14:98:49 | ... .0 | $@ | main.rs:98:15:98:30 | source_string(...) | source_string(...) | +| main.rs:101:14:101:28 | source_tuple(...) | main.rs:101:14:101:28 | source_tuple(...) | main.rs:101:14:101:28 | source_tuple(...) | $@ | main.rs:101:14:101:28 | source_tuple(...) | source_tuple(...) | +| main.rs:102:14:102:30 | ... .0 | main.rs:102:14:102:28 | source_tuple(...) | main.rs:102:14:102:30 | ... .0 | $@ | main.rs:102:14:102:28 | source_tuple(...) | source_tuple(...) | +| main.rs:103:14:103:30 | ... .1 | main.rs:103:14:103:28 | source_tuple(...) | main.rs:103:14:103:30 | ... .1 | $@ | main.rs:103:14:103:28 | source_tuple(...) | source_tuple(...) | +| main.rs:108:14:108:87 | ... .1 | main.rs:108:32:108:47 | source_string(...) | main.rs:108:14:108:87 | ... .1 | $@ | main.rs:108:32:108:47 | source_string(...) | source_string(...) | +| main.rs:114:14:114:66 | ... .0 | main.rs:114:15:114:29 | source_tuple(...) | main.rs:114:14:114:66 | ... .0 | $@ | main.rs:114:15:114:29 | source_tuple(...) | source_tuple(...) | +| main.rs:115:14:115:68 | ... .0 | main.rs:115:15:115:29 | source_tuple(...) | main.rs:115:14:115:68 | ... .0 | $@ | main.rs:115:15:115:29 | source_tuple(...) | source_tuple(...) | +| main.rs:116:14:116:68 | ... .1 | main.rs:116:15:116:29 | source_tuple(...) | main.rs:116:14:116:68 | ... .1 | $@ | main.rs:116:15:116:29 | source_tuple(...) | source_tuple(...) | diff --git a/rust/ql/test/library-tests/dataflow/taint/main.rs b/rust/ql/test/library-tests/dataflow/taint/main.rs index 5e4f8c435011..8d79ee5755c3 100644 --- a/rust/ql/test/library-tests/dataflow/taint/main.rs +++ b/rust/ql/test/library-tests/dataflow/taint/main.rs @@ -81,6 +81,45 @@ mod array_sink { use string::*; +mod tuples { + fn source_string(i: i64) -> String { + "".to_string() + } + + fn source_tuple(i: i64) -> (String, String) { + ("".to_string(), "".to_string()) + } + + fn sink(t: T) { + } + + pub fn tuples() { + sink((source_string(1), "".to_string())); + sink((source_string(1), "".to_string()).0); // $ hasValueFlow=1 + sink((source_string(1), "".to_string()).1); + + sink(source_tuple(2)); // $ hasValueFlow=2 + sink(source_tuple(2).0); // $ MISSING: hasTaintFlow=2 + sink(source_tuple(2).1); // $ MISSING: hasTaintFlow=2 + + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string()))); + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).0); + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).0.0); + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).0.1); // $ hasValueFlow=3 + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).1); + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).1.0); + sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).1.1); + + sink((source_tuple(4), ("".to_string(), "".to_string()))); + sink((source_tuple(4), ("".to_string(), "".to_string())).0); // $ hasValueFlow=4 + sink((source_tuple(4), ("".to_string(), "".to_string())).0.0); // $ MISSING: hasTaintFlow=4 + sink((source_tuple(4), ("".to_string(), "".to_string())).0.1); // $ MISSING: hasTaintFlow=4 + sink((source_tuple(4), ("".to_string(), "".to_string())).1); + sink((source_tuple(4), ("".to_string(), "".to_string())).1.0); + sink((source_tuple(4), ("".to_string(), "".to_string())).1.1); + } +} + fn main() { addition(); negation(); @@ -88,4 +127,5 @@ fn main() { string_slice(); array_source::array_tainted(); array_sink::array_with_taint(); + tuples::tuples(); } From 13df23630b62d6fbc8b8d7084b521ae5c21a8c4e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:37:23 +0000 Subject: [PATCH 2/2] Rust: Effect of lifting content reads as taint steps. --- .../dataflow/taint/inline-taint-flow.expected | 4 ---- rust/ql/test/library-tests/dataflow/taint/main.rs | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected index 95e4764277c8..49d8e4abb194 100644 --- a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected @@ -109,10 +109,6 @@ nodes | main.rs:116:15:116:29 | source_tuple(...) | semmle.label | source_tuple(...) | subpaths testFailures -| main.rs:102:14:102:30 | ... .0 | Fixed missing result: hasTaintFlow=2 | -| main.rs:103:14:103:30 | ... .1 | Fixed missing result: hasTaintFlow=2 | -| main.rs:115:14:115:68 | ... .0 | Fixed missing result: hasTaintFlow=4 | -| main.rs:116:14:116:68 | ... .1 | Fixed missing result: hasTaintFlow=4 | #select | main.rs:13:10:13:14 | ... + ... | main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | $@ | main.rs:12:13:12:22 | source(...) | source(...) | | main.rs:17:10:17:10 | b | main.rs:15:17:15:26 | source(...) | main.rs:17:10:17:10 | b | $@ | main.rs:15:17:15:26 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/taint/main.rs b/rust/ql/test/library-tests/dataflow/taint/main.rs index 8d79ee5755c3..e7c23d38e98d 100644 --- a/rust/ql/test/library-tests/dataflow/taint/main.rs +++ b/rust/ql/test/library-tests/dataflow/taint/main.rs @@ -99,8 +99,8 @@ mod tuples { sink((source_string(1), "".to_string()).1); sink(source_tuple(2)); // $ hasValueFlow=2 - sink(source_tuple(2).0); // $ MISSING: hasTaintFlow=2 - sink(source_tuple(2).1); // $ MISSING: hasTaintFlow=2 + sink(source_tuple(2).0); // $ hasTaintFlow=2 + sink(source_tuple(2).1); // $ hasTaintFlow=2 sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string()))); sink((("".to_string(), source_string(3)), ("".to_string(), "".to_string())).0); @@ -112,8 +112,8 @@ mod tuples { sink((source_tuple(4), ("".to_string(), "".to_string()))); sink((source_tuple(4), ("".to_string(), "".to_string())).0); // $ hasValueFlow=4 - sink((source_tuple(4), ("".to_string(), "".to_string())).0.0); // $ MISSING: hasTaintFlow=4 - sink((source_tuple(4), ("".to_string(), "".to_string())).0.1); // $ MISSING: hasTaintFlow=4 + sink((source_tuple(4), ("".to_string(), "".to_string())).0.0); // $ hasTaintFlow=4 + sink((source_tuple(4), ("".to_string(), "".to_string())).0.1); // $ hasTaintFlow=4 sink((source_tuple(4), ("".to_string(), "".to_string())).1); sink((source_tuple(4), ("".to_string(), "".to_string())).1.0); sink((source_tuple(4), ("".to_string(), "".to_string())).1.1);