coccinelle: add SIZEOF() macro to work-around sizeof(*private)

We have code like `size_t max_size = sizeof(*private)` in three
places. This is evaluated at compile time so its safe to use. However
the new pointer-deref checker in coccinelle is not smart enough to know
this and will flag those as errors. To avoid these false positives
we have some options:
1. Reorder so that we do:
```C
size_t max_size = 0;
assert(private);
max_size = sizeof(*private);
```
2. Use something like `size_t max_size = sizeof(*ASSERT_PTR(private));`
3. Place the assert before the declaration
4. Workaround coccinelle via SIZEOF(*private) that we can then hide
   via parsing_hacks.h
5. Fix coccinelle (OCaml, hard)
6. ... somehting I missed?

None of these is very appealing. I went for (4) but happy about
suggestions.
This commit is contained in:
Michael Vogt
2026-04-12 15:47:48 +02:00
parent 3b8408a756
commit 9d8d0d412f
3 changed files with 16 additions and 3 deletions
+5
View File
@@ -99,6 +99,11 @@
#define CMSG_BUFFER_TYPE(x) union { uint8_t align_check[(size) >= CMSG_SPACE(0) && (size) == CMSG_ALIGN(size) ? 1 : -1]; }
#define SD_ID128_MAKE(...) ((const sd_id128) {})
/* sizeof() does not evaluate its argument, so *ptr inside sizeof() is not a real dereference.
* The SIZEOF() macro is an alias for sizeof() that hides the argument from coccinelle to avoid
* false positives from check-pointer-deref.cocci. See assert-fundamental.h for the definition. */
#define SIZEOF(x) 8
/* Work around a bug in zlib.h parsing on Fedora (and possibly others)
* See: https://github.com/coccinelle/coccinelle/issues/413 */
#define Z_EXPORT
+8
View File
@@ -105,3 +105,11 @@ static inline int __coverity_check_and_return__(int condition) {
* the coccinelle check-pointer-deref warning for parameters that are safely handled before any
* dereference (e.g. passed to a NULL-safe helper like iovec_is_set()). */
#define POINTER_MAY_BE_NULL(ptr) ({ (void) (ptr); })
/* sizeof() does not evaluate its argument - it is a compile-time constant expression - so *ptr
* inside sizeof() is not a real dereference. However, coccinelle cannot distinguish this from an
* actual dereference, and when sizeof(*ptr) appears in a variable initializer the assert(ptr) that
* follows cannot come first (declarations must precede statements). Use this macro in place
* of sizeof() to avoid the false positive - coccinelle sees SIZEOF() as a function call (via
* parsing_hacks.h) and never looks inside the argument. */
#define SIZEOF(x) sizeof(x)
+3 -3
View File
@@ -2507,7 +2507,7 @@ static int tpm2_load_external(
}
static int tpm2_marshal_private(const TPM2B_PRIVATE *private, void **ret, size_t *ret_size) {
size_t max_size = sizeof(*private), blob_size = 0;
size_t max_size = SIZEOF(*private), blob_size = 0;
_cleanup_free_ void *blob = NULL;
TSS2_RC rc;
@@ -2550,7 +2550,7 @@ static int tpm2_unmarshal_private(const void *data, size_t size, TPM2B_PRIVATE *
}
int tpm2_marshal_public(const TPM2B_PUBLIC *public, void **ret, size_t *ret_size) {
size_t max_size = sizeof(*public), blob_size = 0;
size_t max_size = SIZEOF(*public), blob_size = 0;
_cleanup_free_ void *blob = NULL;
TSS2_RC rc;
@@ -2593,7 +2593,7 @@ static int tpm2_unmarshal_public(const void *data, size_t size, TPM2B_PUBLIC *re
}
int tpm2_marshal_nv_public(const TPM2B_NV_PUBLIC *nv_public, void **ret, size_t *ret_size) {
size_t max_size = sizeof(*nv_public), blob_size = 0;
size_t max_size = SIZEOF(*nv_public), blob_size = 0;
_cleanup_free_ void *blob = NULL;
TSS2_RC rc;