From 120d086c4d695298d40394c50fdf751d86d77367 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 18 May 2026 15:31:45 +0100 Subject: [PATCH 1/7] C++: Remove use of 'FunctionWithWrappers' from 'cpp/tainted-format-string'. --- .../CWE/CWE-134/UncontrolledFormatString.ql | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql index bf6f014672fb..f6bbf9404622 100644 --- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql +++ b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql @@ -15,7 +15,7 @@ import cpp import semmle.code.cpp.security.Security -import semmle.code.cpp.security.FunctionWithWrappers +import semmle.code.cpp.security.PrintfLike import semmle.code.cpp.security.FlowSources import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.ir.IR @@ -23,32 +23,18 @@ import Flow::PathGraph predicate isSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() } -/** - * Holds if `f` is a printf-like function or a (possibly nested) wrapper - * that forwards a format-string parameter to one. - * - * Functions that *implement* printf-like behavior (e.g. a custom - * `vsnprintf` variant) internally parse the caller-supplied format string - * and build small, bounded, local format strings such as `"%d"` or `"%ld"` - * for inner `sprintf` calls. Taint that reaches those inner calls via the - * parsed format specifier is not exploitable, so sinks inside such - * functions should be excluded. - */ -private predicate isPrintfImplementation(Function f) { - f instanceof PrintfLikeFunction - or - exists(PrintfLikeFunction printf | printf.wrapperFunction(f, _, _)) +predicate isSink(DataFlow::Node node, FormattingFunction f) { + exists(Call c, int i | + c.getTarget() = f and + i = f.getFormatParameterIndex() and + c.getArgument(i) = node.asIndirectExpr() + ) } module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { isSource(node, _) } - predicate isSink(DataFlow::Node node) { - exists(PrintfLikeFunction printf | - printf.outermostWrapperFunctionCall([node.asExpr(), node.asIndirectExpr()], _) - ) and - not isPrintfImplementation([node.asExpr(), node.asIndirectExpr()].getEnclosingFunction()) - } + predicate isSink(DataFlow::Node node) { isSink(node, _) } private predicate isArithmeticNonCharType(ArithmeticType type) { not type instanceof CharType and @@ -69,14 +55,14 @@ module Config implements DataFlow::ConfigSig { module Flow = TaintTracking::Global; from - PrintfLikeFunction printf, string printfFunction, string sourceType, DataFlow::Node source, - DataFlow::Node sink, Flow::PathNode sourceNode, Flow::PathNode sinkNode + Function printf, string sourceType, DataFlow::Node source, DataFlow::Node sink, + Flow::PathNode sourceNode, Flow::PathNode sinkNode where source = sourceNode.getNode() and sink = sinkNode.getNode() and isSource(source, sourceType) and - printf.outermostWrapperFunctionCall([sink.asExpr(), sink.asIndirectExpr()], printfFunction) and + isSink(sink, printf) and Flow::flowPath(sourceNode, sinkNode) select sink, sourceNode, sinkNode, "The value of this argument may come from $@ and is being used as a formatting argument to " + - printfFunction + ".", source, sourceType + printf + ".", source, sourceType From 842d4fb86aa28c0084e62a388d2fb27f9bfab3ff Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 22 May 2026 13:50:46 +0100 Subject: [PATCH 2/7] C++: Accept test changes. --- .../SAMATE/UncontrolledFormatString.expected | 6 +- .../CWE/CWE-134/semmle/argv/argvLocal.c | 2 +- .../CWE-134/semmle/argv/argvLocal.expected | 62 +++++++------------ .../CWE-134/semmle/funcs/funcsLocal.expected | 16 ++--- .../UncontrolledFormatString.expected | 15 ++--- .../CWE-134/semmle/globalVars/globalVars.c | 2 +- .../CWE/CWE-134/semmle/ifs/ifs.expected | 22 +++---- 7 files changed, 52 insertions(+), 73 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected index 560ecc8bd775..80ac7aeb5a70 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected @@ -22,6 +22,6 @@ nodes | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | semmle.label | *data | subpaths #select -| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink(data), which calls vsnprintf(format). | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | buffer read by recv | -| char_console_fprintf_01_bad.c:49:21:49:24 | *data | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | string read by fgets | -| char_environment_fprintf_01_bad.c:36:21:36:24 | *data | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | an environment variable | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink. | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | buffer read by recv | +| char_console_fprintf_01_bad.c:49:21:49:24 | *data | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf. | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | string read by fgets | +| char_environment_fprintf_01_bad.c:36:21:36:24 | *data | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf. | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | an environment variable | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.c index 5649c0e19b1c..42c9ce8e6484 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.c @@ -7,7 +7,7 @@ int printf(const char *format, ...); void *memcpy(void *s1, const void *s2, size_t n); void *malloc(size_t size); void printWrapper(char *correct) { - printf(correct); + printf(correct); // BAD } int main(int argc, char **argv) { diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected index 7b87c3ff440a..88b333008182 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected @@ -1,13 +1,13 @@ edges | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:9:25:9:31 | *correct | argvLocal.c:10:9:10:15 | *correct | provenance | | +| argvLocal.c:9:25:9:31 | *correct | argvLocal.c:10:9:10:15 | *correct | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | provenance | | -| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:100:2:100:13 | *... = ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:105:14:105:17 | **argv | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 | provenance | DataFlowFunction | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | provenance | DataFlowFunction | -| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | provenance | DataFlowFunction | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:120:13:120:14 | *i3 | provenance | DataFlowFunction | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:126:2:126:19 | ... = ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:149:2:149:17 | *... = ... | provenance | | @@ -17,32 +17,29 @@ edges | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:105:14:105:17 | **argv | provenance | | | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:116:9:116:10 | *i3 | provenance | DataFlowFunction | | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:117:15:117:16 | *i3 | provenance | DataFlowFunction | -| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:117:15:117:16 | *i3 | provenance | DataFlowFunction | | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:120:13:120:14 | *i3 | provenance | DataFlowFunction | | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:126:2:126:19 | ... = ... | provenance | | | argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:149:2:149:17 | *... = ... | provenance | | | argvLocal.c:100:2:100:13 | *... = ... | argvLocal.c:101:9:101:10 | *i1 | provenance | | | argvLocal.c:100:2:100:13 | *... = ... | argvLocal.c:102:15:102:16 | *i1 | provenance | | -| argvLocal.c:100:2:100:13 | *... = ... | argvLocal.c:102:15:102:16 | *i1 | provenance | | | argvLocal.c:100:2:100:13 | *... = ... | argvLocal.c:143:13:143:26 | *... , ... | provenance | | | argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:102:15:102:16 | printWrapper output argument | provenance | | | argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:143:13:143:26 | *... , ... | provenance | | | argvLocal.c:105:14:105:17 | **argv | argvLocal.c:106:9:106:13 | *access to array | provenance | | | argvLocal.c:105:14:105:17 | **argv | argvLocal.c:107:15:107:19 | *access to array | provenance | | -| argvLocal.c:105:14:105:17 | **argv | argvLocal.c:107:15:107:19 | *access to array | provenance | | | argvLocal.c:105:14:105:17 | **argv | argvLocal.c:110:9:110:11 | ** ... | provenance | | | argvLocal.c:105:14:105:17 | **argv | argvLocal.c:111:15:111:17 | ** ... | provenance | | | argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:107:15:107:19 | printWrapper output argument | provenance | | | argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | ** ... | provenance | | | argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:111:15:111:17 | ** ... | provenance | | +| argvLocal.c:111:15:111:17 | ** ... | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:117:15:117:16 | printWrapper output argument | provenance | | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:120:13:120:14 | *i3 | provenance | | | argvLocal.c:120:13:120:14 | *i3 | argvLocal.c:121:9:121:10 | *i4 | provenance | | | argvLocal.c:120:13:120:14 | *i3 | argvLocal.c:122:15:122:16 | *i4 | provenance | | -| argvLocal.c:120:13:120:14 | *i3 | argvLocal.c:122:15:122:16 | *i4 | provenance | | | argvLocal.c:120:13:120:14 | *i3 | argvLocal.c:135:9:135:12 | *... ++ | provenance | | | argvLocal.c:120:13:120:14 | *i3 | argvLocal.c:135:9:135:12 | *... ++ | provenance | | | argvLocal.c:122:15:122:16 | *i4 | argvLocal.c:9:25:9:31 | *correct | provenance | | @@ -51,17 +48,14 @@ edges | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | *... ++ | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:127:9:127:10 | *i5 | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:128:15:128:16 | *i5 | provenance | | -| argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:128:15:128:16 | *i5 | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:131:9:131:14 | *... + ... | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:132:15:132:20 | *... + ... | provenance | | -| argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:132:15:132:20 | *... + ... | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | | argvLocal.c:126:2:126:19 | ... = ... | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | | argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:128:15:128:16 | printWrapper output argument | provenance | | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | *... + ... | provenance | | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | -| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | | argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:9:25:9:31 | *correct | provenance | | @@ -69,48 +63,47 @@ edges | argvLocal.c:132:15:132:20 | printWrapper output argument | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | | argvLocal.c:132:15:132:20 | printWrapper output argument | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | | argvLocal.c:135:9:135:12 | *... ++ | argvLocal.c:136:15:136:18 | *-- ... | provenance | | +| argvLocal.c:136:15:136:18 | *-- ... | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:136:15:136:18 | *-- ... | argvLocal.c:136:15:136:18 | *-- ... | provenance | | +| argvLocal.c:140:15:140:32 | *... ? ... : ... | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:143:13:143:26 | *... , ... | argvLocal.c:144:9:144:10 | *i7 | provenance | | | argvLocal.c:143:13:143:26 | *... , ... | argvLocal.c:145:15:145:16 | *i7 | provenance | | +| argvLocal.c:145:15:145:16 | *i7 | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:149:2:149:17 | *... = ... | argvLocal.c:150:9:150:10 | *i8 | provenance | | | argvLocal.c:149:2:149:17 | *... = ... | argvLocal.c:151:15:151:16 | *i8 | provenance | | +| argvLocal.c:151:15:151:16 | *i8 | argvLocal.c:9:25:9:31 | *correct | provenance | | nodes | argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | | argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | +| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | +| argvLocal.c:10:9:10:15 | *correct | semmle.label | *correct | | argvLocal.c:13:27:13:30 | **argv | semmle.label | **argv | | argvLocal.c:95:9:95:15 | *access to array | semmle.label | *access to array | | argvLocal.c:96:15:96:21 | *access to array | semmle.label | *access to array | -| argvLocal.c:96:15:96:21 | *access to array | semmle.label | *access to array | | argvLocal.c:96:15:96:21 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:100:2:100:13 | *... = ... | semmle.label | *... = ... | | argvLocal.c:101:9:101:10 | *i1 | semmle.label | *i1 | | argvLocal.c:102:15:102:16 | *i1 | semmle.label | *i1 | -| argvLocal.c:102:15:102:16 | *i1 | semmle.label | *i1 | | argvLocal.c:102:15:102:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:105:14:105:17 | **argv | semmle.label | **argv | | argvLocal.c:106:9:106:13 | *access to array | semmle.label | *access to array | | argvLocal.c:107:15:107:19 | *access to array | semmle.label | *access to array | -| argvLocal.c:107:15:107:19 | *access to array | semmle.label | *access to array | | argvLocal.c:107:15:107:19 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:110:9:110:11 | ** ... | semmle.label | ** ... | | argvLocal.c:111:15:111:17 | ** ... | semmle.label | ** ... | | argvLocal.c:116:9:116:10 | *i3 | semmle.label | *i3 | | argvLocal.c:117:15:117:16 | *i3 | semmle.label | *i3 | -| argvLocal.c:117:15:117:16 | *i3 | semmle.label | *i3 | | argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:120:13:120:14 | *i3 | semmle.label | *i3 | | argvLocal.c:121:9:121:10 | *i4 | semmle.label | *i4 | | argvLocal.c:122:15:122:16 | *i4 | semmle.label | *i4 | -| argvLocal.c:122:15:122:16 | *i4 | semmle.label | *i4 | | argvLocal.c:122:15:122:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:126:2:126:19 | ... = ... | semmle.label | ... = ... | | argvLocal.c:127:9:127:10 | *i5 | semmle.label | *i5 | | argvLocal.c:128:15:128:16 | *i5 | semmle.label | *i5 | -| argvLocal.c:128:15:128:16 | *i5 | semmle.label | *i5 | | argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:131:9:131:14 | *... + ... | semmle.label | *... + ... | | argvLocal.c:132:15:132:20 | *... + ... | semmle.label | *... + ... | -| argvLocal.c:132:15:132:20 | *... + ... | semmle.label | *... + ... | | argvLocal.c:132:15:132:20 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:135:9:135:12 | *... ++ | semmle.label | *... ++ | | argvLocal.c:135:9:135:12 | *... ++ | semmle.label | *... ++ | @@ -133,27 +126,16 @@ subpaths | argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument | | argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:132:15:132:20 | printWrapper output argument | #select -| argvLocal.c:95:9:95:15 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:96:15:96:21 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:101:9:101:10 | *i1 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:101:9:101:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:102:15:102:16 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:106:9:106:13 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:106:9:106:13 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:107:15:107:19 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:110:9:110:11 | ** ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:110:9:110:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:111:15:111:17 | ** ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:111:15:111:17 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:116:9:116:10 | *i3 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:121:9:121:10 | *i4 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:121:9:121:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:122:15:122:16 | *i4 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:122:15:122:16 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:127:9:127:10 | *i5 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:127:9:127:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:128:15:128:16 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:131:9:131:14 | *... + ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:131:9:131:14 | *... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:132:15:132:20 | *... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:135:9:135:12 | *... ++ | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:135:9:135:12 | *... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:136:15:136:18 | *-- ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:136:15:136:18 | *-- ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:139:9:139:26 | *... ? ... : ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:139:9:139:26 | *... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:140:15:140:32 | *... ? ... : ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:140:15:140:32 | *... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:144:9:144:10 | *i7 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:144:9:144:10 | *i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:145:15:145:16 | *i7 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:145:15:145:16 | *i7 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:150:9:150:10 | *i8 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:150:9:150:10 | *i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | -| argvLocal.c:151:15:151:16 | *i8 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:151:15:151:16 | *i8 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:10:9:10:15 | *correct | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:10:9:10:15 | *correct | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:95:9:95:15 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:101:9:101:10 | *i1 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:101:9:101:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:106:9:106:13 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:106:9:106:13 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:110:9:110:11 | ** ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:110:9:110:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:116:9:116:10 | *i3 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:121:9:121:10 | *i4 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:121:9:121:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:127:9:127:10 | *i5 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:127:9:127:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:131:9:131:14 | *... + ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:131:9:131:14 | *... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:135:9:135:12 | *... ++ | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:135:9:135:12 | *... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:139:9:139:26 | *... ? ... : ... | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:139:9:139:26 | *... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:144:9:144:10 | *i7 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:144:9:144:10 | *i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | +| argvLocal.c:150:9:150:10 | *i8 | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:150:9:150:10 | *i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | argvLocal.c:13:27:13:30 | **argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index 4447b215aedf..28e89f7da6f6 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -33,11 +33,11 @@ nodes | funcsLocal.c:58:9:58:10 | *e1 | semmle.label | *e1 | subpaths #select -| funcsLocal.c:17:9:17:10 | *i1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | -| funcsLocal.c:27:9:27:10 | *i3 | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:26:8:26:9 | fgets output argument | string read by fgets | -| funcsLocal.c:32:9:32:10 | *i4 | funcsLocal.c:31:13:31:17 | *call to fgets | funcsLocal.c:32:9:32:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:31:13:31:17 | *call to fgets | string read by fgets | -| funcsLocal.c:37:9:37:10 | *i5 | funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:36:7:36:8 | gets output argument | string read by gets | -| funcsLocal.c:42:9:42:10 | *i6 | funcsLocal.c:41:13:41:16 | *call to gets | funcsLocal.c:42:9:42:10 | *i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:41:13:41:16 | *call to gets | string read by gets | -| funcsLocal.c:47:9:47:11 | ** ... | funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:46:7:46:9 | gets output argument | string read by gets | -| funcsLocal.c:53:9:53:11 | ** ... | funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:53:9:53:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:52:8:52:11 | *call to gets | string read by gets | -| funcsLocal.c:58:9:58:10 | *e1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | *e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | +| funcsLocal.c:17:9:17:10 | *i1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | +| funcsLocal.c:27:9:27:10 | *i3 | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:26:8:26:9 | fgets output argument | string read by fgets | +| funcsLocal.c:32:9:32:10 | *i4 | funcsLocal.c:31:13:31:17 | *call to fgets | funcsLocal.c:32:9:32:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:31:13:31:17 | *call to fgets | string read by fgets | +| funcsLocal.c:37:9:37:10 | *i5 | funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:36:7:36:8 | gets output argument | string read by gets | +| funcsLocal.c:42:9:42:10 | *i6 | funcsLocal.c:41:13:41:16 | *call to gets | funcsLocal.c:42:9:42:10 | *i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:41:13:41:16 | *call to gets | string read by gets | +| funcsLocal.c:47:9:47:11 | ** ... | funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:46:7:46:9 | gets output argument | string read by gets | +| funcsLocal.c:53:9:53:11 | ** ... | funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:53:9:53:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:52:8:52:11 | *call to gets | string read by gets | +| funcsLocal.c:58:9:58:10 | *e1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | *e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected index 7408d8360ef5..6cf3ad59e3de 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected @@ -2,12 +2,10 @@ edges | globalVars.c:8:7:8:10 | **copy | globalVars.c:8:7:8:10 | **copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:27:9:27:12 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | -| globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:35:11:35:14 | *copy | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:9:7:9:11 | **copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:38:9:38:13 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | -| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:50:9:50:13 | *copy2 | provenance | | | globalVars.c:11:22:11:25 | **argv | globalVars.c:12:2:12:15 | *... = ... | provenance | | | globalVars.c:12:2:12:15 | *... = ... | globalVars.c:8:7:8:10 | **copy | provenance | | @@ -15,6 +13,7 @@ edges | globalVars.c:15:21:15:23 | *val | globalVars.c:16:2:16:12 | *... = ... | provenance | | | globalVars.c:16:2:16:12 | *... = ... | globalVars.c:9:7:9:11 | **copy2 | provenance | | | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | provenance | | +| globalVars.c:19:25:19:27 | *str | globalVars.c:20:9:20:11 | *str | provenance | | | globalVars.c:23:27:23:30 | **argv | globalVars.c:24:11:24:14 | **argv | provenance | | | globalVars.c:24:11:24:14 | **argv | globalVars.c:11:22:11:25 | **argv | provenance | | | globalVars.c:30:15:30:18 | *copy | globalVars.c:19:25:19:27 | *str | provenance | | @@ -38,17 +37,16 @@ nodes | globalVars.c:16:2:16:12 | *... = ... | semmle.label | *... = ... | | globalVars.c:19:25:19:27 | *str | semmle.label | *str | | globalVars.c:19:25:19:27 | *str | semmle.label | *str | +| globalVars.c:20:9:20:11 | *str | semmle.label | *str | | globalVars.c:23:27:23:30 | **argv | semmle.label | **argv | | globalVars.c:24:11:24:14 | **argv | semmle.label | **argv | | globalVars.c:27:9:27:12 | *copy | semmle.label | *copy | | globalVars.c:30:15:30:18 | *copy | semmle.label | *copy | -| globalVars.c:30:15:30:18 | *copy | semmle.label | *copy | | globalVars.c:30:15:30:18 | printWrapper output argument | semmle.label | printWrapper output argument | | globalVars.c:35:11:35:14 | *copy | semmle.label | *copy | | globalVars.c:35:11:35:14 | setCopy2 output argument | semmle.label | setCopy2 output argument | | globalVars.c:38:9:38:13 | *copy2 | semmle.label | *copy2 | | globalVars.c:41:15:41:19 | *copy2 | semmle.label | *copy2 | -| globalVars.c:41:15:41:19 | *copy2 | semmle.label | *copy2 | | globalVars.c:41:15:41:19 | printWrapper output argument | semmle.label | printWrapper output argument | | globalVars.c:50:9:50:13 | *copy2 | semmle.label | *copy2 | subpaths @@ -56,8 +54,7 @@ subpaths | globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val | globalVars.c:15:21:15:23 | *val | globalVars.c:35:11:35:14 | setCopy2 output argument | | globalVars.c:41:15:41:19 | *copy2 | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | globalVars.c:41:15:41:19 | printWrapper output argument | #select -| globalVars.c:27:9:27:12 | *copy | globalVars.c:23:27:23:30 | **argv | globalVars.c:27:9:27:12 | *copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | -| globalVars.c:30:15:30:18 | *copy | globalVars.c:23:27:23:30 | **argv | globalVars.c:30:15:30:18 | *copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | -| globalVars.c:38:9:38:13 | *copy2 | globalVars.c:23:27:23:30 | **argv | globalVars.c:38:9:38:13 | *copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | -| globalVars.c:41:15:41:19 | *copy2 | globalVars.c:23:27:23:30 | **argv | globalVars.c:41:15:41:19 | *copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | -| globalVars.c:50:9:50:13 | *copy2 | globalVars.c:23:27:23:30 | **argv | globalVars.c:50:9:50:13 | *copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | +| globalVars.c:20:9:20:11 | *str | globalVars.c:23:27:23:30 | **argv | globalVars.c:20:9:20:11 | *str | The value of this argument may come from $@ and is being used as a formatting argument to printf. | globalVars.c:23:27:23:30 | **argv | a command-line argument | +| globalVars.c:27:9:27:12 | *copy | globalVars.c:23:27:23:30 | **argv | globalVars.c:27:9:27:12 | *copy | The value of this argument may come from $@ and is being used as a formatting argument to printf. | globalVars.c:23:27:23:30 | **argv | a command-line argument | +| globalVars.c:38:9:38:13 | *copy2 | globalVars.c:23:27:23:30 | **argv | globalVars.c:38:9:38:13 | *copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | globalVars.c:23:27:23:30 | **argv | a command-line argument | +| globalVars.c:50:9:50:13 | *copy2 | globalVars.c:23:27:23:30 | **argv | globalVars.c:50:9:50:13 | *copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | globalVars.c:23:27:23:30 | **argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/globalVars.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/globalVars.c index c36c708eab04..f74a39366d8f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/globalVars.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/globalVars.c @@ -17,7 +17,7 @@ void setCopy2(char *val) { } void printWrapper(char *str) { - printf(str); + printf(str); // BAD } int main(int argc, char **argv) { diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected index e8d852cbcd27..e21c9387e0ea 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected @@ -47,14 +47,14 @@ nodes | ifs.c:124:9:124:10 | *i9 | semmle.label | *i9 | subpaths #select -| ifs.c:62:9:62:10 | *c7 | ifs.c:16:27:16:30 | **argv | ifs.c:62:9:62:10 | *c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:69:9:69:10 | *c8 | ifs.c:16:27:16:30 | **argv | ifs.c:69:9:69:10 | *c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:75:9:75:10 | *i1 | ifs.c:16:27:16:30 | **argv | ifs.c:75:9:75:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:81:9:81:10 | *i2 | ifs.c:16:27:16:30 | **argv | ifs.c:81:9:81:10 | *i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:87:9:87:10 | *i3 | ifs.c:16:27:16:30 | **argv | ifs.c:87:9:87:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:93:9:93:10 | *i4 | ifs.c:16:27:16:30 | **argv | ifs.c:93:9:93:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:99:9:99:10 | *i5 | ifs.c:16:27:16:30 | **argv | ifs.c:99:9:99:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:106:9:106:10 | *i6 | ifs.c:16:27:16:30 | **argv | ifs.c:106:9:106:10 | *i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:112:9:112:10 | *i7 | ifs.c:16:27:16:30 | **argv | ifs.c:112:9:112:10 | *i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:118:9:118:10 | *i8 | ifs.c:16:27:16:30 | **argv | ifs.c:118:9:118:10 | *i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | -| ifs.c:124:9:124:10 | *i9 | ifs.c:16:27:16:30 | **argv | ifs.c:124:9:124:10 | *i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:62:9:62:10 | *c7 | ifs.c:16:27:16:30 | **argv | ifs.c:62:9:62:10 | *c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:69:9:69:10 | *c8 | ifs.c:16:27:16:30 | **argv | ifs.c:69:9:69:10 | *c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:75:9:75:10 | *i1 | ifs.c:16:27:16:30 | **argv | ifs.c:75:9:75:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:81:9:81:10 | *i2 | ifs.c:16:27:16:30 | **argv | ifs.c:81:9:81:10 | *i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:87:9:87:10 | *i3 | ifs.c:16:27:16:30 | **argv | ifs.c:87:9:87:10 | *i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:93:9:93:10 | *i4 | ifs.c:16:27:16:30 | **argv | ifs.c:93:9:93:10 | *i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:99:9:99:10 | *i5 | ifs.c:16:27:16:30 | **argv | ifs.c:99:9:99:10 | *i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:106:9:106:10 | *i6 | ifs.c:16:27:16:30 | **argv | ifs.c:106:9:106:10 | *i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:112:9:112:10 | *i7 | ifs.c:16:27:16:30 | **argv | ifs.c:112:9:112:10 | *i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:118:9:118:10 | *i8 | ifs.c:16:27:16:30 | **argv | ifs.c:118:9:118:10 | *i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | +| ifs.c:124:9:124:10 | *i9 | ifs.c:16:27:16:30 | **argv | ifs.c:124:9:124:10 | *i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | ifs.c:16:27:16:30 | **argv | a command-line argument | From f0b7eabb9eb917762e9e7a4953bd320a7182e7a5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 22 May 2026 13:54:36 +0100 Subject: [PATCH 3/7] C++: Add tests with missing sinks. --- .../CWE/CWE-134/semmle/funcs/funcsLocal.c | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c index d2b28baac236..4085af5423ab 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c @@ -59,3 +59,70 @@ int main(int argc, char **argv) { return 0; } + +typedef void *va_list; +typedef void *_locale_t; + +int vprintf(const char *format, va_list argptr); +int _vprintf_l(const char *format, _locale_t locale, va_list argptr); + +int vfprintf(FILE *stream, const char *format, va_list argptr); +int _vfprintf_l(FILE *stream, const char *format, _locale_t locale, va_list argptr); + +int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr); +int _vsnprintf(char *buffer, size_t count, const char *format, va_list argptr); +int _vsnprintf_l(char *buffer, size_t count, const char *format, _locale_t locale, va_list argptr); + +int vsnprintf_s( + char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list argptr +); +int _vsnprintf_s( + char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list argptr +); +int _vsnprintf_s_l( + char *buffer, size_t sizeOfBuffer, size_t count, const char *format, _locale_t locale, + va_list argptr +); + +int vsprintf(char *buffer, const char *format, va_list argptr); +int _vsprintf_l(char *buffer, const char *format, _locale_t locale, va_list argptr); + +int _vsprintf_p(char *buffer, size_t sizeInBytes, const char *format, va_list argptr); +int _vsprintf_p_l( + char *buffer, size_t sizeInBytes, const char *format, _locale_t locale, va_list argptr +); + +int vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr); +int _vsprintf_s_l( + char *buffer, size_t numberOfElements, const char *format, _locale_t locale, va_list argptr +); + +int _vscprintf_p(const char *format, va_list argptr); +int _vscprintf_p_l(const char *format, _locale_t locale, va_list argptr); + +void test() { + // BAD: User input flowing to various printf-like functions. + char fmt[1024]; + char out[1024]; + va_list args = 0; + _locale_t locale = 0; + fread(fmt, sizeof(char), 1024, f); + vprintf(fmt, args); // MISSING: BAD + _vprintf_l(fmt, locale, args); // MISSING: BAD + vfprintf(f, fmt, args); // MISSING: BAD + _vfprintf_l(f, fmt, locale, args); // MISSING: BAD + vsnprintf(out, 1024, fmt, args); // MISSING: BAD + _vsnprintf(out, 1024, fmt, args); // MISSING: BAD + _vsnprintf_l(out, 1024, fmt, locale, args); // MISSING: BAD + vsnprintf_s(out, 1024, 1024, fmt, args); // MISSING: BAD + _vsnprintf_s(out, 1024, 1024, fmt, args); // MISSING: BAD + _vsnprintf_s_l(out, 1024, 1024, fmt, locale, args); // MISSING: BAD + vsprintf(out, fmt, args); // MISSING: BAD + _vsprintf_l(out, fmt, locale, args); // MISSING: BAD + _vsprintf_p(out, 1024, fmt, args); // MISSING: BAD + _vsprintf_p_l(out, 1024, fmt, locale, args); // MISSING: BAD + vsprintf_s(out, 1024, fmt, args); // MISSING: BAD + _vsprintf_s_l(out, 1024, fmt, locale, args); // MISSING: BAD + _vscprintf_p(fmt, args); // MISSING: BAD + _vscprintf_p_l(fmt, locale, args); // MISSING: BAD +} \ No newline at end of file From 96277f370f18daec21679bf6235b969f561f2b1c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 21 May 2026 16:46:01 +0100 Subject: [PATCH 4/7] C++: drive-by improvement: use non-extending subtyping. --- .../cpp/models/implementations/Printf.qll | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index d4b054ea0b54..6b9b4dee0645 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -13,9 +13,9 @@ import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `printf`, `wprintf` and their glib variants. */ -private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFunction { +private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ Printf() { - this instanceof TopLevelFunction and ( this.hasGlobalOrStdOrBslName(["printf", "wprintf"]) or this.hasGlobalName(["printf_s", "wprintf_s", "g_printf"]) @@ -37,9 +37,9 @@ private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFu /** * The standard functions `fprintf`, `fwprintf` and their glib variants. */ -private class Fprintf extends FormattingFunction, NonCppThrowingFunction { +private class Fprintf extends FormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ Fprintf() { - this instanceof TopLevelFunction and ( this.hasGlobalOrStdOrBslName(["fprintf", "fwprintf"]) or this.hasGlobalName("g_fprintf") @@ -55,9 +55,9 @@ private class Fprintf extends FormattingFunction, NonCppThrowingFunction { /** * The standard function `sprintf` and its Microsoft and glib variants. */ -private class Sprintf extends FormattingFunction, NonCppThrowingFunction { +private class Sprintf extends FormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ Sprintf() { - this instanceof TopLevelFunction and ( this.hasGlobalOrStdOrBslName([ "sprintf", // sprintf(dst, format, args...) @@ -99,10 +99,9 @@ private class Sprintf extends FormattingFunction, NonCppThrowingFunction { * Implements `Snprintf`. */ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, - NonCppThrowingFunction + NonCppThrowingFunction instanceof TopLevelFunction { SnprintfImpl() { - this instanceof TopLevelFunction and ( this.hasGlobalOrStdOrBslName([ "snprintf", // C99 defines snprintf @@ -175,9 +174,8 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, * and * https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10) */ -private class StringCchPrintf extends FormattingFunction { +private class StringCchPrintf extends FormattingFunction instanceof TopLevelFunction { StringCchPrintf() { - this instanceof TopLevelFunction and exists(string baseName | baseName in [ "StringCchPrintf", //StringCchPrintf(pszDest, cchDest, pszFormat, ...) @@ -207,9 +205,8 @@ private class StringCchPrintf extends FormattingFunction { /** * The standard function `syslog`. */ -private class Syslog extends FormattingFunction, NonCppThrowingFunction { +private class Syslog extends FormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction { Syslog() { - this instanceof TopLevelFunction and this.hasGlobalName("syslog") and not exists(this.getDefinition().getFile().getRelativePath()) } From e073ecb752b70e16c4547e652e7374765df5af8a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 21 May 2026 16:51:58 +0100 Subject: [PATCH 5/7] C++: Make it possible for 'getFirstFormatArgumentIndex' to sometimes have no result. --- .../cpp/models/implementations/Printf.qll | 17 +++++++++++ .../models/interfaces/FormattingFunction.qll | 30 +++++++++---------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 6b9b4dee0645..c43a16d46635 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -10,6 +10,23 @@ import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.NonThrowing +/** + * A formatting function that takes its format arguments through a `va_list` parameter. + */ +abstract private class VaListFormattingFunction extends FormattingFunction { + final override int getFirstFormatArgumentIndex() { none() } + + final int getVaListParameterIndex() { result = this.getNumberOfParameters() - 1 } + + private predicate hasLocaleParameter() { this.getName().matches("%\\_l") } + + final override int getFormatParameterIndex() { + if this.hasLocaleParameter() + then result = this.getVaListParameterIndex() - 2 + else result = this.getVaListParameterIndex() - 1 + } +} + /** * The standard functions `printf`, `wprintf` and their glib variants. */ diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll index 757db13fe8c3..8fb36c54d371 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll @@ -42,21 +42,6 @@ private Type getAFormatterWideTypeOrDefault() { * A standard library function that uses a `printf`-like formatting string. */ abstract class FormattingFunction extends ArrayFunction, TaintFunction { - int firstFormatArgumentIndex; - - FormattingFunction() { - firstFormatArgumentIndex > 0 and - if this.hasDefinition() - then firstFormatArgumentIndex = this.getDefinition().getNumberOfParameters() - else - if this instanceof BuiltInFunction - then firstFormatArgumentIndex = this.getNumberOfParameters() - else - forex(FunctionDeclarationEntry fde | fde = this.getAnExplicitDeclarationEntry() | - firstFormatArgumentIndex = fde.getNumberOfParameters() - ) - } - /** Gets the position at which the format parameter occurs. */ abstract int getFormatParameterIndex(); @@ -135,8 +120,21 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction { * Gets the position of the first format argument, corresponding with * the first format specifier in the format string. We ignore all * implicit function definitions. + * + * There is no result if the formatting function takes a `va_list` argument. */ - int getFirstFormatArgumentIndex() { result = firstFormatArgumentIndex } + int getFirstFormatArgumentIndex() { + result > 0 and + if this.hasDefinition() + then result = this.getDefinition().getNumberOfParameters() + else + if this instanceof BuiltInFunction + then result = this.getNumberOfParameters() + else + forex(FunctionDeclarationEntry fde | fde = this.getAnExplicitDeclarationEntry() | + result = fde.getNumberOfParameters() + ) + } /** * Gets the position of the buffer size argument, if any. From ab27d7d2c0f18166d6e43a764a1aaf630018aa07 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 21 May 2026 16:52:46 +0100 Subject: [PATCH 6/7] C++: Add a bunch of vararg related formatting functions that takes a 'va_list' parameter. --- .../cpp/models/implementations/Printf.qll | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index c43a16d46635..b261aea703d6 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -69,6 +69,38 @@ private class Fprintf extends FormattingFunction, NonCppThrowingFunction instanc override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } } +/** + * The standard functions `vprintf`, `vwprintf` and their Microsoft variants. + */ +private class Vprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ + Vprintf() { + ( + this.hasGlobalOrStdOrBslName(["vprintf", "vwprintf"]) or + this.hasGlobalName(["_vprintf_l", "_vwprintf_l"]) + ) and + not exists(this.getDefinition().getFile().getRelativePath()) + } + + override predicate isOutputGlobal() { any() } +} + +/** + * The standard functions `vfprintf`, `vfwprintf` and their Microsoft variants. + */ +private class Vfprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ + Vfprintf() { + ( + this.hasGlobalOrStdOrBslName(["vfprintf", "vfwprintf"]) or + this.hasGlobalName(["_vfprintf_l", "_vfwprintf_l"]) + ) and + not exists(this.getDefinition().getFile().getRelativePath()) + } + + override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } +} + /** * The standard function `sprintf` and its Microsoft and glib variants. */ @@ -112,6 +144,25 @@ private class Sprintf extends FormattingFunction, NonCppThrowingFunction instanc } } +/** + * The standard function `vsprintf` and its Microsoft variants. + */ +private class Vsprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ + Vsprintf() { + ( + this.hasGlobalOrStdOrBslName("vsprintf") or // vsprintf(dst, format, va_list) + this.hasGlobalName([ + "_vsprintf_l", // _vsprintf_l(dst, format, locale, va_list) + "__vswprintf_l" // __vswprintf_l(dst, format, locale, va_list) + ]) + ) and + not exists(this.getDefinition().getFile().getRelativePath()) + } + + override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false } +} + /** * Implements `Snprintf`. */ @@ -185,6 +236,94 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, } } +/** + * The standard function `vsnprintf`, and its Microsoft variants. + */ +private class VsnprintfImpl extends Snprintf, VaListFormattingFunction, AliasFunction, + SideEffectFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ + VsnprintfImpl() { + ( + this.hasGlobalOrStdOrBslName("vsnprintf") // vsnprintf(dst, count, format, va_list) + or + this.hasGlobalName([ + "vsnprintf_s", // vsnprintf_s(dst, size, count, format, va_list) + "vsprintf_s", // vsprintf_s(dst, size, format, va_list) + "vswprintf_s", // vswprintf_s(dst, size, format, va_list) + "_vsnprintf", // _vsnprintf(dst, count, format, va_list) + "_vsnprintf_l", // _vsnprintf_l(dst, count, format, locale, va_list) + "_vsnprintf_s", // _vsnprintf_s(dst, size, count, format, va_list) + "_vsnprintf_s_l", // _vsnprintf_s_l(dst, size, count, format, locale, va_list) + "_vsnwprintf", // _vsnwprintf(dst, count, format, va_list) + "_vsnwprintf_l", // _vsnwprintf_l(dst, count, format, locale, va_list) + "_vsnwprintf_s", // _vsnwprintf_s(dst, size, count, format, va_list) + "_vsnwprintf_s_l", // _vsnwprintf_s_l(dst, size, count, format, locale, va_list) + "_vsprintf_p", // _vsprintf_p(dst, size, format, va_list) + "_vsprintf_p_l", // _vsprintf_p_l(dst, size, format, locale, va_list) + "_vsprintf_s_l", // _vsprintf_s_l(dst, size, format, locale, va_list) + "_vswprintf_p", // _vswprintf_p(dst, count, format, va_list) + "_vswprintf_p_l", // _vswprintf_p_l(dst, count, format, locale, va_list) + "_vswprintf_s_l" // _vswprintf_s_l(dst, size, format, locale, va_list) + ]) + or + this.hasGlobalOrStdOrBslName("vswprintf") and this.getNumberOfParameters() = 4 + or + this.hasGlobalName("_vswprintf_l") and this.getNumberOfParameters() = 5 + ) and + not exists(this.getDefinition().getFile().getRelativePath()) + } + + override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false } + + override int getSizeParameterIndex() { result = 1 } + + override predicate returnsFullFormatLength() { this.hasName(["vsnprintf", "vsnprintf_s"]) } + + override predicate parameterNeverEscapes(int index) { + index = + [ + this.getOutputParameterIndex(false), this.getFormatParameterIndex(), + this.getVaListParameterIndex() + ] + } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = this.getOutputParameterIndex(false) and buffer = true and mustWrite = false + or + i = this.getVaListParameterIndex() and buffer = false and mustWrite = false + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = this.getFormatParameterIndex() and buffer = true + or + i = this.getVaListParameterIndex() and buffer = false + } +} + +/** + * The Microsoft `_vscprintf_p` functions and variants. + */ +private class Vscprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction +{ + Vscprintf() { + this.hasGlobalName([ + "_vscprintf_p", // _vscprintf_p(format, va_list) + "_vscprintf_p_l", // _vscprintf_p_l(format, locale, va_list) + "_vscwprintf_p", // _vscwprintf_p(format, va_list) + "_vscwprintf_p_l" // _vscwprintf_p_l(format, locale, va_list) + ]) and + not exists(this.getDefinition().getFile().getRelativePath()) + } +} + /** * The Microsoft `StringCchPrintf` function and variants. * See: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/ From 24bdc34f275dcc9eedf3c31bb7ae3f38248ea73f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 22 May 2026 13:57:48 +0100 Subject: [PATCH 7/7] C++: Accept test changes. --- .../SAMATE/UncontrolledFormatString.expected | 8 +++ .../CWE/CWE-134/semmle/funcs/funcsLocal.c | 36 ++++++------ .../CWE-134/semmle/funcs/funcsLocal.expected | 55 +++++++++++++++++++ 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected index 80ac7aeb5a70..c41090cac637 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected @@ -1,7 +1,11 @@ edges +| char_connect_socket_w32_vsnprintf_01_bad.c:40:30:40:33 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:47:32:47:35 | *data | provenance | | | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | provenance | | | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | | +| char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | | | char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:40:30:40:33 | *data | provenance | | | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:37:21:37:43 | ... = ... | provenance | | | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:44:17:44:37 | ... = ... | provenance | | | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | provenance | | @@ -10,9 +14,12 @@ edges | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | provenance | | | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | provenance | TaintFunction | nodes +| char_connect_socket_w32_vsnprintf_01_bad.c:40:30:40:33 | *data | semmle.label | *data | +| char_connect_socket_w32_vsnprintf_01_bad.c:47:32:47:35 | *data | semmle.label | *data | | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument | | char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | semmle.label | ... = ... | | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | semmle.label | *data | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | semmle.label | *data | | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | semmle.label | fgets output argument | | char_console_fprintf_01_bad.c:37:21:37:43 | ... = ... | semmle.label | ... = ... | | char_console_fprintf_01_bad.c:44:17:44:37 | ... = ... | semmle.label | ... = ... | @@ -22,6 +29,7 @@ nodes | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | semmle.label | *data | subpaths #select +| char_connect_socket_w32_vsnprintf_01_bad.c:47:32:47:35 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:47:32:47:35 | *data | The value of this argument may come from $@ and is being used as a formatting argument to vsnprintf. | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | buffer read by recv | | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink. | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | buffer read by recv | | char_console_fprintf_01_bad.c:49:21:49:24 | *data | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf. | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | string read by fgets | | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf. | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | an environment variable | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c index 4085af5423ab..fced7a32d874 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.c @@ -107,22 +107,22 @@ void test() { va_list args = 0; _locale_t locale = 0; fread(fmt, sizeof(char), 1024, f); - vprintf(fmt, args); // MISSING: BAD - _vprintf_l(fmt, locale, args); // MISSING: BAD - vfprintf(f, fmt, args); // MISSING: BAD - _vfprintf_l(f, fmt, locale, args); // MISSING: BAD - vsnprintf(out, 1024, fmt, args); // MISSING: BAD - _vsnprintf(out, 1024, fmt, args); // MISSING: BAD - _vsnprintf_l(out, 1024, fmt, locale, args); // MISSING: BAD - vsnprintf_s(out, 1024, 1024, fmt, args); // MISSING: BAD - _vsnprintf_s(out, 1024, 1024, fmt, args); // MISSING: BAD - _vsnprintf_s_l(out, 1024, 1024, fmt, locale, args); // MISSING: BAD - vsprintf(out, fmt, args); // MISSING: BAD - _vsprintf_l(out, fmt, locale, args); // MISSING: BAD - _vsprintf_p(out, 1024, fmt, args); // MISSING: BAD - _vsprintf_p_l(out, 1024, fmt, locale, args); // MISSING: BAD - vsprintf_s(out, 1024, fmt, args); // MISSING: BAD - _vsprintf_s_l(out, 1024, fmt, locale, args); // MISSING: BAD - _vscprintf_p(fmt, args); // MISSING: BAD - _vscprintf_p_l(fmt, locale, args); // MISSING: BAD + vprintf(fmt, args); // BAD + _vprintf_l(fmt, locale, args); // BAD + vfprintf(f, fmt, args); // BAD + _vfprintf_l(f, fmt, locale, args); // BAD + vsnprintf(out, 1024, fmt, args); // BAD + _vsnprintf(out, 1024, fmt, args); // BAD + _vsnprintf_l(out, 1024, fmt, locale, args); // BAD + vsnprintf_s(out, 1024, 1024, fmt, args); // BAD + _vsnprintf_s(out, 1024, 1024, fmt, args); // BAD + _vsnprintf_s_l(out, 1024, 1024, fmt, locale, args); // BAD + vsprintf(out, fmt, args); // BAD + _vsprintf_l(out, fmt, locale, args); // BAD + _vsprintf_p(out, 1024, fmt, args); // BAD + _vsprintf_p_l(out, 1024, fmt, locale, args); // BAD + vsprintf_s(out, 1024, fmt, args); // BAD + _vsprintf_s_l(out, 1024, fmt, locale, args); // BAD + _vscprintf_p(fmt, args); // BAD + _vscprintf_p_l(fmt, locale, args); // BAD } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index 28e89f7da6f6..9ff344e87d30 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -11,6 +11,24 @@ edges | funcsLocal.c:52:2:52:16 | *... = ... | funcsLocal.c:53:9:53:11 | ** ... | provenance | | | funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:52:2:52:16 | *... = ... | provenance | | | funcsLocal.c:57:2:57:14 | ... = ... | funcsLocal.c:58:9:58:10 | *e1 | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:110:10:110:12 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:111:13:111:15 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:112:14:112:16 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:113:17:113:19 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:114:23:114:25 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:115:24:115:26 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:116:26:116:28 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:117:31:117:33 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:118:32:118:34 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:119:34:119:36 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:120:16:120:18 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:121:19:121:21 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:122:25:122:27 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:123:27:123:29 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:124:24:124:26 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:125:27:125:29 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:126:15:126:17 | *fmt | provenance | | +| funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:127:17:127:19 | *fmt | provenance | | nodes | funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument | | funcsLocal.c:17:9:17:10 | *i1 | semmle.label | *i1 | @@ -31,6 +49,25 @@ nodes | funcsLocal.c:53:9:53:11 | ** ... | semmle.label | ** ... | | funcsLocal.c:57:2:57:14 | ... = ... | semmle.label | ... = ... | | funcsLocal.c:58:9:58:10 | *e1 | semmle.label | *e1 | +| funcsLocal.c:109:8:109:10 | fread output argument | semmle.label | fread output argument | +| funcsLocal.c:110:10:110:12 | *fmt | semmle.label | *fmt | +| funcsLocal.c:111:13:111:15 | *fmt | semmle.label | *fmt | +| funcsLocal.c:112:14:112:16 | *fmt | semmle.label | *fmt | +| funcsLocal.c:113:17:113:19 | *fmt | semmle.label | *fmt | +| funcsLocal.c:114:23:114:25 | *fmt | semmle.label | *fmt | +| funcsLocal.c:115:24:115:26 | *fmt | semmle.label | *fmt | +| funcsLocal.c:116:26:116:28 | *fmt | semmle.label | *fmt | +| funcsLocal.c:117:31:117:33 | *fmt | semmle.label | *fmt | +| funcsLocal.c:118:32:118:34 | *fmt | semmle.label | *fmt | +| funcsLocal.c:119:34:119:36 | *fmt | semmle.label | *fmt | +| funcsLocal.c:120:16:120:18 | *fmt | semmle.label | *fmt | +| funcsLocal.c:121:19:121:21 | *fmt | semmle.label | *fmt | +| funcsLocal.c:122:25:122:27 | *fmt | semmle.label | *fmt | +| funcsLocal.c:123:27:123:29 | *fmt | semmle.label | *fmt | +| funcsLocal.c:124:24:124:26 | *fmt | semmle.label | *fmt | +| funcsLocal.c:125:27:125:29 | *fmt | semmle.label | *fmt | +| funcsLocal.c:126:15:126:17 | *fmt | semmle.label | *fmt | +| funcsLocal.c:127:17:127:19 | *fmt | semmle.label | *fmt | subpaths #select | funcsLocal.c:17:9:17:10 | *i1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | *i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | @@ -41,3 +78,21 @@ subpaths | funcsLocal.c:47:9:47:11 | ** ... | funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:46:7:46:9 | gets output argument | string read by gets | | funcsLocal.c:53:9:53:11 | ** ... | funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:53:9:53:11 | ** ... | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:52:8:52:11 | *call to gets | string read by gets | | funcsLocal.c:58:9:58:10 | *e1 | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | *e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf. | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread | +| funcsLocal.c:110:10:110:12 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:110:10:110:12 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vprintf. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:111:13:111:15 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:111:13:111:15 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vprintf_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:112:14:112:16 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:112:14:112:16 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vfprintf. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:113:17:113:19 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:113:17:113:19 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vfprintf_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:114:23:114:25 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:114:23:114:25 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vsnprintf. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:115:24:115:26 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:115:24:115:26 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsnprintf. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:116:26:116:28 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:116:26:116:28 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsnprintf_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:117:31:117:33 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:117:31:117:33 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vsnprintf_s. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:118:32:118:34 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:118:32:118:34 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsnprintf_s. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:119:34:119:36 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:119:34:119:36 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsnprintf_s_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:120:16:120:18 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:120:16:120:18 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vsprintf. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:121:19:121:21 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:121:19:121:21 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsprintf_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:122:25:122:27 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:122:25:122:27 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsprintf_p. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:123:27:123:29 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:123:27:123:29 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsprintf_p_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:124:24:124:26 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:124:24:124:26 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to vsprintf_s. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:125:27:125:29 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:125:27:125:29 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vsprintf_s_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:126:15:126:17 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:126:15:126:17 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vscprintf_p. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread | +| funcsLocal.c:127:17:127:19 | *fmt | funcsLocal.c:109:8:109:10 | fread output argument | funcsLocal.c:127:17:127:19 | *fmt | The value of this argument may come from $@ and is being used as a formatting argument to _vscprintf_p_l. | funcsLocal.c:109:8:109:10 | fread output argument | string read by fread |