Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

randstruct: gcc-plugin: Fix attribute addition

Based on changes in the 2021 public version of the randstruct
out-of-tree GCC plugin[1], more carefully update the attributes on
resulting decls, to avoid tripping checks in GCC 15's
comptypes_check_enum_int() when it has been configured with
"--enable-checking=misc":

arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
132 | const struct kexec_file_ops kexec_image_ops = {
| ^~~~~~~~~~~~~~
internal_error(char const*, ...), at gcc/gcc/diagnostic-global-context.cc:517
fancy_abort(char const*, int, char const*), at gcc/gcc/diagnostic.cc:1803
comptypes_check_enum_int(tree_node*, tree_node*, bool*), at gcc/gcc/c/c-typeck.cc:1519
...

Link: https://archive.org/download/grsecurity/grsecurity-3.1-5.10.41-202105280954.patch.gz [1]
Reported-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Closes: https://github.com/KSPP/linux/issues/367
Closes: https://lore.kernel.org/lkml/20250530000646.104457-1-thiago.bauermann@linaro.org/
Reported-by: Ingo Saitz <ingo@hannover.ccc.de>
Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745
Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin")
Tested-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Link: https://lore.kernel.org/r/20250530221824.work.623-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>

+43 -11
+32
scripts/gcc-plugins/gcc-common.h
··· 123 123 return cstr; 124 124 } 125 125 126 + static inline void __add_type_attr(tree type, const char *attr, tree args) 127 + { 128 + tree oldattr; 129 + 130 + if (type == NULL_TREE) 131 + return; 132 + oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type)); 133 + if (oldattr != NULL_TREE) { 134 + gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args)); 135 + return; 136 + } 137 + 138 + TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); 139 + TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type)); 140 + } 141 + 142 + static inline void add_type_attr(tree type, const char *attr, tree args) 143 + { 144 + tree main_variant = TYPE_MAIN_VARIANT(type); 145 + 146 + __add_type_attr(TYPE_CANONICAL(type), attr, args); 147 + __add_type_attr(TYPE_CANONICAL(main_variant), attr, args); 148 + __add_type_attr(main_variant, attr, args); 149 + 150 + for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) { 151 + if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type))) 152 + TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant); 153 + 154 + __add_type_attr(TYPE_CANONICAL(type), attr, args); 155 + } 156 + } 157 + 126 158 #define PASS_INFO(NAME, REF, ID, POS) \ 127 159 struct register_pass_info NAME##_pass_info = { \ 128 160 .pass = make_##NAME##_pass(), \
+11 -11
scripts/gcc-plugins/randomize_layout_plugin.c
··· 73 73 74 74 if (TYPE_P(*node)) { 75 75 type = *node; 76 + } else if (TREE_CODE(*node) == FIELD_DECL) { 77 + *no_add_attrs = false; 78 + return NULL_TREE; 76 79 } else { 77 80 gcc_assert(TREE_CODE(*node) == TYPE_DECL); 78 81 type = TREE_TYPE(*node); ··· 351 348 TREE_CHAIN(newtree[i]) = newtree[i+1]; 352 349 TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE; 353 350 351 + add_type_attr(type, "randomize_performed", NULL_TREE); 352 + add_type_attr(type, "designated_init", NULL_TREE); 353 + if (has_flexarray) 354 + add_type_attr(type, "has_flexarray", NULL_TREE); 355 + 354 356 main_variant = TYPE_MAIN_VARIANT(type); 355 - for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) { 357 + for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) 356 358 TYPE_FIELDS(variant) = newtree[0]; 357 - TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant)); 358 - TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant)); 359 - TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant)); 360 - if (has_flexarray) 361 - TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type)); 362 - } 363 359 364 360 /* 365 361 * force a re-layout of the main variant ··· 426 424 if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type)) 427 425 relayout_struct(type); 428 426 429 - for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) { 430 - TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); 431 - TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type)); 432 - } 427 + add_type_attr(type, "randomize_considered", NULL_TREE); 428 + 433 429 #ifdef __DEBUG_PLUGIN 434 430 fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type)); 435 431 #ifdef __DEBUG_VERBOSE