From d6054c9a5104fe486e15f54d94528ea8d01c9ec1 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jan 2025 15:48:04 +0000 Subject: [PATCH] C++: Infer larger buffer sizes for non-static member variables. --- cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll index 95fb7e47593..56776001909 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll @@ -54,13 +54,28 @@ private int isSource(Expr bufferExpr, Element why) { result = bufferExpr.(AllocationExpr).getSizeBytes() and why = bufferExpr or - exists(Type bufferType | + exists(Type bufferType, Variable v | + v = why and // buffer is the address of a variable why = bufferExpr.(AddressOfExpr).getAddressable() and - bufferType = why.(Variable).getUnspecifiedType() and - result = bufferType.getSize() and + bufferType = v.getUnspecifiedType() and not bufferType instanceof ReferenceType and not any(Union u).getAMemberVariable() = why + | + not v instanceof Field and + result = bufferType.getSize() + or + // If it's an address of a field (i.e., a non-static member variable) + // then it's okay to use that address to access the other member variables. + // For example, this is okay: + // ``` + // struct S { uint8_t a, b, c; }; + // S s; + // memset(&s.a, 0, sizeof(S) - offsetof(S, a)); + exists(Field f | + v = f and + result = f.getDeclaringType().getSize() - f.getByteOffset() + ) ) or exists(Union bufferType |