mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
C++: Add double-free tests.
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
edges
|
||||
| test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a |
|
||||
| test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a |
|
||||
| test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a |
|
||||
| test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a |
|
||||
| test_free.cpp:30:10:30:10 | a | test_free.cpp:31:27:31:27 | a |
|
||||
| test_free.cpp:35:10:35:10 | a | test_free.cpp:37:27:37:27 | a |
|
||||
| test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:46:10:46:10 | a |
|
||||
| test_free.cpp:50:27:50:27 | a | test_free.cpp:51:10:51:10 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
nodes
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
| test_free.cpp:14:10:14:10 | a | semmle.label | a |
|
||||
| test_free.cpp:14:10:14:10 | a | semmle.label | a |
|
||||
| test_free.cpp:30:10:30:10 | a | semmle.label | a |
|
||||
| test_free.cpp:31:27:31:27 | a | semmle.label | a |
|
||||
| test_free.cpp:35:10:35:10 | a | semmle.label | a |
|
||||
| test_free.cpp:37:27:37:27 | a | semmle.label | a |
|
||||
| test_free.cpp:42:27:42:27 | a | semmle.label | a |
|
||||
| test_free.cpp:42:27:42:27 | a | semmle.label | a |
|
||||
| test_free.cpp:44:27:44:27 | a | semmle.label | a |
|
||||
| test_free.cpp:44:27:44:27 | a | semmle.label | a |
|
||||
| test_free.cpp:46:10:46:10 | a | semmle.label | a |
|
||||
| test_free.cpp:46:10:46:10 | a | semmle.label | a |
|
||||
| test_free.cpp:46:10:46:10 | a | semmle.label | a |
|
||||
| test_free.cpp:46:10:46:10 | a | semmle.label | a |
|
||||
| test_free.cpp:50:27:50:27 | a | semmle.label | a |
|
||||
| test_free.cpp:51:10:51:10 | a | semmle.label | a |
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:101:10:101:10 | a | semmle.label | a |
|
||||
| test_free.cpp:103:10:103:10 | a | semmle.label | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:129:10:129:11 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:152:27:152:27 | a | semmle.label | a |
|
||||
| test_free.cpp:152:27:152:27 | a | semmle.label | a |
|
||||
| test_free.cpp:154:10:154:10 | a | semmle.label | a |
|
||||
| test_free.cpp:154:10:154:10 | a | semmle.label | a |
|
||||
| test_free.cpp:207:10:207:10 | a | semmle.label | a |
|
||||
| test_free.cpp:207:10:207:10 | a | semmle.label | a |
|
||||
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
|
||||
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
|
||||
subpaths
|
||||
#select
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| test_free.cpp:31:27:31:27 | a | test_free.cpp:30:10:30:10 | a | test_free.cpp:31:27:31:27 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:30:5:30:8 | call to free | call to free |
|
||||
| test_free.cpp:37:27:37:27 | a | test_free.cpp:35:10:35:10 | a | test_free.cpp:37:27:37:27 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:35:5:35:8 | call to free | call to free |
|
||||
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
|
||||
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
|
||||
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
|
||||
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | a | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/DoubleFree.ql
|
||||
229
cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
Normal file
229
cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
void *malloc(int);
|
||||
void free(void *);
|
||||
bool condition();
|
||||
void use(void*);
|
||||
void *realloc(void*, unsigned long);
|
||||
int strlen(char*);
|
||||
int asprintf(char ** strp, const char * fmt, ...);
|
||||
|
||||
|
||||
void* test_double_free1(int *a) {
|
||||
free(a); // GOOD
|
||||
a[5] = 5;
|
||||
*a = 5;
|
||||
free(a); // BAD
|
||||
a = (int*) malloc(8);
|
||||
free(a); // GOOD
|
||||
a = (int*) malloc(8);
|
||||
if (!a) free(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
void test_double_free_aliasing(void *a, void* b) {
|
||||
free(a); // GOOD
|
||||
a = b;
|
||||
free(a); // GOOD
|
||||
free(b); // BAD [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_dominance1(void *a) {
|
||||
free(a);
|
||||
if (condition()) free(a); // BAD
|
||||
}
|
||||
|
||||
void test_dominance2(void *a) {
|
||||
free(a);
|
||||
if (condition()) a = malloc(10);
|
||||
if (condition()) free(a); // BAD
|
||||
}
|
||||
|
||||
void test_post_dominance1(int *a)
|
||||
{
|
||||
if (condition()) free(a); // GOOD
|
||||
if (condition()) a[2] = 5;
|
||||
if (condition()) free(a); // GOOD
|
||||
a[2] = 5;
|
||||
free(a); // BAD
|
||||
}
|
||||
|
||||
void test_post_dominance2(void *a) {
|
||||
if (condition()) free(a);
|
||||
free(a); // BAD
|
||||
}
|
||||
|
||||
void test_post_dominance3(void *a) {
|
||||
if (condition()) free(a);
|
||||
a = malloc(10);
|
||||
free(a); // GOOD
|
||||
}
|
||||
|
||||
void test_use_after_free6(int *a, int *b) {
|
||||
free(a);
|
||||
a=b;
|
||||
free(b);
|
||||
if (condition()) a[0] = 5;
|
||||
}
|
||||
|
||||
void test_use_after_free7(int *a) {
|
||||
a[0] = 42;
|
||||
free(a);
|
||||
|
||||
if (a[3]) {
|
||||
free(a); // BAD
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
public:
|
||||
void f();
|
||||
};
|
||||
|
||||
void test_new1() {
|
||||
A *a = new A();
|
||||
delete(a);
|
||||
a->f();
|
||||
delete(a); // BAD [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_dereference1(A *a) {
|
||||
a->f();
|
||||
free(a);
|
||||
a->f();
|
||||
}
|
||||
|
||||
void* use_after_free(void *a) {
|
||||
free(a);
|
||||
use(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
void test_realloc1(void *a) {
|
||||
free(a);
|
||||
void *b = realloc(a, sizeof(a)*3); // BAD
|
||||
free(a); // BAD
|
||||
free(b); // GOOD
|
||||
}
|
||||
void* test_realloc2(char *a) {
|
||||
void *b = realloc(a, strlen(a)+3); // GOOD
|
||||
|
||||
// From the man page on return values from realloc and reallocarray:
|
||||
// "If these functions fail, the original block is left untouched; it is not freed or moved."
|
||||
if (!b) {
|
||||
free(a); // GOOD
|
||||
}
|
||||
free(b); // GOOD
|
||||
}
|
||||
|
||||
void test_realloc3(void *a) {
|
||||
void *b = realloc(a, 100);
|
||||
if (b) free(b); // GOOD
|
||||
if (!b) {
|
||||
free(a); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
void test_ptr_deref(void ** a) {
|
||||
free(*a);
|
||||
*a = malloc(10);
|
||||
free(*a); // GOOD
|
||||
free(*a); // BAD [NOT DETECTED]
|
||||
*a = malloc(10);
|
||||
free(a[0]); // GOOD
|
||||
free(a[1]); // GOOD
|
||||
}
|
||||
|
||||
struct list {
|
||||
struct list *next;
|
||||
void* data;
|
||||
};
|
||||
|
||||
void test_loop1(struct list ** list_ptr) {
|
||||
struct list *next;
|
||||
while (*list_ptr) {
|
||||
free((*list_ptr)->data); // GOOD
|
||||
next = (*list_ptr)->next;
|
||||
free(*list_ptr); // GOOD
|
||||
*list_ptr = next;
|
||||
}
|
||||
free(list_ptr); // GOOD
|
||||
}
|
||||
|
||||
void test_use_after_free8(struct list * a) {
|
||||
if (condition()) free(a);
|
||||
a->data = malloc(10);
|
||||
free(a); // BAD
|
||||
}
|
||||
|
||||
void test_loop2(char ** a) {
|
||||
while (*a) {
|
||||
free(*a); // GOOD
|
||||
a++;
|
||||
}
|
||||
free(a); // GOOD
|
||||
}
|
||||
|
||||
void* test_realloc4() {
|
||||
void *a = 0;
|
||||
void *b = realloc(a, 10); // GOOD [FALSE POSITIVE]
|
||||
if (!b) { return a; }
|
||||
return b;
|
||||
}
|
||||
|
||||
void test_sizeof(int *a) {
|
||||
free(a);
|
||||
int x = sizeof(a[0]);
|
||||
}
|
||||
|
||||
void call_by_reference(char * &a);
|
||||
int custom_alloc_func(char ** a);
|
||||
|
||||
void test_reassign(char *a) {
|
||||
free(a); // GOOD
|
||||
asprintf(&a, "Hello world");
|
||||
free(a); //GOOD
|
||||
call_by_reference(a);
|
||||
free(a); // GOOD
|
||||
int v;
|
||||
if (v = custom_alloc_func(&a)) return;
|
||||
free(a); // GOOD
|
||||
}
|
||||
|
||||
char* test_return1(char *a) {
|
||||
int ret = condition();
|
||||
if (!ret) free(a);
|
||||
return (ret ? a : 0);
|
||||
}
|
||||
|
||||
char* test_return2(char *a) {
|
||||
int ret = condition();
|
||||
if (!ret) free(a);
|
||||
if (ret) return a;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void test_condition1(char *a) {
|
||||
free(a);
|
||||
if (asprintf(&a, "Hello world") || condition());
|
||||
free(a); //GOOD
|
||||
if (condition() || asprintf(&a, "Hello world"));
|
||||
free(a); // BAD
|
||||
}
|
||||
|
||||
void test_condition2(char *a) {
|
||||
free(a);
|
||||
if (condition()) a = (char*) malloc(10);
|
||||
else custom_alloc_func(&a);
|
||||
free(a); // GOOD
|
||||
}
|
||||
|
||||
void* test_return1(void *a) {
|
||||
free(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
void MmFreePagesFromMdl(void*);
|
||||
void ExFreePool(void*);
|
||||
void test_ms_free(void * memory_descriptor_list) {
|
||||
MmFreePagesFromMdl(memory_descriptor_list); //GOOD
|
||||
ExFreePool(memory_descriptor_list); // GOOD
|
||||
}
|
||||
Reference in New Issue
Block a user