summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-16 13:45:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-16 13:45:43 -0700
commitce5a51bfacf7a2953f8fa309a8fc8540c2e288da (patch)
treec14afaeac549e50eedff24b1f9dce1d06b390cc7
parent8050258bd1eed0f77dd7e3fa15feb23bbcc38e63 (diff)
parent872bb37f6829d4f7f3ed5afe2786add3d4384b4b (diff)
downloadlwn-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.c4
-rw-r--r--arch/x86/Kconfig9
-rw-r--r--arch/x86/include/asm/cfi.h2
-rw-r--r--arch/x86/kernel/alternative.c8
-rw-r--r--drivers/misc/lkdtm/bugs.c30
-rw-r--r--include/linux/fortify-string.h8
-rw-r--r--include/linux/randomize_kstack.h18
-rw-r--r--lib/fortify_kunit.c3
-rw-r--r--scripts/gcc-plugins/gcc-common.h5
-rw-r--r--tools/testing/selftests/lkdtm/tests.txt1
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