1

hardening updates for v6.11-rc1

- 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
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmaVT2IACgkQiXL039xt
 wCbq8A//RhxTdr+l/h2gyMy/Lcy/NMR9KEWklnxdftuM1V1Kzr53yeH/g6Ehw69g
 e8Ag3Sp7Fn4rNBVa+tY6RqzKwfrUHIbeewGI4LkRe19NDWFWc/Od+4tamfRSPf9c
 GL9ZnJZviRm3zByetwr4CbS69HocXFFSSgcpIv/7xOd+haSWWdvEc3KcSnavY/aq
 8wQPkZxzy8ESkOajZj2k0E2l9JP42Ex20qy0KcjweSSYVafKmbTxhKZgriwAKMCD
 Yj2m55fbD6D08vd0Y6S7H4TPilYtRbulXR9FNMtw59UpKeoUceEmyn4B43psDvau
 9XuJF/oFKrXBEJG+OUZogNu5L6uYUaNdYdtb43upu9lCsjrAjmMYfmXDHO2E40V8
 76MikxHtyFAPEzUwg/BH2CGUu9hil+FADd28s8zLuUBpRDitgYudQD+Cqrc34b6s
 QlAX19bX7KFgXqlsdwy6zJNSd3dpoMBVsP58/EhQQfiqv/ZU2TOryZenz0URlH+k
 ZCAbpXYRAzTyGz23qkutRO+6MiKXoheE7gmd9jESiaqyXe2Q6mIMPyoFU50458TH
 xXhXbZc7War8vbJLyWF7fvK/GlooTHu4xOxfNTsxKWiYShI01iiwG1hH+j4ZDVOG
 NBBK2AfX9GM8AOHJolp5EaGmon0AoVsxbRANSs1K4qZ93WTNGLk=
 =LoG2
 -----END PGP SIGNATURE-----

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()
This commit is contained in:
Linus Torvalds 2024-07-16 13:45:43 -07:00
commit ce5a51bfac
10 changed files with 62 additions and 26 deletions

View File

@ -25,6 +25,8 @@
#include "fault.h" #include "fault.h"
#ifdef CONFIG_MMU
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{ {
unsigned long addr = (unsigned long)unsafe_src; 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; return addr >= TASK_SIZE && ULONG_MAX - addr >= size;
} }
#ifdef CONFIG_MMU
/* /*
* This is useful to dump out the page tables associated with * This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'. * 'addr' in mm 'mm'.

View File

@ -2414,6 +2414,15 @@ config STRICT_SIGALTSTACK_SIZE
Say 'N' unless you want to really enforce this check. 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" source "kernel/livepatch/Kconfig"
endmenu endmenu

View File

@ -93,7 +93,7 @@
* *
*/ */
enum cfi_mode { 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_OFF, /* Taditional / IBT depending on .config */
CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */ CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */
CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */ CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */

View File

@ -901,8 +901,8 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { }
#endif /* CONFIG_X86_KERNEL_IBT */ #endif /* CONFIG_X86_KERNEL_IBT */
#ifdef CONFIG_FINEIBT #ifdef CONFIG_CFI_AUTO_DEFAULT
#define __CFI_DEFAULT CFI_DEFAULT #define __CFI_DEFAULT CFI_AUTO
#elif defined(CONFIG_CFI_CLANG) #elif defined(CONFIG_CFI_CLANG)
#define __CFI_DEFAULT CFI_KCFI #define __CFI_DEFAULT CFI_KCFI
#else #else
@ -1010,7 +1010,7 @@ static __init int cfi_parse_cmdline(char *str)
} }
if (!strcmp(str, "auto")) { if (!strcmp(str, "auto")) {
cfi_mode = CFI_DEFAULT; cfi_mode = CFI_AUTO;
} else if (!strcmp(str, "off")) { } else if (!strcmp(str, "off")) {
cfi_mode = CFI_OFF; cfi_mode = CFI_OFF;
cfi_rand = false; 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)) "FineIBT preamble wrong size: %ld", fineibt_preamble_size))
return; return;
if (cfi_mode == CFI_DEFAULT) { if (cfi_mode == CFI_AUTO) {
cfi_mode = CFI_KCFI; cfi_mode = CFI_KCFI;
if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT)) if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT))
cfi_mode = CFI_FINEIBT; cfi_mode = CFI_FINEIBT;

View File

