C++: Model strdupa and strndupa string functions returning memory allocated with alloca

This commit is contained in:
Anders Fugmann
2021-08-18 13:00:07 +02:00
parent 21d03cd365
commit 44752d5ee0
4 changed files with 43 additions and 6 deletions

View File

@@ -16,6 +16,7 @@ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlow
hasGlobalName([
// --- C library allocation
"strdup", // strdup(str)
"strdupa", // strdupa(str) - returns stack allocated buffer
"wcsdup", // wcsdup(str)
"_strdup", // _strdup(str)
"_wcsdup", // _wcsdup(str)
@@ -31,6 +32,8 @@ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlow
input.isParameterDeref(0) and
output.isReturnValueDeref()
}
override predicate requiresDealloc() { not hasGlobalName("strdupa") }
}
/**
@@ -38,11 +41,11 @@ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlow
*/
private class StrndupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction {
StrndupFunction() {
exists(string name |
hasGlobalName(name) and
// --- C library allocation
name = "strndup" // strndup(str, maxlen)
)
hasGlobalName([
// -- C library allocation
"strndup", // strndup(str, maxlen)
"strndupa" // strndupa(str, maxlen) -- returns stack allocated buffer
])
}
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
@@ -56,4 +59,6 @@ private class StrndupFunction extends AllocationFunction, ArrayFunction, DataFlo
) and
output.isReturnValueDeref()
}
override predicate requiresDealloc() { not hasGlobalName("strndupa") }
}

View File

@@ -24,6 +24,8 @@
| test.cpp:126:8:126:9 | i2 |
| test.cpp:127:8:127:9 | i3 |
| test.cpp:128:15:128:16 | v4 |
| test.cpp:185:10:185:12 | cpy |
| test.cpp:199:10:199:12 | cpy |
| virtual.cpp:18:10:18:10 | a |
| virtual.cpp:19:10:19:10 | c |
| virtual.cpp:38:10:38:10 | b |

View File

@@ -10,4 +10,4 @@
| test.cpp:89:18:89:23 | call to malloc | This memory is never freed |
| test.cpp:156:3:156:26 | new | This memory is never freed |
| test.cpp:157:3:157:26 | new[] | This memory is never freed |
| test.cpp:167:14:167:19 | call to strdup | This memory is never freed |
| test.cpp:169:14:169:19 | call to strdup | This memory is never freed |

View File

@@ -155,6 +155,8 @@ int overloadedNew() {
new(std::nothrow) int(3); // BAD
new(std::nothrow) int[2]; // BAD
return 0;
}
// --- strdup ---
@@ -168,3 +170,31 @@ void test_strdup() {
output_msg(cpy);
}
// --- strdupa ---
char *strdupa(const char *s1);
void test_strdupa_no_dealloc() {
char msg[] = "OctoCat";
char *cpy = strdupa(msg); // GOOD
}
void test_strdupa_dealloc() {
char msg[] = "OctoCat";
char *cpy = strdupa(msg);
free(cpy); // BAD [NOT DETECTED]
}
// --- strndupa ---
char *strndupa(const char *s1, size_t maxsize);
void test_strndupa_no_dealloc() {
char msg[] = "OctoCat";
char *cpy = strndupa(msg, 4); // GOOD
}
void test_strndupa_dealloc() {
char msg[] = "OctoCat";
char *cpy = strndupa(msg, 4);
free(cpy); // BAD [NOT DETECTED]
}