This switches to using a manually constructed form of struct tagging
to avoid issues with C++ being unable to parse tagged structs within
anonymous unions, even under 'extern "C"':

  ../linux/include/uapi/linux/pkt_cls.h:25124: error: ‘struct 
tc_u32_sel::<unnamed union>::tc_u32_sel_hdr,’ invalid; an anonymous union may 
only have public non-static data members [-fpermissive]

To avoid having multiple struct member lists, use a define to declare
them.

Reported-by: [email protected]
Closes: https://lore.kernel.org/linux-hardening/[email protected]/
Fixes: 216203bdc228 ("UAPI: net/sched: Use __struct_group() in flex struct 
tc_u32_sel")
Link: https://lore.kernel.org/r/202412120927.943DFEDD@keescook
Signed-off-by: Kees Cook <[email protected]>
---
Cc: Jakub Kicinski <[email protected]>
Cc: Jamal Hadi Salim <[email protected]>
Cc: Cong Wang <[email protected]>
Cc: Jiri Pirko <[email protected]>
Cc: [email protected]
---
 include/uapi/linux/pkt_cls.h | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 2c32080416b5..02aee6ed6bf0 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -245,20 +245,28 @@ struct tc_u32_key {
        int             offmask;
 };
 
+#define tc_u32_sel_hdr_members                 \
+       unsigned char           flags;          \
+       unsigned char           offshift;       \
+       unsigned char           nkeys;          \
+       __be16                  offmask;        \
+       __u16                   off;            \
+       short                   offoff;         \
+       short                   hoff;           \
+       __be32                  hmask
+
+struct tc_u32_sel_hdr {
+       tc_u32_sel_hdr_members;
+};
+
 struct tc_u32_sel {
-       /* New members MUST be added within the __struct_group() macro below. */
-       __struct_group(tc_u32_sel_hdr, hdr, /* no attrs */,
-               unsigned char           flags;
-               unsigned char           offshift;
-               unsigned char           nkeys;
-
-               __be16                  offmask;
-               __u16                   off;
-               short                   offoff;
-
-               short                   hoff;
-               __be32                  hmask;
-       );
+       /* Open-coded struct_group() to avoid C++ errors. */
+       union {
+               struct tc_u32_sel_hdr hdr;
+               struct {
+                       tc_u32_sel_hdr_members;
+               };
+       };
        struct tc_u32_key       keys[];
 };
 
-- 
2.34.1


Reply via email to