Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/ubsan-el2 into kvmarm-master/next

* kvm-arm64/ubsan-el2:
: .
: Add UBSAN support to the EL2 portion of KVM, reusing most of the
: existing logic provided by CONFIG_IBSAN_TRAP.
:
: Patches courtesy of Mostafa Saleh.
: .
KVM: arm64: Handle UBSAN faults
KVM: arm64: Introduce CONFIG_UBSAN_KVM_EL2
ubsan: Remove regs from report_ubsan_failure()
arm64: Introduce esr_is_ubsan_brk()

Signed-off-by: Marc Zyngier <maz@kernel.org>

+41 -10
+5
arch/arm64/include/asm/esr.h
··· 440 440 (esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE; 441 441 } 442 442 443 + static inline bool esr_is_ubsan_brk(unsigned long esr) 444 + { 445 + return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM; 446 + } 447 + 443 448 static inline bool esr_fsc_is_translation_fault(unsigned long esr) 444 449 { 445 450 esr = esr & ESR_ELx_FSC;
+2 -2
arch/arm64/kernel/traps.c
··· 1118 1118 #ifdef CONFIG_UBSAN_TRAP 1119 1119 static int ubsan_handler(struct pt_regs *regs, unsigned long esr) 1120 1120 { 1121 - die(report_ubsan_failure(regs, esr & UBSAN_BRK_MASK), regs, esr); 1121 + die(report_ubsan_failure(esr & UBSAN_BRK_MASK), regs, esr); 1122 1122 return DBG_HOOK_HANDLED; 1123 1123 } 1124 1124 ··· 1145 1145 return kasan_handler(regs, esr) != DBG_HOOK_HANDLED; 1146 1146 #endif 1147 1147 #ifdef CONFIG_UBSAN_TRAP 1148 - if ((esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM) 1148 + if (esr_is_ubsan_brk(esr)) 1149 1149 return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED; 1150 1150 #endif 1151 1151 return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
+6
arch/arm64/kvm/handle_exit.c
··· 10 10 11 11 #include <linux/kvm.h> 12 12 #include <linux/kvm_host.h> 13 + #include <linux/ubsan.h> 13 14 14 15 #include <asm/esr.h> 15 16 #include <asm/exception.h> ··· 475 474 print_nvhe_hyp_panic("BUG", panic_addr); 476 475 } else if (IS_ENABLED(CONFIG_CFI_CLANG) && esr_is_cfi_brk(esr)) { 477 476 kvm_nvhe_report_cfi_failure(panic_addr); 477 + } else if (IS_ENABLED(CONFIG_UBSAN_KVM_EL2) && 478 + ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && 479 + esr_is_ubsan_brk(esr)) { 480 + print_nvhe_hyp_panic(report_ubsan_failure(esr & UBSAN_BRK_MASK), 481 + panic_addr); 478 482 } else { 479 483 print_nvhe_hyp_panic("panic", panic_addr); 480 484 }
+6
arch/arm64/kvm/hyp/nvhe/Makefile
··· 99 99 # causes a build failure. Remove profile optimization flags. 100 100 KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%, $(KBUILD_CFLAGS)) 101 101 KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables 102 + 103 + ifeq ($(CONFIG_UBSAN_KVM_EL2),y) 104 + UBSAN_SANITIZE := y 105 + # Always use brk and not hooks 106 + ccflags-y += $(CFLAGS_UBSAN_TRAP) 107 + endif
+1 -1
arch/x86/kernel/traps.c
··· 351 351 case BUG_UD1_UBSAN: 352 352 if (IS_ENABLED(CONFIG_UBSAN_TRAP)) { 353 353 pr_crit("%s at %pS\n", 354 - report_ubsan_failure(regs, ud_imm), 354 + report_ubsan_failure(ud_imm), 355 355 (void *)regs->ip); 356 356 } 357 357 break;
+3 -3
include/linux/ubsan.h
··· 2 2 #ifndef _LINUX_UBSAN_H 3 3 #define _LINUX_UBSAN_H 4 4 5 - #ifdef CONFIG_UBSAN_TRAP 6 - const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type); 5 + #if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2) 6 + const char *report_ubsan_failure(u32 check_type); 7 7 #else 8 - static inline const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type) 8 + static inline const char *report_ubsan_failure(u32 check_type) 9 9 { 10 10 return NULL; 11 11 }
+9
lib/Kconfig.ubsan
··· 165 165 This is a test module for UBSAN. 166 166 It triggers various undefined behavior, and detect it. 167 167 168 + config UBSAN_KVM_EL2 169 + bool "UBSAN for KVM code at EL2" 170 + depends on ARM64 171 + help 172 + Enable UBSAN when running on ARM64 with KVM in a split mode 173 + (nvhe/hvhe/protected) for the hypervisor code running in EL2. 174 + In this mode, any UBSAN violation in EL2 would panic the kernel 175 + and information similar to UBSAN_TRAP would be printed. 176 + 168 177 endif # if UBSAN
+5 -3
lib/ubsan.c
··· 19 19 20 20 #include "ubsan.h" 21 21 22 - #ifdef CONFIG_UBSAN_TRAP 22 + #if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2) 23 23 /* 24 24 * Only include matches for UBSAN checks that are actually compiled in. 25 25 * The mappings of struct SanitizerKind (the -fsanitize=xxx args) to 26 26 * enum SanitizerHandler (the traps) in Clang is in clang/lib/CodeGen/. 27 27 */ 28 - const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type) 28 + const char *report_ubsan_failure(u32 check_type) 29 29 { 30 30 switch (check_type) { 31 31 #ifdef CONFIG_UBSAN_BOUNDS ··· 97 97 } 98 98 } 99 99 100 - #else 100 + #endif 101 + 102 + #ifndef CONFIG_UBSAN_TRAP 101 103 static const char * const type_check_kinds[] = { 102 104 "load of", 103 105 "store to",
+4 -1
scripts/Makefile.ubsan
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 + # Shared with KVM/arm64. 4 + export CFLAGS_UBSAN_TRAP := $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error) 5 + 3 6 # Enable available and selected UBSAN features. 4 7 ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT) += -fsanitize=alignment 5 8 ubsan-cflags-$(CONFIG_UBSAN_BOUNDS_STRICT) += -fsanitize=bounds-strict ··· 13 10 ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE) += -fsanitize=unreachable 14 11 ubsan-cflags-$(CONFIG_UBSAN_BOOL) += -fsanitize=bool 15 12 ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum 16 - ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error) 13 + ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(CFLAGS_UBSAN_TRAP) 17 14 18 15 export CFLAGS_UBSAN := $(ubsan-cflags-y) 19 16