stddef: Introduce __TRAILING_OVERLAP()

Introduce underlying __TRAILING_OVERLAP() macro to let callers apply
atributes to trailing overlapping members.

For instance, the code below:

| struct flex {
| 	size_t count;
| 	int data[];
| };

| struct {
| 	struct flex f;
| 	struct foo a;
| 	struct boo b;
| } __packed instance;

can now be changed to the following, and preserve the __packed
attribute:

| __TRAILING_OVERLAP(struct flex, f, data, __packed,
| 	struct foo a;
| 	struct boo b;
| ) instance;

Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Link: https://lore.kernel.org/r/f80c529b239ce11f0a51f714fe00ddf839e05f5e.1758115257.git.gustavoars@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
This commit is contained in:
Gustavo A. R. Silva 2025-09-17 15:28:07 +02:00 committed by Kees Cook
parent 413187f790
commit 2bbdcf02c3
1 changed files with 23 additions and 7 deletions

View File

@ -93,6 +93,28 @@ enum {
#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ #define DECLARE_FLEX_ARRAY(TYPE, NAME) \
__DECLARE_FLEX_ARRAY(TYPE, NAME) __DECLARE_FLEX_ARRAY(TYPE, NAME)
/**
* __TRAILING_OVERLAP() - Overlap a flexible-array member with trailing
* members.
*
* Creates a union between a flexible-array member (FAM) in a struct and a set
* of additional members that would otherwise follow it.
*
* @TYPE: Flexible structure type name, including "struct" keyword.
* @NAME: Name for a variable to define.
* @FAM: The flexible-array member within @TYPE
* @ATTRS: Any struct attributes (usually empty)
* @MEMBERS: Trailing overlapping members.
*/
#define __TRAILING_OVERLAP(TYPE, NAME, FAM, ATTRS, MEMBERS) \
union { \
TYPE NAME; \
struct { \
unsigned char __offset_to_FAM[offsetof(TYPE, FAM)]; \
MEMBERS \
} ATTRS; \
}
/** /**
* TRAILING_OVERLAP() - Overlap a flexible-array member with trailing members. * TRAILING_OVERLAP() - Overlap a flexible-array member with trailing members.
* *
@ -105,12 +127,6 @@ enum {
* @MEMBERS: Trailing overlapping members. * @MEMBERS: Trailing overlapping members.
*/ */
#define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS) \ #define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS) \
union { \ __TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS)
TYPE NAME; \
struct { \
unsigned char __offset_to_FAM[offsetof(TYPE, FAM)]; \
MEMBERS \
}; \
}
#endif #endif