Skip to content

Commit 7b03f32

Browse files
committed
C++: Fix false positives.
1 parent 45e92ce commit 7b03f32

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

cpp/ql/src/Critical/SizeCheck2.ql

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,20 @@ predicate baseType(AllocationExpr alloc, Type base) {
3030
}
3131

3232
predicate decideOnSize(Type t, int size) {
33-
// If the codebase has more than one type with the same name, it can have more than one size.
33+
// If the codebase has more than one type with the same name, it can have more than one size. For
34+
// most purposes in this query, we use the smallest.
3435
size = min(t.getSize())
3536
}
3637

38+
predicate mayHaveVarSize(Type t) {
39+
// a member (normally at the end of the type) that looks like it may be intended have variable size.
40+
exists(MemberVariable mv, ArrayType at |
41+
mv.getDeclaringType() = t and
42+
mv.getUnspecifiedType() = at and
43+
not at.getArraySize() > 1
44+
)
45+
}
46+
3747
from AllocationExpr alloc, Type base, int basesize, int allocated
3848
where
3949
baseType(alloc, base) and
@@ -45,7 +55,8 @@ where
4555
size = 0 or
4656
(allocated / size) * size = allocated
4757
) and
48-
not basesize > allocated // covered by SizeCheck.ql
58+
not basesize > allocated and // covered by SizeCheck.ql
59+
not mayHaveVarSize(base.getUnspecifiedType()) // exclude variable size types
4960
select alloc,
5061
"Allocated memory (" + allocated.toString() + " bytes) is not a multiple of the size of '" +
5162
base.getName() + "' (" + basesize.toString() + " bytes)."

cpp/ql/test/query-tests/Critical/SizeCheck/SizeCheck2.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,4 @@
22
| test2.c:17:20:17:25 | call to malloc | Allocated memory (33 bytes) is not a multiple of the size of 'double' (8 bytes). |
33
| test2.c:32:23:32:28 | call to malloc | Allocated memory (28 bytes) is not a multiple of the size of 'long long' (8 bytes). |
44
| test2.c:33:20:33:25 | call to malloc | Allocated memory (20 bytes) is not a multiple of the size of 'double' (8 bytes). |
5-
| test2.c:82:23:82:28 | call to malloc | Allocated memory (135 bytes) is not a multiple of the size of 'MyVarStruct1' (8 bytes). |
6-
| test2.c:83:23:83:28 | call to malloc | Allocated memory (143 bytes) is not a multiple of the size of 'MyVarStruct2' (16 bytes). |
7-
| test2.c:84:23:84:28 | call to malloc | Allocated memory (135 bytes) is not a multiple of the size of 'MyVarStruct3' (8 bytes). |
85
| test2.c:85:24:85:29 | call to malloc | Allocated memory (1159 bytes) is not a multiple of the size of 'MyFixedStruct' (1032 bytes). |

cpp/ql/test/query-tests/Critical/SizeCheck/test2.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ typedef struct _MyFixedStruct {
7979
} MyFixedStruct;
8080

8181
void varStructTests() {
82-
MyVarStruct1 *a = malloc(sizeof(MyVarStruct1) + 127); // GOOD [FALSE POSITIVE]
83-
MyVarStruct2 *b = malloc(sizeof(MyVarStruct2) + 127); // GOOD [FALSE POSITIVE]
84-
MyVarStruct3 *c = malloc(sizeof(MyVarStruct3) + 127); // GOOD [FALSE POSITIVE]
82+
MyVarStruct1 *a = malloc(sizeof(MyVarStruct1) + 127); // GOOD
83+
MyVarStruct2 *b = malloc(sizeof(MyVarStruct2) + 127); // GOOD
84+
MyVarStruct3 *c = malloc(sizeof(MyVarStruct3) + 127); // GOOD
8585
MyFixedStruct *d = malloc(sizeof(MyFixedStruct) + 127); // BAD --- Not a multiple of sizeof(MyFixedStruct)
8686
}

0 commit comments

Comments
 (0)