2024-02-10 01:17:00

by Kees Cook

[permalink] [raw]
Subject: [PATCH 0/2] stddef: Allow attributes to be used when creating flex arrays

Hi,

We're going to have more cases where we need to apply attributes
(e.g. __counted_by) to struct members that have been declared with
DECLARE_FLEX_ARRAY. Add a new ..._ATTR helper to allow for this and
annotate one such user in linux/in.h.

-Kees

Kees Cook (2):
stddef: Allow attributes to be used when creating flex arrays
net/ipv4: Annotate imsf_slist_flex with __counted_by(imsf_numsrc)

include/linux/stddef.h | 16 ++++++++++++++--
include/uapi/linux/in.h | 3 ++-
include/uapi/linux/stddef.h | 25 +++++++++++++++++++------
3 files changed, 35 insertions(+), 9 deletions(-)

--
2.34.1



2024-02-10 01:17:05

by Kees Cook

[permalink] [raw]
Subject: [PATCH 2/2] net/ipv4: Annotate imsf_slist_flex with __counted_by(imsf_numsrc)

The size of the imsf_slist_flex member is determined by imsf_numsrc, so
annotate it as such.

Cc: "David S. Miller" <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Jakub Kicinski <[email protected]>
Cc: Paolo Abeni <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
---
include/uapi/linux/in.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
index e682ab628dfa..445f6ae76f1e 100644
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -199,7 +199,8 @@ struct ip_msfilter {
__u32 imsf_numsrc;
union {
__be32 imsf_slist[1];
- __DECLARE_FLEX_ARRAY(__be32, imsf_slist_flex);
+ __DECLARE_FLEX_ARRAY_ATTR(__be32, imsf_slist_flex,
+ __counted_by(imsf_numsrc));
};
};

--
2.34.1


2024-02-10 01:19:26

by Kees Cook

[permalink] [raw]
Subject: [PATCH 1/2] stddef: Allow attributes to be used when creating flex arrays

With the coming support for the __counted_by struct member attribute, we
will need a way to add such annotations to the places where
DECLARE_FLEX_ARRAY() is used. Introduce DECLARE_FLEX_ARRAY_ATTR() which
takes a third argument: the attributes to apply to the flexible array.

Cc: Gustavo A. R. Silva <[email protected]>
Cc: Rasmus Villemoes <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Keith Packard <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
Cc: Dmitry Antipov <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
---
include/linux/stddef.h | 16 ++++++++++++++--
include/uapi/linux/stddef.h | 25 +++++++++++++++++++------
2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index 929d67710cc5..eb51f6727ecf 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -81,8 +81,20 @@ enum {
__struct_group(TAG, NAME, /* no attrs */, MEMBERS)

/**
- * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
+ * DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
+ * @TYPE: The type of each flexible array element
+ * @NAME: The name of the flexible array member
+ * @ATTRS: The list of member attributes to apply
*
+ * In order to have a flexible array member in a union or alone in a
+ * struct, it needs to be wrapped in an anonymous struct with at least 1
+ * named member, but that member can be empty.
+ */
+#define DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
+ __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS)
+
+/**
+ * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
* @TYPE: The type of each flexible array element
* @NAME: The name of the flexible array member
*
@@ -91,6 +103,6 @@ enum {
* named member, but that member can be empty.
*/
#define DECLARE_FLEX_ARRAY(TYPE, NAME) \
- __DECLARE_FLEX_ARRAY(TYPE, NAME)
+ DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)

#endif
diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
index 2ec6f35cda32..5499c08ad011 100644
--- a/include/uapi/linux/stddef.h
+++ b/include/uapi/linux/stddef.h
@@ -31,24 +31,37 @@

#ifdef __cplusplus
/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */
-#define __DECLARE_FLEX_ARRAY(T, member) \
- T member[0]
+#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
+ TYPE NAME[0] ATTRS
+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+ __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)
#else
/**
- * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
- *
+ * __DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
* @TYPE: The type of each flexible array element
* @NAME: The name of the flexible array member
+ * @ATTRS: The list of member attributes to apply
*
* In order to have a flexible array member in a union or alone in a
* struct, it needs to be wrapped in an anonymous struct with at least 1
* named member, but that member can be empty.
*/
-#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
struct { \
struct { } __empty_ ## NAME; \
- TYPE NAME[]; \
+ TYPE NAME[] ATTRS; \
}
+/**
+ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
+ * @TYPE: The type of each flexible array element
+ * @NAME: The name of the flexible array member
+ *
+ * In order to have a flexible array member in a union or alone in a
+ * struct, it needs to be wrapped in an anonymous struct with at least 1
+ * named member, but that member can be empty.
+ */
+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+ __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)
#endif

