Skip to content

Commit 9e9d57b

Browse files
authored
Merge pull request #21219 from MathiasVP/force-more-uniquess-in-buffer-overflow
C++: Enforce more uniqueness in `Buffer.qll`
2 parents 8e3c373 + 980c4cf commit 9e9d57b

File tree

2 files changed

+39
-35
lines changed

2 files changed

+39
-35
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.

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

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ private Class getRootType(FieldAccess fa) {
6262
* unspecified type of `v` is a `ReferenceType`.
6363
*/
6464
private int getVariableSize(Variable v) {
65-
exists(Type t |
66-
t = v.getUnspecifiedType() and
67-
not t instanceof ReferenceType and
68-
result = t.getSize()
69-
)
65+
result =
66+
unique(Type t |
67+
t = v.getUnspecifiedType() and
68+
not t instanceof ReferenceType
69+
|
70+
t.getSize()
71+
)
7072
}
7173

7274
/**
@@ -79,30 +81,32 @@ private int getSize(VariableAccess va) {
7981
not v instanceof Field and
8082
result = getVariableSize(v)
8183
or
82-
exists(Class c, int trueSize |
83-
// Otherwise, we find the "outermost" object and compute the size
84-
// as the difference between the size of the type of the "outermost
85-
// object" and the offset of the field relative to that type.
86-
// For example, consider the following structs:
87-
// ```
88-
// struct S {
89-
// uint32_t x;
90-
// uint32_t y;
91-
// };
92-
// struct S2 {
93-
// S s;
94-
// uint32_t z;
95-
// };
96-
// ```
97-
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
98-
// is the size of the base object type (i.e., `S2`) minutes the offset
99-
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
100-
// buffer is `12 - 4 = 8`.
101-
c = getRootType(va) and
102-
// we calculate the size based on the last field, to avoid including any padding after it
103-
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f)) and
104-
result = trueSize - v.(Field).getOffsetInClass(c)
105-
)
84+
result =
85+
unique(Class c, int trueSize |
86+
// Otherwise, we find the "outermost" object and compute the size
87+
// as the difference between the size of the type of the "outermost
88+
// object" and the offset of the field relative to that type.
89+
// For example, consider the following structs:
90+
// ```
91+
// struct S {
92+
// uint32_t x;
93+
// uint32_t y;
94+
// };
95+
// struct S2 {
96+
// S s;
97+
// uint32_t z;
98+
// };
99+
// ```
100+
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
101+
// is the size of the base object type (i.e., `S2`) minus the offset
102+
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
103+
// buffer is `12 - 4 = 8`.
104+
c = getRootType(va) and
105+
// we calculate the size based on the last field, to avoid including any padding after it
106+
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f))
107+
|
108+
trueSize - v.(Field).getOffsetInClass(c)
109+
)
106110
)
107111
}
108112

@@ -116,12 +120,8 @@ private int isSource(Expr bufferExpr, Element why) {
116120
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
117121
// buffer is a fixed size array
118122
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
119-
result =
120-
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
121-
size = getSize(bufferExpr)
122-
|
123-
size
124-
) and
123+
// more generous than .getSize() itself, when the array is a class field or similar.
124+
result = getSize(bufferExpr) and
125125
why = bufferVar and
126126
not memberMayBeVarSize(_, bufferVar) and
127127
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and

0 commit comments

Comments
 (0)