From 46627c677ddf7691d6dd032f5c9186fe6913f905 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 14 Jul 2025 15:20:08 +0100 Subject: [PATCH 1/3] C++: Add FP in dataflow through global variables. --- .../dataflow/dataflow-tests/dataflow-consistency.expected | 6 ++++++ .../dataflow/dataflow-tests/test-source-sink.expected | 1 + cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 9492b7dd2760..9abcd6eeee78 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -6,9 +6,15 @@ uniqueEnclosingCallable | test.cpp:1126:33:1129:1 | {...} | Node should have one enclosing callable but has 0. | | test.cpp:1127:3:1127:13 | reads_input | Node should have one enclosing callable but has 0. | | test.cpp:1128:3:1128:21 | not_does_read_input | Node should have one enclosing callable but has 0. | +| test.cpp:1158:18:1158:21 | call to sink | Node should have one enclosing callable but has 0. | +| test.cpp:1158:18:1158:42 | ... , ... | Node should have one enclosing callable but has 0. | +| test.cpp:1158:23:1158:31 | recursion | Node should have one enclosing callable but has 0. | +| test.cpp:1158:35:1158:40 | call to source | Node should have one enclosing callable but has 0. | uniqueCallEnclosingCallable | test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. | | test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. | +| test.cpp:1158:18:1158:21 | call to sink | Call should have one enclosing callable but has 0. | +| test.cpp:1158:35:1158:40 | call to source | Call should have one enclosing callable but has 0. | uniqueType uniqueNodeLocation missingLocation diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 323ce2a43121..66ba5a324def 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -327,6 +327,7 @@ irFlow | test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source | | test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x | | test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | +| test.cpp:1158:18:1158:42 | ... , ... | test.cpp:1158:23:1158:31 | recursion | | true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x | | true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x | | true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index a65659191fb8..8e68a951f5a1 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -1153,4 +1153,6 @@ namespace conflation_regression { *p = source(0); read_deref_deref(p); } -} \ No newline at end of file +} + +int recursion = (sink(recursion), source()); // $ SPURIOUS: ir \ No newline at end of file From a825213c05baa90b3d2c37955dbea77e75f94768 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 14 Jul 2025 15:22:52 +0100 Subject: [PATCH 2/3] C++: Fix FP by not generating a global def entry node for variable 'v' in the 'IRfunction' for 'v' itself. --- .../lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll | 4 ++++ .../dataflow/dataflow-tests/test-source-sink.expected | 1 - cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 863825b375e3..fd9ba967a13d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -153,6 +153,10 @@ private predicate isGlobalDefImpl( GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex ) { exists(VariableAddressInstruction vai | + // The right-hand side of an initialization of a global variable + // creates its own `IRFunction`. We don't want flow into that `IRFunction` + // since the variable is only initialized once. + not vai.getEnclosingFunction() = v and vai.getEnclosingIRFunction() = f and vai.getAstVariable() = v and isUse(_, _, vai, indirection, indirectionIndex) and diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 66ba5a324def..323ce2a43121 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -327,7 +327,6 @@ irFlow | test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source | | test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x | | test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | -| test.cpp:1158:18:1158:42 | ... , ... | test.cpp:1158:23:1158:31 | recursion | | true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x | | true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x | | true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 8e68a951f5a1..b804159d8583 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -1155,4 +1155,4 @@ namespace conflation_regression { } } -int recursion = (sink(recursion), source()); // $ SPURIOUS: ir \ No newline at end of file +int recursion = (sink(recursion), source()); // clean \ No newline at end of file From 1d36405084072f9cde8ec77de5732556c4d57844 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 14 Jul 2025 15:47:06 +0100 Subject: [PATCH 3/3] C++: Accept path changes. --- .../CWE/CWE-134/semmle/consts/NonConstantFormat.expected | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected index c2a952774ff0..b5f6ad602fb8 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected @@ -1,9 +1,6 @@ edges -| consts.cpp:24:7:24:9 | **gv1 | consts.cpp:25:2:25:4 | *a | provenance | | | consts.cpp:24:7:24:9 | **gv1 | consts.cpp:30:9:30:14 | *access to array | provenance | | | consts.cpp:24:7:24:9 | **gv1 | consts.cpp:123:2:123:12 | *... = ... | provenance | | -| consts.cpp:25:2:25:4 | *a | consts.cpp:26:2:26:4 | *{...} | provenance | | -| consts.cpp:26:2:26:4 | *{...} | consts.cpp:24:7:24:9 | **gv1 | provenance | | | consts.cpp:29:7:29:25 | **nonConstFuncToArray | consts.cpp:126:9:126:30 | *call to nonConstFuncToArray | provenance | | | consts.cpp:30:9:30:14 | *access to array | consts.cpp:29:7:29:25 | **nonConstFuncToArray | provenance | | | consts.cpp:85:7:85:8 | gets output argument | consts.cpp:86:9:86:10 | *v1 | provenance | | @@ -38,8 +35,6 @@ edges | consts.cpp:144:16:144:18 | readStringRef output argument | consts.cpp:145:9:145:11 | *v12 | provenance | | nodes | consts.cpp:24:7:24:9 | **gv1 | semmle.label | **gv1 | -| consts.cpp:25:2:25:4 | *a | semmle.label | *a | -| consts.cpp:26:2:26:4 | *{...} | semmle.label | *{...} | | consts.cpp:29:7:29:25 | **nonConstFuncToArray | semmle.label | **nonConstFuncToArray | | consts.cpp:30:9:30:14 | *access to array | semmle.label | *access to array | | consts.cpp:85:7:85:8 | gets output argument | semmle.label | gets output argument |