diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-16 13:45:43 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-16 13:45:43 -0700 |
commit | ce5a51bfacf7a2953f8fa309a8fc8540c2e288da (patch) | |
tree | c14afaeac549e50eedff24b1f9dce1d06b390cc7 | |
parent | 8050258bd1eed0f77dd7e3fa15feb23bbcc38e63 (diff) | |
parent | 872bb37f6829d4f7f3ed5afe2786add3d4384b4b (diff) | |
download | lwn-ce5a51bfacf7a2953f8fa309a8fc8540c2e288da.tar.gz lwn-ce5a51bfacf7a2953f8fa309a8fc8540c2e288da.zip |
Merge tag 'hardening-v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening updates from Kees Cook:
- lkdtm/bugs: add test for hung smp_call_function_single() (Mark
Rutland)
- gcc-plugins: Remove duplicate included header file stringpool.h
(Thorsten Blum)
- ARM: Remove address checking for MMUless devices (Yanjun Yang)
- randomize_kstack: Clean up per-arch entropy and codegen
- KCFI: Make FineIBT mode Kconfig selectable
- fortify: Do not special-case 0-sized destinations
* tag 'hardening-v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
randomize_kstack: Improve stack alignment codegen
ARM: Remove address checking for MMUless devices
gcc-plugins: Remove duplicate included header file stringpool.h
randomize_kstack: Remove non-functional per-arch entropy filtering
fortify: Do not special-case 0-sized destinations
x86/alternatives: Make FineIBT mode Kconfig selectable
lkdtm/bugs: add test for hung smp_call_function_single()
-rw-r--r-- | arch/arm/mm/fault.c | 4 | ||||
-rw-r--r-- | arch/x86/Kconfig | 9 | ||||
-rw-r--r-- | arch/x86/include/asm/cfi.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/alternative.c | 8 | ||||
-rw-r--r-- | drivers/misc/lkdtm/bugs.c | 30 | ||||
-rw-r--r-- | include/linux/fortify-string.h | 8 | ||||
-rw-r--r-- | include/linux/randomize_kstack.h | 18 | ||||
-rw-r--r-- | lib/fortify_kunit.c | 3 | ||||
-rw-r--r-- | scripts/gcc-plugins/gcc-common.h | 5 | ||||
-rw-r--r-- | tools/testing/selftests/lkdtm/tests.txt | 1 |
10 files changed, 62 insertions, 26 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 67c425341a95..ab01b51de559 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -25,6 +25,8 @@ #include "fault.h" +#ifdef CONFIG_MMU + bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) { unsigned long addr = (unsigned long)unsafe_src; @@ -32,8 +34,6 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) return addr >= TASK_SIZE && ULONG_MAX - addr >= size; } -#ifdef CONFIG_MMU - /* * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9778234cf111..7cd41bbaf875 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2414,6 +2414,15 @@ config STRICT_SIGALTSTACK_SIZE Say 'N' unless you want to really enforce this check. +config CFI_AUTO_DEFAULT + bool "Attempt to use FineIBT by default at boot time" + depends on FINEIBT + default y + help + Attempt to use FineIBT by default at boot time. If enabled, + this is the same as booting with "cfi=auto". If disabled, + this is the same as booting with "cfi=kcfi". + source "kernel/livepatch/Kconfig" endmenu diff --git a/arch/x86/include/asm/cfi.h b/arch/x86/include/asm/cfi.h index 7cd752557905..31d19c815f99 100644 --- a/arch/x86/include/asm/cfi.h +++ b/arch/x86/include/asm/cfi.h @@ -93,7 +93,7 @@ * */ enum cfi_mode { - CFI_DEFAULT, /* FineIBT if hardware has IBT, otherwise kCFI */ + CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */ CFI_OFF, /* Taditional / IBT depending on .config */ CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */ CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 333b16181357..d17518ca19b8 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -901,8 +901,8 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { } #endif /* CONFIG_X86_KERNEL_IBT */ -#ifdef CONFIG_FINEIBT -#define __CFI_DEFAULT CFI_DEFAULT +#ifdef CONFIG_CFI_AUTO_DEFAULT +#define __CFI_DEFAULT CFI_AUTO #elif defined(CONFIG_CFI_CLANG) #define __CFI_DEFAULT CFI_KCFI #else @@ -1010,7 +1010,7 @@ static __init int cfi_parse_cmdline(char *str) } if (!strcmp(str, "auto")) { - cfi_mode = CFI_DEFAULT; + cfi_mode = CFI_AUTO; } else if (!strcmp(str, "off")) { cfi_mode = CFI_OFF; cfi_rand = false; @@ -1270,7 +1270,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, "FineIBT preamble wrong size: %ld", fineibt_preamble_size)) return; - if (cfi_mode == CFI_DEFAULT) { + if (cfi_mode == CFI_AUTO) { cfi_mode = CFI_KCFI; if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT)) cfi_mode = CFI_FINEIBT; diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index 5178c02b21eb..62ba01525479 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -286,6 +286,35 @@ static void lkdtm_HARDLOCKUP(void) cpu_relax(); } +static void __lkdtm_SMP_CALL_LOCKUP(void *unused) +{ + for (;;) + cpu_relax(); +} + +static void lkdtm_SMP_CALL_LOCKUP(void) +{ + unsigned int cpu, target; + + cpus_read_lock(); + + cpu = get_cpu(); + target = cpumask_any_but(cpu_online_mask, cpu); + + if (target >= nr_cpu_ids) { + pr_err("FAIL: no other online CPUs\n"); + goto out_put_cpus; + } + + smp_call_function_single(target, __lkdtm_SMP_CALL_LOCKUP, NULL, 1); + + pr_err("FAIL: did not hang\n"); + +out_put_cpus: + put_cpu(); + cpus_read_unlock(); +} + static void lkdtm_SPINLOCKUP(void) { /* Must be called twice to trigger. */ @@ -680,6 +709,7 @@ static struct crashtype crashtypes[] = { CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), CRASHTYPE(SOFTLOCKUP), CRASHTYPE(HARDLOCKUP), + CRASHTYPE(SMP_CALL_LOCKUP), CRASHTYPE(SPINLOCKUP), CRASHTYPE(HUNG_TASK), CRASHTYPE(OVERFLOW_SIGNED), diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 7e0f340bf363..0d99bf11d260 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -601,11 +601,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, /* * Warn when writing beyond destination field size. * - * We must ignore p_size_field == 0 for existing 0-element - * fake flexible arrays, until they are all converted to - * proper flexible arrays. - * - * The implementation of __builtin_*object_size() behaves + * Note the implementation of __builtin_*object_size() behaves * like sizeof() when not directly referencing a flexible * array member, which means there will be many bounds checks * that will appear at run-time, without a way for them to be @@ -613,7 +609,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, * is specifically the flexible array member). * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101832 */ - if (p_size_field != 0 && p_size_field != SIZE_MAX && + if (p_size_field != SIZE_MAX && p_size != p_size_field && p_size_field < size) return true; diff --git a/include/linux/randomize_kstack.h b/include/linux/randomize_kstack.h index 6d92b68efbf6..1d982dbdd0d0 100644 --- a/include/linux/randomize_kstack.h +++ b/include/linux/randomize_kstack.h @@ -32,13 +32,19 @@ DECLARE_PER_CPU(u32, kstack_offset); #endif /* - * Use, at most, 10 bits of entropy. We explicitly cap this to keep the - * "VLA" from being unbounded (see above). 10 bits leaves enough room for - * per-arch offset masks to reduce entropy (by removing higher bits, since - * high entropy may overly constrain usable stack space), and for - * compiler/arch-specific stack alignment to remove the lower bits. + * Use, at most, 6 bits of entropy (on 64-bit; 8 on 32-bit). This cap is + * to keep the "VLA" from being unbounded (see above). Additionally clear + * the bottom 4 bits (on 64-bit systems, 2 for 32-bit), since stack + * alignment will always be at least word size. This makes the compiler + * code gen better when it is applying the actual per-arch alignment to + * the final offset. The resulting randomness is reasonable without overly + * constraining usable stack space. */ -#define KSTACK_OFFSET_MAX(x) ((x) & 0x3FF) +#ifdef CONFIG_64BIT +#define KSTACK_OFFSET_MAX(x) ((x) & 0b1111110000) +#else +#define KSTACK_OFFSET_MAX(x) ((x) & 0b1111111100) +#endif /** * add_random_kstack_offset - Increase stack utilization by previously diff --git a/lib/fortify_kunit.c b/lib/fortify_kunit.c index e17d520f532c..27ea8bf0252c 100644 --- a/lib/fortify_kunit.c +++ b/lib/fortify_kunit.c @@ -910,10 +910,9 @@ static void fortify_test_##memfunc(struct kunit *test) \ memfunc(zero.buf, srcB, 0 + unconst); \ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ - /* We currently explicitly ignore zero-sized dests. */ \ memfunc(zero.buf, srcB, 1 + unconst); \ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ - KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \ } __fortify_test(memcpy) __fortify_test(memmove) diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 1ae39b9f4a95..3222c1070444 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -62,11 +62,7 @@ #include "pass_manager.h" #include "predict.h" #include "ipa-utils.h" - -#if BUILDING_GCC_VERSION >= 8000 #include "stringpool.h" -#endif - #include "attribs.h" #include "varasm.h" #include "stor-layout.h" @@ -78,7 +74,6 @@ #include "context.h" #include "tree-ssa-alias.h" #include "tree-ssa.h" -#include "stringpool.h" #if BUILDING_GCC_VERSION >= 7000 #include "tree-vrp.h" #endif diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt index 368973f05250..cff124c1eddd 100644 --- a/tools/testing/selftests/lkdtm/tests.txt +++ b/tools/testing/selftests/lkdtm/tests.txt @@ -31,6 +31,7 @@ SLAB_FREE_CROSS SLAB_FREE_PAGE #SOFTLOCKUP Hangs the system #HARDLOCKUP Hangs the system +#SMP_CALL_LOCKUP Hangs the system #SPINLOCKUP Hangs the system #HUNG_TASK Hangs the system EXEC_DATA |