Skip to content

Commit cdcd3ed

Browse files
authored
Merge pull request #2647 from geoffw0/modelpure
CPP: Improve strlen model
2 parents 79811fc + 4f02183 commit cdcd3ed

File tree

8 files changed

+54
-43
lines changed

8 files changed

+54
-43
lines changed

change-notes/1.24/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
3535
about the _name or scope_ of variables should remain unchanged.
3636
* The `LocalScopeVariableReachability` library is deprecated in favor of
3737
`StackVariableReachability`. The functionality is the same.
38+
* The models library models `strlen` in more detail, and includes common variations such as `wcslen`.
3839
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
3940
the following improvements:
4041
* The library now models data flow through `strdup` and similar functions.

cpp/ql/src/semmle/code/cpp/commons/NullTermination.qll

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,6 @@ predicate functionArgumentMustBeNullTerminated(Function f, int i) {
8080
f.(ArrayFunction).hasArrayInput(i)
8181
or
8282
f instanceof StrcatFunction and i = 0
83-
or
84-
f.hasName("strlen") and i = 0
85-
or
86-
f.hasName("strcmp") and i in [0 .. 1]
87-
or
88-
f.hasName("strchr") and i = 0
89-
or
90-
f.hasName("strstr") and i in [0 .. 1]
9183
}
9284

