Merge pull request #6603 from geoffw0/impropnulltests

C++: Add test cases for cpp/improper-null-termination.
This commit is contained in:
Mathias Vorreiter Pedersen
2021-09-07 09:55:36 +01:00
committed by GitHub
4 changed files with 243 additions and 5 deletions

View File

@@ -11,4 +11,15 @@
| test.cpp:130:14:130:19 | buffer | Variable $@ may not be null terminated. | test.cpp:127:7:127:12 | buffer | buffer |
| test.cpp:139:10:139:15 | buffer | Variable $@ may not be null terminated. | test.cpp:136:8:136:13 | buffer | buffer |
| test.cpp:147:14:147:19 | buffer | Variable $@ may not be null terminated. | test.cpp:143:8:143:13 | buffer | buffer |
| test.cpp:170:10:170:15 | buffer | Variable $@ may not be null terminated. | test.cpp:166:8:166:13 | buffer | buffer |
| test.cpp:182:10:182:15 | buffer | Variable $@ may not be null terminated. | test.cpp:178:8:178:13 | buffer | buffer |
| test.cpp:234:10:234:15 | buffer | Variable $@ may not be null terminated. | test.cpp:232:8:232:13 | buffer | buffer |
| test.cpp:262:10:262:15 | buffer | Variable $@ may not be null terminated. | test.cpp:259:8:259:13 | buffer | buffer |
| test.cpp:283:10:283:15 | buffer | Variable $@ may not be null terminated. | test.cpp:280:8:280:13 | buffer | buffer |
| test.cpp:300:10:300:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:295:8:295:14 | buffer2 | buffer2 |
| test.cpp:312:10:312:15 | buffer | Variable $@ may not be null terminated. | test.cpp:308:8:308:13 | buffer | buffer |
| test.cpp:327:18:327:23 | buffer | Variable $@ may not be null terminated. | test.cpp:326:8:326:13 | buffer | buffer |
| test.cpp:346:11:346:16 | buffer | Variable $@ may not be null terminated. | test.cpp:341:8:341:13 | buffer | buffer |
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
| test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 |
| test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer |
| test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer |

View File

@@ -0,0 +1,2 @@
| test.cpp:410:10:410:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:409:18:409:23 | buffer | User-provided value |
| test.cpp:425:10:425:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:424:9:424:14 | buffer | User-provided value |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-170/ImproperNullTerminationTainted.ql

View File

@@ -1,16 +1,16 @@
typedef unsigned int size_t;
typedef signed int ssize_t;
typedef struct {} FILE;
size_t strlen(const char *s);
char *strcpy(char *s1, const char *s2);
char *strcat(char *s1, const char *s2);
char *strdup(const char *s1);
void *malloc(size_t size);
void *memset(void *s, int c, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void read(int src, void *out, int num);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ssize_t readlink(const char *path, char *buffer, size_t buffer_size);
ssize_t readlinkat(int fd, const char *path, char *buffer, size_t buffer_size);
@@ -154,6 +154,18 @@ void test_readlink(int fd, const char *path, size_t sz)
strdup(buffer); // GOOD
}
{
char buffer[1024];
ssize_t len;
len = readlink(path, buffer, sizeof(buffer));
if (len >= 0)
{
buffer[len - 1] = 0;
strdup(buffer); // GOOD
}
}
{
char buffer[1024];
@@ -209,3 +221,215 @@ void test_readlink(int fd, const char *path, size_t sz)
strdup(buffer); // GOOD
}
}
void doNothing(char *data) { };
void doNothing2(const char *data);
void clearBuffer(char *data, size_t size);
void test_strcat()
{
{
char buffer[1024];
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
buffer[0] = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[10] = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[0] = '\0';
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[0] = 'a';
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
*buffer = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
strcpy(buffer, "con");
strcat(buffer, "tent"); // GOOD
}
{
char buffer[1024];
doNothing(buffer);
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
doNothing2(buffer);
strcat(buffer, "content"); // BAD [NOT DETECTED]
}
{
char buffer1[1024];
char buffer2[1024];
char *buffer_ptr = buffer1;
*buffer_ptr = 0;
strcat(buffer1, "content"); // GOOD
strcat(buffer2, "content"); // BAD
strcat(buffer_ptr, "content"); // GOOD
buffer_ptr = buffer2;
strcat(buffer_ptr, "content"); // BAD [NOT DETECTED]
}
{
char buffer[1024];
char *buffer_ptr = buffer;
*buffer_ptr = 'a';
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
clearBuffer(buffer, 1024);
strcat(buffer, "content"); // GOOD
}
}
void test_strlen(bool cond1, bool cond2)
{
{
char buffer[1024];
int i = strlen(buffer); // BAD
}
{
char buffer[1024] = {0};
int i = strlen(buffer); // GOOD
}
{
char *ptr = "content";
int i = strlen(ptr); // GOOD
}
{
char buffer[1024];
if (cond1)
buffer[0] = 0;
if (cond1)
strlen(buffer); // GOOD [FALSE POSITIVE]
}
{
char buffer[1024];
if (cond1)
buffer[0] = 0;
if (cond2)
strlen(buffer); // BAD
}
}
void test_strcpy()
{
{
char buffer1[1024];
char buffer2[1024];
strcpy(buffer1, buffer2); // BAD
}
{
char buffer1[1024];
char buffer2[1024];
strcpy(buffer2, "content"); // GOOD
strcpy(buffer1, buffer2); // GOOD
}
}
void strcatWrapper(char *data, const char *with)
{
strcat(data, with);
}
void strcatWrapper2(char *data, const char *with)
{
strcatWrapper(data, with);
}
void test_wrappers()
{
{
char buffer[1024];
strcatWrapper(buffer, "content"); // BAD
}
{
char buffer[1024];
strcatWrapper2(buffer, "content"); // BAD
}
}
void test_read_fread(int read_src, FILE *s)
{
const size_t buffer_size = 80;
{
char buffer[buffer_size];
read(read_src, buffer, buffer_size * sizeof(char));
strlen(buffer); // BAD
}
{
char buffer[buffer_size];
read(read_src, buffer, buffer_size * sizeof(char));
buffer[buffer_size - 1] = 0;
strlen(buffer); // GOOD
}
{
char buffer[buffer_size];
fread(buffer, sizeof(char), buffer_size, s);
strlen(buffer); // BAD
}
{
char buffer[buffer_size];
fread(buffer, sizeof(char), buffer_size, s);
buffer[buffer_size - 1] = 0;
strlen(buffer); // GOOD
}
}