mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
hardening fixes for v6.1-rc3
- Fix older Clang vs recent overflow KUnit test additions. (Nick Desaulniers, Kees Cook) - Fix kern-doc visibility for overflow helpers. (Kees Cook) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmNa1bQWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJhsxD/9+/HP6GIKUqQlmCiAzRat9cdhB OnvcKAYDeITz/UUOqC6OBeSESPpJ215Bk8mU8Wxcy/M0jLFZrazU4epVqpwAxCMj lWhHNi7wV2mzfnJuNctgSaPvvuGBdt1hQVMUbaiJOiahYJt28BYmDWH0rfJayrs8 cxJnsLychTsEMJ0HjM+YzaSzrk75rTE6Y2GakHdx3ZoyNyL8j8XsBt2itqjlaOVk SPBKhbqpxM5lt4tpaUK/mn6UuRKdIdeCZAkcpYU6ETmvi/sk3tNyHuzMf0BQzsEw G6Pjlp7rMl+JYKdNju0jEiD3XLqmj8I8yAOLUGoFOib01IdTRUEt40Ln62YmNaaw SUJN8V9WZzpaPqpH7R9pxv3F0yfzMHfFRO7s8SzAGm3MXHdej7sdw/1PoriIx1l7 e070xffEpsHUDGZaD9h8pxQw3jIDrCpfWucqY05wZzor05ROkUHbZRNViyPiGoa6 KEw1uj3DJpLNmrFWLenKYbb+A17wsCo+eRYvDPCdJmpfm+u7gtyATi7y0pdUls0z vJS/K4fWr4WwzMZq7PLXkIgkaXZzwCcFEA8PNXDxXUHO27vgcX43jsRhtkL0PsDK eEV2GCr2czM2dXO275oB9e8Ey2l8awGG/t20AmrsvjFE1s0UmP0shTEVHCgKfygz sz/8Gnsv7N5InK7R3g== =K0Vr -----END PGP SIGNATURE----- Merge tag 'hardening-v6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull hardening fixes from Kees Cook: - Fix older Clang vs recent overflow KUnit test additions (Nick Desaulniers, Kees Cook) - Fix kern-doc visibility for overflow helpers (Kees Cook) * tag 'hardening-v6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: overflow: Refactor test skips for Clang-specific issues overflow: disable failing tests for older clang versions overflow: Fix kern-doc markup for functions
This commit is contained in:
commit
2eb72d85ac
@ -118,6 +118,12 @@ Text Searching
|
||||
CRC and Math Functions in Linux
|
||||
===============================
|
||||
|
||||
Arithmetic Overflow Checking
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/overflow.h
|
||||
:internal:
|
||||
|
||||
CRC Functions
|
||||
-------------
|
||||
|
||||
|
@ -107,9 +107,6 @@ Kernel utility functions
|
||||
.. kernel-doc:: kernel/panic.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/overflow.h
|
||||
:internal:
|
||||
|
||||
Device Resource Management
|
||||
--------------------------
|
||||
|
||||
|
@ -51,8 +51,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
|
||||
return unlikely(overflow);
|
||||
}
|
||||
|
||||
/** check_add_overflow() - Calculate addition with overflow checking
|
||||
*
|
||||
/**
|
||||
* check_add_overflow() - Calculate addition with overflow checking
|
||||
* @a: first addend
|
||||
* @b: second addend
|
||||
* @d: pointer to store sum
|
||||
@ -66,8 +66,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
|
||||
#define check_add_overflow(a, b, d) \
|
||||
__must_check_overflow(__builtin_add_overflow(a, b, d))
|
||||
|
||||
/** check_sub_overflow() - Calculate subtraction with overflow checking
|
||||
*
|
||||
/**
|
||||
* check_sub_overflow() - Calculate subtraction with overflow checking
|
||||
* @a: minuend; value to subtract from
|
||||
* @b: subtrahend; value to subtract from @a
|
||||
* @d: pointer to store difference
|
||||
@ -81,8 +81,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
|
||||
#define check_sub_overflow(a, b, d) \
|
||||
__must_check_overflow(__builtin_sub_overflow(a, b, d))
|
||||
|
||||
/** check_mul_overflow() - Calculate multiplication with overflow checking
|
||||
*
|
||||
/**
|
||||
* check_mul_overflow() - Calculate multiplication with overflow checking
|
||||
* @a: first factor
|
||||
* @b: second factor
|
||||
* @d: pointer to store product
|
||||
@ -96,23 +96,24 @@ static inline bool __must_check __must_check_overflow(bool overflow)
|
||||
#define check_mul_overflow(a, b, d) \
|
||||
__must_check_overflow(__builtin_mul_overflow(a, b, d))
|
||||
|
||||
/** check_shl_overflow() - Calculate a left-shifted value and check overflow
|
||||
*
|
||||
/**
|
||||
* check_shl_overflow() - Calculate a left-shifted value and check overflow
|
||||
* @a: Value to be shifted
|
||||
* @s: How many bits left to shift
|
||||
* @d: Pointer to where to store the result
|
||||
*
|
||||
* Computes *@d = (@a << @s)
|
||||
*
|
||||
* Returns true if '*d' cannot hold the result or when 'a << s' doesn't
|
||||
* Returns true if '*@d' cannot hold the result or when '@a << @s' doesn't
|
||||
* make sense. Example conditions:
|
||||
* - 'a << s' causes bits to be lost when stored in *d.
|
||||
* - 's' is garbage (e.g. negative) or so large that the result of
|
||||
* 'a << s' is guaranteed to be 0.
|
||||
* - 'a' is negative.
|
||||
* - 'a << s' sets the sign bit, if any, in '*d'.
|
||||
*
|
||||
* '*d' will hold the results of the attempted shift, but is not
|
||||
* - '@a << @s' causes bits to be lost when stored in *@d.
|
||||
* - '@s' is garbage (e.g. negative) or so large that the result of
|
||||
* '@a << @s' is guaranteed to be 0.
|
||||
* - '@a' is negative.
|
||||
* - '@a << @s' sets the sign bit, if any, in '*@d'.
|
||||
*
|
||||
* '*@d' will hold the results of the attempted shift, but is not
|
||||
* considered "safe for use" if true is returned.
|
||||
*/
|
||||
#define check_shl_overflow(a, s, d) __must_check_overflow(({ \
|
||||
@ -129,7 +130,6 @@ static inline bool __must_check __must_check_overflow(bool overflow)
|
||||
|
||||
/**
|
||||
* size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
|
||||
*
|
||||
* @factor1: first factor
|
||||
* @factor2: second factor
|
||||
*
|
||||
@ -149,7 +149,6 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
|
||||
|
||||
/**
|
||||
* size_add() - Calculate size_t addition with saturation at SIZE_MAX
|
||||
*
|
||||
* @addend1: first addend
|
||||
* @addend2: second addend
|
||||
*
|
||||
@ -169,7 +168,6 @@ static inline size_t __must_check size_add(size_t addend1, size_t addend2)
|
||||
|
||||
/**
|
||||
* size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX
|
||||
*
|
||||
* @minuend: value to subtract from
|
||||
* @subtrahend: value to subtract from @minuend
|
||||
*
|
||||
@ -192,7 +190,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
||||
|
||||
/**
|
||||
* array_size() - Calculate size of 2-dimensional array.
|
||||
*
|
||||
* @a: dimension one
|
||||
* @b: dimension two
|
||||
*
|
||||
@ -205,7 +202,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
||||
|
||||
/**
|
||||
* array3_size() - Calculate size of 3-dimensional array.
|
||||
*
|
||||
* @a: dimension one
|
||||
* @b: dimension two
|
||||
* @c: dimension three
|
||||
@ -220,7 +216,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
||||
/**
|
||||
* flex_array_size() - Calculate size of a flexible array member
|
||||
* within an enclosing structure.
|
||||
*
|
||||
* @p: Pointer to the structure.
|
||||
* @member: Name of the flexible array member.
|
||||
* @count: Number of elements in the array.
|
||||
@ -237,7 +232,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
||||
|
||||
/**
|
||||
* struct_size() - Calculate size of structure with trailing flexible array.
|
||||
*
|
||||
* @p: Pointer to the structure.
|
||||
* @member: Name of the array member.
|
||||
* @count: Number of elements in the array.
|
||||
|
@ -16,6 +16,34 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#define SKIP(cond, reason) do { \
|
||||
if (cond) { \
|
||||
kunit_skip(test, reason); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Clang 11 and earlier generate unwanted libcalls for signed output
|
||||
* on unsigned input.
|
||||
*/
|
||||
#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
|
||||
# define SKIP_SIGN_MISMATCH(t) SKIP(t, "Clang 11 unwanted libcalls")
|
||||
#else
|
||||
# define SKIP_SIGN_MISMATCH(t) do { } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
|
||||
* 32-bit hosts.
|
||||
*/
|
||||
#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 && \
|
||||
BITS_PER_LONG != 64
|
||||
# define SKIP_64_ON_32(t) SKIP(t, "Clang 13 unwanted libcalls")
|
||||
#else
|
||||
# define SKIP_64_ON_32(t) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t) \
|
||||
static const struct test_ ## t1 ## _ ## t2 ## __ ## t { \
|
||||
t1 a; \
|
||||
@ -94,7 +122,6 @@ DEFINE_TEST_ARRAY(u32) = {
|
||||
{-4U, 5U, 1U, -9U, -20U, true, false, true},
|
||||
};
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
DEFINE_TEST_ARRAY(u64) = {
|
||||
{0, 0, 0, 0, 0, false, false, false},
|
||||
{1, 1, 2, 0, 1, false, false, false},
|
||||
@ -118,7 +145,6 @@ DEFINE_TEST_ARRAY(u64) = {
|
||||
false, true, false},
|
||||
{-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
|
||||
};
|
||||
#endif
|
||||
|
||||
DEFINE_TEST_ARRAY(s8) = {
|
||||
{0, 0, 0, 0, 0, false, false, false},
|
||||
@ -194,7 +220,6 @@ DEFINE_TEST_ARRAY(s32) = {
|
||||
{S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
|
||||
};
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
DEFINE_TEST_ARRAY(s64) = {
|
||||
{0, 0, 0, 0, 0, false, false, false},
|
||||
|
||||
@ -223,7 +248,6 @@ DEFINE_TEST_ARRAY(s64) = {
|
||||
{-128, -1, -129, -127, 128, false, false, false},
|
||||
{0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
|
||||
};
|
||||
#endif
|
||||
|
||||
#define check_one_op(t, fmt, op, sym, a, b, r, of) do { \
|
||||
int _a_orig = a, _a_bump = a + 1; \
|
||||
@ -246,7 +270,7 @@ DEFINE_TEST_ARRAY(s64) = {
|
||||
|
||||
#define DEFINE_TEST_FUNC_TYPED(n, t, fmt) \
|
||||
static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
|
||||
{ \
|
||||
{ \
|
||||
check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of); \
|
||||
check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of); \
|
||||
check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of); \
|
||||
@ -257,6 +281,12 @@ static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
|
||||
static void n ## _overflow_test(struct kunit *test) { \
|
||||
unsigned i; \
|
||||
\
|
||||
SKIP_64_ON_32(__same_type(t, u64)); \
|
||||
SKIP_64_ON_32(__same_type(t, s64)); \
|
||||
SKIP_SIGN_MISMATCH(__same_type(n ## _tests[0].a, u32) && \
|
||||
__same_type(n ## _tests[0].b, u32) && \
|
||||
__same_type(n ## _tests[0].sum, int)); \
|
||||
\
|
||||
for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i) \
|
||||
do_test_ ## n(test, &n ## _tests[i]); \
|
||||
kunit_info(test, "%zu %s arithmetic tests finished\n", \
|
||||
@ -272,10 +302,8 @@ DEFINE_TEST_FUNC(u16, "%d");
|
||||
DEFINE_TEST_FUNC(s16, "%d");
|
||||
DEFINE_TEST_FUNC(u32, "%u");
|
||||
DEFINE_TEST_FUNC(s32, "%d");
|
||||
#if BITS_PER_LONG == 64
|
||||
DEFINE_TEST_FUNC(u64, "%llu");
|
||||
DEFINE_TEST_FUNC(s64, "%lld");
|
||||
#endif
|
||||
|
||||
DEFINE_TEST_ARRAY_TYPED(u32, u32, u8) = {
|
||||
{0, 0, 0, 0, 0, false, false, false},
|
||||
@ -715,13 +743,10 @@ static struct kunit_case overflow_test_cases[] = {
|
||||
KUNIT_CASE(s16_s16__s16_overflow_test),
|
||||
KUNIT_CASE(u32_u32__u32_overflow_test),
|
||||
KUNIT_CASE(s32_s32__s32_overflow_test),
|
||||
/* Clang 13 and earlier generate unwanted libcalls on 32-bit. */
|
||||
#if BITS_PER_LONG == 64
|
||||
KUNIT_CASE(u64_u64__u64_overflow_test),
|
||||
KUNIT_CASE(s64_s64__s64_overflow_test),
|
||||
#endif
|
||||
KUNIT_CASE(u32_u32__u8_overflow_test),
|
||||
KUNIT_CASE(u32_u32__int_overflow_test),
|
||||
KUNIT_CASE(u32_u32__u8_overflow_test),
|
||||
KUNIT_CASE(u8_u8__int_overflow_test),
|
||||
KUNIT_CASE(int_int__u8_overflow_test),
|
||||
KUNIT_CASE(shift_sane_test),
|
||||
|
Loading…
Reference in New Issue
Block a user