#ifndef __counted_by
--
2.34.1


2024-02-10 03:48:12

by Gustavo A. R. Silva

[permalink] [raw]
Subject: Re: [PATCH 1/2] stddef: Allow attributes to be used when creating flex arrays



On 2/9/24 19:16, Kees Cook wrote:
> With the coming support for the __counted_by struct member attribute, we
> will need a way to add such annotations to the places where
> DECLARE_FLEX_ARRAY() is used. Introduce DECLARE_FLEX_ARRAY_ATTR() which
> takes a third argument: the attributes to apply to the flexible array.
>
> Cc: Gustavo A. R. Silva <[email protected]>
> Cc: Rasmus Villemoes <[email protected]>
> Cc: Dan Williams <[email protected]>
> Cc: Keith Packard <[email protected]>
> Cc: Miguel Ojeda <[email protected]>
> Cc: Alexey Dobriyan <[email protected]>
> Cc: Dmitry Antipov <[email protected]>
> Signed-off-by: Kees Cook <[email protected]>

Nice!

Reviewed-by: Gustavo A. R. Silva <[email protected]>

Thanks
--
Gustavo

> ---
> include/linux/stddef.h | 16 ++++++++++++++--
> include/uapi/linux/stddef.h | 25 +++++++++++++++++++------
> 2 files changed, 33 insertions(+), 8 deletions(-)
>
> diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> index 929d67710cc5..eb51f6727ecf 100644
> --- a/include/linux/stddef.h
> +++ b/include/linux/stddef.h
> @@ -81,8 +81,20 @@ enum {
> __struct_group(TAG, NAME, /* no attrs */, MEMBERS)
>
> /**
> - * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> + * DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
> + * @TYPE: The type of each flexible array element
> + * @NAME: The name of the flexible array member
> + * @ATTRS: The list of member attributes to apply
> *
> + * In order to have a flexible array member in a union or alone in a
> + * struct, it needs to be wrapped in an anonymous struct with at least 1
> + * named member, but that member can be empty.
> + */
> +#define DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
> + __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS)
> +
> +/**
> + * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> * @TYPE: The type of each flexible array element
> * @NAME: The name of the flexible array member
> *
> @@ -91,6 +103,6 @@ enum {
> * named member, but that member can be empty.
> */
> #define DECLARE_FLEX_ARRAY(TYPE, NAME) \
> - __DECLARE_FLEX_ARRAY(TYPE, NAME)
> + DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)
>
> #endif
> diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
> index 2ec6f35cda32..5499c08ad011 100644
> --- a/include/uapi/linux/stddef.h
> +++ b/include/uapi/linux/stddef.h
> @@ -31,24 +31,37 @@
>
> #ifdef __cplusplus
> /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */
> -#define __DECLARE_FLEX_ARRAY(T, member) \
> - T member[0]
> +#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
> + TYPE NAME[0] ATTRS
> +#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
> + __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)
> #else
> /**
> - * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> - *
> + * __DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
> * @TYPE: The type of each flexible array element
> * @NAME: The name of the flexible array member
> + * @ATTRS: The list of member attributes to apply
> *
> * In order to have a flexible array member in a union or alone in a
> * struct, it needs to be wrapped in an anonymous struct with at least 1
> * named member, but that member can be empty.
> */
> -#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
> +#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
> struct { \
> struct { } __empty_ ## NAME; \
> - TYPE NAME[]; \
> + TYPE NAME[] ATTRS; \
> }
> +/**
> + * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> + * @TYPE: The type of each flexible array element
> + * @NAME: The name of the flexible array member
> + *
> + * In order to have a flexible array member in a union or alone in a
> + * struct, it needs to be wrapped in an anonymous struct with at least 1
> + * named member, but that member can be empty.
> + */
> +#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
> + __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, /* no attributes */)
> #endif
>
> #ifndef __counted_by

2024-02-10 03:50:57

by Gustavo A. R. Silva

[permalink] [raw]
Subject: Re: [PATCH 2/2] net/ipv4: Annotate imsf_slist_flex with __counted_by(imsf_numsrc)



