Skip to content

Commit 2d0a561

Browse files
committed
C++: Prevent flow out of pointer-difference expressions.
1 parent c1d41b3 commit 2d0a561

File tree

3 files changed

+8
-50
lines changed

3 files changed

+8
-50
lines changed

cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class TaintedAllocationSizeConfiguration extends TaintTrackingConfiguration {
4242
e instanceof AssignArithmeticOperation
4343
) and
4444
not convertedExprMightOverflow(e)
45+
or
46+
// Subtracting two pointers is either well-defined (and the result will likely be small), or
47+
// terribly undefined and dangerous. Here, we assume that the programmer has ensured that the
48+
// result is well-defined (i.e., the two pointers point to the same object), and thus the result
49+
// will likely be small.
50+
e = any(PointerDiffExpr diff).getAnOperand()
4551
}
4652
}
4753

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,6 @@ edges
2727
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
2828
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
2929
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
30-
| test.cpp:75:25:75:29 | start | test.cpp:79:18:79:28 | ... - ... |
31-
| test.cpp:75:25:75:29 | start | test.cpp:79:18:79:28 | ... - ... |
32-
| test.cpp:75:38:75:40 | end | test.cpp:79:18:79:28 | ... - ... |
33-
| test.cpp:75:38:75:40 | end | test.cpp:79:18:79:28 | ... - ... |
34-
| test.cpp:97:18:97:23 | buffer | test.cpp:100:4:100:15 | buffer |
35-
| test.cpp:97:18:97:23 | buffer | test.cpp:100:17:100:22 | buffer indirection |
36-
| test.cpp:97:18:97:23 | buffer | test.cpp:101:4:101:15 | ... + ... |
37-
| test.cpp:97:18:97:23 | buffer | test.cpp:101:4:101:15 | buffer |
38-
| test.cpp:97:18:97:23 | fread output argument | test.cpp:100:4:100:15 | buffer |
39-
| test.cpp:97:18:97:23 | fread output argument | test.cpp:100:17:100:22 | buffer indirection |
40-
| test.cpp:97:18:97:23 | fread output argument | test.cpp:101:4:101:15 | ... + ... |
41-
| test.cpp:97:18:97:23 | fread output argument | test.cpp:101:4:101:15 | buffer |
42-
| test.cpp:100:4:100:15 | buffer | test.cpp:100:17:100:22 | processData1 output argument |
43-
| test.cpp:100:17:100:22 | buffer indirection | test.cpp:100:17:100:22 | processData1 output argument |
44-
| test.cpp:100:17:100:22 | processData1 output argument | test.cpp:101:4:101:15 | ... + ... |
45-
| test.cpp:100:17:100:22 | processData1 output argument | test.cpp:101:4:101:15 | buffer |
46-
| test.cpp:101:4:101:15 | ... + ... | test.cpp:75:38:75:40 | end |
47-
| test.cpp:101:4:101:15 | buffer | test.cpp:75:25:75:29 | start |
4830
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... |
4931
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... |
5032
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:41 | ... * ... |
@@ -87,12 +69,6 @@ edges
8769
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
8870
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
8971
| test.cpp:295:18:295:21 | get_size output argument [array content] | test.cpp:295:18:295:21 | Chi |
90-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | (size_t)... |
91-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | (size_t)... |
92-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | offset |
93-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | offset |
94-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | offset |
95-
| test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | offset |
9672
nodes
9773
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
9874
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
@@ -118,21 +94,6 @@ nodes
11894
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
11995
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
12096
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
121-
| test.cpp:64:25:64:30 | *buffer | semmle.label | *buffer |
122-
| test.cpp:64:25:64:30 | *buffer | semmle.label | *buffer |
123-
| test.cpp:64:25:64:30 | buffer | semmle.label | buffer |
124-
| test.cpp:75:25:75:29 | start | semmle.label | start |
125-
| test.cpp:75:38:75:40 | end | semmle.label | end |
126-
| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... |
127-
| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... |
128-
| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... |
129-
| test.cpp:97:18:97:23 | buffer | semmle.label | buffer |
130-
| test.cpp:97:18:97:23 | fread output argument | semmle.label | fread output argument |
131-
| test.cpp:100:4:100:15 | buffer | semmle.label | buffer |
132-
| test.cpp:100:17:100:22 | buffer indirection | semmle.label | buffer indirection |
133-
| test.cpp:100:17:100:22 | processData1 output argument | semmle.label | processData1 output argument |
134-
| test.cpp:101:4:101:15 | ... + ... | semmle.label | ... + ... |
135-
| test.cpp:101:4:101:15 | buffer | semmle.label | buffer |
13697
| test.cpp:123:18:123:23 | call to getenv | semmle.label | call to getenv |
13798
| test.cpp:123:18:123:31 | (const char *)... | semmle.label | (const char *)... |
13899
| test.cpp:127:24:127:41 | ... * ... | semmle.label | ... * ... |
@@ -185,21 +146,13 @@ nodes
185146
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
186147
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
187148
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
188-
| test.cpp:321:15:321:20 | call to getenv | semmle.label | call to getenv |
189-
| test.cpp:321:15:321:20 | call to getenv | semmle.label | call to getenv |
190-
| test.cpp:324:9:324:14 | (size_t)... | semmle.label | (size_t)... |
191-
| test.cpp:324:9:324:14 | (size_t)... | semmle.label | (size_t)... |
192-
| test.cpp:324:9:324:14 | offset | semmle.label | offset |
193-
| test.cpp:324:9:324:14 | offset | semmle.label | offset |
194-
| test.cpp:324:9:324:14 | offset | semmle.label | offset |
195149
#select
196150
| test.cpp:42:31:42:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
197151
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
198152
| test.cpp:45:31:45:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
199153
| test.cpp:48:25:48:30 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
200154
| test.cpp:49:17:49:30 | new[] | test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
201155
| test.cpp:52:21:52:27 | call to realloc | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
202-
| test.cpp:79:9:79:29 | new[] | test.cpp:97:18:97:23 | buffer | test.cpp:79:18:79:28 | ... - ... | This allocation size is derived from $@ and might overflow | test.cpp:97:18:97:23 | buffer | user input (fread) |
203156
| test.cpp:127:17:127:22 | call to malloc | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:123:18:123:23 | call to getenv | user input (getenv) |
204157
| test.cpp:134:3:134:8 | call to malloc | test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:132:19:132:24 | call to getenv | user input (getenv) |
205158
| test.cpp:215:14:215:19 | call to malloc | test.cpp:227:24:227:29 | call to getenv | test.cpp:215:21:215:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:227:24:227:29 | call to getenv | user input (getenv) |
@@ -209,4 +162,3 @@ nodes
209162
| test.cpp:253:4:253:9 | call to malloc | test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:249:20:249:25 | call to getenv | user input (getenv) |
210163
| test.cpp:281:4:281:9 | call to malloc | test.cpp:241:18:241:23 | call to getenv | test.cpp:281:11:281:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:241:18:241:23 | call to getenv | user input (getenv) |
211164
| test.cpp:298:3:298:8 | call to malloc | test.cpp:241:18:241:23 | call to getenv | test.cpp:298:10:298:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:241:18:241:23 | call to getenv | user input (getenv) |
212-
| test.cpp:324:2:324:7 | call to malloc | test.cpp:321:15:321:20 | call to getenv | test.cpp:324:9:324:14 | offset | This allocation size is derived from $@ and might overflow | test.cpp:321:15:321:20 | call to getenv | user input (getenv) |

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void processData2(char *start, char *end)
7676
{
7777
char *copy;
7878

79-
copy = new char[end - start]; // GOOD [FALSE POSITIVE]
79+
copy = new char[end - start]; // GOOD
8080

8181
// ...
8282

@@ -321,5 +321,5 @@ void ptr_diff_case() {
321321
char* user = getenv("USER");
322322
char* admin_begin_pos = strstr(user, "ADMIN");
323323
int offset = admin_begin_pos ? user - admin_begin_pos : 0;
324-
malloc(offset); // GOOD [FALSE POSITIVE]
324+
malloc(offset); // GOOD
325325
}

0 commit comments

Comments
 (0)