Commit cd2e103d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hardening-v6.16-rc1-fix1-take2' of...

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
parents bb1556ec f39f18f3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1757,7 +1757,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,

		addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
					  &solicited_addr);
		for (j = 0; j < c; j++)
		for (j = 0; j < n_nsc && j < c; j++)
			if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
					  &solicited_addr) == 0)
				break;
+19 −6
Original line number Diff line number Diff line
@@ -389,24 +389,37 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
	struct_size((type *)NULL, member, count)

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

/**
 * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
 * Enables caller macro to pass (different) initializer.
 *
 * @type: structure type name, including "struct" keyword.
 * @name: Name for a variable to define.
 * @member: Name of the array member.
 * @count: Number of elements in the array; must be compile-time const.
 * @initializer: Initializer expression (e.g., pass `= { }` at minimum).
 */
#define _DEFINE_FLEX(type, name, member, count, initializer...)			\
	__DEFINE_FLEX(type, name, member, count, = { .obj initializer })

/**
 * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing
 * 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)
 * elements in array @member.
 */
#define DEFINE_RAW_FLEX(type, name, member, count)	\
	_DEFINE_FLEX(type, name, member, count, = {})
	__DEFINE_FLEX(type, name, member, count, = { })

/**
 * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
+2 −0
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ config UBSAN_UNREACHABLE

config UBSAN_INTEGER_WRAP
	bool "Perform checking for integer arithmetic wrap-around"
	# This is very experimental so drop the next line if you really want it
	depends on BROKEN
	depends on !COMPILE_TEST
	depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all)
	depends on $(cc-option,-fsanitize=signed-integer-overflow)
+32 −0
Original line number Diff line number Diff line
@@ -115,6 +115,38 @@ static inline tree build_const_char_string(int len, const char *str)
	return cstr;
}

static inline void __add_type_attr(tree type, const char *attr, tree args)
{
	tree oldattr;

	if (type == NULL_TREE)
		return;
	oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type));
	if (oldattr != NULL_TREE) {
		gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args));
		return;
	}

	TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
	TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type));
}

static inline void add_type_attr(tree type, const char *attr, tree args)
{
	tree main_variant = TYPE_MAIN_VARIANT(type);

	__add_type_attr(TYPE_CANONICAL(type), attr, args);
	__add_type_attr(TYPE_CANONICAL(main_variant), attr, args);
	__add_type_attr(main_variant, attr, args);

	for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) {
		if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type)))
			TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant);

		__add_type_attr(TYPE_CANONICAL(type), attr, args);
	}
}

#define PASS_INFO(NAME, REF, ID, POS)		\
struct register_pass_info NAME##_pass_info = {	\
	.pass = make_##NAME##_pass(),		\
+11 −11
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int f

	if (TYPE_P(*node)) {
		type = *node;
	} else if (TREE_CODE(*node) == FIELD_DECL) {
		*no_add_attrs = false;
		return NULL_TREE;
	} else {
		gcc_assert(TREE_CODE(*node) == TYPE_DECL);
		type = TREE_TYPE(*node);
@@ -348,15 +351,14 @@ static int relayout_struct(tree type)
		TREE_CHAIN(newtree[i]) = newtree[i+1];
	TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;

	add_type_attr(type, "randomize_performed", NULL_TREE);
	add_type_attr(type, "designated_init", NULL_TREE);
	if (has_flexarray)
		add_type_attr(type, "has_flexarray", NULL_TREE);

	main_variant = TYPE_MAIN_VARIANT(type);
	for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
	for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant))
		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));
		if (has_flexarray)
			TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
	}

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

	for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
		TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
		TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
	}
	add_type_attr(type, "randomize_considered", NULL_TREE);

#ifdef __DEBUG_PLUGIN
	fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
#ifdef __DEBUG_VERBOSE