Skip to content

Commit 9946eaf

Browse files
committed
Merge tag 'hardening-v6.14-rc2' of git://git.kernel.org/pub/scm/linux/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
2 parents f4a45f1 + 6270f4d commit 9946eaf

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

include/linux/compiler.h

+19-13
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,25 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
191191
__v; \
192192
})
193193

194+
#ifdef __CHECKER__
195+
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) (0)
196+
#else /* __CHECKER__ */
197+
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) ((int)sizeof(struct {_Static_assert(!(e), msg);}))
198+
#endif /* __CHECKER__ */
199+
200+
/* &a[0] degrades to a pointer: a different type from an array */
201+
#define __is_array(a) (!__same_type((a), &(a)[0]))
202+
#define __must_be_array(a) __BUILD_BUG_ON_ZERO_MSG(!__is_array(a), \
203+
"must be array")
204+
205+
#define __is_byte_array(a) (__is_array(a) && sizeof((a)[0]) == 1)
206+
#define __must_be_byte_array(a) __BUILD_BUG_ON_ZERO_MSG(!__is_byte_array(a), \
207+
"must be byte array")
208+
209+
/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */
210+
#define __must_be_cstr(p) \
211+
__BUILD_BUG_ON_ZERO_MSG(__annotated(p, nonstring), "must be cstr (NUL-terminated)")
212+
194213
#endif /* __KERNEL__ */
195214

196215
/**
@@ -231,19 +250,6 @@ static inline void *offset_to_ptr(const int *off)
231250

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

234-
#ifdef __CHECKER__
235-
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) (0)
236-
#else /* __CHECKER__ */
237-
#define __BUILD_BUG_ON_ZERO_MSG(e, msg) ((int)sizeof(struct {_Static_assert(!(e), msg);}))
238-
#endif /* __CHECKER__ */
239-
240-
/* &a[0] degrades to a pointer: a different type from an array */
241-
#define __must_be_array(a) __BUILD_BUG_ON_ZERO_MSG(__same_type((a), &(a)[0]), "must be array")
242-
243-
/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */
244-
#define __must_be_cstr(p) \
245-
__BUILD_BUG_ON_ZERO_MSG(__annotated(p, nonstring), "must be cstr (NUL-terminated)")
246-
247253
/*
248254
* This returns a constant expression while determining if an argument is
249255
* a constant expression, most importantly without evaluating the argument.

include/linux/string.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
414414
* must be discoverable by the compiler.
415415
*/
416416
#define strtomem_pad(dest, src, pad) do { \
417-
const size_t _dest_len = __builtin_object_size(dest, 1); \
417+
const size_t _dest_len = __must_be_byte_array(dest) + \
418+
ARRAY_SIZE(dest); \
418419
const size_t _src_len = __builtin_object_size(src, 1); \
419420
\
420421
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
@@ -437,7 +438,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
437438
* must be discoverable by the compiler.
438439
*/
439440
#define strtomem(dest, src) do { \
440-
const size_t _dest_len = __builtin_object_size(dest, 1); \
441+
const size_t _dest_len = __must_be_byte_array(dest) + \
442+
ARRAY_SIZE(dest); \
441443
const size_t _src_len = __builtin_object_size(src, 1); \
442444
\
443445
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
@@ -456,7 +458,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
456458
* Note that sizes of @dest and @src must be known at compile-time.
457459
*/
458460
#define memtostr(dest, src) do { \
459-
const size_t _dest_len = __builtin_object_size(dest, 1); \
461+
const size_t _dest_len = __must_be_byte_array(dest) + \
462+
ARRAY_SIZE(dest); \
460463
const size_t _src_len = __builtin_object_size(src, 1); \
461464
const size_t _src_chars = strnlen(src, _src_len); \
462465
const size_t _copy_len = min(_dest_len - 1, _src_chars); \
@@ -481,7 +484,8 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
481484
* Note that sizes of @dest and @src must be known at compile-time.
482485
*/
483486
#define memtostr_pad(dest, src) do { \
484-
const size_t _dest_len = __builtin_object_size(dest, 1); \
487+
const size_t _dest_len = __must_be_byte_array(dest) + \
488+
ARRAY_SIZE(dest); \
485489
const size_t _src_len = __builtin_object_size(src, 1); \
486490
const size_t _src_chars = strnlen(src, _src_len); \
487491
const size_t _copy_len = min(_dest_len - 1, _src_chars); \

lib/stackinit_kunit.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
7575
*/
7676
#ifdef CONFIG_M68K
7777
#define FILL_SIZE_STRING 8
78+
#define FILL_SIZE_ARRAY 2
7879
#else
7980
#define FILL_SIZE_STRING 16
81+
#define FILL_SIZE_ARRAY 8
8082
#endif
8183

8284
#define INIT_CLONE_SCALAR /**/
@@ -345,11 +347,11 @@ union test_small_start {
345347
short three;
346348
unsigned long four;
347349
struct big_struct {
348-
unsigned long array[8];
350+
unsigned long array[FILL_SIZE_ARRAY];
349351
} big;
350352
};
351353

352-
/* Mismatched sizes, with one and two being small */
354+
/* Mismatched sizes, with three and four being small */
353355
union test_small_end {
354356
short one;
355357
unsigned long two;

0 commit comments

Comments
 (0)