Skip to content

Commit e6ea705

Browse files
committed
CPP: Switch from a blacklist to whitelist approach for determining null termination.
1 parent fbd9d9b commit e6ea705

File tree

4 files changed

+19
-17
lines changed

4 files changed

+19
-17
lines changed

cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import cpp
1818
import semmle.code.cpp.dataflow.DataFlow
19-
import semmle.code.cpp.models.implementations.Memcpy
19+
import semmle.code.cpp.models.interfaces.ArrayFunction
2020

2121
class MallocCall extends FunctionCall {
2222
MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
@@ -33,11 +33,19 @@ class MallocCall extends FunctionCall {
3333
}
3434

3535
predicate terminationProblem(MallocCall malloc, string msg) {
36+
// malloc(strlen(...))
3637
malloc.getAllocatedSize() instanceof StrlenCall and
37-
not exists(FunctionCall fc, MemcpyFunction memcpy, int ix |
38-
DataFlow::localExprFlow(malloc, fc.getArgument(ix)) and
39-
fc.getTarget() = memcpy and
40-
memcpy.hasArrayOutput(ix)
38+
// flows into a null-terminated string function
39+
exists(ArrayFunction af, FunctionCall fc, int arg |
40+
DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
41+
fc.getTarget() = af and
42+
(
43+
// null terminated string
44+
af.hasArrayWithNullTerminator(arg)
45+
or
46+
// likely a null terminated string (such as `strcpy`, `strcat`)
47+
af.hasArrayWithUnknownSize(arg)
48+
)
4149
) and
4250
msg = "This allocation does not include space to null-terminate the string."
4351
}
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
| test2.cpp:35:28:35:33 | call to malloc | This allocation does not include space to null-terminate the string. |
21
| test.c:16:20:16:25 | call to malloc | This allocation does not include space to null-terminate the string. |
32
| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
43
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
54
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
6-
| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
7-
| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
85
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
96
| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
10-
| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |
11-
| test.cpp:89:35:89:40 | call to malloc | This allocation does not include space to null-terminate the string. |
12-
| test.cpp:99:28:99:33 | call to malloc | This allocation does not include space to null-terminate the string. |

cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void good1(wchar_t *wstr) {
4141
}
4242

4343
void bad3(char *str) {
44-
// BAD -- zero-termination proved by sprintf (as destination)
44+
// BAD -- zero-termination proved by sprintf (as destination) [NOT DETECTED]
4545
char *buffer = (char *)malloc(strlen(str));
4646
sprintf(buffer, "%s", str);
4747
free(buffer);
@@ -51,7 +51,7 @@ void decode(char *dest, char *src);
5151
void wdecode(wchar_t *dest, wchar_t *src);
5252

5353
void bad4(char *str) {
54-
// BAD -- zero-termination proved by wprintf (as parameter)
54+
// BAD -- zero-termination proved by wprintf (as parameter) [NOT DETECTED]
5555
char *buffer = (char *)malloc(strlen(str));
5656
decode(buffer, str);
5757
wprintf(L"%s", buffer);
@@ -75,7 +75,7 @@ void bad6(char *str, char *dest) {
7575
}
7676

7777
void bad7(char *str, char *str2) {
78-
// BAD -- zero-termination proved by strcmp
78+
// BAD -- zero-termination proved by strcmp [NOT DETECTED]
7979
char *buffer = (char *)malloc(strlen(str));
8080
decode(buffer, str);
8181
if (strcmp(buffer, str2) == 0) {
@@ -85,7 +85,7 @@ void bad7(char *str, char *str2) {
8585
}
8686

8787
void bad8(wchar_t *str) {
88-
// BAD -- zero-termination proved by wcslen
88+
// BAD -- zero-termination proved by wcslen [NOT DETECTED]
8989
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str));
9090
wdecode(wbuffer, str);
9191
if (wcslen(wbuffer) == 0) {
@@ -95,7 +95,7 @@ void bad8(wchar_t *str) {
9595
}
9696

9797
void good2(char *str, char *dest) {
98-
// GOOD -- zero-termination not proven [FALSE POSITIVE]
98+
// GOOD -- zero-termination not proven
9999
char *buffer = (char *)malloc(strlen(str));
100100
decode(buffer, str);
101101
free(buffer);

cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace std
3131
//// Test code /////
3232

3333
void bad1(char *str) {
34-
// BAD -- Not allocating space for '\0' terminator
34+
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
3535
char *buffer = (char *)malloc(strlen(str));
3636
std::string str2(buffer);
3737
free(buffer);

0 commit comments

Comments
 (0)