Skip to content

Commit 048b372

Browse files
authored
Merge pull request #15587 from MathiasVP/fix-memset-model
C++: Fix `memset` model
2 parents 565f8e8 + a799399 commit 048b372

File tree

5 files changed

+27
-0
lines changed

5 files changed

+27
-0
lines changed

cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,28 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
2222
])
2323
}
2424

25+
/**
26+
* Gets the index of the parameter that specifies the fill character to insert, if any.
27+
*/
28+
private int getFillCharParameterIndex() {
29+
(
30+
this.hasGlobalOrStdOrBslName("memset")
31+
or
32+
this.hasGlobalOrStdName("wmemset")
33+
or
34+
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk"])
35+
) and
36+
result = 1
37+
}
38+
2539
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
2640

2741
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
2842
input.isParameter(0) and
2943
output.isReturnValue()
44+
or
45+
input.isParameter(this.getFillCharParameterIndex()) and
46+
(output.isParameterDeref(0) or output.isReturnValueDeref())
3047
}
3148

3249
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {

cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ postWithInFlow
165165
| test.cpp:931:5:931:18 | global_pointer [post update] | PostUpdateNode should not be the target of local flow. |
166166
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
167167
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
168+
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
168169
viableImplInCallContextTooLarge
169170
uniqueParameterNodeAtPosition
170171
uniqueParameterNodePosition

cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ postWithInFlow
2525
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
2626
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
2727
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
28+
| test.cpp:1045:9:1045:11 | memset output argument | PostUpdateNode should not be the target of local flow. |
2829
viableImplInCallContextTooLarge
2930
uniqueParameterNodeAtPosition
3031
uniqueParameterNodePosition

cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ irFlow
309309
| test.cpp:994:18:994:32 | *call to indirect_source | test.cpp:1003:19:1003:28 | *translated |
310310
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1027:19:1027:28 | *translated |
311311
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1031:19:1031:28 | *translated |
312+
| test.cpp:1045:14:1045:19 | call to source | test.cpp:1046:7:1046:10 | * ... |
312313
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
313314
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
314315
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |

cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,4 +1037,11 @@ namespace test_gettext {
10371037
sink(translated); // clean
10381038
indirect_sink(translated); // clean
10391039
}
1040+
}
1041+
1042+
void* memset(void*, int, size_t);
1043+
1044+
void memset_test(char* buf) { // $ ast-def=buf
1045+
memset(buf, source(), 10);
1046+
sink(*buf); // $ ir MISSING: ast
10401047
}

0 commit comments

Comments
 (0)