Skip to content

Commit c6f0126

Browse files
authored
Merge pull request #1263 from geoffw0/bufferoverflowqueries
CPP: Resolve overlap between OverflowCalculated.ql and NoSpaceForZeroTerminator.ql
2 parents c674f54 + 56e0adf commit c6f0126

9 files changed

Lines changed: 87 additions & 13 deletions

File tree

change-notes/1.21/analysis-cpp.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
| **Query** | **Expected impact** | **Change** |
1313
|----------------------------|------------------------|------------------------------------------------------------------|
14+
| Buffer not sufficient for string (`cpp/overflow-calculated`) | Fewer results | This query no longer reports results that would be found by the 'No space for zero terminator' (`cpp/no-space-for-terminator`) query. |
15+
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | This query now detects calls to `std::malloc`. |
1416
| Commented-out code (`cpp/commented-out-code`) | More correct results | Commented out preprocessor code is now detected by this query. |
1517
| Dead code due to goto or break statement (`cpp/dead-code-goto`) | Fewer false positive results | Functions containing preprocessor logic are now excluded from this analysis. |
1618
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed an issue where functions were being identified as allocation functions inappropriately. Also affects `cpp/new-array-delete-mismatch` and `cpp/new-delete-array-mismatch`. |

cpp/ql/src/Critical/OverflowCalculated.ql

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import cpp
1313

1414
class MallocCall extends FunctionCall
1515
{
16-
MallocCall() { this.getTarget().hasQualifiedName("malloc") }
16+
MallocCall() {
17+
this.getTarget().hasQualifiedName("malloc") or
18+
this.getTarget().hasQualifiedName("std::malloc")
19+
}
1720

1821
Expr getAllocatedSize() {
1922
if this.getArgument(0) instanceof VariableAccess then
@@ -25,12 +28,6 @@ class MallocCall extends FunctionCall
2528
}
2629
}
2730

28-
predicate terminationProblem(MallocCall malloc, string msg)
29-
{
30-
malloc.getAllocatedSize() instanceof StrlenCall and
31-
msg = "This allocation does not include space to null-terminate the string."
32-
}
33-
3431
predicate spaceProblem(FunctionCall append, string msg)
3532
{
3633
exists(MallocCall malloc, StrlenCall strlen, AddExpr add, FunctionCall insert, Variable buffer |
@@ -48,5 +45,5 @@ predicate spaceProblem(FunctionCall append, string msg)
4845
}
4946

5047
from Expr problem, string msg
51-
where terminationProblem(problem, msg) or spaceProblem(problem, msg)
48+
where spaceProblem(problem, msg)
5249
select problem, msg

cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@
1515
*/
1616
import cpp
1717

18-
class MallocCall extends FunctionCall {
19-
MallocCall() { this.getTarget().hasGlobalName("malloc") }
18+
class MallocCall extends FunctionCall
19+
{
20+
MallocCall() {
21+
this.getTarget().hasQualifiedName("malloc") or
22+
this.getTarget().hasQualifiedName("std::malloc")
23+
}
2024

2125
Expr getAllocatedSize() {
2226
if this.getArgument(0) instanceof VariableAccess then
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| tests1.cpp:26:21:26:26 | call to malloc | This allocation does not include space to null-terminate the string. |
2+
| tests1.cpp:67:21:67:26 | call to malloc | This allocation does not include space to null-terminate the string. |
3+
| tests1.cpp:89:25:89:30 | call to malloc | This allocation does not include space to null-terminate the string. |
4+
| tests3.cpp:25:21:25:31 | call to malloc | This allocation does not include space to null-terminate the string. |
5+
| tests3.cpp:30:21:30:31 | call to malloc | This allocation does not include space to null-terminate the string. |

cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.qlref renamed to cpp/ql/test/query-tests/Critical/OverflowCalculated/NoSpaceForZeroTerminator.qlref

File renamed without changes.
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
| tests1.cpp:26:21:26:26 | call to malloc | This allocation does not include space to null-terminate the string. |
2-
| tests1.cpp:67:21:67:26 | call to malloc | This allocation does not include space to null-terminate the string. |
3-
| tests1.cpp:89:25:89:30 | call to malloc | This allocation does not include space to null-terminate the string. |
41
| tests2.cpp:34:4:34:9 | call to strcat | This buffer only contains enough room for 'str1' (copied on line 33) |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// tests1.cpp
2+
3+
typedef unsigned int size_t;
4+
5+
char *strcpy(char *destination, const char *source);
6+
char *strcat(char *destination, const char *source);
7+
size_t strlen(const char *str);
8+
9+
namespace std
10+
{
11+
void *malloc(size_t size);
12+
void free(void *ptr);
13+
}
14+
15+
const char *str3global = "123";
16+
17+
void tests3(int case_num)
18+
{
19+
const char *str3local = "123";
20+
char *buffer = 0;
21+
22+
switch (case_num)
23+
{
24+
case 1:
25+
buffer = (char *)std::malloc(strlen(str3global)); // BAD
26+
strcpy(buffer, str3global);
27+
break;
28+
29+
case 2:
30+
buffer = (char *)std::malloc(strlen(str3local)); // BAD
31+
strcpy(buffer, str3local);
32+
break;
33+
34+
case 3:
35+
buffer = (char *)std::malloc(strlen(str3global) + 1); // GOOD
36+
strcpy(buffer, str3global);
37+
break;
38+
39+
case 4:
40+
buffer = (char *)std::malloc(strlen(str3local) + 1); // GOOD
41+
strcpy(buffer, str3local);
42+
break;
43+
}
44+
45+
if (buffer != 0)
46+
{
47+
std::free(buffer);
48+
}
49+
}
50+
51+
void test3b()
52+
{
53+
char *buffer = new char[strlen(str3global)]; // BAD [NOT DETECTED]
54+
55+
strcpy(buffer, str3global);
56+
57+
delete buffer;
58+
}
59+
60+
void test3c()
61+
{
62+
char *buffer = new char[10]; // BAD [NOT DETECTED]
63+
64+
strcpy(buffer, "123456");
65+
strcat(buffer, "123456");
66+
67+
delete buffer;
68+
}

cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.expected renamed to cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected

File renamed without changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql

0 commit comments

Comments
 (0)