Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
"Gustavo A. R. Silva" <[email protected]>
| Newsgroups | org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi! On 7/17/26 10:17, Jesse Taube wrote: > On Wed, Jul 15, 2026 at 12:12 PM Kees Cook <[email protected]> wrote: >> >> On Tue, Jul 14, 2026 at 11:18:18AM -0400, Jesse Taube wrote: >>> Add new DECLARE_SIZED_FLEX() helper to set the default size of a >>> flexible-array member. The code is identical to the declaration in >>> __DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX(). >>> >>> Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of >>> DECLARE_FLEX_ARRAY() with a counted-by attribute. >>> >>> Also add default sized variants of >>> DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and >>> DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX(). >> >> Where do you want to use these new helpers? >> >>> Signed-off-by: Jesse Taube <[email protected]> >>> --- >>> include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++--- >>> 1 file changed, 54 insertions(+), 4 deletions(-) >>> >>> diff --git a/include/linux/overflow.h b/include/linux/overflow.h >>> index a8cb6319b4fb..a3384cae49e5 100644 >>> --- a/include/linux/overflow.h >>> +++ b/include/linux/overflow.h >>> @@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr >>> */ >>> #define struct_offset(p, member) (offsetof(typeof(*(p)), member)) >>> >>> +/** >>> + * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family. >>> + * Allows for easily declaring a structure with a trailing flexible array member >>> + * to have a specific size. >>> + * >>> + * @obj: object to be given a specific size >>> + * @name: Name of the array member. >>> + * @count: Number of elements in the array; must be compile-time const. >>> + */ >>> +#define __DECLARE_SIZED_FLEX(obj, name, count) \ >>> + _Static_assert(__builtin_constant_p(count), \ >>> + "default sized flex array members require compile-time const count"); \ >>> + union { \ >>> + u8 bytes[struct_size_t(obj, name, count)]; \ >>> + obj; \ >>> + } >>> + >>> +/** >>> + * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array >>> + * >>> + * @type: Type name. >>> + * @name: Name of the array member. >>> + * @counter: Name of the __counted_by member. >>> + */ >>> +#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\ >>> + struct { \ >>> + size_t counter; \ >>> + type name[] __counted_by(counter); \ >>> + } >>> + >>> +/** >>> + * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array >>> + * member with a default size. >>> + * >>> + * @type: Type name. >>> + * @name: Name of the array member. >>> + * @count: Number of elements in the array; must be compile-time const. >>> + */ >>> +#define DECLARE_SIZED_FLEX(type, name, count) \ >>> + __DECLARE_SIZED_FLEX(type name[], name, count) >>> + >>> +/** >>> + * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible >>> + * array member counted by count, with a default size. >>> + * >>> + * @type: Type name. >>> + * @name: Name of the array member. >>> + * @counter: Name of the __counted_by member. >>> + * @count: Number of elements in the array; must be compile-time const. >>> + */ >>> +#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count) \ >>> + __DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count) >> >> I ask about where these will be used because one of the things I want to >> keep tied together is the "counter" and "count", which usually means the >> declaration should be combined with an initializer in some way so that >> the counter gets assigned, as DEFINE_FLEX() ultimately does. >> >> I'm worried that extracting the internal construction of __DEFINE_FLEX >> means we may run the risk of increasing the risk of losing that tie. > > We can add a comment to make sure to set count, or use DEFINE_FLEX > to allocate it. Im not sure if there is a way for this to be a compile time > error though. > >> So, I'd love to understand how you want to use this, as that would help >> my understanding and potentially shape the design so we can keep counter >> and count strongly associated. > > Basically, I want to use `DECLARE_COUNTED_SIZED_FLEX` for a version of > this patch that > uses `__counted_by` > https://lore.kernel.org/linux-scsi/[email protected]/ > I have checked that it does always set the `counter` variable correctly. > > As for `DECLARE_COUNTED_FLEX_ARRAY` there is already `DECLARE_FLEX_ARRAY` and > the counted variant is already used in a few places. A good example is > `struct max77759_maxq_response` which subsiqently gets allocated with > `DEFINE_FLEX` > https://elixir.bootlin.com/linux/v7.2-rc1/source/include/linux/mfd/max77759.h#L253 > > I assume you are ok with adding `__DECLARE_SIZED_FLEX` and > `DECLARE_SIZED_FLEX` as > they are usefull in cases where keeping structure offsets is > important, similar to > TRAILING_OVERLAP. An example of where `__DECLARE_SIZED_FLEX` could be used is: > https://lore.kernel.org/all/[email protected]/ Please show us examples of how exactly you'd use the helpers you propose for the cases you mentioned above. Thanks -Gustavo > > Thanks, > Jesse Taube > >> >>> + >>> /** >>> * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. >>> * Enables caller macro to pass arbitrary trailing expressions >>> @@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr >>> #define __DEFINE_FLEX(type, name, member, count, trailer...) \ >>> _Static_assert(__builtin_constant_p(count), \ >>> "onstack flex array members require compile-time const count"); \ >>> - union { \ >>> - u8 bytes[struct_size_t(type, member, count)]; \ >>> - type obj; \ >>> - } name##_u trailer; \ >>> + __DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer; \ >>> type *name = (type *)&name##_u >> >> -Kees >> >> -- >> Kees Cook >> >