Skip to contentSkip to conversation

stddef: Allow attributes to be used when creating flex arrays

PATCH Superseded Kees Cook 4 participants 8 messages Feb 10, 2024 – Feb 13, 2024

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Kees Cook

author
#0 lore raw

cover 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(-)
Signature · 1 line
2.34.1
author
#1 lore raw

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]>
---
 include/linux/stddef.h      | 16 ++++++++++++++--
 include/uapi/linux/stddef.h | 25 +++++++++++++++++++------
 2 files changed, 33 insertions(+), 8 deletions(-)
include/linux/stddef.h +14 -2
index 929d67710cc5..eb51f6727ecf 100644
@@ -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
include/uapi/linux/stddef.h +19 -6
index 2ec6f35cda32..5499c08ad011 100644
@@ -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
Signature · 1 line
2.34.1
Reviewed-by on v1 1/2
#2 lore raw
Quoted 5 lines · Kees Cook

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.

Quoted 8 lines
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]>

Nice!

Thanks

Signature · 1 line
Gustavo
Quoted 87 lines
---
  include/linux/stddef.h      | 16 ++++++++++++++--
  include/uapi/linux/stddef.h | 25 +++++++++++++++++++------
  2 files changed, 33 insertions(+), 8 deletions(-)
include/linux/stddef.h +14 -2
index 929d67710cc5..eb51f6727ecf 100644
@@ -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
include/uapi/linux/stddef.h +19 -6
index 2ec6f35cda32..5499c08ad011 100644
@@ -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
#3 lore raw
In reply to Kees Cook
Quoted 17 lines · Kees Cook

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.
*/

include/uapi/linux/stddef.h line 53

Quoted 7 lines
include/uapi/linux/stddef.h +2 -2
-#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

author
#4 lore raw
Quoted 28 lines · Rasmus Villemoes
Quoted 17 lines · Kees Cook

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.
*/

include/uapi/linux/stddef.h line 53

Quoted 7 lines
include/uapi/linux/stddef.h +2 -2
-#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

Quoted 5 lines

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

?

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

Signature · 1 line
Kees Cook
author
#5 lore raw

PATCH 2/2 net/ipv4: Annotate imsf_slist_flex with __counted_by(imsf_numsrc)

In reply to Kees Cook

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]>
---
 include/uapi/linux/in.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
include/uapi/linux/in.h +2 -1
index e682ab628dfa..445f6ae76f1e 100644
@@ -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));
 	};
 };
 
Signature · 1 line
2.34.1
Reviewed-by on v1 2/2
#6 lore raw

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

Quoted 11 lines · Kees Cook

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]>

LGTM:

Thanks!

Signature · 1 line
Gustavo
Quoted 18 lines
---
  include/uapi/linux/in.h | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
include/uapi/linux/in.h +2 -1
index e682ab628dfa..445f6ae76f1e 100644
@@ -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));
  	};
  };