Skip to content

Commit 3172d57

Browse files
committed
C++: Relax constraints on Buffer::memberMayBeVarSize
1 parent 4ab9b81 commit 3172d57

File tree

3 files changed

+14
-18
lines changed

3 files changed

+14
-18
lines changed

cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import cpp
22
import semmle.code.cpp.dataflow.DataFlow
33

44
/**
5-
* Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For
6-
* example:
5+
* Holds if `v` is a member variable of `c` that looks like it might be variable sized
6+
* in practice. For example:
77
* ```
88
* struct myStruct { // c
99
* int amount;
1010
* char data[1]; // v
1111
* };
1212
* ```
13-
* This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition,
14-
* there must be at least one instance where a `c` pointer is allocated with additional space. For
15-
* example, holds for `c` if it occurs as
13+
* This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`.
14+
* In addition, if the size of the structure is taken, there must be at least one instance
15+
* where a `c` pointer is allocated with additional space.
16+
* For example, holds for `c` if it occurs as
1617
* ```
1718
* malloc(sizeof(c) + 100 * sizeof(char))
1819
* ```
@@ -29,7 +30,14 @@ predicate memberMayBeVarSize(Class c, MemberVariable v) {
2930
// v is an array of size at most 1
3031
v.getUnspecifiedType().(ArrayType).getArraySize() <= 1
3132
) and
33+
// If the size is taken, then arithmetic is performed on the result at least once
3234
(
35+
not exists(SizeofOperator so |
36+
// `sizeof(c)` is taken
37+
so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
38+
so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
39+
)
40+
or
3341
exists(SizeofOperator so |
3442
// `sizeof(c)` is taken
3543
so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
@@ -38,16 +46,6 @@ predicate memberMayBeVarSize(Class c, MemberVariable v) {
3846
// arithmetic is performed on the result
3947
so.getParent*() instanceof AddExpr
4048
)
41-
or
42-
exists(AddressOfExpr aoe |
43-
// `&(c.v)` is taken
44-
aoe.getAddressable() = v
45-
)
46-
or
47-
exists(BuiltInOperationBuiltInOffsetOf oo |
48-
// `offsetof(c, v)` using a builtin
49-
oo.getAChild().(VariableAccess).getTarget() = v
50-
)
5149
)
5250
}
5351

cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,4 @@
8080
| var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
8181
| var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
8282
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
83-
| var_size_struct.cpp:171:3:171:8 | call to memset | This 'memset' operation accesses 100 bytes but the $@ is only 1 byte. | var_size_struct.cpp:125:17:125:19 | arr | destination buffer |
83+
| var_size_struct.cpp:169:3:169:8 | call to memset | This 'memset' operation accesses 100 bytes but the $@ is only 1 byte. | var_size_struct.cpp:125:17:125:19 | arr | destination buffer |

cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ void useVarStruct34(varStruct5 *vs5) {
161161
varStruct5 *vs5b = (varStruct5 *)malloc(sizeof(*vs5));
162162
varStruct6 *vs6 = (varStruct6 *)malloc(offsetof(varStruct6, arr) + 9); // establish varStruct6 as variable size
163163
varStruct7 *vs7 = (varStruct7 *)malloc(sizeForVarStruct7(9)); // establish varStruct7 as variable size
164-
varStruct8 *vs8a = (varStruct8 *)malloc(sizeof(varStruct8) + 9); // establish varStruct8 as variable size
165-
varStruct8 *vs8b = (varStruct8 *)malloc(sizeof(varStruct8));
166164
varStruct9 *vs9 = (varStruct9 *)malloc(__builtin_offsetof(varStruct9, arr) + 9); // establish varStruct9 as variable size
167165
}
168166

0 commit comments

Comments
 (0)