diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-16 09:21:01 +0530 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-16 09:21:01 +0530 |
| commit | 481329ec5b31d2c48ac6b8b703c8008133884c7e (patch) | |
| tree | 406bb78e41609a198710f5e3d4880a5734a00aba /drivers | |
| parent | 673f72944dde6614a56b37a61c6097f584c90ce6 (diff) | |
| parent | 122b52f0bab007ebeb414c8280c1def17b9ed1f4 (diff) | |
Merge tag 'hardening-v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening updates from Kees Cook:
- lkdtm:
- Add case to provoke a crash in EFI runtime services (Ard Biesheuvel)
- add PPC_RADIX_TLBIEL test and missed isync (Sayali Patil)
- stddef: Document designated initializer semantics for
__TRAILING_OVERLAP() (Gustavo A. R. Silva)
- strarray: drop redundant allocation, add __counted_by_ptr (Thorsten
Blum)
* tag 'hardening-v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
lkdtm/powerpc: add PPC_RADIX_TLBIEL test for radix MCE validation
lkdtm/powerpc: add isync after slbmte to enforce SLB update ordering
lkdtm: Add case to provoke a crash in EFI runtime services
lib/string_helpers: annotate struct strarray with __counted_by_ptr
lib/string_helpers: drop redundant allocation in kasprintf_strarray
MAINTAINERS: add kernel hardening keyword __counted_by_ptr
stddef: Document designated initializer semantics for __TRAILING_OVERLAP()
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/misc/lkdtm/Makefile | 2 | ||||
| -rw-r--r-- | drivers/misc/lkdtm/bugs.c | 27 | ||||
| -rw-r--r-- | drivers/misc/lkdtm/core.c | 2 | ||||
| -rw-r--r-- | drivers/misc/lkdtm/powerpc.c | 49 |
4 files changed, 78 insertions, 2 deletions
diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile index 03ebe33185f9..4e58d16fc01e 100644 --- a/drivers/misc/lkdtm/Makefile +++ b/drivers/misc/lkdtm/Makefile @@ -11,7 +11,7 @@ lkdtm-$(CONFIG_LKDTM) += usercopy.o lkdtm-$(CONFIG_LKDTM) += kstack_erase.o lkdtm-$(CONFIG_LKDTM) += cfi.o lkdtm-$(CONFIG_LKDTM) += fortify.o -lkdtm-$(CONFIG_PPC_64S_HASH_MMU) += powerpc.o +lkdtm-$(CONFIG_PPC_BOOK3S_64) += powerpc.o KASAN_SANITIZE_stackleak.o := n diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index e0098f314570..3eca2ef64aff 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -7,6 +7,7 @@ */ #include "lkdtm.h" #include <linux/cpu.h> +#include <linux/efi.h> #include <linux/list.h> #include <linux/hrtimer.h> #include <linux/sched.h> @@ -817,6 +818,29 @@ static noinline void lkdtm_CORRUPT_PAC(void) #endif } +static void __maybe_unused lkdtm_EFI_RUNTIME_CRASH(void) +{ + static unsigned long size __ro_after_init = sizeof(efi_char16_t); + efi_status_t status; + + if (!efi.get_next_variable || + !efi_enabled(EFI_RUNTIME_SERVICES) || + !efi_rt_services_supported(EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) { + pr_err("FAIL: EFI GetNextVariableName() is not available\n"); + return; + } + + /* + * Provoke a fault by asking the firmware to write to a read-only + * variable. + */ + status = efi.get_next_variable(&size, L"", &(efi_guid_t){}); + + if (status != EFI_ABORTED || efi_enabled(EFI_RUNTIME_SERVICES)) + pr_err("FAIL: EFI GetNextVariable() did not abort (%#lx)\n", + status); +} + static struct crashtype crashtypes[] = { CRASHTYPE(PANIC), CRASHTYPE(PANIC_STOP_IRQOFF), @@ -850,6 +874,9 @@ static struct crashtype crashtypes[] = { CRASHTYPE(UNSET_SMEP), CRASHTYPE(DOUBLE_FAULT), CRASHTYPE(CORRUPT_PAC), +#ifdef CONFIG_EFI + CRASHTYPE(EFI_RUNTIME_CRASH), +#endif }; struct crashtype_category bugs_crashtypes = { diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 5732fd59a227..ededa32d6744 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -96,7 +96,7 @@ static const struct crashtype_category *crashtype_categories[] = { &stackleak_crashtypes, &cfi_crashtypes, &fortify_crashtypes, -#ifdef CONFIG_PPC_64S_HASH_MMU +#ifdef CONFIG_PPC_BOOK3S_64 &powerpc_crashtypes, #endif }; diff --git a/drivers/misc/lkdtm/powerpc.c b/drivers/misc/lkdtm/powerpc.c index be385449911a..6eaac79ea26b 100644 --- a/drivers/misc/lkdtm/powerpc.c +++ b/drivers/misc/lkdtm/powerpc.c @@ -5,6 +5,7 @@ #include <linux/vmalloc.h> #include <asm/mmu.h> +#ifdef CONFIG_PPC_64S_HASH_MMU /* Inserts new slb entries */ static void insert_slb_entry(unsigned long p, int ssize, int page_size) { @@ -17,11 +18,14 @@ static void insert_slb_entry(unsigned long p, int ssize, int page_size) : "r" (mk_vsid_data(p, ssize, flags)), "r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED)) : "memory"); + isync(); asm volatile("slbmte %0,%1" : : "r" (mk_vsid_data(p, ssize, flags)), "r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED + 1)) : "memory"); + isync(); + preempt_enable(); } @@ -84,6 +88,7 @@ static void insert_dup_slb_entry_0(void) : "r" (vsid), "r" (esid | SLB_NUM_BOLTED) : "memory"); + isync(); asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); @@ -93,15 +98,42 @@ static void insert_dup_slb_entry_0(void) : "r" (vsid), "r" (esid | (SLB_NUM_BOLTED + 1)) : "memory"); + isync(); pr_info("%s accessing test address 0x%lx: 0x%lx\n", __func__, test_address, *test_ptr); preempt_enable(); } +#endif /* CONFIG_PPC_64S_HASH_MMU */ + +static __always_inline void tlbiel_va(unsigned long va, + unsigned long pid, + unsigned long ap, + unsigned long ric) +{ + unsigned long rb, rs, prs, r; + + rb = va & ~(PPC_BITMASK(52, 63)); + rb |= ap << PPC_BITLSHIFT(58); + rs = pid << PPC_BITLSHIFT(31); + + prs = 1; /* process scoped */ + r = 1; /* radix format */ + + /* + * Trigger an MCE by issuing radix tlbiel with an invalid operand combination. + * The combination of RIC = 2 with IS = 0 (Invalidation selector specified + * in the RB register) is invalid. + * This invalid combination causes hardware to raise a machine check. + */ + asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) + : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); +} static void lkdtm_PPC_SLB_MULTIHIT(void) { +#ifdef CONFIG_PPC_64S_HASH_MMU if (!radix_enabled()) { pr_info("Injecting SLB multihit errors\n"); /* @@ -117,10 +149,27 @@ static void lkdtm_PPC_SLB_MULTIHIT(void) } else { pr_err("XFAIL: This test is for ppc64 and with hash mode MMU only\n"); } +#else + pr_err("XFAIL: This test requires CONFIG_PPC_64S_HASH_MMU\n"); +#endif +} + +static void lkdtm_PPC_RADIX_TLBIEL(void) +{ + unsigned long addr = PAGE_OFFSET; + + if (radix_enabled()) { + pr_info("Injecting Radix TLB invalidation MCE\n"); + tlbiel_va(addr, 0, 0, RIC_FLUSH_ALL); + pr_info("Recovered from radix tlbiel attempt\n"); + } else { + pr_err("XFAIL: This test is for ppc64 and with radix mode MMU only\n"); + } } static struct crashtype crashtypes[] = { CRASHTYPE(PPC_SLB_MULTIHIT), + CRASHTYPE(PPC_RADIX_TLBIEL), }; struct crashtype_category powerpc_crashtypes = { |
