Skip to contentSkip to conversation

randstruct: gcc-plugin: Remove bogus void member

PATCH In review Kees Cook 6 participants 17 messages Apr 27, 2025 – May 30, 2025

Subsystems (5)
lore
Share & tools
lore

Kees Cook

author maintainer
#0 lore raw

cover randstruct: gcc-plugin: Remove bogus void member

Hi,

Okay, I've tracked down the problem with the randstruct GCC plugin, and written a KUnit test to validate behaviors. This lets us add it back the COMPILE_TEST builds.

No need for https://lore.kernel.org/all/[email protected]/

-Kees

Kees Cook (3):
randstruct: gcc-plugin: Remove bogus void member lib/tests: Add randstruct KUnit test
Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

 MAINTAINERS                                   |   1 +
 lib/Kconfig.debug                             |   8 +
 lib/tests/Makefile                            |   1 +
 lib/tests/randstruct_kunit.c                  | 283 ++++++++++++++++++
 scripts/gcc-plugins/randomize_layout_plugin.c |  18 +-
 security/Kconfig.hardening                    |   2 +-
 6 files changed, 295 insertions(+), 18 deletions(-)
 create mode 100644 lib/tests/randstruct_kunit.c
Signature · 1 line
2.34.1
author maintainer
#1 lore raw

PATCH 1/3 randstruct: gcc-plugin: Remove bogus void member

When building the randomized replacement tree of struct members, the randstruct GCC plugin would insert, as the first member, a 0-sized void member. This appears as though it was done to catch non-designated ("unnamed") static initializers, which wouldn't be stable since they depend on the original struct layout order.

This was accomplished by having the side-effect of the "void member" tripping an assert in GCC internals (count_type_elements) if the member list ever needed to be counted (e.g. for figuring out the order of members during a non-designated initialization), which would catch impossible type (void) in the struct:

security/landlock/fs.c: In function ‘hook_file_ioctl_common’:
security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7075
1745 | .u.op = &(struct lsm_ioctlop_audit) {
| ^

static HOST_WIDE_INT
count_type_elements (const_tree type, bool for_ctor_p) {
switch (TREE_CODE (type))
...

    case VOID_TYPE:
    default:
      gcc_unreachable ();
    }
}

However this is a redundant safety measure since randstruct uses the __designated_initializer attribute both internally and within the __randomized_layout attribute macro so that this would be enforced by the compiler directly even when randstruct was not enabled (via -Wdesignated-init).

A recent change in Landlock ended up tripping the same member counting routine when using a full-struct copy initializer as part of an anonymous initializer. This, however, is a false positive as the initializer is copying between identical structs (and hence identical layouts). The "path" member is "struct path", a randomized struct, and is being copied to from another "struct path", the "f_path" member:

        landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) {
                .type = LANDLOCK_REQUEST_FS_ACCESS,
                .audit = {
                        .type = LSM_AUDIT_DATA_IOCTL_OP,
                        .u.op = &(struct lsm_ioctlop_audit) {
                                .path = file->f_path,
                                .cmd = cmd,
                        },
                },
	...

As can be seen with the coming randstruct KUnit test, there appears to be no behavioral problems with this kind of initialization when the void member is removed from the randstruct GCC plugin, so remove it.

---
Cc: "Mickaël Salaün" <[email protected]>
Cc: Mark Brown <[email protected]>
Cc: "Günther Noack" <[email protected]>
Cc: Arnd Bergmann <[email protected]>

---
 scripts/gcc-plugins/randomize_layout_plugin.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)
scripts/gcc-plugins/randomize_layout_plugin.c +1 -17
index 5694df3da2e9..971a1908a8cc 100644
@@ -344,29 +344,13 @@ static int relayout_struct(tree type)
 
 	shuffle(type, (tree *)newtree, shuffle_length);
 