On 2/9/24 19:16, Kees Cook wrote:
> The size of the imsf_slist_flex member is determined by imsf_numsrc, so
> annotate it as such.
>
> Cc: "David S. Miller" <[email protected]>
> Cc: Eric Dumazet <[email protected]>
> Cc: Jakub Kicinski <[email protected]>
> Cc: Paolo Abeni <[email protected]>
> Cc: "Gustavo A. R. Silva" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Kees Cook <[email protected]>

LGTM:

Reviewed-by: Gustavo A. R. Silva <[email protected]>

Thanks!
--
Gustavo

> ---
> include/uapi/linux/in.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
> index e682ab628dfa..445f6ae76f1e 100644
> --- a/include/uapi/linux/in.h
> +++ b/include/uapi/linux/in.h
> @@ -199,7 +199,8 @@ struct ip_msfilter {
> __u32 imsf_numsrc;
> union {
> __be32 imsf_slist[1];
> - __DECLARE_FLEX_ARRAY(__be32, imsf_slist_flex);
> + __DECLARE_FLEX_ARRAY_ATTR(__be32, imsf_slist_flex,
> + __counted_by(imsf_numsrc));
> };
> };
>

2024-02-13 01:50:48

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH 2/2] net/ipv4: Annotate imsf_slist_flex with __counted_by(imsf_numsrc)

On Fri, 9 Feb 2024 17:16:42 -0800 Kees Cook wrote:
> The size of the imsf_slist_flex member is determined by imsf_numsrc, so
> annotate it as such.

Acked-by: Jakub Kicinski <[email protected]>

2024-02-13 07:22:26

by Rasmus Villemoes

[permalink] [raw]
Subject: Re: [PATCH 1/2] stddef: Allow attributes to be used when creating flex arrays

On 10/02/2024 02.16, Kees Cook wrote:
> With the coming support for the __counted_by struct member attribute, we
> will need a way to add such annotations to the places where
> DECLARE_FLEX_ARRAY() is used. Introduce DECLARE_FLEX_ARRAY_ATTR() which
> takes a third argument: the attributes to apply to the flexible array.
>

> - * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> - *
> + * __DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
> * @TYPE: The type of each flexible array element
> * @NAME: The name of the flexible array member
> + * @ATTRS: The list of member attributes to apply
> *
> * In order to have a flexible array member in a union or alone in a
> * struct, it needs to be wrapped in an anonymous struct with at least 1
> * named member, but that member can be empty.
> */
> -#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
> +#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
> struct { \
> struct { } __empty_ ## NAME; \
> - TYPE NAME[]; \
> + TYPE NAME[] ATTRS; \
> }

Is it too ugly to not introduce a separate _ATTR macro but instead just do

#define __DECLARE_FLEX_ARRAY(TYPE, NAME, ...) \
...
TYPE NAME[] __VA_ARGS__;

?

Rasmus


2024-02-13 23:30:42

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH 1/2] stddef: Allow attributes to be used when creating flex arrays

On Tue, Feb 13, 2024 at 08:22:00AM +0100, Rasmus Villemoes wrote:
> On 10/02/2024 02.16, Kees Cook wrote:
> > With the coming support for the __counted_by struct member attribute, we
> > will need a way to add such annotations to the places where
> > DECLARE_FLEX_ARRAY() is used. Introduce DECLARE_FLEX_ARRAY_ATTR() which
> > takes a third argument: the attributes to apply to the flexible array.
> >
>
> > - * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
> > - *
> > + * __DECLARE_FLEX_ARRAY_ATTR() - Declare a flexible array usable in a union
> > * @TYPE: The type of each flexible array element
> > * @NAME: The name of the flexible array member
> > + * @ATTRS: The list of member attributes to apply
> > *
> > * In order to have a flexible array member in a union or alone in a
> > * struct, it needs to be wrapped in an anonymous struct with at least 1
> > * named member, but that member can be empty.
> > */
> > -#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
> > +#define __DECLARE_FLEX_ARRAY_ATTR(TYPE, NAME, ATTRS) \
> > struct { \
> > struct { } __empty_ ## NAME; \
> > - TYPE NAME[]; \
> > + TYPE NAME[] ATTRS; \
> > }
>
> Is it too ugly to not introduce a separate _ATTR macro but instead just do
>
> #define __DECLARE_FLEX_ARRAY(TYPE, NAME, ...) \
> ...
> TYPE NAME[] __VA_ARGS__;
>
> ?

Oh, yes. That will be much nicer, I think! I will send a v2...

--
Kees Cook