Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family

From: Jesse Taube

Date: Fri Jul 17 2026 - 12:18:47 EST


On Wed, Jul 15, 2026 at 12:12 PM Kees Cook <kees@xxxxxxxxxx> 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 <jtaubepe@xxxxxxxxxx>
> > ---
> > 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/97526d45-ec7d-48a0-bdc6-659f75839f53@xxxxxxxxxxxxxx/
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/20260714185621.610105-1-jtaubepe@xxxxxxxxxx/

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
>