-	/*
-	 * set up a bogus anonymous struct field designed to error out on unnamed struct initializers
-	 * as gcc provides no other way to detect such code
-	 */
-	list = make_node(FIELD_DECL);
-	TREE_CHAIN(list) = newtree[0];
-	TREE_TYPE(list) = void_type_node;
-	DECL_SIZE(list) = bitsize_zero_node;
-	DECL_NONADDRESSABLE_P(list) = 1;
-	DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node;
-	DECL_SIZE_UNIT(list) = size_zero_node;
-	DECL_FIELD_OFFSET(list) = size_zero_node;
-	DECL_CONTEXT(list) = type;
-	// to satisfy the constify plugin
-	TREE_READONLY(list) = 1;
-
 	for (i = 0; i < num_fields - 1; i++)
 		TREE_CHAIN(newtree[i]) = newtree[i+1];
 	TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
 
 	main_variant = TYPE_MAIN_VARIANT(type);
 	for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
-		TYPE_FIELDS(variant) = list;
+		TYPE_FIELDS(variant) = newtree[0];
 		TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
 		TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
 		TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
Signature · 1 line
2.34.1
author maintainer
#2 lore raw

PATCH 2/3 lib/tests: Add randstruct KUnit test

In reply to Kees Cook

Perform basic validation about layout randomization and initialization tracking when using CONFIG_RANDSTRUCT=y. Tested using:

$ ./tools/testing/kunit/kunit.py run \
	--kconfig_add CONFIG_RANDSTRUCT_FULL=y \
	randstruct
[17:22:30] ================= randstruct (2 subtests) ==================
[17:22:30] [PASSED] randstruct_layout
[17:22:30] [PASSED] randstruct_initializers
[17:22:30] =================== [PASSED] randstruct ====================
[17:22:30] ============================================================
[17:22:30] Testing complete. Ran 2 tests: passed: 2
[17:22:30] Elapsed time: 5.091s total, 0.001s configuring, 4.974s building, 0.086s running

Adding "--make_option LLVM=1" can be used to test Clang, which also passes.

---
Cc: Bill Wendling <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: Petr Mladek <[email protected]>
Cc: David Gow <[email protected]>
Cc: Rae Moar <[email protected]>
Cc: Tamir Duberstein <[email protected]>
Cc: Diego Vieira <[email protected]>
Cc: Luis Chamberlain <[email protected]>
Cc: <[email protected]>

---
 MAINTAINERS                  |   1 +
 lib/Kconfig.debug            |   8 +
 lib/tests/Makefile           |   1 +
 lib/tests/randstruct_kunit.c | 283 +++++++++++++++++++++++++++++++++++
 4 files changed, 293 insertions(+)
 create mode 100644 lib/tests/randstruct_kunit.c
MAINTAINERS +1 -0
index fa1e04e87d1d..aeb3e7911852 100644
@@ -12879,6 +12879,7 @@ F:	include/linux/overflow.h
 F:	include/linux/randomize_kstack.h
 F:	include/linux/ucopysize.h
 F:	kernel/configs/hardening.config
+F:	lib/tests/randstruct_kunit.c
 F:	lib/tests/usercopy_kunit.c
 F:	mm/usercopy.c
 F:	security/Kconfig.hardening
lib/Kconfig.debug +8 -0
index f9051ab610d5..6479cec900c7 100644
@@ -2863,6 +2863,14 @@ config OVERFLOW_KUNIT_TEST
 
 	  If unsure, say N.
 
+config RANDSTRUCT_KUNIT_TEST
+	tristate "Test randstruct structure layout randomization at runtime" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Builds unit tests for the checking CONFIG_RANDSTRUCT=y, which
+	  randomizes structure layouts.
+
 config STACKINIT_KUNIT_TEST
 	tristate "Test level of stack variable initialization" if !KUNIT_ALL_TESTS
 	depends on KUNIT
lib/tests/Makefile +1 -0
index 5a4794c1826e..56d645014482 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
 CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
 obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
 obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
+obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
 obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o
 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
 obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
lib/tests/randstruct_kunit.c new file +283 -0

283 lines not on this page · raw message

Signature · 1 line
2.34.1
#3 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

kernel test robot noticed the following build errors:

