Skip to content

Commit cd2e103

Browse files
committed
Merge tag 'hardening-v6.16-rc1-fix1-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening fixes from Kees Cook: - randstruct: gcc-plugin: Fix attribute addition with GCC 15 - ubsan: integer-overflow: depend on BROKEN to keep this out of CI - overflow: Introduce __DEFINE_FLEX for having no initializer - wifi: iwlwifi: mld: Work around Clang loop unrolling bug [ Take two after a jump scare due to some repo rewriting by 'b4' - Linus ] * tag 'hardening-v6.16-rc1-fix1-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: randstruct: gcc-plugin: Fix attribute addition overflow: Introduce __DEFINE_FLEX for having no initializer ubsan: integer-overflow: depend on BROKEN to keep this out of CI wifi: iwlwifi: mld: Work around Clang loop unrolling bug
2 parents bb1556e + f39f18f commit cd2e103

File tree

5 files changed

+65
-18
lines changed

5 files changed

+65
-18
lines changed

drivers/net/wireless/intel/iwlwifi/mld/d3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
17571757

17581758
addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
17591759
&solicited_addr);
1760-
for (j = 0; j < c; j++)
1760+
for (j = 0; j < n_nsc && j < c; j++)
17611761
if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
17621762
&solicited_addr) == 0)
17631763
break;

include/linux/overflow.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -389,24 +389,37 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
389389
struct_size((type *)NULL, member, count)
390390

391391
/**
392-
* _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
393-
* Enables caller macro to pass (different) initializer.
392+
* __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
393+
* Enables caller macro to pass arbitrary trailing expressions
394394
*
395395
* @type: structure type name, including "struct" keyword.
396396
* @name: Name for a variable to define.
397397
* @member: Name of the array member.
398398
* @count: Number of elements in the array; must be compile-time const.
399-
* @initializer: Initializer expression (e.g., pass `= { }` at minimum).
399+
* @trailer: Trailing expressions for attributes and/or initializers.
400400
*/
401-
#define _DEFINE_FLEX(type, name, member, count, initializer...) \
401+
#define __DEFINE_FLEX(type, name, member, count, trailer...) \
402402
_Static_assert(__builtin_constant_p(count), \
403403
"onstack flex array members require compile-time const count"); \
404404
union { \
405405
u8 bytes[struct_size_t(type, member, count)]; \
406406
type obj; \
407-
} name##_u = { .obj initializer }; \
407+
} name##_u trailer; \
408408
type *name = (type *)&name##_u
409409

410+
/**
411+
* _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
412+
* Enables caller macro to pass (different) initializer.
413+
*
414+
* @type: structure type name, including "struct" keyword.
415+
* @name: Name for a variable to define.
416+
* @member: Name of the array member.
417+
* @count: Number of elements in the array; must be compile-time const.
418+
* @initializer: Initializer expression (e.g., pass `= { }` at minimum).
419+
*/
420+
#define _DEFINE_FLEX(type, name, member, count, initializer...) \
421+
__DEFINE_FLEX(type, name, member, count, = { .obj initializer })
422+
410423
/**
411424
* DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing
412425
* flexible array member, when it does not have a __counted_by annotation.
@@ -424,7 +437,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
424437
* elements in array @member.
425438
*/
426439
#define DEFINE_RAW_FLEX(type, name, member, count) \
427-
_DEFINE_FLEX(type, name, member, count, = {})
440+
__DEFINE_FLEX(type, name, member, count, = { })
428441

429442
/**
430443
* DEFINE_FLEX() - Define an on-stack instance of structure with a trailing

lib/Kconfig.ubsan

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ config UBSAN_UNREACHABLE
118118

119119
config UBSAN_INTEGER_WRAP
120120
bool "Perform checking for integer arithmetic wrap-around"
121+
# This is very experimental so drop the next line if you really want it
122+
depends on BROKEN
121123
depends on !COMPILE_TEST
122124
depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all)
123125
depends on $(cc-option,-fsanitize=signed-integer-overflow)

scripts/gcc-plugins/gcc-common.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,38 @@ static inline tree build_const_char_string(int len, const char *str)
115115
return cstr;
116116
}
117117

118+
static inline void __add_type_attr(tree type, const char *attr, tree args)
119+
{
120+
tree oldattr;
121+
122+
if (type == NULL_TREE)
123+
return;
124+
oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type));
125+
if (oldattr != NULL_TREE) {
126+
gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args));
127+
return;
128+
}
129+
130+
TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
131+
TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type));
132+
}
133+
134+
static inline void add_type_attr(tree type, const char *attr, tree args)
135+
{
136+
tree main_variant = TYPE_MAIN_VARIANT(type);
137+
138+
__add_type_attr(TYPE_CANONICAL(type), attr, args);
139+
__add_type_attr(TYPE_CANONICAL(main_variant), attr, args);
140+
__add_type_attr(main_variant, attr, args);
141+
142+
for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) {
143+
if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type)))
144+
TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant);
145+
146+
__add_type_attr(TYPE_CANONICAL(type), attr, args);
147+
}
148+
}
149+
118150
#define PASS_INFO(NAME, REF, ID, POS) \
119151
struct register_pass_info NAME##_pass_info = { \
120152
.pass = make_##NAME##_pass(), \

scripts/gcc-plugins/randomize_layout_plugin.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int f
7373

7474
if (TYPE_P(*node)) {
7575
type = *node;
76+
} else if (TREE_CODE(*node) == FIELD_DECL) {
77+
*no_add_attrs = false;
78+
return NULL_TREE;
7679
} else {
7780
gcc_assert(TREE_CODE(*node) == TYPE_DECL);
7881
type = TREE_TYPE(*node);
@@ -348,15 +351,14 @@ static int relayout_struct(tree type)
348351
TREE_CHAIN(newtree[i]) = newtree[i+1];
349352
TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
350353

354+
add_type_attr(type, "randomize_performed", NULL_TREE);
355+
add_type_attr(type, "designated_init", NULL_TREE);
356+
if (has_flexarray)
357+
add_type_attr(type, "has_flexarray", NULL_TREE);
358+
351359
main_variant = TYPE_MAIN_VARIANT(type);
352-
for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
360+
for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant))
353361
TYPE_FIELDS(variant) = newtree[0];
354-
TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
355-
TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
356-
TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
357-
if (has_flexarray)
358-
TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
359-
}
360362

361363
/*
362364
* force a re-layout of the main variant
@@ -424,10 +426,8 @@ static void randomize_type(tree type)
424426
if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type))
425427
relayout_struct(type);
426428

427-
for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
428-
TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
429-
TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
430-
}
429+
add_type_attr(type, "randomize_considered", NULL_TREE);
430+
431431
#ifdef __DEBUG_PLUGIN
432432
fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
433433
#ifdef __DEBUG_VERBOSE

0 commit comments

Comments
 (0)