Files
codeql/cpp/ql/test/query-tests/Security/CWE/CWE-193/test.cpp
Mathias Vorreiter Pedersen 3ea39a2553 C++: Add some query tests.
2024-03-13 11:39:34 +00:00

871 lines
18 KiB
C++

using size_t = decltype(sizeof 0); void* malloc(size_t size);
void test1(int size) {
char* p = (char*)malloc(size);
char* q = p + size; // $ alloc=L4
char a = *q; // $ deref=L5->L6 // BAD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L5->L8+1 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
char g = *(q - size - 1); // GOOD
}
void test2(int size) {
char* p = (char*)malloc(size);
char* q = p + size - 1; // $ alloc=L16
char a = *q; // GOOD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L17->L20 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
char g = *(q - size - 1); // GOOD
}
void test3(int size) {
char* p = (char*)malloc(size + 1);
char* q = p + (size + 1); // $ alloc=L28+1
char a = *q; // $ deref=L29->L30 // BAD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L29->L32+1 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
char g = *(q - size - 1); // GOOD
}
void test4(int size) {
char* p = (char*)malloc(size - 1);
char* q = p + (size - 1); // $ MISSING: alloc=L40-1
char a = *q; // $ MISSING: deref=L42 // BAD [NOT DETECTED]
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ MISSING: deref=L44+1 // BAD [NOT DETECTED]
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
char g = *(q - size - 1); // GOOD
}
char* mk_array(int size, char** end) {
char* begin = (char*)malloc(size);
*end = begin + size; // $ alloc=L52
return begin;
}
void test5(int size) {
char* end;
char* begin = mk_array(size, &end);
for (char* p = begin; p != end; ++p) {
*p = 0; // GOOD
}
for (char* p = begin; p <= end; ++p) {
*p = 0; // $ deref=L53->L62->L67 deref=L53->L66->L67 // BAD
}
for (char* p = begin; p < end; ++p) {
*p = 0; // GOOD
}
}
struct array_t {
char* begin;
char* end;
};
array_t mk_array(int size) {
array_t arr;
arr.begin = (char*)malloc(size);
arr.end = arr.begin + size; // $ MISSING: alloc=L82
return arr;
}
void test6(int size) {
array_t arr = mk_array(size);
for (char* p = arr.begin; p != arr.end; ++p) {
*p = 0; // GOOD
}
for (char* p = arr.begin; p <= arr.end; ++p) {
*p = 0; // $ MISSING: deref=L83->L91->L96 deref=L83->L95->L96 // BAD [NOT DETECTED]
}
for (char* p = arr.begin; p < arr.end; ++p) {
*p = 0; // GOOD
}
}
void test7_callee(array_t arr) {
for (char* p = arr.begin; p != arr.end; ++p) {
*p = 0; // GOOD
}
for (char* p = arr.begin; p <= arr.end; ++p) {
*p = 0; // $ MISSING: deref=L83->L105->L110 deref=L83->L109->L110 // BAD [NOT DETECTED]
}
for (char* p = arr.begin; p < arr.end; ++p) {
*p = 0; // GOOD
}
}
void test7(int size) {
test7_callee(mk_array(size));
}
void test8(int size) {
array_t arr;
char* p = (char*)malloc(size);
arr.begin = p;
arr.end = p + size; // $ alloc=L124
for (int i = 0; i < arr.end - arr.begin; i++) {
*(arr.begin + i) = 0; // GOOD
}
for (int i = 0; i != arr.end - arr.begin; i++) {
*(arr.begin + i) = 0; // GOOD
}
for (int i = 0; i <= arr.end - arr.begin; i++) {
*(arr.begin + i) = 0; // BAD [NOT DETECTED]
}
}
array_t *mk_array_p(int size) {
array_t *arr = (array_t*) malloc(sizeof(array_t));
arr->begin = (char*)malloc(size);
arr->end = arr->begin + size; // $ MISSING: alloc=L143
return arr;
}
void test9(int size) {
array_t *arr = mk_array_p(size);
for (char* p = arr->begin; p != arr->end; ++p) {
*p = 0; // GOOD
}
for (char* p = arr->begin; p <= arr->end; ++p) {
*p = 0; // $ MISSING: deref=L144->L156->L157 // BAD [NOT DETECTED]
}
for (char* p = arr->begin; p < arr->end; ++p) {
*p = 0; // GOOD
}
}
void test10_callee(array_t *arr) {
for (char* p = arr->begin; p != arr->end; ++p) {
*p = 0; // GOOD
}
for (char* p = arr->begin; p <= arr->end; ++p) {
*p = 0; // $ MISSING: deref=L144->L166->L171 deref=L144->L170->L171 // BAD [NOT DETECTED]
}
for (char* p = arr->begin; p < arr->end; ++p) {
*p = 0; // GOOD
}
}
void test10(int size) {
test10_callee(mk_array_p(size));
}
void deref_plus_one(char* q) {
char a = *(q + 1); // BAD [NOT DETECTED]
}
void test11(unsigned size) {
char *p = (char*)malloc(size);
char *q = p + size - 1; // $ alloc=L188
deref_plus_one(q);
}
void test12(unsigned len, unsigned index) {
char* p = (char *)malloc(len);
char* end = p + len; // $ alloc=L194
if(p + index > end) {
return;
}
p[index] = '\0'; // $ MISSING: deref=L195->L201 // BAD [NOT DETECTED]
}
void test13(unsigned len, unsigned index) {
char* p = (char *)malloc(len);
char* end = p + len; // $ alloc=L205
char* q = p + index;
if(q > end) {
return;
}
*q = '\0'; // $ deref=L206->L213 // BAD
}
bool unknown();
void test14(size_t n, char *p) {
while (unknown()) {
n++;
p = (char *)malloc(n);
p[n - 1] = 'a'; // GOOD
}
}
void test15(unsigned index) {
unsigned size = index + 13;
if(size < index) {
return;
}
int* newname = new int[size];
newname[index] = 0; // GOOD
}
void test16(unsigned index) {
unsigned size = index + 13;
if(size >= index) {
int* newname = new int[size];
newname[index] = 0; // GOOD
}
}
void *realloc(void *, unsigned);
void test17(unsigned *p, unsigned x, unsigned k) {
if(k > 0 && p[1] <= p[0]){
unsigned n = 3*p[0] + k;
p = (unsigned*)realloc(p, n);
p[0] = n;
unsigned i = p[1];
// The following access is okay because:
// n = 3*p[0] + k >= p[0] + k >= p[1] + k > p[1] = i
// (where p[0] denotes the original value for p[0])
p[i] = x; // GOOD
}
}
void test17(unsigned len)
{
int *xs = new int[len];
int *end = xs + len; // $ alloc=L260
for (int *x = xs; x <= end; x++)
{
int i = *x; // $ deref=L261->L264 // BAD
}
}
void test18(unsigned len)
{
int *xs = new int[len];
int *end = xs + len; // $ alloc=L270
for (int *x = xs; x <= end; x++)
{
*x = 0; // $ deref=L271->L274 // BAD
}
}
void test19(unsigned len)
{
int *xs = new int[len];
int *end = xs + len; // $ alloc=L280
for (int *x = xs; x < end; x++)
{
int i = *x; // GOOD
}
}
void test20(unsigned len)
{
int *xs = new int[len];
int *end = xs + len; // $ alloc=L290
for (int *x = xs; x < end; x++)
{
*x = 0; // GOOD
}
}
void* test21_get(int n);
void test21() {
int n = 0;
while (test21_get(n)) n+=2;
void** xs = new void*[n];
for (int i = 0; i < n; i += 2) {
xs[i] = test21_get(i); // GOOD
xs[i+1] = test21_get(i+1); // GOOD
}
}
void test22(unsigned size, int val) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L313 // GOOD
char **current = &end;
do {
if (*current - xs < 1) // GOOD
return;
*--(*current) = 0; // GOOD
val >>= 8;
} while (val > 0);
}
void test23(unsigned size, int val) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L325
char **current = &end;
if (val < 1) {
if(*current - xs < 1)
return;
*--(*current) = 0; // GOOD
return;
}
if (val < 2) {
if(*current - xs < 2)
return;
*--(*current) = 0; // GOOD
*--(*current) = 0; // GOOD
}
}
void test24(unsigned size) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L347
if (xs < end) {
int val = *xs++; // GOOD
}
}
void test25(unsigned size) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L355
char *end_plus_one = end + 1;
int val1 = *end_plus_one; // $ deref=L356->L358+1 // BAD
int val2 = *(end_plus_one + 1); // $ deref=L356->L359+2 // BAD
}
void test26(unsigned size) {
char *xs = new char[size];
char *p = xs;
char *end = p + size; // $ alloc=L363
if (p + 4 <= end) {
p += 4;
}
if (p < end) {
int val = *p; // GOOD
}
}
void test27(unsigned size, bool b) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L377
if (b) {
end++;
}
int val = *end; // $ deref=L378->L384+1 // BAD
}
void test28(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L388
if (xs >= end)
return;
xs++;
if (xs >= end)
return;
xs[0] = 0; // GOOD
}
void test28_simple(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L399
if (xs < end) {
xs++;
if (xs < end) {
xs[0] = 0; // GOOD
}
}
}
void test28_simple2(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L410
if (xs < end) {
xs++;
if (xs < end + 1) {
xs[0] = 0; // $ deref=L411->L415 // BAD
}
}
}
void test28_simple3(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L421
if (xs < end) {
xs++;
if (xs - 1 < end) {
xs[0] = 0; // $ deref=L422->L426 // BAD
}
}
}
void test28_simple4(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L432
if (xs < end) {
end++;
xs++;
if (xs < end) {
xs[0] = 0; // $ deref=L433->L438 // BAD
}
}
}
void test28_simple5(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L444
end++;
if (xs < end) {
xs++;
if (xs < end) {
xs[0] = 0; // $ deref=L445->L450 // BAD
}
}
}
void test28_simple6(unsigned size) {
char *xs = new char[size + 1];
char *end = &xs[size];
end++;
if (xs < end) {
xs++;
if (xs < end) {
xs[0] = 0; // GOOD
}
}
}
void test28_simple7(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L468
end++;
if (xs < end) {
xs++;
if (xs < end - 1) {
xs[0] = 0; // GOOD
}
}
}
void test28_simple8(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L480
end += 500;
if (xs < end) {
xs++;
if (xs < end - 1) {
xs[0] = 0; // $ deref=L481->L486+498 // BAD
}
}
}
struct test29_struct {
char* xs;
};
void test29(unsigned size) {
test29_struct val;
val.xs = new char[size];
size++;
val.xs = new char[size];
val.xs[size - 1] = 0; // GOOD
}
void test30(int *size)
{
int new_size = 0, tmp_size = 0;
test30(&tmp_size);
if (tmp_size + 1 > new_size) {
new_size = tmp_size + 1;
char *xs = new char[new_size];
for (int i = 0; i < new_size; i++) {
xs[i] = 0; // GOOD
}
}
*size = new_size;
}
void test31(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
unsigned dst_pos = src_pos;
if (dst_pos < size - 3) {
xs[dst_pos++] = 0; // GOOD
}
}
void test31_simple1(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple2(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size + 1) {
xs[src_pos] = 0; // $ alloc=L543 deref=L548 // BAD
}
}
void test31_simple3(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
if (src_pos - 1 < size) {
xs[src_pos] = 0; // $ alloc=L554 deref=L559 // BAD
}
}
void test31_simple4(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size - 1) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple5(unsigned size, unsigned src_pos)
{
char *xs = new char[size];
if (src_pos > size) {
src_pos = size;
}
if (src_pos + 1 < size) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple1_plus1(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple2_plus1(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size + 1) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple3_plus1(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos - 1 < size) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple4_plus1(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size - 1) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple5_plus1(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos + 1 < size) {
xs[src_pos] = 0; // GOOD
}
}
void test31_simple1_sub1(unsigned size, unsigned src_pos)
{
char *xs = new char[size - 1];
if (src_pos > size) {
src_pos = size;
}
if (src_pos < size) {
xs[src_pos] = 0; // $ alloc=L642-1 deref=L647 // BAD
}
}
void test32(unsigned size) {
char *xs = new char[size];
char *end = &xs[size]; // $ alloc=L652
if (xs >= end)
return;
xs++;
if (xs >= end)
return;
xs++;
if (xs >= end)
return;
xs[0] = 0; // GOOD
}
void test33(unsigned size, unsigned src_pos)
{
char *xs = new char[size + 1];
if (src_pos > size) {
src_pos = size;
}
unsigned dst_pos = src_pos;
while (dst_pos < size - 1) {
dst_pos++;
if (true)
xs[dst_pos++] = 0; // GOOD
}
}
int* pointer_arithmetic(int *p, int offset) {
return p + offset; // $ alloc=L684
}
void test_missing_call_context_1(unsigned size) {
int* p = new int[size];
int* end = pointer_arithmetic(p, size);
}
void test_missing_call_context_2(unsigned size) {
int* p = new int[size];
int* end_minus_one = pointer_arithmetic(p, size - 1);
*end_minus_one = '0'; // $ deref=L680->L690->L691 // GOOD
}
void test34(unsigned size) {
char *p = new char[size];
char *end = p + size + 1; // $ alloc=L695
if (p + 1 < end) {
p += 1;
}
if (p + 1 < end) {
int val = *p; // GOOD
}
}
void deref(char* q) {
char x = *q; // $ MISSING: deref=L714->L705->L706 // BAD [NOT DETECTED]
}
void test35(size_t size, char* q)
{
char* p = new char[size];
char* end = p + size; // $ alloc=L711
if(q <= end) {
deref(q);
}
}
void test21_simple(bool b) {
int n = 0;
if (b) n = 2;
int* xs = new int[n];
for (int i = 0; i < n; i += 2) {
xs[i+1] = 0; // GOOD
}
}
void test36(unsigned size, unsigned n) {
int* p = new int[size + 2];
if(n < size + 1) {
int* end = p + (n + 2); // $ alloc=L730+2
*end = 0; // $ deref=L732->L733 // BAD
}
}
void test37(size_t n)
{
int *p = new int[n];
for (size_t i = n; i != 0u; i--)
{
p[n - i] = 0; // GOOD
}
}
unsigned get(char);
void exit(int);
void error(const char * msg) {
exit(1);
}
void test38(unsigned size) {
char * alloc = new char[size];
unsigned pos = 0;
while (pos < size) {
char kind = alloc[pos];
unsigned n = get(alloc[pos]);
if (pos + n >= size) {
error("");
}
switch (kind) {
case '0':
if (n != 1)
error("");
char x = alloc[pos + 1]; // $ alloc=L754 deref=L767 // GOOD [FALSE POSITIVE]
break;
case '1':
if (n != 2)
error("");
char a = alloc[pos + 1]; // $ alloc=L754 deref=L772 // GOOD [FALSE POSITIVE]
char b = alloc[pos + 2];
break;
}
pos += 1 + n;
}
}
void test38_simple(unsigned size, unsigned pos, unsigned numParams) {
char * p = new char[size];
if (pos < size) {
if (pos + numParams < size) {
if (numParams == 1) {
char x = p[pos + 1]; // $ alloc=L781 deref=L786 // GOOD [FALSE POSITIVE]
}
}
}
}
void mk_array_no_field_flow(int size, char** begin, char** end) {
*begin = (char*)malloc(size);
*end = *begin + size; // $ alloc=L793
}
void test6_no_field_flow(int size) {
char* begin;
char* end;
mk_array_no_field_flow(size, &begin, &end);
for (char* p = begin; p != end; ++p) {
*p = 0; // GOOD
}
for (char* p = begin; p <= end; ++p) {
*p = 0; // $ deref=L794->L802->L807 deref=L794->L806->L807 // BAD
}
for (char* p = begin; p < end; ++p) {
*p = 0; // GOOD
}
}
void test7_callee_no_field_flow(char* begin, char* end) {
for (char* p = begin; p != end; ++p) {
*p = 0; // GOOD
}
for (char* p = begin; p <= end; ++p) {
*p = 0; // $ deref=L794->L815->L821 deref=L794->L816->L821 deref=L794->L820->L821 // BAD
}
for (char* p = begin; p < end; ++p) {
*p = 0; // GOOD
}
}
void test7_no_field_flow(int size) {
char* begin;
char* end;
mk_array_no_field_flow(size, &begin, &end);
test7_callee_no_field_flow(begin, end);
}
void test15_with_malloc(size_t index) {
size_t size = index + 13;
if(size < index) {
return;
}
int* newname = (int*)malloc(size);
newname[index] = 0; // $ SPURIOUS: alloc=L841 deref=L842 // GOOD [FALSE POSITIVE]
}
void test16_with_malloc(size_t index) {
size_t size = index + 13;
if(size >= index) {
int* newname = (int*)malloc(size);
newname[index] = 0; // $ SPURIOUS: alloc=L848 deref=L849 // GOOD [FALSE POSITIVE]
}
}
# define MyMalloc(size) malloc(((size) == 0 ? 1 : (size)))
void test_regression(size_t size) {
int* p = (int*)MyMalloc(size + 1);
int* chend = p + (size + 1); // $ alloc=L856+1
if(p <= chend) {
*p = 42; // $ deref=L857->L860 // BAD
}
}
void* g_malloc(size_t size);
void test17(int size) {
char* p = (char*)g_malloc(size);
char* q = p + size; // $ alloc=L868
char a = *q; // $ deref=L869->L870 // BAD
}