Hi Kees,

kernel test robot noticed the following build errors:

[auto build test ERROR on kees/for-next/hardening]
[also build test ERROR on linus/master v6.15-rc3 next-20250424] [cannot apply to akpm-mm/mm-nonmm-unstable soc/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/randstruct-gcc-plugin-Remove-bogus-void-member/20250427-093946
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
patch link:    https://lore.kernel.org/r/20250427013836.877214-2-kees%40kernel.org
patch subject: [PATCH 2/3] lib/tests: Add randstruct KUnit test
config: s390-randconfig-002-20250427 (https://download.01.org/0day-ci/archive/20250427/[email protected]/config)
compiler: s390-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250427/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

>> lib/tests/randstruct_kunit.c:36:36: error: expected ',' before ')' token
    _Static_assert(MEMBER_NAME_MAX == 8);
                                       ^
                                       ,

cc1: warning: unrecognized command line option '-Wno-unterminated-string-initialization'

vim +36 lib/tests/randstruct_kunit.c

    19	
    20	#define DO_MANY_MEMBERS(macro, args...)	\
    21		macro(a, args)			\
    22		macro(b, args)			\
    23		macro(c, args)			\
    24		macro(d, args)			\
    25		macro(e, args)			\
    26		macro(f, args)			\
    27		macro(g, args)			\
    28		macro(h, args)
    29	
    30	#define do_enum(x, ignored)	MEMBER_NAME_ ## x,
    31	enum randstruct_member_names {
    32		DO_MANY_MEMBERS(do_enum)
    33		MEMBER_NAME_MAX,
    34	};
    35	/* Make sure the macros are working: want 8 test members. */
  > 36	_Static_assert(MEMBER_NAME_MAX == 8);
    37	
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
#4 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

In reply to Kees Cook
kernel test robot noticed the following build warnings:

Hi Kees,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on linus/master v6.15-rc3 next-20250424] [cannot apply to akpm-mm/mm-nonmm-unstable soc/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/randstruct-gcc-plugin-Remove-bogus-void-member/20250427-093946
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
patch link:    https://lore.kernel.org/r/20250427013836.877214-2-kees%40kernel.org
patch subject: [PATCH 2/3] lib/tests: Add randstruct KUnit test
config: riscv-randconfig-001-20250427 (https://download.01.org/0day-ci/archive/20250427/[email protected]/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250427/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> lib/tests/randstruct_kunit.c:36:36: warning: '_Static_assert' with no message is a C23 extension [-Wc23-extensions]
      36 | _Static_assert(MEMBER_NAME_MAX == 8);
         |                                    ^
         |                                    , ""

1 warning generated.

vim +/_Static_assert +36 lib/tests/randstruct_kunit.c

    19	
    20	#define DO_MANY_MEMBERS(macro, args...)	\
    21		macro(a, args)			\
    22		macro(b, args)			\
    23		macro(c, args)			\
    24		macro(d, args)			\
    25		macro(e, args)			\
    26		macro(f, args)			\
    27		macro(g, args)			\
    28		macro(h, args)
    29	
    30	#define do_enum(x, ignored)	MEMBER_NAME_ ## x,
    31	enum randstruct_member_names {
    32		DO_MANY_MEMBERS(do_enum)
    33		MEMBER_NAME_MAX,
    34	};
    35	/* Make sure the macros are working: want 8 test members. */
  > 36	_Static_assert(MEMBER_NAME_MAX == 8);
    37	
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
author maintainer
#5 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

Quoted 24 lines · kernel test robot

Hi Kees,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on linus/master v6.15-rc3 next-20250424] [cannot apply to akpm-mm/mm-nonmm-unstable soc/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/randstruct-gcc-plugin-Remove-bogus-void-member/20250427-093946
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
patch link:    https://lore.kernel.org/r/20250427013836.877214-2-kees%40kernel.org
patch subject: [PATCH 2/3] lib/tests: Add randstruct KUnit test
config: riscv-randconfig-001-20250427 (https://download.01.org/0day-ci/archive/20250427/[email protected]/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250427/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

Quoted 7 lines

All warnings (new ones prefixed by >>):

Quoted 1 line
Quoted 1 line

lib/tests/randstruct_kunit.c:36:36: warning: '_Static_assert' with no message is a C23 extension [-Wc23-extensions]

      36 | _Static_assert(MEMBER_NAME_MAX == 8);
         |                                    ^
         |                                    , ""

1 warning generated.

Thanks! I've fixed this locally.

Signature · 1 line
Kees Cook
#6 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

In reply to Kees Cook
kernel test robot noticed the following build warnings:

Hi Kees,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on linus/master v6.15-rc3 next-20250424] [cannot apply to akpm-mm/mm-nonmm-unstable soc/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/randstruct-gcc-plugin-Remove-bogus-void-member/20250427-093946
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
patch link:    https://lore.kernel.org/r/20250427013836.877214-2-kees%40kernel.org
patch subject: [PATCH 2/3] lib/tests: Add randstruct KUnit test
config: powerpc64-randconfig-002-20250427 (https://download.01.org/0day-ci/archive/20250427/[email protected]/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250427/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> lib/tests/randstruct_kunit.c:36:36: warning: '_Static_assert' with no message is a C2x extension [-Wc2x-extensions]
      36 | _Static_assert(MEMBER_NAME_MAX == 8);
         |                                    ^
         |                                    , ""

1 warning generated.

vim +/_Static_assert +36 lib/tests/randstruct_kunit.c

    19	
    20	#define DO_MANY_MEMBERS(macro, args...)	\
    21		macro(a, args)			\
    22		macro(b, args)			\
    23		macro(c, args)			\
    24		macro(d, args)			\
    25		macro(e, args)			\
    26		macro(f, args)			\
    27		macro(g, args)			\
    28		macro(h, args)
    29	
    30	#define do_enum(x, ignored)	MEMBER_NAME_ ## x,
    31	enum randstruct_member_names {
    32		DO_MANY_MEMBERS(do_enum)
    33		MEMBER_NAME_MAX,
    34	};
    35	/* Make sure the macros are working: want 8 test members. */
  > 36	_Static_assert(MEMBER_NAME_MAX == 8);
    37	
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Acked-by on v1 2/3
#7 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

In reply to Kees Cook
Quoted 15 lines · Kees Cook

Perform basic validation about layout randomization and initialization tracking when using CONFIG_RANDSTRUCT=y. Tested using:

$ ./tools/testing/kunit/kunit.py run \
        --kconfig_add CONFIG_RANDSTRUCT_FULL=y \
        randstruct
[17:22:30] ================= randstruct (2 subtests) ==================
[17:22:30] [PASSED] randstruct_layout
[17:22:30] [PASSED] randstruct_initializers
[17:22:30] =================== [PASSED] randstruct ====================
[17:22:30] ============================================================
[17:22:30] Testing complete. Ran 2 tests: passed: 2
[17:22:30] Elapsed time: 5.091s total, 0.001s configuring, 4.974s building, 0.086s running
Quoted 5 lines

Adding "--make_option LLVM=1" can be used to test Clang, which also passes.

---

This works here for me. I'm a little wary of the prospect of the "unlucky or broken" message making the test fail if we're just unlucky, but it seems unlikely enough that we can deal with it later if it ever becomes a problem.

Cheers,
-- David

author maintainer
#8 lore raw

Re: [PATCH 2/3] lib/tests: Add randstruct KUnit test

Quoted 22 lines · David Gow
Quoted 15 lines · Kees Cook

Perform basic validation about layout randomization and initialization tracking when using CONFIG_RANDSTRUCT=y. Tested using:

$ ./tools/testing/kunit/kunit.py run \
        --kconfig_add CONFIG_RANDSTRUCT_FULL=y \
        randstruct
[17:22:30] ================= randstruct (2 subtests) ==================
[17:22:30] [PASSED] randstruct_layout
[17:22:30] [PASSED] randstruct_initializers
[17:22:30] =================== [PASSED] randstruct ====================
[17:22:30] ============================================================
[17:22:30] Testing complete. Ran 2 tests: passed: 2
[17:22:30] Elapsed time: 5.091s total, 0.001s configuring, 4.974s building, 0.086s running
Quoted 5 lines

Adding "--make_option LLVM=1" can be used to test Clang, which also passes.

---

Quoted 6 lines

This works here for me. I'm a little wary of the prospect of the "unlucky or broken" message making the test fail if we're just unlucky, but it seems unlikely enough that we can deal with it later if it ever becomes a problem.

Thanks!

Yeah, I wonder if it might be an interesting adjustment to the shuffling to make sure it isn't a no-op? Like, it would shuffle with the original hash, and if it's a no-op, it could permute the hash again, and then try again? Hmmm...

Signature · 1 line
Kees Cook
author maintainer
#9 lore raw

PATCH 3/3 Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

In reply to Kees Cook

This reverts commit f5c68a4e84f9feca3be578199ec648b676db2030.

It is again possible to build "allmodconfig" with the randstruct GCC plugin, so enable it for COMPILE_TEST to catch future bugs.

---
 security/Kconfig.hardening | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
security/Kconfig.hardening +1 -1
index 3fe9d7b945c4..c17366ce8224 100644
@@ -344,7 +344,7 @@ config CC_HAS_RANDSTRUCT
 
 choice
 	prompt "Randomize layout of sensitive kernel structures"
-	default RANDSTRUCT_FULL if COMPILE_TEST && CC_HAS_RANDSTRUCT
+	default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT)
 	default RANDSTRUCT_NONE
 	help
 	  If you enable this, the layouts of structures that are entirely
Signature · 1 line
2.34.1
#10 lore raw

Re: [PATCH 3/3] Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

Hello,

This commit was reported by our CI as breaking the allmodconfig build for the arm and arm64 architectures when using GCC 15. This is due to
https://github.com/KSPP/linux/issues/367 :

-00:05:08 *** WARNING *** there are active plugins, do not report this as a bug unless you can reproduce it without enabling any plugins.

00:05:08 Event                            | Plugins
00:05:08 PLUGIN_FINISH_TYPE               | randomize_layout_plugin
00:05:08 PLUGIN_FINISH_DECL               | randomize_layout_plugin
00:05:08 PLUGIN_ATTRIBUTES                | latent_entropy_plugin randomize_layout_plugin
00:05:08 PLUGIN_START_UNIT                | latent_entropy_plugin stackleak_plugin
00:05:08 PLUGIN_ALL_IPA_PASSES_START      | randomize_layout_plugin

00:05:08 arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
00:05:08 132 | const struct kexec_file_ops kexec_image_ops = {
00:05:08 | ^~~~~~~~~~~~~~
00:05:08 0x225bdff internal_error(char const*, ...)
00:05:08 ../../../../../../gcc/gcc/diagnostic-global-context.cc:517
00:05:08 0x7cb197 fancy_abort(char const*, int, char const*)
00:05:08 ../../../../../../gcc/gcc/diagnostic.cc:1803
00:05:08 0x81f0e7 comptypes_check_enum_int(tree_node*, tree_node*, bool*)
00:05:08 ../../../../../../gcc/gcc/c/c-typeck.cc:1519
00:05:08 0x81f0e7 comptypes_check_enum_int(tree_node*, tree_node*, bool*)
00:05:08 ../../../../../../gcc/gcc/c/c-typeck.cc:1513
00:05:08 0x7e3b83 diagnose_mismatched_decls
00:05:08 ../../../../../../gcc/gcc/c/c-decl.cc:2170
00:05:08 0x7e64f3 duplicate_decls
00:05:08 ../../../../../../gcc/gcc/c/c-decl.cc:3169
00:05:08 0x7ea1eb pushdecl(tree_node*)
00:05:08 ../../../../../../gcc/gcc/c/c-decl.cc:3376
00:05:08 0x803c03 start_decl(c_declarator*, c_declspecs*, bool, tree_node*, bool, unsigned long*)
00:05:08 ../../../../../../gcc/gcc/c/c-decl.cc:5755
00:05:08 0x864c67 c_parser_declaration_or_fndef
00:05:08 ../../../../../../gcc/gcc/c/c-parser.cc:2851
00:05:08 0x8a7b33 c_parser_external_declaration
00:05:08 ../../../../../../gcc/gcc/c/c-parser.cc:2110
00:05:08 0x8a8ba3 c_parser_translation_unit
00:05:08 ../../../../../../gcc/gcc/c/c-parser.cc:1964
00:05:08 0x8a8ba3 c_parse_file()
00:05:08 ../../../../../../gcc/gcc/c/c-parser.cc:29839
00:05:08 0x931eff c_common_parse_file()
00:05:08 ../../../../../../gcc/gcc/c-family/c-opts.cc:1385
00:05:08 Please submit a full bug report, with preprocessed source (by using -freport-bug).
00:05:08 Please include the complete backtrace with any bug report.
00:05:08 See <https://gcc.gnu.org/bugs/> for instructions.
00:05:08 make[4]: *** [scripts/Makefile.build:203: arch/arm64/kernel/kexec_image.o] Error 1

The same error repeats for several other source files.

author maintainer
#11 lore raw

Re: [PATCH 3/3] Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

Quoted 7 lines · Thiago Jung Bauermann

This commit was reported by our CI as breaking the allmodconfig build for the arm and arm64 architectures when using GCC 15. This is due to
https://github.com/KSPP/linux/issues/367 :

00:05:08 arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
00:05:08 132 | const struct kexec_file_ops kexec_image_ops = {
00:05:08 | ^~~~~~~~~~~~~~

I'm not able to reproduce this. Which specific version of GCC 15 and on what distro are you seeing this?

This is Fedora 42 for me:

$ aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-gcc (GCC) 15.1.1 20250425 (Red Hat Cross 15.1.1-1)
...
$ make O=gcc-arm64 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig
$ grep RANDSTRUCT gcc-arm64/.config
# CONFIG_RANDSTRUCT_NONE is not set
CONFIG_RANDSTRUCT_FULL=y
# CONFIG_RANDSTRUCT_PERFORMANCE is not set
CONFIG_RANDSTRUCT=y
CONFIG_GCC_PLUGIN_RANDSTRUCT=y
CONFIG_RANDSTRUCT_KUNIT_TEST=m
$ make O=gcc-arm64 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- all -s
$ file gcc-arm64/vmlinux
gcc-arm64/vmlinux: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=b53656cb73bb82f4e19edbfa54241c203daa3fed, not stripped

And the new KUnit randstruct selftests all pass as well:

$ ./tools/testing/kunit/kunit.py run \
	--arch arm64 --cross_compile aarch64-linux-gnu- \
	--kconfig_add CONFIG_RANDSTRUCT_FULL=y randstruct
...
# Totals: pass:5 fail:0 skip:0 total:5
Signature · 1 line
Kees Cook
#12 lore raw

Re: [PATCH 3/3] Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

Quoted 11 lines · Kees Cook
Quoted 7 lines · Thiago Jung Bauermann

This commit was reported by our CI as breaking the allmodconfig build for the arm and arm64 architectures when using GCC 15. This is due to
https://github.com/KSPP/linux/issues/367 :

00:05:08 arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
00:05:08 132 | const struct kexec_file_ops kexec_image_ops = {
00:05:08 | ^~~~~~~~~~~~~~

I'm not able to reproduce this. Which specific version of GCC 15 and on what distro are you seeing this?

It looks like this was also reported to Debian (I originally noticed it in the #gcc channel on OFTC a couple of weeks ago but forgot to mention it):

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745

It looks like the difference might be whether GCC was built with additional checks or not based on the last couple of comments in that bug.

Cheers,
Nathan

author maintainer
#13 lore raw

Re: [PATCH 3/3] Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

Quoted 17 lines · Nathan Chancellor
Quoted 11 lines · Kees Cook
Quoted 7 lines · Thiago Jung Bauermann

This commit was reported by our CI as breaking the allmodconfig build for the arm and arm64 architectures when using GCC 15. This is due to
https://github.com/KSPP/linux/issues/367 :

00:05:08 arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
00:05:08 132 | const struct kexec_file_ops kexec_image_ops = {
00:05:08 | ^~~~~~~~~~~~~~

I'm not able to reproduce this. Which specific version of GCC 15 and on what distro are you seeing this?

It looks like this was also reported to Debian (I originally noticed it in the #gcc channel on OFTC a couple of weeks ago but forgot to mention it):

Quoted 5 lines

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745

It looks like the difference might be whether GCC was built with additional checks or not based on the last couple of comments in that bug.

Ah, thanks for the additional pointer! Yeah, discussion has continued on https://github.com/KSPP/linux/issues/367 which shows it's a problem for GCC builds configured with "--enable-checking=yes"

It seems like this check is overly strict? I'm building GCC now to see which aspect of the plugin is tripping it... I assume its decl finalization, but we'll see.

Signature · 1 line
Kees Cook
author maintainer
#14 lore raw

Re: [PATCH 3/3] Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

In reply to Nathan Chancellor
Quoted 17 lines · Nathan Chancellor
Quoted 11 lines · Kees Cook
Quoted 7 lines · Thiago Jung Bauermann

This commit was reported by our CI as breaking the allmodconfig build for the arm and arm64 architectures when using GCC 15. This is due to
https://github.com/KSPP/linux/issues/367 :

00:05:08 arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
00:05:08 132 | const struct kexec_file_ops kexec_image_ops = {
00:05:08 | ^~~~~~~~~~~~~~

I'm not able to reproduce this. Which specific version of GCC 15 and on what distro are you seeing this?

It looks like this was also reported to Debian (I originally noticed it in the #gcc channel on OFTC a couple of weeks ago but forgot to mention it):

Quoted 5 lines

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745

It looks like the difference might be whether GCC was built with additional checks or not based on the last couple of comments in that bug.

Proposed fix here:
https://lore.kernel.org/lkml/[email protected]/

Signature · 1 line
Kees Cook
#15 lore raw
In reply to Kees Cook
Quoted 7 lines · Kees Cook

Hi,

Okay, I've tracked down the problem with the randstruct GCC plugin, and written a KUnit test to validate behaviors. This lets us add it back the COMPILE_TEST builds.

No need for https://lore.kernel.org/all/[email protected]/

Hi,

What is the status of this patch series? Do you plan to send it for v6.15?

Quoted 21 lines

-Kees

Kees Cook (3):
randstruct: gcc-plugin: Remove bogus void member lib/tests: Add randstruct KUnit test
Revert "hardening: Disable GCC randstruct for COMPILE_TEST"

 MAINTAINERS                                   |   1 +
 lib/Kconfig.debug                             |   8 +
 lib/tests/Makefile                            |   1 +
 lib/tests/randstruct_kunit.c                  | 283 ++++++++++++++++++
 scripts/gcc-plugins/randomize_layout_plugin.c |  18 +-
 security/Kconfig.hardening                    |   2 +-
 6 files changed, 295 insertions(+), 18 deletions(-)
 create mode 100644 lib/tests/randstruct_kunit.c
Signature · 1 line
2.34.1
author maintainer
#16 lore raw
Quoted 7 lines · Mickaël Salaün
Quoted 6 lines · Kees Cook

Hi,

Okay, I've tracked down the problem with the randstruct GCC plugin, and written a KUnit test to validate behaviors. This lets us add it back the COMPILE_TEST builds.

Quoted 6 lines
Quoted 1 line

No need for https://lore.kernel.org/all/[email protected]/

Hi,

What is the status of this patch series? Do you plan to send it for v6.15?

Since it is pretty late for v6.15 and exposes missed designated initializers, I was planning to send it (and the designated initializer fixes) for the v6.16 merge window and have them all go into -stable for v6.15.

Signature · 1 line
Kees Cook