@ -286,6 +286,35 @@ static void lkdtm_HARDLOCKUP(void)
cpu_relax(); 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) static void lkdtm_SPINLOCKUP(void)
{ {
/* Must be called twice to trigger. */ /* Must be called twice to trigger. */
@ -680,6 +709,7 @@ static struct crashtype crashtypes[] = {
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
CRASHTYPE(SOFTLOCKUP), CRASHTYPE(SOFTLOCKUP),
CRASHTYPE(HARDLOCKUP), CRASHTYPE(HARDLOCKUP),
CRASHTYPE(SMP_CALL_LOCKUP),
CRASHTYPE(SPINLOCKUP), CRASHTYPE(SPINLOCKUP),
CRASHTYPE(HUNG_TASK), CRASHTYPE(HUNG_TASK),
CRASHTYPE(OVERFLOW_SIGNED), CRASHTYPE(OVERFLOW_SIGNED),

View File

@ -601,11 +601,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
/* /*
* Warn when writing beyond destination field size. * Warn when writing beyond destination field size.
* *
* We must ignore p_size_field == 0 for existing 0-element * Note the implementation of __builtin_*object_size() behaves
* fake flexible arrays, until they are all converted to
* proper flexible arrays.
*
* The implementation of __builtin_*object_size() behaves
* like sizeof() when not directly referencing a flexible * like sizeof() when not directly referencing a flexible
* array member, which means there will be many bounds checks * array member, which means there will be many bounds checks
* that will appear at run-time, without a way for them to be * 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). * is specifically the flexible array member).
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101832 * 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) p_size != p_size_field && p_size_field < size)
return true; return true;

View File

@ -32,13 +32,19 @@ DECLARE_PER_CPU(u32, kstack_offset);
#endif #endif
/* /*
* Use, at most, 10 bits of entropy. We explicitly cap this to keep the * Use, at most, 6 bits of entropy (on 64-bit; 8 on 32-bit). This cap is
* "VLA" from being unbounded (see above). 10 bits leaves enough room for * to keep the "VLA" from being unbounded (see above). Additionally clear
* per-arch offset masks to reduce entropy (by removing higher bits, since * the bottom 4 bits (on 64-bit systems, 2 for 32-bit), since stack
* high entropy may overly constrain usable stack space), and for * alignment will always be at least word size. This makes the compiler
* compiler/arch-specific stack alignment to remove the lower bits. * 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 * add_random_kstack_offset - Increase stack utilization by previously

View File

@ -910,10 +910,9 @@ static void fortify_test_##memfunc(struct kunit *test) \
memfunc(zero.buf, srcB, 0 + unconst); \ memfunc(zero.buf, srcB, 0 + unconst); \
KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
/* We currently explicitly ignore zero-sized dests. */ \
memfunc(zero.buf, srcB, 1 + unconst); \ memfunc(zero.buf, srcB, 1 + unconst); \
KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 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(memcpy)
__fortify_test(memmove) __fortify_test(memmove)

View File

@ -62,11 +62,7 @@
#include "pass_manager.h" #include "pass_manager.h"
#include "predict.h" #include "predict.h"
#include "ipa-utils.h" #include "ipa-utils.h"
#if BUILDING_GCC_VERSION >= 8000
#include "stringpool.h" #include "stringpool.h"
#endif
#include "attribs.h" #include "attribs.h"
#include "varasm.h" #include "varasm.h"
#include "stor-layout.h" #include "stor-layout.h"
@ -78,7 +74,6 @@
#include "context.h" #include "context.h"
#include "tree-ssa-alias.h" #include "tree-ssa-alias.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "stringpool.h"
#if BUILDING_GCC_VERSION >= 7000 #if BUILDING_GCC_VERSION >= 7000
#include "tree-vrp.h" #include "tree-vrp.h"
#endif #endif

View File

@ -31,6 +31,7 @@ SLAB_FREE_CROSS
SLAB_FREE_PAGE SLAB_FREE_PAGE
#SOFTLOCKUP Hangs the system #SOFTLOCKUP Hangs the system
#HARDLOCKUP Hangs the system #HARDLOCKUP Hangs the system
#SMP_CALL_LOCKUP Hangs the system
#SPINLOCKUP Hangs the system #SPINLOCKUP Hangs the system
#HUNG_TASK Hangs the system #HUNG_TASK Hangs the system
EXEC_DATA EXEC_DATA