9385
/**

cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,16 @@ class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideE
3030
name = "strtol" or
3131
name = "strtoll" or
3232
name = "strtoq" or
33-
name = "strtoul"
33+
name = "strtoul" or
34+
name = "wcslen"
35+
)
36+
or
37+
hasGlobalName(name) and
38+
(
39+
name = "_mbslen" or
40+
name = "_mbslen_l" or
41+
name = "_mbstrlen" or
42+
name = "_mbstrlen_l"
3443
)
3544
)
3645
}
@@ -39,6 +48,10 @@ class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideE
3948
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
4049
}
4150

51+
override predicate hasArrayWithNullTerminator(int bufParam) {
52+
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
53+
}
54+
4255
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
4356
exists(ParameterIndex i |
4457
input.isParameter(i) and
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
| test.c:15:3:15:18 | ... = ... | test.c:15:3:15:8 | buffer |
2-
| test.c:22:11:22:34 | ... = ... | test.c:22:24:22:27 | args |
3-
| test.c:23:5:23:15 | ... = ... | test.c:23:6:23:8 | ptr |
4-
| test.c:36:3:36:12 | call to addNullAsm | test.c:36:14:36:19 | buffer |
5-
| test.c:41:3:41:13 | call to expression | test.c:41:7:41:12 | buffer |
6-
| test.c:48:2:48:10 | ... = ... | test.c:48:3:48:6 | data |
7-
| test.c:49:2:49:15 | ... = ... | test.c:49:3:49:6 | data |
8-
| test.c:52:2:52:12 | ... = ... | test.c:52:2:52:5 | data |
9-
| test.c:55:16:55:19 | data | test.c:55:16:55:19 | data |
10-
| test.c:56:2:56:13 | ... = ... | test.c:56:2:56:6 | data2 |
11-
| test.c:59:2:59:14 | ... = ... | test.c:59:11:59:14 | data |
12-
| test.c:60:2:60:18 | ... = ... | test.c:60:11:60:14 | data |
13-
| test.c:63:2:63:7 | call to strcpy | test.c:63:9:63:12 | data |
14-
| test.c:64:2:64:8 | call to addNull | test.c:64:10:64:13 | data |
15-
| test.c:65:2:65:15 | call to addNullVarargs | test.c:65:20:65:23 | data |
16-
| test.c:66:2:66:11 | call to addNullAsm | test.c:66:13:66:16 | data |
17-
| test.c:67:2:67:15 | call to addNullWrapper | test.c:67:17:67:20 | data |
18-
| test.c:68:2:68:23 | call to addNullFunctionPointer | test.c:68:25:68:28 | data |
19-
| test.c:86:2:86:13 | ... = ... | test.c:86:2:86:6 | data2 |
20-
| test.c:100:2:100:7 | call to strcpy | test.c:100:9:100:14 | buffer |
21-
| test.c:108:2:108:21 | ... = ... | test.c:108:2:108:5 | data |
22-
| test.c:114:2:114:18 | call to strlenWrapperSafe | test.c:114:20:114:23 | data |
23-
| test.c:115:2:115:7 | call to strcpy | test.c:115:9:115:12 | data |
1+
| test.c:18:3:18:18 | ... = ... | test.c:18:3:18:8 | buffer |
2+
| test.c:25:11:25:34 | ... = ... | test.c:25:24:25:27 | args |
3+
| test.c:26:5:26:15 | ... = ... | test.c:26:6:26:8 | ptr |
4+
| test.c:39:3:39:12 | call to addNullAsm | test.c:39:14:39:19 | buffer |
5+
| test.c:44:3:44:13 | call to expression | test.c:44:7:44:12 | buffer |
6+
| test.c:51:2:51:10 | ... = ... | test.c:51:3:51:6 | data |
7+
| test.c:52:2:52:15 | ... = ... | test.c:52:3:52:6 | data |
8+
| test.c:55:2:55:12 | ... = ... | test.c:55:2:55:5 | data |
9+
| test.c:58:16:58:19 | data | test.c:58:16:58:19 | data |
10+
| test.c:59:2:59:13 | ... = ... | test.c:59:2:59:6 | data2 |
11+
| test.c:62:2:62:14 | ... = ... | test.c:62:11:62:14 | data |
12+
| test.c:63:2:63:18 | ... = ... | test.c:63:11:63:14 | data |
13+
| test.c:66:2:66:7 | call to strcpy | test.c:66:9:66:12 | data |
14+
| test.c:67:2:67:8 | call to addNull | test.c:67:10:67:13 | data |
15+
| test.c:68:2:68:15 | call to addNullVarargs | test.c:68:20:68:23 | data |
16+
| test.c:69:2:69:11 | call to addNullAsm | test.c:69:13:69:16 | data |
17+
| test.c:70:2:70:15 | call to addNullWrapper | test.c:70:17:70:20 | data |
18+
| test.c:71:2:71:23 | call to addNullFunctionPointer | test.c:71:25:71:28 | data |
19+
| test.c:89:2:89:13 | ... = ... | test.c:89:2:89:6 | data2 |
20+
| test.c:103:2:103:7 | call to strcpy | test.c:103:9:103:14 | buffer |
21+
| test.c:111:2:111:21 | ... = ... | test.c:111:2:111:5 | data |
22+
| test.c:117:2:117:18 | call to strlenWrapperSafe | test.c:117:20:117:23 | data |
23+
| test.c:118:2:118:7 | call to strcpy | test.c:118:9:118:12 | data |

cpp/ql/test/library-tests/nulltermination/test.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ char* strcat(char* destination, const char* source);
88
char* strcpy(char* destination, const char* source);
99
int strlen(const char* str);
1010
char* strcpy(char* destination, const char* source);
11+
char* strstr(char* s1, const char* s2);
12+
const char* strchr(const char* s, int c);
13+
int strcmp(const char *s1, const char *s2);
1114

1215
char* global = " ";
1316

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
| test.c:94:16:94:19 | data |
2-
| test.c:99:9:99:12 | data |
3-
| test.c:100:17:100:20 | data |
4-
| test.c:101:9:101:14 | buffer |
5-
| test.c:101:17:101:20 | data |
1+
| test.c:97:16:97:19 | data |
62
| test.c:102:9:102:12 | data |
7-
| test.c:103:9:103:12 | data |
8-
| test.c:103:15:103:20 | buffer |
9-
| test.c:104:16:104:19 | data |
10-
| test.c:109:16:109:19 | data |
3+
| test.c:103:17:103:20 | data |
4+
| test.c:104:9:104:14 | buffer |
5+
| test.c:104:17:104:20 | data |
6+
| test.c:105:9:105:12 | data |
7+
| test.c:106:9:106:12 | data |
8+
| test.c:106:15:106:20 | buffer |
9+
| test.c:107:16:107:19 | data |
10+
| test.c:112:16:112:19 | data |

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
77
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
88
| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
9+
| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |
10+
| test.cpp:89:35:89:40 | call to malloc | This allocation does not include space to null-terminate the string. |
911
| test.cpp:106:24:106:48 | new[] | 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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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 [NOT DETECTED]
78+
// BAD -- zero-termination proved by strcmp
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 [NOT DETECTED]
88+
// BAD -- zero-termination proved by wcslen
8989
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str));
9090
wdecode(wbuffer, str);
9191
if (wcslen(wbuffer) == 0) {

0 commit comments

Comments
 (0)