Skip to content

Commit 724c6ce

Browse files
alobakinkees
authored andcommitted
stddef: make __struct_group() UAPI C++-friendly
For the most part of the C++ history, it couldn't have type declarations inside anonymous unions for different reasons. At the same time, __struct_group() relies on the latters, so when the @tag argument is not empty, C++ code doesn't want to build (even under `extern "C"`): ../linux/include/uapi/linux/pkt_cls.h:25:24: error: 'struct tc_u32_sel::<unnamed union>::tc_u32_sel_hdr,' invalid; an anonymous union may only have public non-static data members [-fpermissive] The safest way to fix this without trying to switch standards (which is impossible in UAPI anyway) etc., is to disable tag declaration for that language. This won't break anything since for now it's not buildable at all. Use a separate definition for __struct_group() when __cplusplus is defined to mitigate the error, including the version from tools/. Fixes: 50d7bd3 ("stddef: Introduce struct_group() helper macro") Reported-by: Christopher Ferris <[email protected]> Closes: https://lore.kernel.org/linux-hardening/[email protected] Suggested-by: Kees Cook <[email protected]> # __struct_group_tag() Signed-off-by: Alexander Lobakin <[email protected]> Reviewed-by: Gustavo A. R. Silva <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Kees Cook <[email protected]>
1 parent 239d873 commit 724c6ce

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

include/uapi/linux/stddef.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
#define __always_inline inline
99
#endif
1010

11+
/* Not all C++ standards support type declarations inside an anonymous union */
12+
#ifndef __cplusplus
13+
#define __struct_group_tag(TAG) TAG
14+
#else
15+
#define __struct_group_tag(TAG)
16+
#endif
17+
1118
/**
1219
* __struct_group() - Create a mirrored named and anonyomous struct
1320
*
@@ -20,13 +27,13 @@
2027
* and size: one anonymous and one named. The former's members can be used
2128
* normally without sub-struct naming, and the latter can be used to
2229
* reason about the start, end, and size of the group of struct members.
23-
* The named struct can also be explicitly tagged for layer reuse, as well
24-
* as both having struct attributes appended.
30+
* The named struct can also be explicitly tagged for layer reuse (C only),
31+
* as well as both having struct attributes appended.
2532
*/
2633
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
2734
union { \
2835
struct { MEMBERS } ATTRS; \
29-
struct TAG { MEMBERS } ATTRS NAME; \
36+
struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \
3037
} ATTRS
3138

3239
#ifdef __cplusplus

tools/include/uapi/linux/stddef.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
#define __always_inline __inline__
99
#endif
1010

11+
/* Not all C++ standards support type declarations inside an anonymous union */
12+
#ifndef __cplusplus
13+
#define __struct_group_tag(TAG) TAG
14+
#else
15+
#define __struct_group_tag(TAG)
16+
#endif
17+
1118
/**
1219
* __struct_group() - Create a mirrored named and anonyomous struct
1320
*
@@ -20,14 +27,14 @@
2027
* and size: one anonymous and one named. The former's members can be used
2128
* normally without sub-struct naming, and the latter can be used to
2229
* reason about the start, end, and size of the group of struct members.
23-
* The named struct can also be explicitly tagged for layer reuse, as well
24-
* as both having struct attributes appended.
30+
* The named struct can also be explicitly tagged for layer reuse (C only),
31+
* as well as both having struct attributes appended.
2532
*/
2633
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
2734
union { \
2835
struct { MEMBERS } ATTRS; \
29-
struct TAG { MEMBERS } ATTRS NAME; \
30-
}
36+
struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \
37+
} ATTRS
3138

3239
/**
3340
* __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union

0 commit comments

Comments
 (0)