Skip to content

Commit

Permalink
Merge tag 'hardening-v6.14-rc2' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/kees/linux

Pull hardening fixes from Kees Cook:
 "Address a KUnit stack initialization regression that got tickled on
  m68k, and solve a Clang(v14 and earlier) bug found by 0day:

   - Fix stackinit KUnit regression on m68k

   - Use ARRAY_SIZE() for memtostr*()/strtomem*()"

* tag 'hardening-v6.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  string.h: Use ARRAY_SIZE() for memtostr*()/strtomem*()
  compiler.h: Introduce __must_be_byte_array()
  compiler.h: Move C string helpers into C-only kernel section
  stackinit: Fix comment for test_small_end
  stackinit: Keep selftest union size small on m68k
  • Loading branch information
Linus Torvalds committed Feb 8, 2025
2 parents f4a45f1 + 6270f4d commit 9946eaf
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
32 changes: 19 additions & 13 deletions include/linux/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,25 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
__v; \
})

#ifdef __CHECKER__
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) (0)
#else /* __CHECKER__ */
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) ((int)sizeof(struct {_Static_assert(!(e), msg);}))
#endif /* __CHECKER__ */

/* &a[0] degrades to a pointer: a different type from an array */
#define __is_array(a) (!__same_type((a), &(a)[0]))
#define __must_be_array(a) __BUILD_BUG_ON_ZERO_MSG(!__is_array(a), \
"must be array")

#define __is_byte_array(a) (__is_array(a) && sizeof((a)[0]) == 1)
#define __must_be_byte_array(a) __BUILD_BUG_ON_ZERO_MSG(!__is_byte_array(a), \
"must be byte array")

/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */
#define __must_be_cstr(p) \
__BUILD_BUG_ON_ZERO_MSG(__annotated(p, nonstring), "must be cstr (NUL-terminated)")

#endif /* __KERNEL__ */

/**
Expand Down Expand Up @@ -231,19 +250,6 @@ static inline void *offset_to_ptr(const int *off)

#define __ADDRESSABLE_ASM_STR(sym) __stringify(__ADDRESSABLE_ASM(sym))

#ifdef __CHECKER__
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) (0)
#else /* __CHECKER__ */
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) ((int)sizeof(struct {_Static_assert(!(e), msg);}))
#endif /* __CHECKER__ */

/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) __BUILD_BUG_ON_ZERO_MSG(__same_type((a), &(a)[0]), "must be array")

/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */
#define __must_be_cstr(p) \
__BUILD_BUG_ON_ZERO_MSG(__annotated(p, nonstring), "must be cstr (NUL-terminated)")

/*
* This returns a constant expression while determining if an argument is
* a constant expression, most importantly without evaluating the argument.
Expand Down
12 changes: 8 additions & 4 deletions include/linux/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
* must be discoverable by the compiler.
*/
#define strtomem_pad(dest, src, pad) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _dest_len = __must_be_byte_array(dest) + \
ARRAY_SIZE(dest); \
const size_t _src_len = __builtin_object_size(src, 1); \
\
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
Expand All @@ -437,7 +438,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
* must be discoverable by the compiler.
*/
#define strtomem(dest, src) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _dest_len = __must_be_byte_array(dest) + \
ARRAY_SIZE(dest); \
const size_t _src_len = __builtin_object_size(src, 1); \
\
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
Expand All @@ -456,7 +458,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
* Note that sizes of @dest and @src must be known at compile-time.
*/
#define memtostr(dest, src) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _dest_len = __must_be_byte_array(dest) + \
ARRAY_SIZE(dest); \
const size_t _src_len = __builtin_object_size(src, 1); \
const size_t _src_chars = strnlen(src, _src_len); \
const size_t _copy_len = min(_dest_len - 1, _src_chars); \
Expand All @@ -481,7 +484,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
* Note that sizes of @dest and @src must be known at compile-time.
*/
#define memtostr_pad(dest, src) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _dest_len = __must_be_byte_array(dest) + \
ARRAY_SIZE(dest); \
const size_t _src_len = __builtin_object_size(src, 1); \
const size_t _src_chars = strnlen(src, _src_len); \
const size_t _copy_len = min(_dest_len - 1, _src_chars); \
Expand Down
6 changes: 4 additions & 2 deletions lib/stackinit_kunit.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
*/
#ifdef CONFIG_M68K
#define FILL_SIZE_STRING 8
#define FILL_SIZE_ARRAY 2
#else
#define FILL_SIZE_STRING 16
#define FILL_SIZE_ARRAY 8
#endif

#define INIT_CLONE_SCALAR /**/
Expand Down Expand Up @@ -345,11 +347,11 @@ union test_small_start {
short three;
unsigned long four;
struct big_struct {
unsigned long array[8];
unsigned long array[FILL_SIZE_ARRAY];
} big;
};

/* Mismatched sizes, with one and two being small */
/* Mismatched sizes, with three and four being small */
union test_small_end {
short one;
unsigned long two;
Expand Down

0 comments on commit 9946eaf

Please sign in to comment.