Skip to content

Commit 71fe6f5

Browse files
committed
C++: Use fully converted expressions in 'cpp/use-after-free' and 'cpp/double-free'.
1 parent 0d7769f commit 71fe6f5

File tree

4 files changed

+11
-32
lines changed

4 files changed

+11
-32
lines changed

cpp/ql/src/Critical/FlowAfterFree.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ module FlowFromFree<isSinkSig/2 isASink, isExcludedSig/2 isExcluded> {
9898
* is being freed by a deallocation expression `dealloc`.
9999
*/
100100
predicate isFree(DataFlow::Node n, Expr e, DeallocationExpr dealloc) {
101-
e = dealloc.getFreedExpr() and
102-
e = n.asExpr() and
101+
exists(Expr conv |
102+
e = conv.getUnconverted() and
103+
conv = dealloc.getFreedExpr().getFullyConverted() and
104+
conv = n.asConvertedExpr()
105+
) and
103106
// Ignore realloc functions
104107
not exists(dealloc.(FunctionCall).getTarget().(AllocationFunction).getReallocPtrArg())
105108
}

cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@ edges
66
| test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a |
77
| test_free.cpp:50:27:50:27 | a | test_free.cpp:51:10:51:10 | a |
88
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
9-
| test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a |
109
| test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a |
1110
| test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... |
1211
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
1312
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
14-
| test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p |
15-
| test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p |
1613
nodes
1714
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
1815
| test_free.cpp:14:10:14:10 | a | semmle.label | a |
@@ -28,8 +25,6 @@ nodes
2825
| test_free.cpp:51:10:51:10 | a | semmle.label | a |
2926
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
3027
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
31-
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
32-
| test_free.cpp:85:12:85:12 | a | semmle.label | a |
3328
| test_free.cpp:101:10:101:10 | a | semmle.label | a |
3429
| test_free.cpp:103:10:103:10 | a | semmle.label | a |
3530
| test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... |
@@ -38,10 +33,6 @@ nodes
3833
| test_free.cpp:154:10:154:10 | a | semmle.label | a |
3934
| test_free.cpp:207:10:207:10 | a | semmle.label | a |
4035
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
41-
| test_free.cpp:252:7:252:7 | p | semmle.label | p |
42-
| test_free.cpp:255:10:255:10 | p | semmle.label | p |
43-
| test_free.cpp:260:9:260:9 | p | semmle.label | p |
44-
| test_free.cpp:263:12:263:12 | p | semmle.label | p |
4536
subpaths
4637
#select
4738
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -51,10 +42,7 @@ subpaths
5142
| test_free.cpp:46:10:46:10 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
5243
| test_free.cpp:51:10:51:10 | a | test_free.cpp:50:27:50:27 | a | test_free.cpp:51:10:51:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:50:22:50:25 | call to free | call to free |
5344
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
54-
| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
5545
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
5646
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free |
5747
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
5848
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
59-
| test_free.cpp:255:10:255:10 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
60-
| test_free.cpp:263:12:263:12 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |

cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ edges
44
| test_free.cpp:42:27:42:27 | a | test_free.cpp:45:5:45:5 | a |
55
| test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a |
66
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
7-
| test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a |
87
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
98
| test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a |
109
| test_free.cpp:101:10:101:10 | a | test_free.cpp:102:23:102:23 | a |
1110
| test_free.cpp:152:27:152:27 | a | test_free.cpp:153:5:153:5 | a |
1211
| test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... |
1312
| test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... |
1413
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
15-
| test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p |
16-
| test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p |
1714
nodes
1815
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
1916
| test_free.cpp:12:5:12:5 | a | semmle.label | a |
@@ -24,8 +21,6 @@ nodes
2421
| test_free.cpp:45:5:45:5 | a | semmle.label | a |
2522
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
2623
| test_free.cpp:71:9:71:9 | a | semmle.label | a |
27-
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
28-
| test_free.cpp:84:5:84:5 | a | semmle.label | a |
2924
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
3025
| test_free.cpp:91:5:91:5 | a | semmle.label | a |
3126
| test_free.cpp:95:10:95:10 | a | semmle.label | a |
@@ -40,24 +35,17 @@ nodes
4035
| test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... |
4136
| test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... |
4237
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
43-
| test_free.cpp:252:7:252:7 | p | semmle.label | p |
44-
| test_free.cpp:254:6:254:6 | p | semmle.label | p |
45-
| test_free.cpp:260:9:260:9 | p | semmle.label | p |
46-
| test_free.cpp:262:6:262:6 | p | semmle.label | p |
4738
subpaths
4839
#select
4940
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
5041
| test_free.cpp:13:5:13:6 | * ... | test_free.cpp:11:10:11:10 | a | test_free.cpp:13:5:13:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
5142
| test_free.cpp:45:5:45:5 | a | test_free.cpp:42:27:42:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
5243
| test_free.cpp:45:5:45:5 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
5344
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
54-
| test_free.cpp:84:5:84:5 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | Memory may have been previously freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
5545
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
5646
| test_free.cpp:96:9:96:9 | a | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | Memory may have been previously freed by $@. | test_free.cpp:95:5:95:8 | call to free | call to free |
5747
| test_free.cpp:102:23:102:23 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:102:23:102:23 | a | Memory may have been previously freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
5848
| test_free.cpp:153:5:153:5 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:153:5:153:5 | a | Memory may have been previously freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
5949
| test_free.cpp:236:9:236:10 | * ... | test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:233:9:233:12 | call to free | call to free |
6050
| test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free |
6151
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
62-
| test_free.cpp:254:6:254:6 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p | Memory may have been previously freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
63-
| test_free.cpp:262:6:262:6 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p | Memory may have been previously freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |

cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class A {
8181
void test_new1() {
8282
A *a = new A();
8383
delete(a);
84-
a->f(); // BAD
85-
delete(a); // BAD
84+
a->f(); // BAD [NOT DETECTED]
85+
delete(a); // BAD [NOT DETECTED]
8686
}
8787

8888
void test_dereference1(A *a) {
@@ -251,14 +251,14 @@ void test_deref(char **a) {
251251
void test_ref(char *&p) {
252252
free(p);
253253
p = (char *)malloc(sizeof(char)*10);
254-
use(p); // GOOD [FALSE POSITIVE]
255-
free(p); // GOOD [FALSE POSITIVE]
254+
use(p); // GOOD
255+
free(p); // GOOD
256256
}
257257

258258

259259
void test_ref_delete(int *&p) {
260260
delete p;
261261
p = new int;
262-
use(p); // GOOD [FALSE POSITIVE]
263-
delete p; // GOOD [FALSE POSITIVE]
262+
use(p); // GOOD
263+
delete p; // GOOD
264264
}

0 commit comments

Comments
 (0)